00001 #include "oblasti.h"
00002 #include <iostream>
00003 #include <vector>
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 using namespace std;
00020
00021
00022 Oblasti::Oblasti(SpolecnaData & sd):
00023 sd (sd)
00024 {
00025 short mez;
00026 poplpr = new short [sd.ne];
00027 seplpr = new Plocha**[sd.ne];
00028 for (long i = 0; i < sd.ne; i++)
00029 {
00030
00031 sd.nnod[i] == KR_BODU ? mez = KR_POCET_PLOCH : mez = CT_POCET_PLOCH;
00032 poplpr[i] = mez;
00033 seplpr[i] = new Plocha*[mez];
00034 }
00035
00036 znamePlochy = SpolecnaData::poleShort(sd.ne, 0);
00037 }
00038
00039 Oblasti::~Oblasti()
00040 {
00041 for (long i = 0; i < sd.ne; i++)
00042 {
00043
00044 for (long j = 0; j < this->poplpr[i]; j++)
00045 delete seplpr[i][j];
00046
00047 delete [] seplpr[i];
00048 }
00049
00050 delete [] seplpr;
00051
00052 delete [] this->poplpr;
00053
00054 for(size_t i = 0; i < oblasti.size();i++)
00055 delete oblasti[i];
00056 delete [] znamePlochy;
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 void Oblasti::vyhledejOblasti()
00075 {
00076 const short FRESH = -1;
00077 const short OPEN = 0;
00078 const short CLOSE = 1;
00079 short * stav = SpolecnaData::poleShort(sd.ne, FRESH);
00080 stav[0] = OPEN;
00081 long openPrvek, topStack = 0;
00082 bool freshNalezen;
00083 Oblast * oblast = new Oblast(sd, poplpr, seplpr, znamePlochy);
00084 oblasti.push_back(oblast);
00085 oblasti[0]->vlozPrvek(0);
00086 while (true)
00087 {
00088 openPrvek = -1;
00089 freshNalezen = false;
00090 for (long i = 0; i < sd.nadjelel[topStack]; i++)
00091 {
00092 if (stav[ sd.adjelel[topStack][i] ] == FRESH)
00093 {
00094 stav[ sd.adjelel[topStack][i] ] = OPEN;
00095 topStack = sd.adjelel[topStack][i];
00096 oblasti[oblasti.size()-1]->vlozPrvek(sd.adjelel[topStack][i]);
00097 freshNalezen = true;
00098 break;
00099 }
00100 if ( stav[ sd.adjelel[topStack][i] ] == OPEN )
00101 openPrvek = sd.adjelel[topStack][i];
00102 }
00103
00104 if (freshNalezen)continue;
00105 if (openPrvek == -1)
00106 {
00107
00108 if (najdiFreshStart(&topStack,stav,FRESH,OPEN))
00109 {
00110 oblast = new Oblast(sd,poplpr,seplpr, znamePlochy);
00111 oblasti.push_back(oblast);
00112 oblasti[oblasti.size()-1]->vlozPrvek(topStack);
00113 continue;
00114 }
00115 break;
00116 }
00117 stav[topStack] = CLOSE;
00118 topStack = openPrvek;
00119 }
00120 delete [] stav;
00121 }
00122
00123
00124
00125 bool Oblasti::najdiFreshStart(long * topStack, short * stav, const short & FRESH, const short & OPEN)
00126 {
00127 for(long i = 0; i < sd.ne; i++)
00128 {
00129 if (stav[i] == FRESH)
00130 {
00131 stav[i] = OPEN;
00132 *topStack = i;
00133 return true;
00134 }
00135 }
00136 return false;
00137 }
00138
00139
00140
00141 void Oblasti::hledejStycnePlochy()
00142 {
00143 size_t i, k;
00144 set<MyPair, Less> nlist;
00145 vector<long> adjel;
00146 deque <double *> nvector;
00147 set<Plocha *, Comparator>::iterator it1;
00148 set<Plocha *, Comparator>::iterator it2;
00149
00150 Plocha * p1;
00151 Plocha * p2;
00152 FOR (k, oblasti.size()-1)
00153 {
00154 for (it1 = oblasti[k]->mp.begin();it1 != oblasti[k]->mp.end(); it1++)
00155 {
00156 p1 = *it1;
00157 if (p1->typ == STYCNA) continue;
00158 for (i = k+1; i < oblasti.size(); i++)
00159 {
00160 for (it2 = oblasti[i]->mp.begin();it2 != oblasti[i]->mp.end(); it2++)
00161 {
00162 p2 = *it2;
00163 if (p2->typ == STYCNA) continue;
00164 if (*p1 == *p2)
00165 {
00166 p1->typ = STYCNA;
00167 p2->typ = STYCNA;
00168 nlists.push_back(nlist);
00169 adjels.push_back(adjel);
00170 nvectors.push_back(nvector);
00171 projdiStycnouPlochu(p1,p2);
00172 }
00173 }
00174 }
00175 if (p1->typ == NEVI_SE)
00176 {
00177 p1->typ = VNEJSI;
00178 znamePlochy[p1->prvek]++;
00179 }
00180 }
00181 }
00182 }
00183
00184 void Oblasti::projdiStycnouPlochu(Plocha * p1, Plocha * p2)
00185 {
00186 short i, j;
00187 Plocha * soused1, * soused2;
00188 Plocha * tmp1, * tmp2;
00189 bool majiStycnou;
00190 this->route.clear();
00191 routeAdd(p1,p2);
00192 while(!route.empty())
00193 {
00194 p2 = *(this->route.end()-1);
00195 p1 = *(this->route.end()-2);
00196 majiStycnou = false;
00197 FOR(i,poplpr[p1->prvek])
00198 {
00199 tmp1 = seplpr[p1->prvek][i];
00200 if ( tmp1->typ != VNITRNI ) continue;
00201 soused1 = tmp1->sousedni[0];
00202 if ( znamePlochy[soused1->prvek] == poplpr[soused1->prvek] )
00203 {
00204 tmp1->typ = CLOSE;
00205 continue;
00206 }
00207 FOR(j,poplpr[p2->prvek])
00208 {
00209 tmp2 = seplpr[p2->prvek][j];
00210 if (tmp2->typ != VNITRNI)continue;
00211 soused2 = tmp2->sousedni[0];
00212 if ( znamePlochy[soused2->prvek] == poplpr[soused2->prvek] )
00213 {
00214 tmp2->typ = CLOSE;
00215 continue;
00216 }
00217 majiStycnou = stycnaPlocha(soused1, soused2);
00218 if (majiStycnou)
00219 {
00220 tmp1->typ = CLOSE;
00221 tmp2->typ = CLOSE;
00222 soused1->typ = CLOSE;
00223 soused2->typ = CLOSE;
00224 break;
00225 }
00226 }
00227 if (majiStycnou) break;
00228 }
00229 if (majiStycnou) continue;
00230 route.pop_back();
00231 route.pop_back();
00232 }
00233 }
00234
00235
00236
00237 bool Oblasti::stycnaPlocha(Plocha * soused1, Plocha * soused2)
00238 {
00239 short i, j;
00240 FOR(i,poplpr[soused1->prvek])
00241 {
00242 soused1 = seplpr[soused1->prvek][i];
00243 if ( soused1->typ != NEVI_SE ) continue;
00244 FOR(j,poplpr[soused1->prvek])
00245 {
00246 soused2 = seplpr[soused2->prvek][j];
00247 if ( soused2->typ != NEVI_SE ) continue;
00248 if ( *soused1 != *soused2 ) continue;
00249 soused1->typ = STYCNA;
00250 soused2->typ = STYCNA;
00251 routeAdd(soused1,soused2);
00252 if (soused1->pbp == soused2->pbp)return true;
00253 if (soused1->pbp < soused2->pbp) ctyrstenKrychle(soused1, soused2);
00254 ctyrstenKrychle(soused2, soused1);
00255 return true;
00256 }
00257 }
00258 return false;
00259 }
00260
00261 void Oblasti::ctyrstenKrychle (Plocha * triangle, Plocha * rect)
00262 {
00263 short i, j;
00264 Plocha * soused;
00265 FOR(i,poplpr[triangle->prvek])
00266 {
00267 if (seplpr[triangle->prvek][i]->typ != VNITRNI) continue;
00268 soused = triangle->sousedni[0];
00269 if (triangle->pbp != soused->pbp)continue;
00270 if ( znamePlochy[soused->prvek] == poplpr[soused->prvek] )
00271 {
00272 seplpr[triangle->prvek][i]->typ = CLOSE;
00273 continue;
00274 }
00275 FOR(j,poplpr[soused->prvek])
00276 {
00277 soused = seplpr[soused->prvek][j];
00278 if ( soused->typ != NEVI_SE ) continue;
00279 if ( *soused != *rect ) continue;
00280 soused->typ = STYCNA;
00281 routeAdd(rect,soused);
00282 return;
00283 }
00284 }
00285 }
00286
00287
00288 void Oblasti::ulozStycneBodyAPrvky(Plocha *p1, Plocha *p2)
00289 {
00290 MyPair mp;
00291 for( short i = 0; i < KR_PLOCHA_BODU; i++)
00292 if (Plocha::shoda[i] > -1)
00293 {
00294 mp.node1 = p1->bodyp[i];
00295 mp.node2 = p2->bodyp[ Plocha::shoda[i] ];
00296
00297 if (nlists[nlists.size()-1].find(mp) == nlists[nlists.size()-1].end())
00298 nlists[nlists.size()-1].insert(mp);
00299 }
00300 adjels[adjels.size()-1].push_back(p1->prvek);
00301 adjels[adjels.size()-1].push_back(p2->prvek);
00302
00303 }
00304
00305
00306 void Oblasti::routeAdd(Plocha *p1, Plocha *p2)
00307 {
00308 this->route.push_back(p1);
00309 this->route.push_back(p2);
00310 ulozStycneBodyAPrvky(p1,p2);
00311 normalovyVektor(p1);
00312 }
00313
00314
00315 void Oblasti::normalovyVektor(Plocha *p)
00316 {
00317 short i;
00318 double u[3];
00319 double v[3];
00320 double * nv = new double[3];
00321 FOR(i,3)u[i]= sd.xyz[p->bodyp[2]][i] - sd.xyz[p->bodyp[0]][i];
00322 FOR(i,3)v[i]= sd.xyz[p->bodyp[2]][i] - sd.xyz[p->bodyp[1]][i];
00323 nv[0]= u[1] * v[2] - v[1] * u[2];
00324 nv[1]= u[2] * v[0] - v[2] * u[0];
00325 nv[2]= u[0] * v[1] - v[0] * u[1];
00326 if(!nvectors[nvectors.size()-1].size())
00327 {
00328 nvectors[nvectors.size()-1].push_back(nv);
00329 return;
00330 }
00331
00332 double * nvlast = *(nvectors[nvectors.size()-1].end()-1);
00333 u[0] = 0;
00334 FOR(i,3)u[0]+= nv[i] * nvlast[i];
00335 if (u[0] < 0)FOR(i,3)nv[i] *= -1;
00336 (*(nvectors.end()-1)).push_back(nv);
00337 }
00338