Changes in src/tesselation.cpp [b8d4a3:68f03d]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/tesselation.cpp
rb8d4a3 r68f03d 7 7 8 8 #include <fstream> 9 #include <assert.h> 9 10 10 11 #include "helpers.hpp" … … 14 15 #include "tesselation.hpp" 15 16 #include "tesselationhelpers.hpp" 17 #include "triangleintersectionlist.hpp" 16 18 #include "vector.hpp" 19 #include "vector_ops.hpp" 17 20 #include "verbose.hpp" 21 #include "Plane.hpp" 22 #include "Exceptions/LinearDependenceException.hpp" 18 23 19 24 class molecule; … … 24 29 */ 25 30 BoundaryPointSet::BoundaryPointSet() : 26 LinesCount(0), 27 value(0.), 28 Nr(-1) 29 { 30 Info FunctionInfo(__func__); 31 Log() << Verbose(1) << "Adding noname." << endl; 32 }; 31 LinesCount(0), value(0.), Nr(-1) 32 { 33 Info FunctionInfo(__func__); 34 DoLog(1) && (Log() << Verbose(1) << "Adding noname." << endl); 35 } 36 ; 33 37 34 38 /** Constructor of BoundaryPointSet with Tesselpoint. … … 36 40 */ 37 41 BoundaryPointSet::BoundaryPointSet(TesselPoint * const Walker) : 38 LinesCount(0), 39 node(Walker), 40 value(0.), 41 Nr(Walker->nr) 42 { 43 Info FunctionInfo(__func__); 44 Log() << Verbose(1) << "Adding Node " << *Walker << endl; 45 }; 42 LinesCount(0), node(Walker), value(0.), Nr(Walker->nr) 43 { 44 Info FunctionInfo(__func__); 45 DoLog(1) && (Log() << Verbose(1) << "Adding Node " << *Walker << endl); 46 } 47 ; 46 48 47 49 /** Destructor of BoundaryPointSet. … … 51 53 BoundaryPointSet::~BoundaryPointSet() 52 54 { 53 55 Info FunctionInfo(__func__); 54 56 //Log() << Verbose(0) << "Erasing point nr. " << Nr << "." << endl; 55 57 if (!lines.empty()) 56 eLog() << Verbose(2) << "Memory Leak! I " << *this << " am still connected to some lines." << endl;58 DoeLog(2) && (eLog() << Verbose(2) << "Memory Leak! I " << *this << " am still connected to some lines." << endl); 57 59 node = NULL; 58 }; 60 } 61 ; 59 62 60 63 /** Add a line to the LineMap of this point. … … 63 66 void BoundaryPointSet::AddLine(BoundaryLineSet * const line) 64 67 { 65 Info FunctionInfo(__func__); 66 Log() << Verbose(1) << "Adding " << *this << " to line " << *line << "." 67 << endl; 68 if (line->endpoints[0] == this) 69 { 70 lines.insert(LinePair(line->endpoints[1]->Nr, line)); 71 } 72 else 73 { 74 lines.insert(LinePair(line->endpoints[0]->Nr, line)); 75 } 68 Info FunctionInfo(__func__); 69 DoLog(1) && (Log() << Verbose(1) << "Adding " << *this << " to line " << *line << "." << endl); 70 if (line->endpoints[0] == this) { 71 lines.insert(LinePair(line->endpoints[1]->Nr, line)); 72 } else { 73 lines.insert(LinePair(line->endpoints[0]->Nr, line)); 74 } 76 75 LinesCount++; 77 }; 76 } 77 ; 78 78 79 79 /** output operator for BoundaryPointSet. … … 83 83 ostream & operator <<(ostream &ost, const BoundaryPointSet &a) 84 84 { 85 ost << "[" << a.Nr << "|" << a.node-> Name<< " at " << *a.node->node << "]";85 ost << "[" << a.Nr << "|" << a.node->getName() << " at " << *a.node->node << "]"; 86 86 return ost; 87 87 } … … 93 93 */ 94 94 BoundaryLineSet::BoundaryLineSet() : 95 96 { 97 95 Nr(-1) 96 { 97 Info FunctionInfo(__func__); 98 98 for (int i = 0; i < 2; i++) 99 99 endpoints[i] = NULL; 100 }; 100 } 101 ; 101 102 102 103 /** Constructor of BoundaryLineSet with two endpoints. … … 107 108 BoundaryLineSet::BoundaryLineSet(BoundaryPointSet * const Point[2], const int number) 108 109 { 109 110 Info FunctionInfo(__func__); 110 111 // set number 111 112 Nr = number; … … 118 119 skipped = false; 119 120 // clear triangles list 120 Log() << Verbose(0) << "New Line with endpoints " << *this << "." << endl; 121 }; 121 DoLog(0) && (Log() << Verbose(0) << "New Line with endpoints " << *this << "." << endl); 122 } 123 ; 122 124 123 125 /** Constructor of BoundaryLineSet with two endpoints. … … 140 142 skipped = false; 141 143 // clear triangles list 142 Log() << Verbose(0) << "New Line with endpoints " << *this << "." << endl; 143 }; 144 DoLog(0) && (Log() << Verbose(0) << "New Line with endpoints " << *this << "." << endl); 145 } 146 ; 144 147 145 148 /** Destructor for BoundaryLineSet. … … 149 152 BoundaryLineSet::~BoundaryLineSet() 150 153 { 151 154 Info FunctionInfo(__func__); 152 155 int Numbers[2]; 153 156 … … 180 183 //Log() << Verbose(0) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl; 181 184 if (endpoints[i] != NULL) { 182 delete (endpoints[i]);185 delete (endpoints[i]); 183 186 endpoints[i] = NULL; 184 187 } … … 187 190 } 188 191 if (!triangles.empty()) 189 eLog() << Verbose(2) << "Memory Leak! I " << *this << " am still connected to some triangles." << endl; 190 }; 192 DoeLog(2) && (eLog() << Verbose(2) << "Memory Leak! I " << *this << " am still connected to some triangles." << endl); 193 } 194 ; 191 195 192 196 /** Add triangle to TriangleMap of this boundary line. … … 195 199 void BoundaryLineSet::AddTriangle(BoundaryTriangleSet * const triangle) 196 200 { 197 198 Log() << Verbose(0) << "Add " << triangle->Nr << " to line " << *this << "." << endl;201 Info FunctionInfo(__func__); 202 DoLog(0) && (Log() << Verbose(0) << "Add " << triangle->Nr << " to line " << *this << "." << endl); 199 203 triangles.insert(TrianglePair(triangle->Nr, triangle)); 200 }; 204 } 205 ; 201 206 202 207 /** Checks whether we have a common endpoint with given \a *line. … … 206 211 bool BoundaryLineSet::IsConnectedTo(const BoundaryLineSet * const line) const 207 212 { 208 213 Info FunctionInfo(__func__); 209 214 if ((endpoints[0] == line->endpoints[0]) || (endpoints[1] == line->endpoints[0]) || (endpoints[0] == line->endpoints[1]) || (endpoints[1] == line->endpoints[1])) 210 215 return true; 211 216 else 212 217 return false; 213 }; 218 } 219 ; 214 220 215 221 /** Checks whether the adjacent triangles of a baseline are convex or not. … … 221 227 bool BoundaryLineSet::CheckConvexityCriterion() const 222 228 { 223 229 Info FunctionInfo(__func__); 224 230 Vector BaseLineCenter, BaseLineNormal, BaseLine, helper[2], NormalCheck; 225 231 // get the two triangles 226 232 if (triangles.size() != 2) { 227 eLog() << Verbose(0) << "Baseline " << *this << " is connected to less than two triangles, Tesselation incomplete!" << endl;233 DoeLog(0) && (eLog() << Verbose(0) << "Baseline " << *this << " is connected to less than two triangles, Tesselation incomplete!" << endl); 228 234 return true; 229 235 } … … 231 237 // have a normal vector on the base line pointing outwards 232 238 //Log() << Verbose(0) << "INFO: " << *this << " has vectors at " << *(endpoints[0]->node->node) << " and at " << *(endpoints[1]->node->node) << "." << endl; 233 BaseLineCenter.CopyVector(endpoints[0]->node->node); 234 BaseLineCenter.AddVector(endpoints[1]->node->node); 235 BaseLineCenter.Scale(1./2.); 236 BaseLine.CopyVector(endpoints[0]->node->node); 237 BaseLine.SubtractVector(endpoints[1]->node->node); 239 BaseLineCenter = (1./2.)*((*endpoints[0]->node->node) + (*endpoints[1]->node->node)); 240 BaseLine = (*endpoints[0]->node->node) - (*endpoints[1]->node->node); 241 238 242 //Log() << Verbose(0) << "INFO: Baseline is " << BaseLine << " and its center is at " << BaseLineCenter << "." << endl; 239 243 … … 241 245 NormalCheck.Zero(); 242 246 double sign = -1.; 243 int i =0;247 int i = 0; 244 248 class BoundaryPointSet *node = NULL; 245 for (TriangleMap::const_iterator runner = triangles.begin(); runner != triangles.end(); runner++) {249 for (TriangleMap::const_iterator runner = triangles.begin(); runner != triangles.end(); runner++) { 246 250 //Log() << Verbose(0) << "INFO: NormalVector of " << *(runner->second) << " is " << runner->second->NormalVector << "." << endl; 247 NormalCheck .AddVector(&runner->second->NormalVector);248 NormalCheck .Scale(sign);251 NormalCheck += runner->second->NormalVector; 252 NormalCheck *= sign; 249 253 sign = -sign; 250 254 if (runner->second->NormalVector.NormSquared() > MYEPSILON) 251 BaseLineNormal .CopyVector(&runner->second->NormalVector); // yes, copy second on top of first255 BaseLineNormal = runner->second->NormalVector; // yes, copy second on top of first 252 256 else { 253 eLog() << Verbose(0) << "Triangle " << *runner->second << " has zero normal vector!" << endl;257 DoeLog(0) && (eLog() << Verbose(0) << "Triangle " << *runner->second << " has zero normal vector!" << endl); 254 258 } 255 259 node = runner->second->GetThirdEndpoint(this); 256 260 if (node != NULL) { 257 261 //Log() << Verbose(0) << "INFO: Third node for triangle " << *(runner->second) << " is " << *node << " at " << *(node->node->node) << "." << endl; 258 helper[i].CopyVector(node->node->node); 259 helper[i].SubtractVector(&BaseLineCenter); 260 helper[i].MakeNormalVector(&BaseLine); // we want to compare the triangle's heights' angles! 262 helper[i] = (*node->node->node) - BaseLineCenter; 263 helper[i].MakeNormalTo(BaseLine); // we want to compare the triangle's heights' angles! 261 264 //Log() << Verbose(0) << "INFO: Height vector with respect to baseline is " << helper[i] << "." << endl; 262 265 i++; 263 266 } else { 264 eLog() << Verbose(1) << "I cannot find third node in triangle, something's wrong." << endl;267 DoeLog(1) && (eLog() << Verbose(1) << "I cannot find third node in triangle, something's wrong." << endl); 265 268 return true; 266 269 } … … 268 271 //Log() << Verbose(0) << "INFO: BaselineNormal is " << BaseLineNormal << "." << endl; 269 272 if (NormalCheck.NormSquared() < MYEPSILON) { 270 Log() << Verbose(0) << "ACCEPT: Normalvectors of both triangles are the same: convex." << endl;273 DoLog(0) && (Log() << Verbose(0) << "ACCEPT: Normalvectors of both triangles are the same: convex." << endl); 271 274 return true; 272 275 } … … 274 277 double angle = GetAngle(helper[0], helper[1], BaseLineNormal); 275 278 if ((angle - M_PI) > -MYEPSILON) { 276 Log() << Verbose(0) << "ACCEPT: Angle is greater than pi: convex." << endl;279 DoLog(0) && (Log() << Verbose(0) << "ACCEPT: Angle is greater than pi: convex." << endl); 277 280 return true; 278 281 } else { 279 Log() << Verbose(0) << "REJECT: Angle is less than pi: concave." << endl;282 DoLog(0) && (Log() << Verbose(0) << "REJECT: Angle is less than pi: concave." << endl); 280 283 return false; 281 284 } … … 288 291 bool BoundaryLineSet::ContainsBoundaryPoint(const BoundaryPointSet * const point) const 289 292 { 290 291 for (int i=0;i<2;i++)293 Info FunctionInfo(__func__); 294 for (int i = 0; i < 2; i++) 292 295 if (point == endpoints[i]) 293 296 return true; 294 297 return false; 295 }; 298 } 299 ; 296 300 297 301 /** Returns other endpoint of the line. … … 301 305 class BoundaryPointSet *BoundaryLineSet::GetOtherEndpoint(const BoundaryPointSet * const point) const 302 306 { 303 307 Info FunctionInfo(__func__); 304 308 if (endpoints[0] == point) 305 309 return endpoints[1]; … … 308 312 else 309 313 return NULL; 310 }; 314 } 315 ; 311 316 312 317 /** output operator for BoundaryLineSet. … … 314 319 * \param &a boundary line 315 320 */ 316 ostream & operator <<(ostream &ost, const 317 { 318 ost << "[" << a.Nr << "|" << a.endpoints[0]->node-> Name << " at " << *a.endpoints[0]->node->node << "," << a.endpoints[1]->node->Name<< " at " << *a.endpoints[1]->node->node << "]";321 ostream & operator <<(ostream &ost, const BoundaryLineSet &a) 322 { 323 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->getName() << " at " << *a.endpoints[0]->node->node << "," << a.endpoints[1]->node->getName() << " at " << *a.endpoints[1]->node->node << "]"; 319 324 return ost; 320 }; 325 } 326 ; 321 327 322 328 // ======================================== Triangles on Boundary ================================= … … 327 333 Nr(-1) 328 334 { 329 330 for (int i = 0; i < 3; i++) 331 {332 endpoints[i] = NULL;333 lines[i] = NULL;334 335 };335 Info FunctionInfo(__func__); 336 for (int i = 0; i < 3; i++) { 337 endpoints[i] = NULL; 338 lines[i] = NULL; 339 } 340 } 341 ; 336 342 337 343 /** Constructor for BoundaryTriangleSet with three lines. … … 342 348 Nr(number) 343 349 { 344 350 Info FunctionInfo(__func__); 345 351 // set number 346 352 // set lines … … 354 360 // for all three lines 355 361 for (int j = 0; j < 2; j++) { // for both endpoints 356 OrderMap.insert(pair<int, class BoundaryPointSet *> ( 357 line[i]->endpoints[j]->Nr, line[i]->endpoints[j])); 362 OrderMap.insert(pair<int, class BoundaryPointSet *> (line[i]->endpoints[j]->Nr, line[i]->endpoints[j])); 358 363 // and we don't care whether insertion fails 359 364 } 360 365 // set endpoints 361 366 int Counter = 0; 362 Log() << Verbose(0) << "New triangle " << Nr << " with end points: " << endl;367 DoLog(0) && (Log() << Verbose(0) << "New triangle " << Nr << " with end points: " << endl); 363 368 for (PointMap::iterator runner = OrderMap.begin(); runner != OrderMap.end(); runner++) { 364 369 endpoints[Counter] = runner->second; 365 Log() << Verbose(0) << " " << *endpoints[Counter] << endl;370 DoLog(0) && (Log() << Verbose(0) << " " << *endpoints[Counter] << endl); 366 371 Counter++; 367 372 } 368 373 if (Counter < 3) { 369 eLog() << Verbose(0) << "We have a triangle with only two distinct endpoints!" << endl;374 DoeLog(0) && (eLog() << Verbose(0) << "We have a triangle with only two distinct endpoints!" << endl); 370 375 performCriticalExit(); 371 376 } 372 }; 377 } 378 ; 373 379 374 380 /** Destructor of BoundaryTriangleSet. … … 378 384 BoundaryTriangleSet::~BoundaryTriangleSet() 379 385 { 380 386 Info FunctionInfo(__func__); 381 387 for (int i = 0; i < 3; i++) { 382 388 if (lines[i] != NULL) { … … 385 391 } 386 392 if (lines[i]->triangles.empty()) { 387 388 389 393 //Log() << Verbose(0) << *lines[i] << " is no more attached to any triangle, erasing." << endl; 394 delete (lines[i]); 395 lines[i] = NULL; 390 396 } 391 397 } 392 398 } 393 399 //Log() << Verbose(0) << "Erasing triangle Nr." << Nr << " itself." << endl; 394 }; 400 } 401 ; 395 402 396 403 /** Calculates the normal vector for this triangle. … … 400 407 void BoundaryTriangleSet::GetNormalVector(const Vector &OtherVector) 401 408 { 402 409 Info FunctionInfo(__func__); 403 410 // get normal vector 404 NormalVector.MakeNormalVector(endpoints[0]->node->node, endpoints[1]->node->node, endpoints[2]->node->node); 411 NormalVector = Plane(*(endpoints[0]->node->node), 412 *(endpoints[1]->node->node), 413 *(endpoints[2]->node->node)).getNormal(); 405 414 406 415 // make it always point inward (any offset vector onto plane projected onto normal vector suffices) 407 if (NormalVector.ScalarProduct( &OtherVector) > 0.)416 if (NormalVector.ScalarProduct(OtherVector) > 0.) 408 417 NormalVector.Scale(-1.); 409 Log() << Verbose(1) << "Normal Vector is " << NormalVector << "." << endl; 410 }; 418 DoLog(1) && (Log() << Verbose(1) << "Normal Vector is " << NormalVector << "." << endl); 419 } 420 ; 411 421 412 422 /** Finds the point on the triangle \a *BTS through which the line defined by \a *MolCenter and \a *x crosses. … … 422 432 * \return true - \a *Intersection contains intersection on plane defined by triangle, false - zero vector if outside of triangle. 423 433 */ 434 424 435 bool BoundaryTriangleSet::GetIntersectionInsideTriangle(const Vector * const MolCenter, const Vector * const x, Vector * const Intersection) const 425 436 { … … 428 439 Vector helper; 429 440 430 if (!Intersection->GetIntersectionWithPlane(&NormalVector, endpoints[0]->node->node, MolCenter, x)) { 431 eLog() << Verbose(1) << "Alas! Intersection with plane failed - at least numerically - the intersection is not on the plane!" << endl; 441 try { 442 *Intersection = Plane(NormalVector, *(endpoints[0]->node->node)).GetIntersection(*MolCenter, *x); 443 } 444 catch (LinearDependenceException &excp) { 445 Log() << Verbose(1) << excp; 446 DoeLog(1) && (eLog() << Verbose(1) << "Alas! Intersection with plane failed - at least numerically - the intersection is not on the plane!" << endl); 432 447 return false; 433 448 } 434 449 435 Log() << Verbose(1) << "INFO: Triangle is " << *this << "." << endl;436 Log() << Verbose(1) << "INFO: Line is from " << *MolCenter << " to " << *x << "." << endl;437 Log() << Verbose(1) << "INFO: Intersection is " << *Intersection << "." << endl;438 439 if (Intersection->DistanceSquared( endpoints[0]->node->node) < MYEPSILON) {440 Log() << Verbose(1) << "Intersection coindices with first endpoint." << endl;450 DoLog(1) && (Log() << Verbose(1) << "INFO: Triangle is " << *this << "." << endl); 451 DoLog(1) && (Log() << Verbose(1) << "INFO: Line is from " << *MolCenter << " to " << *x << "." << endl); 452 DoLog(1) && (Log() << Verbose(1) << "INFO: Intersection is " << *Intersection << "." << endl); 453 454 if (Intersection->DistanceSquared(*endpoints[0]->node->node) < MYEPSILON) { 455 DoLog(1) && (Log() << Verbose(1) << "Intersection coindices with first endpoint." << endl); 441 456 return true; 442 } else if (Intersection->DistanceSquared( endpoints[1]->node->node) < MYEPSILON) {443 Log() << Verbose(1) << "Intersection coindices with second endpoint." << endl;457 } else if (Intersection->DistanceSquared(*endpoints[1]->node->node) < MYEPSILON) { 458 DoLog(1) && (Log() << Verbose(1) << "Intersection coindices with second endpoint." << endl); 444 459 return true; 445 } else if (Intersection->DistanceSquared( endpoints[2]->node->node) < MYEPSILON) {446 Log() << Verbose(1) << "Intersection coindices with third endpoint." << endl;460 } else if (Intersection->DistanceSquared(*endpoints[2]->node->node) < MYEPSILON) { 461 DoLog(1) && (Log() << Verbose(1) << "Intersection coindices with third endpoint." << endl); 447 462 return true; 448 463 } 449 464 // Calculate cross point between one baseline and the line from the third endpoint to intersection 450 int i =0;465 int i = 0; 451 466 do { 452 if (CrossPoint.GetIntersectionOfTwoLinesOnPlane(endpoints[i%3]->node->node, endpoints[(i+1)%3]->node->node, endpoints[(i+2)%3]->node->node, Intersection, &NormalVector)) { 453 helper.CopyVector(endpoints[(i+1)%3]->node->node); 454 helper.SubtractVector(endpoints[i%3]->node->node); 455 CrossPoint.SubtractVector(endpoints[i%3]->node->node); // cross point was returned as absolute vector 456 const double s = CrossPoint.ScalarProduct(&helper)/helper.NormSquared(); 457 Log() << Verbose(1) << "INFO: Factor s is " << s << "." << endl; 467 try { 468 CrossPoint = GetIntersectionOfTwoLinesOnPlane(*(endpoints[i%3]->node->node), 469 *(endpoints[(i+1)%3]->node->node), 470 *(endpoints[(i+2)%3]->node->node), 471 *Intersection); 472 helper = (*endpoints[(i+1)%3]->node->node) - (*endpoints[i%3]->node->node); 473 CrossPoint -= (*endpoints[i%3]->node->node); // cross point was returned as absolute vector 474 const double s = CrossPoint.ScalarProduct(helper)/helper.NormSquared(); 475 DoLog(1) && (Log() << Verbose(1) << "INFO: Factor s is " << s << "." << endl); 458 476 if ((s < -MYEPSILON) || ((s-1.) > MYEPSILON)) { 459 Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << "outside of triangle." << endl;477 DoLog(1) && (Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << "outside of triangle." << endl); 460 478 i=4; 461 479 break; 462 480 } 463 481 i++; 464 } else482 } catch (LinearDependenceException &excp){ 465 483 break; 466 } while (i<3); 467 if (i==3) { 468 Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << " inside of triangle." << endl; 484 } 485 } while (i < 3); 486 if (i == 3) { 487 DoLog(1) && (Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << " inside of triangle." << endl); 469 488 return true; 470 489 } else { 471 Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << " outside of triangle." << endl;490 DoLog(1) && (Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << " outside of triangle." << endl); 472 491 return false; 473 492 } 474 }; 475 476 /** Finds the point on the triangle \a *BTS through which the line defined by \a *MolCenter and \a *x crosses. 477 * We call Vector::GetIntersectionWithPlane() to receive the intersection point with the plane 493 } 494 ; 495 496 /** Finds the point on the triangle to the point \a *x. 497 * We call Vector::GetIntersectionWithPlane() with \a * and the center of the triangle to receive an intersection point. 498 * Then we check the in-plane part (the part projected down onto plane). We check whether it crosses one of the 499 * boundary lines. If it does, we return this intersection as closest point, otherwise the projected point down. 478 500 * Thus we test if it's really on the plane and whether it's inside the triangle on the plane or not. 479 501 * The latter is done as follows: We calculate the cross point of one of the triangle's baseline with the line … … 490 512 491 513 // 1. get intersection with plane 492 Log() << Verbose(1) << "INFO: Looking for closest point of triangle " << *this << " to " << *x << "." << endl;514 DoLog(1) && (Log() << Verbose(1) << "INFO: Looking for closest point of triangle " << *this << " to " << *x << "." << endl); 493 515 GetCenter(&Direction); 494 if (!ClosestPoint->GetIntersectionWithPlane(&NormalVector, endpoints[0]->node->node, x, &Direction)) { 495 ClosestPoint->CopyVector(x); 516 try { 517 *ClosestPoint = Plane(NormalVector, *(endpoints[0]->node->node)).GetIntersection(*x, Direction); 518 } 519 catch (LinearDependenceException &excp) { 520 (*ClosestPoint) = (*x); 496 521 } 497 522 498 523 // 2. Calculate in plane part of line (x, intersection) 499 Vector InPlane; 500 InPlane.CopyVector(x); 501 InPlane.SubtractVector(ClosestPoint); // points from plane intersection to straight-down point 502 InPlane.ProjectOntoPlane(&NormalVector); 503 InPlane.AddVector(ClosestPoint); 504 505 Log() << Verbose(2) << "INFO: Triangle is " << *this << "." << endl; 506 Log() << Verbose(2) << "INFO: Line is from " << Direction << " to " << *x << "." << endl; 507 Log() << Verbose(2) << "INFO: In-plane part is " << InPlane << "." << endl; 524 Vector InPlane = (*x) - (*ClosestPoint); // points from plane intersection to straight-down point 525 InPlane.ProjectOntoPlane(NormalVector); 526 InPlane += *ClosestPoint; 527 528 DoLog(2) && (Log() << Verbose(2) << "INFO: Triangle is " << *this << "." << endl); 529 DoLog(2) && (Log() << Verbose(2) << "INFO: Line is from " << Direction << " to " << *x << "." << endl); 530 DoLog(2) && (Log() << Verbose(2) << "INFO: In-plane part is " << InPlane << "." << endl); 508 531 509 532 // Calculate cross point between one baseline and the desired point such that distance is shortest … … 513 536 Vector CrossPoint[3]; 514 537 Vector helper; 515 for (int i =0;i<3;i++) {538 for (int i = 0; i < 3; i++) { 516 539 // treat direction of line as normal of a (cut)plane and the desired point x as the plane offset, the intersect line with point 517 Direction.CopyVector(endpoints[(i+1)%3]->node->node); 518 Direction.SubtractVector(endpoints[i%3]->node->node); 540 Direction = (*endpoints[(i+1)%3]->node->node) - (*endpoints[i%3]->node->node); 519 541 // calculate intersection, line can never be parallel to Direction (is the same vector as PlaneNormal); 520 CrossPoint[i].GetIntersectionWithPlane(&Direction, &InPlane, endpoints[i%3]->node->node, endpoints[(i+1)%3]->node->node); 521 CrossDirection[i].CopyVector(&CrossPoint[i]); 522 CrossDirection[i].SubtractVector(&InPlane); 523 CrossPoint[i].SubtractVector(endpoints[i%3]->node->node); // cross point was returned as absolute vector 524 const double s = CrossPoint[i].ScalarProduct(&Direction)/Direction.NormSquared(); 525 Log() << Verbose(2) << "INFO: Factor s is " << s << "." << endl; 542 CrossPoint[i] = Plane(Direction, InPlane).GetIntersection(*(endpoints[i%3]->node->node), *(endpoints[(i+1)%3]->node->node)); 543 CrossDirection[i] = CrossPoint[i] - InPlane; 544 CrossPoint[i] -= (*endpoints[i%3]->node->node); // cross point was returned as absolute vector 545 const double s = CrossPoint[i].ScalarProduct(Direction)/Direction.NormSquared(); 546 DoLog(2) && (Log() << Verbose(2) << "INFO: Factor s is " << s << "." << endl); 526 547 if ((s >= -MYEPSILON) && ((s-1.) <= MYEPSILON)) { 527 CrossPoint[i].AddVector(endpoints[i%3]->node->node); // make cross point absolute again528 Log() << Verbose(2) << "INFO: Crosspoint is " << CrossPoint[i] << ", intersecting BoundaryLine between " << *endpoints[i%3]->node->node << " and " << *endpoints[(i+1)%3]->node->node << "." << endl;529 const double distance = CrossPoint[i].DistanceSquared( x);548 CrossPoint[i] += (*endpoints[i%3]->node->node); // make cross point absolute again 549 DoLog(2) && (Log() << Verbose(2) << "INFO: Crosspoint is " << CrossPoint[i] << ", intersecting BoundaryLine between " << *endpoints[i % 3]->node->node << " and " << *endpoints[(i + 1) % 3]->node->node << "." << endl); 550 const double distance = CrossPoint[i].DistanceSquared(*x); 530 551 if ((ShortestDistance < 0.) || (ShortestDistance > distance)) { 531 552 ShortestDistance = distance; 532 ClosestPoint->CopyVector(&CrossPoint[i]);553 (*ClosestPoint) = CrossPoint[i]; 533 554 } 534 555 } else … … 536 557 } 537 558 InsideFlag = true; 538 for (int i=0;i<3;i++) { 539 const double sign = CrossDirection[i].ScalarProduct(&CrossDirection[(i+1)%3]); 540 const double othersign = CrossDirection[i].ScalarProduct(&CrossDirection[(i+2)%3]);; 541 if ((sign > -MYEPSILON) && (othersign > -MYEPSILON)) // have different sign 559 for (int i = 0; i < 3; i++) { 560 const double sign = CrossDirection[i].ScalarProduct(CrossDirection[(i + 1) % 3]); 561 const double othersign = CrossDirection[i].ScalarProduct(CrossDirection[(i + 2) % 3]); 562 563 if ((sign > -MYEPSILON) && (othersign > -MYEPSILON)) // have different sign 542 564 InsideFlag = false; 543 565 } 544 566 if (InsideFlag) { 545 ClosestPoint->CopyVector(&InPlane);546 ShortestDistance = InPlane.DistanceSquared( x);547 } else { 548 for (int i =0;i<3;i++) {549 const double distance = x->DistanceSquared( endpoints[i]->node->node);567 (*ClosestPoint) = InPlane; 568 ShortestDistance = InPlane.DistanceSquared(*x); 569 } else { // also check endnodes 570 for (int i = 0; i < 3; i++) { 571 const double distance = x->DistanceSquared(*endpoints[i]->node->node); 550 572 if ((ShortestDistance < 0.) || (ShortestDistance > distance)) { 551 573 ShortestDistance = distance; 552 ClosestPoint->CopyVector(endpoints[i]->node->node);574 (*ClosestPoint) = (*endpoints[i]->node->node); 553 575 } 554 576 } 555 577 } 556 Log() << Verbose(1) << "INFO: Closest Point is " << *ClosestPoint << " with shortest squared distance is " << ShortestDistance << "." << endl;578 DoLog(1) && (Log() << Verbose(1) << "INFO: Closest Point is " << *ClosestPoint << " with shortest squared distance is " << ShortestDistance << "." << endl); 557 579 return ShortestDistance; 558 }; 580 } 581 ; 559 582 560 583 /** Checks whether lines is any of the three boundary lines this triangle contains. … … 564 587 bool BoundaryTriangleSet::ContainsBoundaryLine(const BoundaryLineSet * const line) const 565 588 { 566 567 for (int i=0;i<3;i++)589 Info FunctionInfo(__func__); 590 for (int i = 0; i < 3; i++) 568 591 if (line == lines[i]) 569 592 return true; 570 593 return false; 571 }; 594 } 595 ; 572 596 573 597 /** Checks whether point is any of the three endpoints this triangle contains. … … 577 601 bool BoundaryTriangleSet::ContainsBoundaryPoint(const BoundaryPointSet * const point) const 578 602 { 579 580 for (int i=0;i<3;i++)603 Info FunctionInfo(__func__); 604 for (int i = 0; i < 3; i++) 581 605 if (point == endpoints[i]) 582 606 return true; 583 607 return false; 584 }; 608 } 609 ; 585 610 586 611 /** Checks whether point is any of the three endpoints this triangle contains. … … 590 615 bool BoundaryTriangleSet::ContainsBoundaryPoint(const TesselPoint * const point) const 591 616 { 592 593 for (int i=0;i<3;i++)617 Info FunctionInfo(__func__); 618 for (int i = 0; i < 3; i++) 594 619 if (point == endpoints[i]->node) 595 620 return true; 596 621 return false; 597 }; 622 } 623 ; 598 624 599 625 /** Checks whether three given \a *Points coincide with triangle's endpoints. … … 603 629 bool BoundaryTriangleSet::IsPresentTupel(const BoundaryPointSet * const Points[3]) const 604 630 { 605 Info FunctionInfo(__func__); 606 Log() << Verbose(1) << "INFO: Checking " << Points[0] << "," << Points[1] << "," << Points[2] << " against " << endpoints[0] << "," << endpoints[1] << "," << endpoints[2] << "." << endl; 607 return (((endpoints[0] == Points[0]) 608 || (endpoints[0] == Points[1]) 609 || (endpoints[0] == Points[2]) 610 ) && ( 611 (endpoints[1] == Points[0]) 612 || (endpoints[1] == Points[1]) 613 || (endpoints[1] == Points[2]) 614 ) && ( 615 (endpoints[2] == Points[0]) 616 || (endpoints[2] == Points[1]) 617 || (endpoints[2] == Points[2]) 618 619 )); 620 }; 631 Info FunctionInfo(__func__); 632 DoLog(1) && (Log() << Verbose(1) << "INFO: Checking " << Points[0] << "," << Points[1] << "," << Points[2] << " against " << endpoints[0] << "," << endpoints[1] << "," << endpoints[2] << "." << endl); 633 return (((endpoints[0] == Points[0]) || (endpoints[0] == Points[1]) || (endpoints[0] == Points[2])) && ((endpoints[1] == Points[0]) || (endpoints[1] == Points[1]) || (endpoints[1] == Points[2])) && ((endpoints[2] == Points[0]) || (endpoints[2] == Points[1]) || (endpoints[2] == Points[2]) 634 635 )); 636 } 637 ; 621 638 622 639 /** Checks whether three given \a *Points coincide with triangle's endpoints. … … 626 643 bool BoundaryTriangleSet::IsPresentTupel(const BoundaryTriangleSet * const T) const 627 644 { 628 Info FunctionInfo(__func__); 629 return (((endpoints[0] == T->endpoints[0]) 630 || (endpoints[0] == T->endpoints[1]) 631 || (endpoints[0] == T->endpoints[2]) 632 ) && ( 633 (endpoints[1] == T->endpoints[0]) 634 || (endpoints[1] == T->endpoints[1]) 635 || (endpoints[1] == T->endpoints[2]) 636 ) && ( 637 (endpoints[2] == T->endpoints[0]) 638 || (endpoints[2] == T->endpoints[1]) 639 || (endpoints[2] == T->endpoints[2]) 640 641 )); 642 }; 645 Info FunctionInfo(__func__); 646 return (((endpoints[0] == T->endpoints[0]) || (endpoints[0] == T->endpoints[1]) || (endpoints[0] == T->endpoints[2])) && ((endpoints[1] == T->endpoints[0]) || (endpoints[1] == T->endpoints[1]) || (endpoints[1] == T->endpoints[2])) && ((endpoints[2] == T->endpoints[0]) || (endpoints[2] == T->endpoints[1]) || (endpoints[2] == T->endpoints[2]) 647 648 )); 649 } 650 ; 643 651 644 652 /** Returns the endpoint which is not contained in the given \a *line. … … 648 656 class BoundaryPointSet *BoundaryTriangleSet::GetThirdEndpoint(const BoundaryLineSet * const line) const 649 657 { 650 658 Info FunctionInfo(__func__); 651 659 // sanity check 652 660 if (!ContainsBoundaryLine(line)) 653 661 return NULL; 654 for (int i=0;i<3;i++)662 for (int i = 0; i < 3; i++) 655 663 if (!line->ContainsBoundaryPoint(endpoints[i])) 656 664 return endpoints[i]; 657 665 // actually, that' impossible :) 658 666 return NULL; 659 }; 667 } 668 ; 660 669 661 670 /** Calculates the center point of the triangle. … … 665 674 void BoundaryTriangleSet::GetCenter(Vector * const center) const 666 675 { 667 676 Info FunctionInfo(__func__); 668 677 center->Zero(); 669 for (int i=0;i<3;i++)670 center->AddVector(endpoints[i]->node->node);671 center->Scale(1. /3.);672 Log() << Verbose(1) << "INFO: Center is at " << *center << "." << endl;678 for (int i = 0; i < 3; i++) 679 (*center) += (*endpoints[i]->node->node); 680 center->Scale(1. / 3.); 681 DoLog(1) && (Log() << Verbose(1) << "INFO: Center is at " << *center << "." << endl); 673 682 } 674 683 … … 679 688 ostream &operator <<(ostream &ost, const BoundaryTriangleSet &a) 680 689 { 681 ost << "[" << a.Nr << "|" << a.endpoints[0]->node-> Name << "," << a.endpoints[1]->node->Name << "," << a.endpoints[2]->node->Name<< "]";682 // ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << ","683 // << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "," << a.endpoints[2]->node->Name << " at " << *a.endpoints[2]->node->node << "]";690 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->getName() << "," << a.endpoints[1]->node->getName() << "," << a.endpoints[2]->node->getName() << "]"; 691 // ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << "," 692 // << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "," << a.endpoints[2]->node->Name << " at " << *a.endpoints[2]->node->node << "]"; 684 693 return ost; 685 }; 694 } 695 ; 686 696 687 697 // ======================================== Polygons on Boundary ================================= … … 693 703 { 694 704 Info FunctionInfo(__func__); 695 }; 705 } 706 ; 696 707 697 708 /** Destructor of BoundaryPolygonSet. … … 703 714 Info FunctionInfo(__func__); 704 715 endpoints.clear(); 705 Log() << Verbose(1) << "Erasing polygon Nr." << Nr << " itself." << endl; 706 }; 716 DoLog(1) && (Log() << Verbose(1) << "Erasing polygon Nr." << Nr << " itself." << endl); 717 } 718 ; 707 719 708 720 /** Calculates the normal vector for this triangle. … … 718 730 Vector *TotalNormal = new Vector; 719 731 PointSet::const_iterator Runner[3]; 720 for (int i =0;i<3; i++) {732 for (int i = 0; i < 3; i++) { 721 733 Runner[i] = endpoints.begin(); 722 for (int j = 0; j <i; j++) { // go as much further734 for (int j = 0; j < i; j++) { // go as much further 723 735 Runner[i]++; 724 736 if (Runner[i] == endpoints.end()) { 725 eLog() << Verbose(0) << "There are less than three endpoints in the polygon!" << endl;737 DoeLog(0) && (eLog() << Verbose(0) << "There are less than three endpoints in the polygon!" << endl); 726 738 performCriticalExit(); 727 739 } … … 729 741 } 730 742 TotalNormal->Zero(); 731 int counter=0; 732 for (; Runner[2] != endpoints.end(); ) { 733 TemporaryNormal.MakeNormalVector((*Runner[0])->node->node, (*Runner[1])->node->node, (*Runner[2])->node->node); 734 for (int i=0;i<3;i++) // increase each of them 743 int counter = 0; 744 for (; Runner[2] != endpoints.end();) { 745 TemporaryNormal = Plane(*((*Runner[0])->node->node), 746 *((*Runner[1])->node->node), 747 *((*Runner[2])->node->node)).getNormal(); 748 for (int i = 0; i < 3; i++) // increase each of them 735 749 Runner[i]++; 736 TotalNormal->AddVector(&TemporaryNormal);737 } 738 TotalNormal->Scale(1. /(double)counter);750 (*TotalNormal) += TemporaryNormal; 751 } 752 TotalNormal->Scale(1. / (double) counter); 739 753 740 754 // make it always point inward (any offset vector onto plane projected onto normal vector suffices) 741 if (TotalNormal->ScalarProduct( &OtherVector) > 0.)755 if (TotalNormal->ScalarProduct(OtherVector) > 0.) 742 756 TotalNormal->Scale(-1.); 743 Log() << Verbose(1) << "Normal Vector is " << *TotalNormal << "." << endl;757 DoLog(1) && (Log() << Verbose(1) << "Normal Vector is " << *TotalNormal << "." << endl); 744 758 745 759 return TotalNormal; 746 }; 760 } 761 ; 747 762 748 763 /** Calculates the center point of the triangle. … … 756 771 int counter = 0; 757 772 for(PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) { 758 center->AddVector((*Runner)->node->node);773 (*center) += (*(*Runner)->node->node); 759 774 counter++; 760 775 } 761 center->Scale(1. /(double)counter);762 Log() << Verbose(1) << "Center is at " << *center << "." << endl;776 center->Scale(1. / (double) counter); 777 DoLog(1) && (Log() << Verbose(1) << "Center is at " << *center << "." << endl); 763 778 } 764 779 … … 771 786 Info FunctionInfo(__func__); 772 787 return ContainsPresentTupel(triangle->endpoints, 3); 773 }; 788 } 789 ; 774 790 775 791 /** Checks whether the polygons contains both endpoints of the line. … … 781 797 Info FunctionInfo(__func__); 782 798 return ContainsPresentTupel(line->endpoints, 2); 783 }; 799 } 800 ; 784 801 785 802 /** Checks whether point is any of the three endpoints this triangle contains. … … 790 807 { 791 808 Info FunctionInfo(__func__); 792 for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) {793 Log() << Verbose(0) << "Checking against " << **Runner << endl;809 for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) { 810 DoLog(0) && (Log() << Verbose(0) << "Checking against " << **Runner << endl); 794 811 if (point == (*Runner)) { 795 Log() << Verbose(0) << " Contained." << endl;812 DoLog(0) && (Log() << Verbose(0) << " Contained." << endl); 796 813 return true; 797 814 } 798 815 } 799 Log() << Verbose(0) << " Not contained." << endl;816 DoLog(0) && (Log() << Verbose(0) << " Not contained." << endl); 800 817 return false; 801 }; 818 } 819 ; 802 820 803 821 /** Checks whether point is any of the three endpoints this triangle contains. … … 808 826 { 809 827 Info FunctionInfo(__func__); 810 for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++)828 for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) 811 829 if (point == (*Runner)->node) { 812 Log() << Verbose(0) << " Contained." << endl;830 DoLog(0) && (Log() << Verbose(0) << " Contained." << endl); 813 831 return true; 814 832 } 815 Log() << Verbose(0) << " Not contained." << endl;833 DoLog(0) && (Log() << Verbose(0) << " Not contained." << endl); 816 834 return false; 817 }; 835 } 836 ; 818 837 819 838 /** Checks whether given array of \a *Points coincide with polygons's endpoints. … … 826 845 Info FunctionInfo(__func__); 827 846 int counter = 0; 828 Log() << Verbose(1) << "Polygon is " << *this << endl;829 for (int i=0;i<dim;i++) {830 Log() << Verbose(1) << " Testing endpoint " << *Points[i] << endl;847 DoLog(1) && (Log() << Verbose(1) << "Polygon is " << *this << endl); 848 for (int i = 0; i < dim; i++) { 849 DoLog(1) && (Log() << Verbose(1) << " Testing endpoint " << *Points[i] << endl); 831 850 if (ContainsBoundaryPoint(Points[i])) { 832 851 counter++; … … 838 857 else 839 858 return false; 840 }; 859 } 860 ; 841 861 842 862 /** Checks whether given PointList coincide with polygons's endpoints. … … 848 868 Info FunctionInfo(__func__); 849 869 size_t counter = 0; 850 Log() << Verbose(1) << "Polygon is " << *this << endl;851 for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) {852 Log() << Verbose(1) << " Testing endpoint " << **Runner << endl;870 DoLog(1) && (Log() << Verbose(1) << "Polygon is " << *this << endl); 871 for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) { 872 DoLog(1) && (Log() << Verbose(1) << " Testing endpoint " << **Runner << endl); 853 873 if (ContainsBoundaryPoint(*Runner)) 854 874 counter++; … … 859 879 else 860 880 return false; 861 }; 881 } 882 ; 862 883 863 884 /** Checks whether given set of \a *Points coincide with polygons's endpoints. … … 867 888 bool BoundaryPolygonSet::ContainsPresentTupel(const BoundaryPolygonSet * const P) const 868 889 { 869 return ContainsPresentTupel((const PointSet)P->endpoints); 870 }; 890 return ContainsPresentTupel((const PointSet) P->endpoints); 891 } 892 ; 871 893 872 894 /** Gathers all the endpoints' triangles in a unique set. … … 876 898 { 877 899 Info FunctionInfo(__func__); 878 pair 900 pair<TriangleSet::iterator, bool> Tester; 879 901 TriangleSet *triangles = new TriangleSet; 880 902 881 for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++)882 for (LineMap::const_iterator Walker = (*Runner)->lines.begin(); Walker != (*Runner)->lines.end(); Walker++)883 for (TriangleMap::const_iterator Sprinter = (Walker->second)->triangles.begin(); Sprinter != (Walker->second)->triangles.end(); Sprinter++) {903 for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) 904 for (LineMap::const_iterator Walker = (*Runner)->lines.begin(); Walker != (*Runner)->lines.end(); Walker++) 905 for (TriangleMap::const_iterator Sprinter = (Walker->second)->triangles.begin(); Sprinter != (Walker->second)->triangles.end(); Sprinter++) { 884 906 //Log() << Verbose(0) << " Testing triangle " << *(Sprinter->second) << endl; 885 907 if (ContainsBoundaryTriangle(Sprinter->second)) { 886 908 Tester = triangles->insert(Sprinter->second); 887 909 if (Tester.second) 888 Log() << Verbose(0) << "Adding triangle " << *(Sprinter->second) << endl;910 DoLog(0) && (Log() << Verbose(0) << "Adding triangle " << *(Sprinter->second) << endl); 889 911 } 890 912 } 891 913 892 Log() << Verbose(1) << "The Polygon of " << endpoints.size() << " endpoints has " << triangles->size() << " unique triangles in total." << endl;914 DoLog(1) && (Log() << Verbose(1) << "The Polygon of " << endpoints.size() << " endpoints has " << triangles->size() << " unique triangles in total." << endl); 893 915 return triangles; 894 }; 916 } 917 ; 895 918 896 919 /** Fills the endpoints of this polygon from the triangles attached to \a *line. … … 901 924 { 902 925 Info FunctionInfo(__func__); 903 pair 926 pair<PointSet::iterator, bool> Tester; 904 927 if (line == NULL) 905 928 return false; 906 Log() << Verbose(1) << "Filling polygon from line " << *line << endl;907 for (TriangleMap::const_iterator Runner = line->triangles.begin(); Runner != line->triangles.end(); Runner++) {908 for (int i =0;i<3;i++) {929 DoLog(1) && (Log() << Verbose(1) << "Filling polygon from line " << *line << endl); 930 for (TriangleMap::const_iterator Runner = line->triangles.begin(); Runner != line->triangles.end(); Runner++) { 931 for (int i = 0; i < 3; i++) { 909 932 Tester = endpoints.insert((Runner->second)->endpoints[i]); 910 933 if (Tester.second) 911 Log() << Verbose(1) << " Inserting endpoint " << *((Runner->second)->endpoints[i]) << endl;934 DoLog(1) && (Log() << Verbose(1) << " Inserting endpoint " << *((Runner->second)->endpoints[i]) << endl); 912 935 } 913 936 } 914 937 915 938 return true; 916 }; 939 } 940 ; 917 941 918 942 /** output operator for BoundaryPolygonSet. … … 923 947 { 924 948 ost << "[" << a.Nr << "|"; 925 for (PointSet::const_iterator Runner = a.endpoints.begin(); Runner != a.endpoints.end();) {926 ost << (*Runner)->node->Name;927 Runner++;928 if (Runner != a.endpoints.end())929 ost << ",";930 } 931 ost << "]";949 for (PointSet::const_iterator Runner = a.endpoints.begin(); Runner != a.endpoints.end();) { 950 ost << (*Runner)->node->getName(); 951 Runner++; 952 if (Runner != a.endpoints.end()) 953 ost << ","; 954 } 955 ost << "]"; 932 956 return ost; 933 }; 957 } 958 ; 934 959 935 960 // =========================================================== class TESSELPOINT =========================================== … … 942 967 node = NULL; 943 968 nr = -1; 944 Name = Malloc<char> (1, "TesselPoint::TtesselPoint - Name"); 945 Name = strcpy(Name, "-"); 946 }; 969 } 970 ; 947 971 948 972 /** Destructor for class TesselPoint. … … 951 975 { 952 976 //Info FunctionInfo(__func__); 953 }; 977 } 978 ; 954 979 955 980 /** Prints LCNode to screen. 956 981 */ 957 ostream & operator << 958 { 959 ost << "[" << (a.Name) << "|" << a.Name << " at" << *a.node << "]";982 ostream & operator <<(ostream &ost, const TesselPoint &a) 983 { 984 ost << "[" << a.getName() << "|" << *a.node << "]"; 960 985 return ost; 961 }; 986 } 987 ; 962 988 963 989 /** Prints LCNode to screen. 964 990 */ 965 ostream & TesselPoint::operator << 966 { 967 991 ostream & TesselPoint::operator <<(ostream &ost) 992 { 993 Info FunctionInfo(__func__); 968 994 ost << "[" << (nr) << "|" << this << "]"; 969 995 return ost; 996 } 997 ; 998 999 // =========================================================== class POINTCLOUD ============================================ 1000 1001 /** Constructor of class PointCloud. 1002 */ 1003 PointCloud::PointCloud() 1004 { 1005 //Info FunctionInfo(__func__); 1006 } 1007 ; 1008 1009 /** Destructor for class PointCloud. 1010 */ 1011 PointCloud::~PointCloud() 1012 { 1013 //Info FunctionInfo(__func__); 1014 } 1015 ; 1016 1017 // ============================ CandidateForTesselation ============================= 1018 1019 /** Constructor of class CandidateForTesselation. 1020 */ 1021 CandidateForTesselation::CandidateForTesselation(BoundaryLineSet* line) : 1022 BaseLine(line), ThirdPoint(NULL), T(NULL), ShortestAngle(2. * M_PI), OtherShortestAngle(2. * M_PI) 1023 { 1024 Info FunctionInfo(__func__); 1025 } 1026 ; 1027 1028 /** Constructor of class CandidateForTesselation. 1029 */ 1030 CandidateForTesselation::CandidateForTesselation(TesselPoint *candidate, BoundaryLineSet* line, BoundaryPointSet* point, Vector OptCandidateCenter, Vector OtherOptCandidateCenter) : 1031 BaseLine(line), ThirdPoint(point), T(NULL), ShortestAngle(2. * M_PI), OtherShortestAngle(2. * M_PI) 1032 { 1033 Info FunctionInfo(__func__); 1034 OptCenter = OptCandidateCenter; 1035 OtherOptCenter = OtherOptCandidateCenter; 970 1036 }; 971 1037 972 1038 973 // =========================================================== class POINTCLOUD ============================================974 975 /** Constructor of class PointCloud.976 */977 PointCloud::PointCloud()978 {979 //Info FunctionInfo(__func__);980 };981 982 /** Destructor for class PointCloud.983 */984 PointCloud::~PointCloud()985 {986 //Info FunctionInfo(__func__);987 };988 989 // ============================ CandidateForTesselation =============================990 991 /** Constructor of class CandidateForTesselation.992 */993 CandidateForTesselation::CandidateForTesselation (BoundaryLineSet* line) :994 BaseLine(line),995 ShortestAngle(2.*M_PI),996 OtherShortestAngle(2.*M_PI)997 {998 Info FunctionInfo(__func__);999 };1000 1001 1002 /** Constructor of class CandidateForTesselation.1003 */1004 CandidateForTesselation::CandidateForTesselation (TesselPoint *candidate, BoundaryLineSet* line, Vector OptCandidateCenter, Vector OtherOptCandidateCenter) :1005 BaseLine(line),1006 ShortestAngle(2.*M_PI),1007 OtherShortestAngle(2.*M_PI)1008 {1009 Info FunctionInfo(__func__);1010 OptCenter.CopyVector(&OptCandidateCenter);1011 OtherOptCenter.CopyVector(&OtherOptCandidateCenter);1012 };1013 1014 1039 /** Destructor for class CandidateForTesselation. 1015 1040 */ 1016 CandidateForTesselation::~CandidateForTesselation() { 1017 BaseLine = NULL; 1018 }; 1041 CandidateForTesselation::~CandidateForTesselation() 1042 { 1043 } 1044 ; 1045 1046 /** Checks validity of a given sphere of a candidate line. 1047 * Sphere must touch all candidates and the baseline endpoints and there must be no other atoms inside. 1048 * \param RADIUS radius of sphere 1049 * \param *LC LinkedCell structure with other atoms 1050 * \return true - sphere is valid, false - sphere contains other points 1051 */ 1052 bool CandidateForTesselation::CheckValidity(const double RADIUS, const LinkedCell *LC) const 1053 { 1054 Info FunctionInfo(__func__); 1055 1056 const double radiusSquared = RADIUS * RADIUS; 1057 list<const Vector *> VectorList; 1058 VectorList.push_back(&OptCenter); 1059 //VectorList.push_back(&OtherOptCenter); // don't check the other (wrong) center 1060 1061 if (!pointlist.empty()) 1062 DoLog(1) && (Log() << Verbose(1) << "INFO: Checking whether sphere contains candidate list and baseline " << *BaseLine->endpoints[0] << "<->" << *BaseLine->endpoints[1] << " only ..." << endl); 1063 else 1064 DoLog(1) && (Log() << Verbose(1) << "INFO: Checking whether sphere with no candidates contains baseline " << *BaseLine->endpoints[0] << "<->" << *BaseLine->endpoints[1] << " only ..." << endl); 1065 // check baseline for OptCenter and OtherOptCenter being on sphere's surface 1066 for (list<const Vector *>::const_iterator VRunner = VectorList.begin(); VRunner != VectorList.end(); ++VRunner) { 1067 for (int i = 0; i < 2; i++) { 1068 const double distance = fabs((*VRunner)->DistanceSquared(*BaseLine->endpoints[i]->node->node) - radiusSquared); 1069 if (distance > HULLEPSILON) { 1070 DoeLog(1) && (eLog() << Verbose(1) << "Endpoint " << *BaseLine->endpoints[i] << " is out of sphere at " << *(*VRunner) << " by " << distance << "." << endl); 1071 return false; 1072 } 1073 } 1074 } 1075 1076 // check Candidates for OptCenter and OtherOptCenter being on sphere's surface 1077 for (TesselPointList::const_iterator Runner = pointlist.begin(); Runner != pointlist.end(); ++Runner) { 1078 const TesselPoint *Walker = *Runner; 1079 for (list<const Vector *>::const_iterator VRunner = VectorList.begin(); VRunner != VectorList.end(); ++VRunner) { 1080 const double distance = fabs((*VRunner)->DistanceSquared(*Walker->node) - radiusSquared); 1081 if (distance > HULLEPSILON) { 1082 DoeLog(1) && (eLog() << Verbose(1) << "Candidate " << *Walker << " is out of sphere at " << *(*VRunner) << " by " << distance << "." << endl); 1083 return false; 1084 } else { 1085 DoLog(1) && (Log() << Verbose(1) << "Candidate " << *Walker << " is inside by " << distance << "." << endl); 1086 } 1087 } 1088 } 1089 1090 DoLog(1) && (Log() << Verbose(1) << "INFO: Checking whether sphere contains no others points ..." << endl); 1091 bool flag = true; 1092 for (list<const Vector *>::const_iterator VRunner = VectorList.begin(); VRunner != VectorList.end(); ++VRunner) { 1093 // get all points inside the sphere 1094 TesselPointList *ListofPoints = LC->GetPointsInsideSphere(RADIUS, (*VRunner)); 1095 1096 DoLog(1) && (Log() << Verbose(1) << "The following atoms are inside sphere at " << OtherOptCenter << ":" << endl); 1097 for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner) 1098 DoLog(1) && (Log() << Verbose(1) << " " << *(*Runner) << " with distance " << (*Runner)->node->distance(OtherOptCenter) << "." << endl); 1099 1100 // remove baseline's endpoints and candidates 1101 for (int i = 0; i < 2; i++) { 1102 DoLog(1) && (Log() << Verbose(1) << "INFO: removing baseline tesselpoint " << *BaseLine->endpoints[i]->node << "." << endl); 1103 ListofPoints->remove(BaseLine->endpoints[i]->node); 1104 } 1105 for (TesselPointList::const_iterator Runner = pointlist.begin(); Runner != pointlist.end(); ++Runner) { 1106 DoLog(1) && (Log() << Verbose(1) << "INFO: removing candidate tesselpoint " << *(*Runner) << "." << endl); 1107 ListofPoints->remove(*Runner); 1108 } 1109 if (!ListofPoints->empty()) { 1110 DoeLog(1) && (eLog() << Verbose(1) << "CheckValidity: There are still " << ListofPoints->size() << " points inside the sphere." << endl); 1111 flag = false; 1112 DoeLog(1) && (eLog() << Verbose(1) << "External atoms inside of sphere at " << *(*VRunner) << ":" << endl); 1113 for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner) 1114 DoeLog(1) && (eLog() << Verbose(1) << " " << *(*Runner) << endl); 1115 } 1116 delete (ListofPoints); 1117 1118 // check with animate_sphere.tcl VMD script 1119 if (ThirdPoint != NULL) { 1120 DoLog(1) && (Log() << Verbose(1) << "Check by: animate_sphere 0 " << BaseLine->endpoints[0]->Nr + 1 << " " << BaseLine->endpoints[1]->Nr + 1 << " " << ThirdPoint->Nr + 1 << " " << RADIUS << " " << OldCenter[0] << " " << OldCenter[1] << " " << OldCenter[2] << " " << (*VRunner)->at(0) << " " << (*VRunner)->at(1) << " " << (*VRunner)->at(2) << endl); 1121 } else { 1122 DoLog(1) && (Log() << Verbose(1) << "Check by: ... missing third point ..." << endl); 1123 DoLog(1) && (Log() << Verbose(1) << "Check by: animate_sphere 0 " << BaseLine->endpoints[0]->Nr + 1 << " " << BaseLine->endpoints[1]->Nr + 1 << " ??? " << RADIUS << " " << OldCenter[0] << " " << OldCenter[1] << " " << OldCenter[2] << " " << (*VRunner)->at(0) << " " << (*VRunner)->at(1) << " " << (*VRunner)->at(2) << endl); 1124 } 1125 } 1126 return flag; 1127 } 1128 ; 1019 1129 1020 1130 /** output operator for CandidateForTesselation. … … 1022 1132 * \param &a boundary line 1023 1133 */ 1024 ostream & operator <<(ostream &ost, const 1025 { 1026 ost << "[" << a.BaseLine->Nr << "|" << a.BaseLine->endpoints[0]->node-> Name << "," << a.BaseLine->endpoints[1]->node->Name<< "] with ";1134 ostream & operator <<(ostream &ost, const CandidateForTesselation &a) 1135 { 1136 ost << "[" << a.BaseLine->Nr << "|" << a.BaseLine->endpoints[0]->node->getName() << "," << a.BaseLine->endpoints[1]->node->getName() << "] with "; 1027 1137 if (a.pointlist.empty()) 1028 1138 ost << "no candidate."; … … 1035 1145 for (TesselPointList::const_iterator Runner = a.pointlist.begin(); Runner != a.pointlist.end(); Runner++) 1036 1146 ost << *(*Runner) << " "; 1037 ost << " at angle " << (a.ShortestAngle) << ".";1147 ost << " at angle " << (a.ShortestAngle) << "."; 1038 1148 } 1039 1149 1040 1150 return ost; 1041 } ;1042 1151 } 1152 ; 1043 1153 1044 1154 // =========================================================== class TESSELATION =========================================== … … 1047 1157 */ 1048 1158 Tesselation::Tesselation() : 1049 PointsOnBoundaryCount(0), 1050 LinesOnBoundaryCount(0), 1051 TrianglesOnBoundaryCount(0), 1052 LastTriangle(NULL), 1053 TriangleFilesWritten(0), 1054 InternalPointer(PointsOnBoundary.begin()) 1055 { 1056 Info FunctionInfo(__func__); 1159 PointsOnBoundaryCount(0), LinesOnBoundaryCount(0), TrianglesOnBoundaryCount(0), LastTriangle(NULL), TriangleFilesWritten(0), InternalPointer(PointsOnBoundary.begin()) 1160 { 1161 Info FunctionInfo(__func__); 1057 1162 } 1058 1163 ; … … 1063 1168 Tesselation::~Tesselation() 1064 1169 { 1065 1066 Log() << Verbose(0) << "Free'ing TesselStruct ... " << endl;1170 Info FunctionInfo(__func__); 1171 DoLog(0) && (Log() << Verbose(0) << "Free'ing TesselStruct ... " << endl); 1067 1172 for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) { 1068 1173 if (runner->second != NULL) { … … 1070 1175 runner->second = NULL; 1071 1176 } else 1072 eLog() << Verbose(1) << "The triangle " << runner->first << " has already been free'd." << endl;1073 } 1074 Log() << Verbose(0) << "This envelope was written to file " << TriangleFilesWritten << " times(s)." << endl;1177 DoeLog(1) && (eLog() << Verbose(1) << "The triangle " << runner->first << " has already been free'd." << endl); 1178 } 1179 DoLog(0) && (Log() << Verbose(0) << "This envelope was written to file " << TriangleFilesWritten << " times(s)." << endl); 1075 1180 } 1076 1181 ; … … 1078 1183 /** PointCloud implementation of GetCenter 1079 1184 * Uses PointsOnBoundary and STL stuff. 1080 */ 1185 */ 1081 1186 Vector * Tesselation::GetCenter(ofstream *out) const 1082 1187 { 1083 1084 Vector *Center = new Vector(0., 0.,0.);1085 int num =0;1188 Info FunctionInfo(__func__); 1189 Vector *Center = new Vector(0., 0., 0.); 1190 int num = 0; 1086 1191 for (GoToFirst(); (!IsEnd()); GoToNext()) { 1087 Center->AddVector(GetPoint()->node);1192 (*Center) += (*GetPoint()->node); 1088 1193 num++; 1089 1194 } 1090 Center->Scale(1. /num);1195 Center->Scale(1. / num); 1091 1196 return Center; 1092 }; 1197 } 1198 ; 1093 1199 1094 1200 /** PointCloud implementation of GoPoint 1095 1201 * Uses PointsOnBoundary and STL stuff. 1096 */ 1202 */ 1097 1203 TesselPoint * Tesselation::GetPoint() const 1098 1204 { 1099 1205 Info FunctionInfo(__func__); 1100 1206 return (InternalPointer->second->node); 1101 }; 1207 } 1208 ; 1102 1209 1103 1210 /** PointCloud implementation of GetTerminalPoint. 1104 1211 * Uses PointsOnBoundary and STL stuff. 1105 */ 1212 */ 1106 1213 TesselPoint * Tesselation::GetTerminalPoint() const 1107 1214 { 1108 1215 Info FunctionInfo(__func__); 1109 1216 PointMap::const_iterator Runner = PointsOnBoundary.end(); 1110 1217 Runner--; 1111 1218 return (Runner->second->node); 1112 }; 1219 } 1220 ; 1113 1221 1114 1222 /** PointCloud implementation of GoToNext. 1115 1223 * Uses PointsOnBoundary and STL stuff. 1116 */ 1224 */ 1117 1225 void Tesselation::GoToNext() const 1118 1226 { 1119 1227 Info FunctionInfo(__func__); 1120 1228 if (InternalPointer != PointsOnBoundary.end()) 1121 1229 InternalPointer++; 1122 }; 1230 } 1231 ; 1123 1232 1124 1233 /** PointCloud implementation of GoToPrevious. 1125 1234 * Uses PointsOnBoundary and STL stuff. 1126 */ 1235 */ 1127 1236 void Tesselation::GoToPrevious() const 1128 1237 { 1129 1238 Info FunctionInfo(__func__); 1130 1239 if (InternalPointer != PointsOnBoundary.begin()) 1131 1240 InternalPointer--; 1132 }; 1241 } 1242 ; 1133 1243 1134 1244 /** PointCloud implementation of GoToFirst. 1135 1245 * Uses PointsOnBoundary and STL stuff. 1136 */ 1246 */ 1137 1247 void Tesselation::GoToFirst() const 1138 1248 { 1139 1249 Info FunctionInfo(__func__); 1140 1250 InternalPointer = PointsOnBoundary.begin(); 1141 }; 1251 } 1252 ; 1142 1253 1143 1254 /** PointCloud implementation of GoToLast. … … 1146 1257 void Tesselation::GoToLast() const 1147 1258 { 1148 1259 Info FunctionInfo(__func__); 1149 1260 InternalPointer = PointsOnBoundary.end(); 1150 1261 InternalPointer--; 1151 }; 1262 } 1263 ; 1152 1264 1153 1265 /** PointCloud implementation of IsEmpty. 1154 1266 * Uses PointsOnBoundary and STL stuff. 1155 */ 1267 */ 1156 1268 bool Tesselation::IsEmpty() const 1157 1269 { 1158 1270 Info FunctionInfo(__func__); 1159 1271 return (PointsOnBoundary.empty()); 1160 }; 1272 } 1273 ; 1161 1274 1162 1275 /** PointCloud implementation of IsLast. 1163 1276 * Uses PointsOnBoundary and STL stuff. 1164 */ 1277 */ 1165 1278 bool Tesselation::IsEnd() const 1166 1279 { 1167 1280 Info FunctionInfo(__func__); 1168 1281 return (InternalPointer == PointsOnBoundary.end()); 1169 } ;1170 1282 } 1283 ; 1171 1284 1172 1285 /** Gueses first starting triangle of the convex envelope. … … 1177 1290 void Tesselation::GuessStartingTriangle() 1178 1291 { 1179 1292 Info FunctionInfo(__func__); 1180 1293 // 4b. create a starting triangle 1181 1294 // 4b1. create all distances … … 1187 1300 1188 1301 // with A chosen, take each pair B,C and sort 1189 if (A != PointsOnBoundary.end()) 1190 { 1191 B = A; 1192 B++; 1193 for (; B != PointsOnBoundary.end(); B++) 1194 { 1195 C = B; 1196 C++; 1197 for (; C != PointsOnBoundary.end(); C++) 1198 { 1199 tmp = A->second->node->node->DistanceSquared(B->second->node->node); 1200 distance = tmp * tmp; 1201 tmp = A->second->node->node->DistanceSquared(C->second->node->node); 1202 distance += tmp * tmp; 1203 tmp = B->second->node->node->DistanceSquared(C->second->node->node); 1204 distance += tmp * tmp; 1205 DistanceMMap.insert(DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator> (B, C))); 1206 } 1207 } 1208 } 1302 if (A != PointsOnBoundary.end()) { 1303 B = A; 1304 B++; 1305 for (; B != PointsOnBoundary.end(); B++) { 1306 C = B; 1307 C++; 1308 for (; C != PointsOnBoundary.end(); C++) { 1309 tmp = A->second->node->node->DistanceSquared(*B->second->node->node); 1310 distance = tmp * tmp; 1311 tmp = A->second->node->node->DistanceSquared(*C->second->node->node); 1312 distance += tmp * tmp; 1313 tmp = B->second->node->node->DistanceSquared(*C->second->node->node); 1314 distance += tmp * tmp; 1315 DistanceMMap.insert(DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator> (B, C))); 1316 } 1317 } 1318 } 1209 1319 // // listing distances 1210 1320 // Log() << Verbose(1) << "Listing DistanceMMap:"; … … 1216 1326 // 1. we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate 1217 1327 DistanceMultiMap::iterator baseline = DistanceMMap.begin(); 1218 for (; baseline != DistanceMMap.end(); baseline++) 1219 { 1220 // we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate 1221 // 2. next, we have to check whether all points reside on only one side of the triangle 1222 // 3. construct plane vector 1223 PlaneVector.MakeNormalVector(A->second->node->node, 1224 baseline->second.first->second->node->node, 1225 baseline->second.second->second->node->node); 1226 Log() << Verbose(2) << "Plane vector of candidate triangle is " << PlaneVector << endl; 1227 // 4. loop over all points 1228 double sign = 0.; 1229 PointMap::iterator checker = PointsOnBoundary.begin(); 1230 for (; checker != PointsOnBoundary.end(); checker++) 1231 { 1232 // (neglecting A,B,C) 1233 if ((checker == A) || (checker == baseline->second.first) || (checker 1234 == baseline->second.second)) 1235 continue; 1236 // 4a. project onto plane vector 1237 TrialVector.CopyVector(checker->second->node->node); 1238 TrialVector.SubtractVector(A->second->node->node); 1239 distance = TrialVector.ScalarProduct(&PlaneVector); 1240 if (fabs(distance) < 1e-4) // we need to have a small epsilon around 0 which is still ok 1241 continue; 1242 Log() << Verbose(2) << "Projection of " << checker->second->node->Name << " yields distance of " << distance << "." << endl; 1243 tmp = distance / fabs(distance); 1244 // 4b. Any have different sign to than before? (i.e. would lie outside convex hull with this starting triangle) 1245 if ((sign != 0) && (tmp != sign)) 1246 { 1247 // 4c. If so, break 4. loop and continue with next candidate in 1. loop 1248 Log() << Verbose(2) << "Current candidates: " 1249 << A->second->node->Name << "," 1250 << baseline->second.first->second->node->Name << "," 1251 << baseline->second.second->second->node->Name << " leaves " 1252 << checker->second->node->Name << " outside the convex hull." 1253 << endl; 1254 break; 1255 } 1256 else 1257 { // note the sign for later 1258 Log() << Verbose(2) << "Current candidates: " 1259 << A->second->node->Name << "," 1260 << baseline->second.first->second->node->Name << "," 1261 << baseline->second.second->second->node->Name << " leave " 1262 << checker->second->node->Name << " inside the convex hull." 1263 << endl; 1264 sign = tmp; 1265 } 1266 // 4d. Check whether the point is inside the triangle (check distance to each node 1267 tmp = checker->second->node->node->DistanceSquared(A->second->node->node); 1268 int innerpoint = 0; 1269 if ((tmp < A->second->node->node->DistanceSquared( 1270 baseline->second.first->second->node->node)) && (tmp 1271 < A->second->node->node->DistanceSquared( 1272 baseline->second.second->second->node->node))) 1273 innerpoint++; 1274 tmp = checker->second->node->node->DistanceSquared( 1275 baseline->second.first->second->node->node); 1276 if ((tmp < baseline->second.first->second->node->node->DistanceSquared( 1277 A->second->node->node)) && (tmp 1278 < baseline->second.first->second->node->node->DistanceSquared( 1279 baseline->second.second->second->node->node))) 1280 innerpoint++; 1281 tmp = checker->second->node->node->DistanceSquared( 1282 baseline->second.second->second->node->node); 1283 if ((tmp < baseline->second.second->second->node->node->DistanceSquared( 1284 baseline->second.first->second->node->node)) && (tmp 1285 < baseline->second.second->second->node->node->DistanceSquared( 1286 A->second->node->node))) 1287 innerpoint++; 1288 // 4e. If so, break 4. loop and continue with next candidate in 1. loop 1289 if (innerpoint == 3) 1290 break; 1291 } 1292 // 5. come this far, all on same side? Then break 1. loop and construct triangle 1293 if (checker == PointsOnBoundary.end()) 1294 { 1295 Log() << Verbose(2) << "Looks like we have a candidate!" << endl; 1296 break; 1297 } 1298 } 1299 if (baseline != DistanceMMap.end()) 1300 { 1301 BPS[0] = baseline->second.first->second; 1302 BPS[1] = baseline->second.second->second; 1303 BLS[0] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount); 1304 BPS[0] = A->second; 1305 BPS[1] = baseline->second.second->second; 1306 BLS[1] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount); 1307 BPS[0] = baseline->second.first->second; 1308 BPS[1] = A->second; 1309 BLS[2] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount); 1310 1311 // 4b3. insert created triangle 1312 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 1313 TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS)); 1314 TrianglesOnBoundaryCount++; 1315 for (int i = 0; i < NDIM; i++) 1316 { 1317 LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount, BTS->lines[i])); 1318 LinesOnBoundaryCount++; 1319 } 1320 1321 Log() << Verbose(1) << "Starting triangle is " << *BTS << "." << endl; 1322 } 1323 else 1324 { 1325 eLog() << Verbose(0) << "No starting triangle found." << endl; 1326 } 1328 for (; baseline != DistanceMMap.end(); baseline++) { 1329 // we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate 1330 // 2. next, we have to check whether all points reside on only one side of the triangle 1331 // 3. construct plane vector 1332 PlaneVector = Plane(*A->second->node->node, 1333 *baseline->second.first->second->node->node, 1334 *baseline->second.second->second->node->node).getNormal(); 1335 DoLog(2) && (Log() << Verbose(2) << "Plane vector of candidate triangle is " << PlaneVector << endl); 1336 // 4. loop over all points 1337 double sign = 0.; 1338 PointMap::iterator checker = PointsOnBoundary.begin(); 1339 for (; checker != PointsOnBoundary.end(); checker++) { 1340 // (neglecting A,B,C) 1341 if ((checker == A) || (checker == baseline->second.first) || (checker == baseline->second.second)) 1342 continue; 1343 // 4a. project onto plane vector 1344 TrialVector = (*checker->second->node->node); 1345 TrialVector.SubtractVector(*A->second->node->node); 1346 distance = TrialVector.ScalarProduct(PlaneVector); 1347 if (fabs(distance) < 1e-4) // we need to have a small epsilon around 0 which is still ok 1348 continue; 1349 DoLog(2) && (Log() << Verbose(2) << "Projection of " << checker->second->node->getName() << " yields distance of " << distance << "." << endl); 1350 tmp = distance / fabs(distance); 1351 // 4b. Any have different sign to than before? (i.e. would lie outside convex hull with this starting triangle) 1352 if ((sign != 0) && (tmp != sign)) { 1353 // 4c. If so, break 4. loop and continue with next candidate in 1. loop 1354 DoLog(2) && (Log() << Verbose(2) << "Current candidates: " << A->second->node->getName() << "," << baseline->second.first->second->node->getName() << "," << baseline->second.second->second->node->getName() << " leaves " << checker->second->node->getName() << " outside the convex hull." << endl); 1355 break; 1356 } else { // note the sign for later 1357 DoLog(2) && (Log() << Verbose(2) << "Current candidates: " << A->second->node->getName() << "," << baseline->second.first->second->node->getName() << "," << baseline->second.second->second->node->getName() << " leave " << checker->second->node->getName() << " inside the convex hull." << endl); 1358 sign = tmp; 1359 } 1360 // 4d. Check whether the point is inside the triangle (check distance to each node 1361 tmp = checker->second->node->node->DistanceSquared(*A->second->node->node); 1362 int innerpoint = 0; 1363 if ((tmp < A->second->node->node->DistanceSquared(*baseline->second.first->second->node->node)) && (tmp < A->second->node->node->DistanceSquared(*baseline->second.second->second->node->node))) 1364 innerpoint++; 1365 tmp = checker->second->node->node->DistanceSquared(*baseline->second.first->second->node->node); 1366 if ((tmp < baseline->second.first->second->node->node->DistanceSquared(*A->second->node->node)) && (tmp < baseline->second.first->second->node->node->DistanceSquared(*baseline->second.second->second->node->node))) 1367 innerpoint++; 1368 tmp = checker->second->node->node->DistanceSquared(*baseline->second.second->second->node->node); 1369 if ((tmp < baseline->second.second->second->node->node->DistanceSquared(*baseline->second.first->second->node->node)) && (tmp < baseline->second.second->second->node->node->DistanceSquared(*A->second->node->node))) 1370 innerpoint++; 1371 // 4e. If so, break 4. loop and continue with next candidate in 1. loop 1372 if (innerpoint == 3) 1373 break; 1374 } 1375 // 5. come this far, all on same side? Then break 1. loop and construct triangle 1376 if (checker == PointsOnBoundary.end()) { 1377 DoLog(2) && (Log() << Verbose(2) << "Looks like we have a candidate!" << endl); 1378 break; 1379 } 1380 } 1381 if (baseline != DistanceMMap.end()) { 1382 BPS[0] = baseline->second.first->second; 1383 BPS[1] = baseline->second.second->second; 1384 BLS[0] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount); 1385 BPS[0] = A->second; 1386 BPS[1] = baseline->second.second->second; 1387 BLS[1] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount); 1388 BPS[0] = baseline->second.first->second; 1389 BPS[1] = A->second; 1390 BLS[2] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount); 1391 1392 // 4b3. insert created triangle 1393 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 1394 TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS)); 1395 TrianglesOnBoundaryCount++; 1396 for (int i = 0; i < NDIM; i++) { 1397 LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount, BTS->lines[i])); 1398 LinesOnBoundaryCount++; 1399 } 1400 1401 DoLog(1) && (Log() << Verbose(1) << "Starting triangle is " << *BTS << "." << endl); 1402 } else { 1403 DoeLog(0) && (eLog() << Verbose(0) << "No starting triangle found." << endl); 1404 } 1327 1405 } 1328 1406 ; … … 1343 1421 void Tesselation::TesselateOnBoundary(const PointCloud * const cloud) 1344 1422 { 1345 1423 Info FunctionInfo(__func__); 1346 1424 bool flag; 1347 1425 PointMap::iterator winner; … … 1362 1440 // get peak point with respect to this base line's only triangle 1363 1441 BTS = baseline->second->triangles.begin()->second; // there is only one triangle so far 1364 Log() << Verbose(0) << "Current baseline is between " << *(baseline->second) << "." << endl;1442 DoLog(0) && (Log() << Verbose(0) << "Current baseline is between " << *(baseline->second) << "." << endl); 1365 1443 for (int i = 0; i < 3; i++) 1366 1444 if ((BTS->endpoints[i] != baseline->second->endpoints[0]) && (BTS->endpoints[i] != baseline->second->endpoints[1])) 1367 1445 peak = BTS->endpoints[i]; 1368 Log() << Verbose(1) << " and has peak " << *peak << "." << endl;1446 DoLog(1) && (Log() << Verbose(1) << " and has peak " << *peak << "." << endl); 1369 1447 1370 1448 // prepare some auxiliary vectors 1371 1449 Vector BaseLineCenter, BaseLine; 1372 BaseLineCenter.CopyVector(baseline->second->endpoints[0]->node->node); 1373 BaseLineCenter.AddVector(baseline->second->endpoints[1]->node->node); 1374 BaseLineCenter.Scale(1. / 2.); // points now to center of base line 1375 BaseLine.CopyVector(baseline->second->endpoints[0]->node->node); 1376 BaseLine.SubtractVector(baseline->second->endpoints[1]->node->node); 1450 BaseLineCenter = 0.5 * ((*baseline->second->endpoints[0]->node->node) + 1451 (*baseline->second->endpoints[1]->node->node)); 1452 BaseLine = (*baseline->second->endpoints[0]->node->node) - (*baseline->second->endpoints[1]->node->node); 1377 1453 1378 1454 // offset to center of triangle 1379 1455 CenterVector.Zero(); 1380 1456 for (int i = 0; i < 3; i++) 1381 CenterVector .AddVector(BTS->endpoints[i]->node->node);1457 CenterVector += (*BTS->endpoints[i]->node->node); 1382 1458 CenterVector.Scale(1. / 3.); 1383 Log() << Verbose(2) << "CenterVector of base triangle is " << CenterVector << endl;1459 DoLog(2) && (Log() << Verbose(2) << "CenterVector of base triangle is " << CenterVector << endl); 1384 1460 1385 1461 // normal vector of triangle 1386 NormalVector.CopyVector(Center); 1387 NormalVector.SubtractVector(&CenterVector); 1462 NormalVector = (*Center) - CenterVector; 1388 1463 BTS->GetNormalVector(NormalVector); 1389 NormalVector .CopyVector(&BTS->NormalVector);1390 Log() << Verbose(2) << "NormalVector of base triangle is " << NormalVector << endl;1464 NormalVector = BTS->NormalVector; 1465 DoLog(2) && (Log() << Verbose(2) << "NormalVector of base triangle is " << NormalVector << endl); 1391 1466 1392 1467 // vector in propagation direction (out of triangle) 1393 1468 // project center vector onto triangle plane (points from intersection plane-NormalVector to plane-CenterVector intersection) 1394 PropagationVector.MakeNormalVector(&BaseLine, &NormalVector); 1395 TempVector.CopyVector(&CenterVector); 1396 TempVector.SubtractVector(baseline->second->endpoints[0]->node->node); // TempVector is vector on triangle plane pointing from one baseline egde towards center! 1469 PropagationVector = Plane(BaseLine, NormalVector,0).getNormal(); 1470 TempVector = CenterVector - (*baseline->second->endpoints[0]->node->node); // TempVector is vector on triangle plane pointing from one baseline egde towards center! 1397 1471 //Log() << Verbose(0) << "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << "." << endl; 1398 if (PropagationVector.ScalarProduct( &TempVector) > 0) // make sure normal propagation vector points outward from baseline1472 if (PropagationVector.ScalarProduct(TempVector) > 0) // make sure normal propagation vector points outward from baseline 1399 1473 PropagationVector.Scale(-1.); 1400 Log() << Verbose(2) << "PropagationVector of base triangle is " << PropagationVector << endl;1474 DoLog(2) && (Log() << Verbose(2) << "PropagationVector of base triangle is " << PropagationVector << endl); 1401 1475 winner = PointsOnBoundary.end(); 1402 1476 … … 1404 1478 for (PointMap::iterator target = PointsOnBoundary.begin(); target != PointsOnBoundary.end(); target++) { 1405 1479 if ((target->second != baseline->second->endpoints[0]) && (target->second != baseline->second->endpoints[1])) { // don't take the same endpoints 1406 Log() << Verbose(1) << "Target point is " << *(target->second) << ":" << endl;1480 DoLog(1) && (Log() << Verbose(1) << "Target point is " << *(target->second) << ":" << endl); 1407 1481 1408 1482 // first check direction, so that triangles don't intersect 1409 VirtualNormalVector.CopyVector(target->second->node->node); 1410 VirtualNormalVector.SubtractVector(&BaseLineCenter); // points from center of base line to target 1411 VirtualNormalVector.ProjectOntoPlane(&NormalVector); 1412 TempAngle = VirtualNormalVector.Angle(&PropagationVector); 1413 Log() << Verbose(2) << "VirtualNormalVector is " << VirtualNormalVector << " and PropagationVector is " << PropagationVector << "." << endl; 1414 if (TempAngle > (M_PI/2.)) { // no bends bigger than Pi/2 (90 degrees) 1415 Log() << Verbose(2) << "Angle on triangle plane between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", bad direction!" << endl; 1483 VirtualNormalVector = (*target->second->node->node) - BaseLineCenter; 1484 VirtualNormalVector.ProjectOntoPlane(NormalVector); 1485 TempAngle = VirtualNormalVector.Angle(PropagationVector); 1486 DoLog(2) && (Log() << Verbose(2) << "VirtualNormalVector is " << VirtualNormalVector << " and PropagationVector is " << PropagationVector << "." << endl); 1487 if (TempAngle > (M_PI / 2.)) { // no bends bigger than Pi/2 (90 degrees) 1488 DoLog(2) && (Log() << Verbose(2) << "Angle on triangle plane between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", bad direction!" << endl); 1416 1489 continue; 1417 1490 } else 1418 Log() << Verbose(2) << "Angle on triangle plane between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", good direction!" << endl;1491 DoLog(2) && (Log() << Verbose(2) << "Angle on triangle plane between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", good direction!" << endl); 1419 1492 1420 1493 // check first and second endpoint (if any connecting line goes to target has at least not more than 1 triangle) … … 1422 1495 LineChecker[1] = baseline->second->endpoints[1]->lines.find(target->first); 1423 1496 if (((LineChecker[0] != baseline->second->endpoints[0]->lines.end()) && (LineChecker[0]->second->triangles.size() == 2))) { 1424 Log() << Verbose(2) << *(baseline->second->endpoints[0]) << " has line " << *(LineChecker[0]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[0]->second->triangles.size() << " triangles." << endl;1497 DoLog(2) && (Log() << Verbose(2) << *(baseline->second->endpoints[0]) << " has line " << *(LineChecker[0]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[0]->second->triangles.size() << " triangles." << endl); 1425 1498 continue; 1426 1499 } 1427 1500 if (((LineChecker[1] != baseline->second->endpoints[1]->lines.end()) && (LineChecker[1]->second->triangles.size() == 2))) { 1428 Log() << Verbose(2) << *(baseline->second->endpoints[1]) << " has line " << *(LineChecker[1]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[1]->second->triangles.size() << " triangles." << endl;1501 DoLog(2) && (Log() << Verbose(2) << *(baseline->second->endpoints[1]) << " has line " << *(LineChecker[1]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[1]->second->triangles.size() << " triangles." << endl); 1429 1502 continue; 1430 1503 } … … 1432 1505 // check whether the envisaged triangle does not already exist (if both lines exist and have same endpoint) 1433 1506 if ((((LineChecker[0] != baseline->second->endpoints[0]->lines.end()) && (LineChecker[1] != baseline->second->endpoints[1]->lines.end()) && (GetCommonEndpoint(LineChecker[0]->second, LineChecker[1]->second) == peak)))) { 1434 Log() << Verbose(4) << "Current target is peak!" << endl;1507 DoLog(4) && (Log() << Verbose(4) << "Current target is peak!" << endl); 1435 1508 continue; 1436 1509 } 1437 1510 1438 1511 // check for linear dependence 1439 TempVector.CopyVector(baseline->second->endpoints[0]->node->node); 1440 TempVector.SubtractVector(target->second->node->node); 1441 helper.CopyVector(baseline->second->endpoints[1]->node->node); 1442 helper.SubtractVector(target->second->node->node); 1443 helper.ProjectOntoPlane(&TempVector); 1512 TempVector = (*baseline->second->endpoints[0]->node->node) - (*target->second->node->node); 1513 helper = (*baseline->second->endpoints[1]->node->node) - (*target->second->node->node); 1514 helper.ProjectOntoPlane(TempVector); 1444 1515 if (fabs(helper.NormSquared()) < MYEPSILON) { 1445 Log() << Verbose(2) << "Chosen set of vectors is linear dependent." << endl;1516 DoLog(2) && (Log() << Verbose(2) << "Chosen set of vectors is linear dependent." << endl); 1446 1517 continue; 1447 1518 } … … 1449 1520 // in case NOT both were found, create virtually this triangle, get its normal vector, calculate angle 1450 1521 flag = true; 1451 VirtualNormalVector.MakeNormalVector(baseline->second->endpoints[0]->node->node, baseline->second->endpoints[1]->node->node, target->second->node->node); 1452 TempVector.CopyVector(baseline->second->endpoints[0]->node->node); 1453 TempVector.AddVector(baseline->second->endpoints[1]->node->node); 1454 TempVector.AddVector(target->second->node->node); 1455 TempVector.Scale(1./3.); 1456 TempVector.SubtractVector(Center); 1522 VirtualNormalVector = Plane(*(baseline->second->endpoints[0]->node->node), 1523 *(baseline->second->endpoints[1]->node->node), 1524 *(target->second->node->node)).getNormal(); 1525 TempVector = (1./3.) * ((*baseline->second->endpoints[0]->node->node) + 1526 (*baseline->second->endpoints[1]->node->node) + 1527 (*target->second->node->node)); 1528 TempVector -= (*Center); 1457 1529 // make it always point outward 1458 if (VirtualNormalVector.ScalarProduct( &TempVector) < 0)1530 if (VirtualNormalVector.ScalarProduct(TempVector) < 0) 1459 1531 VirtualNormalVector.Scale(-1.); 1460 1532 // calculate angle 1461 TempAngle = NormalVector.Angle( &VirtualNormalVector);1462 Log() << Verbose(2) << "NormalVector is " << VirtualNormalVector << " and the angle is " << TempAngle << "." << endl;1533 TempAngle = NormalVector.Angle(VirtualNormalVector); 1534 DoLog(2) && (Log() << Verbose(2) << "NormalVector is " << VirtualNormalVector << " and the angle is " << TempAngle << "." << endl); 1463 1535 if ((SmallestAngle - TempAngle) > MYEPSILON) { // set to new possible winner 1464 1536 SmallestAngle = TempAngle; 1465 1537 winner = target; 1466 Log() << Verbose(2) << "New winner " << *winner->second->node << " due to smaller angle between normal vectors." << endl;1538 DoLog(2) && (Log() << Verbose(2) << "New winner " << *winner->second->node << " due to smaller angle between normal vectors." << endl); 1467 1539 } else if (fabs(SmallestAngle - TempAngle) < MYEPSILON) { // check the angle to propagation, both possible targets are in one plane! (their normals have same angle) 1468 1540 // hence, check the angles to some normal direction from our base line but in this common plane of both targets... 1469 helper.CopyVector(target->second->node->node); 1470 helper.SubtractVector(&BaseLineCenter); 1471 helper.ProjectOntoPlane(&BaseLine); 1541 helper = (*target->second->node->node) - BaseLineCenter; 1542 helper.ProjectOntoPlane(BaseLine); 1472 1543 // ...the one with the smaller angle is the better candidate 1473 TempVector.CopyVector(target->second->node->node); 1474 TempVector.SubtractVector(&BaseLineCenter); 1475 TempVector.ProjectOntoPlane(&VirtualNormalVector); 1476 TempAngle = TempVector.Angle(&helper); 1477 TempVector.CopyVector(winner->second->node->node); 1478 TempVector.SubtractVector(&BaseLineCenter); 1479 TempVector.ProjectOntoPlane(&VirtualNormalVector); 1480 if (TempAngle < TempVector.Angle(&helper)) { 1481 TempAngle = NormalVector.Angle(&VirtualNormalVector); 1544 TempVector = (*target->second->node->node) - BaseLineCenter; 1545 TempVector.ProjectOntoPlane(VirtualNormalVector); 1546 TempAngle = TempVector.Angle(helper); 1547 TempVector = (*winner->second->node->node) - BaseLineCenter; 1548 TempVector.ProjectOntoPlane(VirtualNormalVector); 1549 if (TempAngle < TempVector.Angle(helper)) { 1550 TempAngle = NormalVector.Angle(VirtualNormalVector); 1482 1551 SmallestAngle = TempAngle; 1483 1552 winner = target; 1484 Log() << Verbose(2) << "New winner " << *winner->second->node << " due to smaller angle " << TempAngle << " to propagation direction." << endl;1553 DoLog(2) && (Log() << Verbose(2) << "New winner " << *winner->second->node << " due to smaller angle " << TempAngle << " to propagation direction." << endl); 1485 1554 } else 1486 Log() << Verbose(2) << "Keeping old winner " << *winner->second->node << " due to smaller angle to propagation direction." << endl;1555 DoLog(2) && (Log() << Verbose(2) << "Keeping old winner " << *winner->second->node << " due to smaller angle to propagation direction." << endl); 1487 1556 } else 1488 Log() << Verbose(2) << "Keeping old winner " << *winner->second->node << " due to smaller angle between normal vectors." << endl;1557 DoLog(2) && (Log() << Verbose(2) << "Keeping old winner " << *winner->second->node << " due to smaller angle between normal vectors." << endl); 1489 1558 } 1490 1559 } // end of loop over all boundary points … … 1492 1561 // 5b. The point of the above whose triangle has the greatest angle with the triangle the current line belongs to (it only belongs to one, remember!): New triangle 1493 1562 if (winner != PointsOnBoundary.end()) { 1494 Log() << Verbose(0) << "Winning target point is " << *(winner->second) << " with angle " << SmallestAngle << "." << endl;1563 DoLog(0) && (Log() << Verbose(0) << "Winning target point is " << *(winner->second) << " with angle " << SmallestAngle << "." << endl); 1495 1564 // create the lins of not yet present 1496 1565 BLS[0] = baseline->second; … … 1516 1585 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 1517 1586 BTS->GetCenter(&helper); 1518 helper .SubtractVector(Center);1519 helper .Scale(-1);1587 helper -= (*Center); 1588 helper *= -1; 1520 1589 BTS->GetNormalVector(helper); 1521 1590 TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS)); 1522 1591 TrianglesOnBoundaryCount++; 1523 1592 } else { 1524 eLog() << Verbose(2) << "I could not determine a winner for this baseline " << *(baseline->second) << "." << endl;1593 DoeLog(2) && (eLog() << Verbose(2) << "I could not determine a winner for this baseline " << *(baseline->second) << "." << endl); 1525 1594 } 1526 1595 1527 1596 // 5d. If the set of lines is not yet empty, go to 5. and continue 1528 1597 } else 1529 Log() << Verbose(0) << "Baseline candidate " << *(baseline->second) << " has a triangle count of " << baseline->second->triangles.size() << "." << endl;1598 DoLog(0) && (Log() << Verbose(0) << "Baseline candidate " << *(baseline->second) << " has a triangle count of " << baseline->second->triangles.size() << "." << endl); 1530 1599 } while (flag); 1531 1600 1532 1601 // exit 1533 delete(Center); 1534 }; 1602 delete (Center); 1603 } 1604 ; 1535 1605 1536 1606 /** Inserts all points outside of the tesselated surface into it by adding new triangles. … … 1542 1612 bool Tesselation::InsertStraddlingPoints(const PointCloud *cloud, const LinkedCell *LC) 1543 1613 { 1544 1614 Info FunctionInfo(__func__); 1545 1615 Vector Intersection, Normal; 1546 1616 TesselPoint *Walker = NULL; … … 1552 1622 cloud->GoToFirst(); 1553 1623 BoundaryPoints = new LinkedCell(this, 5.); 1554 while (!cloud->IsEnd()) { 1624 while (!cloud->IsEnd()) { // we only have to go once through all points, as boundary can become only bigger 1555 1625 if (AddFlag) { 1556 delete (BoundaryPoints);1626 delete (BoundaryPoints); 1557 1627 BoundaryPoints = new LinkedCell(this, 5.); 1558 1628 AddFlag = false; 1559 1629 } 1560 1630 Walker = cloud->GetPoint(); 1561 Log() << Verbose(0) << "Current point is " << *Walker << "." << endl;1631 DoLog(0) && (Log() << Verbose(0) << "Current point is " << *Walker << "." << endl); 1562 1632 // get the next triangle 1563 1633 triangles = FindClosestTrianglesToVector(Walker->node, BoundaryPoints); 1564 1634 BTS = triangles->front(); 1565 1635 if ((triangles == NULL) || (BTS->ContainsBoundaryPoint(Walker))) { 1566 Log() << Verbose(0) << "No triangles found, probably a tesselation point itself." << endl;1636 DoLog(0) && (Log() << Verbose(0) << "No triangles found, probably a tesselation point itself." << endl); 1567 1637 cloud->GoToNext(); 1568 1638 continue; 1569 1639 } else { 1570 1640 } 1571 Log() << Verbose(0) << "Closest triangle is " << *BTS << "." << endl;1641 DoLog(0) && (Log() << Verbose(0) << "Closest triangle is " << *BTS << "." << endl); 1572 1642 // get the intersection point 1573 1643 if (BTS->GetIntersectionInsideTriangle(Center, Walker->node, &Intersection)) { 1574 Log() << Verbose(0) << "We have an intersection at " << Intersection << "." << endl;1644 DoLog(0) && (Log() << Verbose(0) << "We have an intersection at " << Intersection << "." << endl); 1575 1645 // we have the intersection, check whether in- or outside of boundary 1576 if ((Center->DistanceSquared( Walker->node) - Center->DistanceSquared(&Intersection)) < -MYEPSILON) {1646 if ((Center->DistanceSquared(*Walker->node) - Center->DistanceSquared(Intersection)) < -MYEPSILON) { 1577 1647 // inside, next! 1578 Log() << Verbose(0) << *Walker << " is inside wrt triangle " << *BTS << "." << endl;1648 DoLog(0) && (Log() << Verbose(0) << *Walker << " is inside wrt triangle " << *BTS << "." << endl); 1579 1649 } else { 1580 1650 // outside! 1581 Log() << Verbose(0) << *Walker << " is outside wrt triangle " << *BTS << "." << endl;1651 DoLog(0) && (Log() << Verbose(0) << *Walker << " is outside wrt triangle " << *BTS << "." << endl); 1582 1652 class BoundaryLineSet *OldLines[3], *NewLines[3]; 1583 1653 class BoundaryPointSet *OldPoints[3], *NewPoint; 1584 1654 // store the three old lines and old points 1585 for (int i =0;i<3;i++) {1655 for (int i = 0; i < 3; i++) { 1586 1656 OldLines[i] = BTS->lines[i]; 1587 1657 OldPoints[i] = BTS->endpoints[i]; 1588 1658 } 1589 Normal .CopyVector(&BTS->NormalVector);1659 Normal = BTS->NormalVector; 1590 1660 // add Walker to boundary points 1591 Log() << Verbose(0) << "Adding " << *Walker << " to BoundaryPoints." << endl;1661 DoLog(0) && (Log() << Verbose(0) << "Adding " << *Walker << " to BoundaryPoints." << endl); 1592 1662 AddFlag = true; 1593 if (AddBoundaryPoint(Walker, 0))1663 if (AddBoundaryPoint(Walker, 0)) 1594 1664 NewPoint = BPS[0]; 1595 1665 else 1596 1666 continue; 1597 1667 // remove triangle 1598 Log() << Verbose(0) << "Erasing triangle " << *BTS << "." << endl;1668 DoLog(0) && (Log() << Verbose(0) << "Erasing triangle " << *BTS << "." << endl); 1599 1669 TrianglesOnBoundary.erase(BTS->Nr); 1600 delete (BTS);1670 delete (BTS); 1601 1671 // create three new boundary lines 1602 for (int i =0;i<3;i++) {1672 for (int i = 0; i < 3; i++) { 1603 1673 BPS[0] = NewPoint; 1604 1674 BPS[1] = OldPoints[i]; 1605 1675 NewLines[i] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount); 1606 Log() << Verbose(1) << "Creating new line " << *NewLines[i] << "." << endl;1676 DoLog(1) && (Log() << Verbose(1) << "Creating new line " << *NewLines[i] << "." << endl); 1607 1677 LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount, NewLines[i])); // no need for check for unique insertion as BPS[0] is definitely a new one 1608 1678 LinesOnBoundaryCount++; 1609 1679 } 1610 1680 // create three new triangle with new point 1611 for (int i =0;i<3;i++) { // find all baselines1681 for (int i = 0; i < 3; i++) { // find all baselines 1612 1682 BLS[0] = OldLines[i]; 1613 1683 int n = 1; 1614 for (int j =0;j<3;j++) {1684 for (int j = 0; j < 3; j++) { 1615 1685 if (NewLines[j]->IsConnectedTo(BLS[0])) { 1616 if (n >2) {1617 eLog() << Verbose(2) << BLS[0] << " connects to all of the new lines?!" << endl;1686 if (n > 2) { 1687 DoeLog(2) && (eLog() << Verbose(2) << BLS[0] << " connects to all of the new lines?!" << endl); 1618 1688 return false; 1619 1689 } else … … 1626 1696 BTS->GetNormalVector(Normal); 1627 1697 Normal.Scale(-1.); 1628 Log() << Verbose(0) << "Created new triangle " << *BTS << "." << endl;1698 DoLog(0) && (Log() << Verbose(0) << "Created new triangle " << *BTS << "." << endl); 1629 1699 TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS)); 1630 1700 TrianglesOnBoundaryCount++; … … 1632 1702 } 1633 1703 } else { // something is wrong with FindClosestTriangleToPoint! 1634 eLog() << Verbose(1) << "The closest triangle did not produce an intersection!" << endl;1704 DoeLog(1) && (eLog() << Verbose(1) << "The closest triangle did not produce an intersection!" << endl); 1635 1705 return false; 1636 1706 } … … 1639 1709 1640 1710 // exit 1641 delete (Center);1711 delete (Center); 1642 1712 return true; 1643 }; 1713 } 1714 ; 1644 1715 1645 1716 /** Adds a point to the tesselation::PointsOnBoundary list. … … 1650 1721 bool Tesselation::AddBoundaryPoint(TesselPoint * Walker, const int n) 1651 1722 { 1652 1723 Info FunctionInfo(__func__); 1653 1724 PointTestPair InsertUnique; 1654 1725 BPS[n] = new class BoundaryPointSet(Walker); … … 1658 1729 return true; 1659 1730 } else { 1660 delete (BPS[n]);1731 delete (BPS[n]); 1661 1732 BPS[n] = InsertUnique.first->second; 1662 1733 return false; … … 1672 1743 void Tesselation::AddTesselationPoint(TesselPoint* Candidate, const int n) 1673 1744 { 1674 1745 Info FunctionInfo(__func__); 1675 1746 PointTestPair InsertUnique; 1676 1747 TPS[n] = new class BoundaryPointSet(Candidate); … … 1680 1751 } else { 1681 1752 delete TPS[n]; 1682 Log() << Verbose(0) << "Node " << *((InsertUnique.first)->second->node) << " is already present in PointsOnBoundary." << endl;1753 DoLog(0) && (Log() << Verbose(0) << "Node " << *((InsertUnique.first)->second->node) << " is already present in PointsOnBoundary." << endl); 1683 1754 TPS[n] = (InsertUnique.first)->second; 1684 1755 } … … 1693 1764 void Tesselation::SetTesselationPoint(TesselPoint* Candidate, const int n) const 1694 1765 { 1695 1766 Info FunctionInfo(__func__); 1696 1767 PointMap::const_iterator FindPoint = PointsOnBoundary.find(Candidate->nr); 1697 1768 if (FindPoint != PointsOnBoundary.end()) … … 1699 1770 else 1700 1771 TPS[n] = NULL; 1701 }; 1772 } 1773 ; 1702 1774 1703 1775 /** Function tries to add line from current Points in BPS to BoundaryLineSet. 1704 1776 * If successful it raises the line count and inserts the new line into the BLS, 1705 1777 * if unsuccessful, it writes the line which had been present into the BLS, deleting the new constructed one. 1778 * @param *OptCenter desired OptCenter if there are more than one candidate line 1779 * @param *candidate third point of the triangle to be, for checking between multiple open line candidates 1706 1780 * @param *a first endpoint 1707 1781 * @param *b second endpoint 1708 1782 * @param n index of Tesselation::BLS giving the line with both endpoints 1709 1783 */ 1710 void Tesselation::AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n) { 1784 void Tesselation::AddTesselationLine(const Vector * const OptCenter, const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n) 1785 { 1711 1786 bool insertNewLine = true; 1712 1713 1787 LineMap::iterator FindLine = a->lines.find(b->node->nr); 1788 BoundaryLineSet *WinningLine = NULL; 1714 1789 if (FindLine != a->lines.end()) { 1715 Log() << Verbose(1) << "INFO: There is at least one line between " << *a << " and " << *b << ": " << *(FindLine->second) << "." << endl;1716 1717 pair<LineMap::iterator, LineMap::iterator> FindPair;1790 DoLog(1) && (Log() << Verbose(1) << "INFO: There is at least one line between " << *a << " and " << *b << ": " << *(FindLine->second) << "." << endl); 1791 1792 pair<LineMap::iterator, LineMap::iterator> FindPair; 1718 1793 FindPair = a->lines.equal_range(b->node->nr); 1719 1794 1720 for (FindLine = FindPair.first; FindLine != FindPair.second; FindLine++) { 1795 for (FindLine = FindPair.first; (FindLine != FindPair.second) && (insertNewLine); FindLine++) { 1796 DoLog(1) && (Log() << Verbose(1) << "INFO: Checking line " << *(FindLine->second) << " ..." << endl); 1721 1797 // If there is a line with less than two attached triangles, we don't need a new line. 1722 if (FindLine->second->triangles.size() < 2) {1723 insertNewLine = false;1724 Log() << Verbose(0) << "Using existing line " << *FindLine->second << endl;1725 1726 BPS[0] = FindLine->second->endpoints[0];1727 BPS[1] = FindLine->second->endpoints[1];1728 BLS[n] = FindLine->second;1729 1730 // remove existing line from OpenLines1731 CandidateMap::iterator CandidateLine = OpenLines.find(BLS[n]);1732 if (CandidateLine != OpenLines.end()) {1733 Log() << Verbose(1) << " Removing line from OpenLines." << endl;1734 delete(CandidateLine->second);1735 OpenLines.erase(CandidateLine);1736 } else {1737 eLog() << Verbose(1) << "Line exists and is attached to less than two triangles, but not in OpenLines!" << endl;1798 if (FindLine->second->triangles.size() == 1) { 1799 CandidateMap::iterator Finder = OpenLines.find(FindLine->second); 1800 if (!Finder->second->pointlist.empty()) 1801 DoLog(1) && (Log() << Verbose(1) << "INFO: line " << *(FindLine->second) << " is open with candidate " << **(Finder->second->pointlist.begin()) << "." << endl); 1802 else 1803 DoLog(1) && (Log() << Verbose(1) << "INFO: line " << *(FindLine->second) << " is open with no candidate." << endl); 1804 // get open line 1805 for (TesselPointList::const_iterator CandidateChecker = Finder->second->pointlist.begin(); CandidateChecker != Finder->second->pointlist.end(); ++CandidateChecker) { 1806 if ((*(CandidateChecker) == candidate->node) && (OptCenter == NULL || OptCenter->DistanceSquared(Finder->second->OptCenter) < MYEPSILON )) { // stop searching if candidate matches 1807 DoLog(1) && (Log() << Verbose(1) << "ACCEPT: Candidate " << *(*CandidateChecker) << " has the right center " << Finder->second->OptCenter << "." << endl); 1808 insertNewLine = false; 1809 WinningLine = FindLine->second; 1810 break; 1811 } else { 1812 DoLog(1) && (Log() << Verbose(1) << "REJECT: Candidate " << *(*CandidateChecker) << "'s center " << Finder->second->OptCenter << " does not match desired on " << *OptCenter << "." << endl); 1813 } 1738 1814 } 1739 1740 break;1741 1815 } 1742 1816 } … … 1744 1818 1745 1819 if (insertNewLine) { 1746 AlwaysAddTesselationTriangleLine(a, b, n); 1820 AddNewTesselationTriangleLine(a, b, n); 1821 } else { 1822 AddExistingTesselationTriangleLine(WinningLine, n); 1747 1823 } 1748 1824 } … … 1757 1833 * @param n index of Tesselation::BLS giving the line with both endpoints 1758 1834 */ 1759 void Tesselation::A lwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n)1760 { 1761 1762 Log() << Verbose(0) << "Adding open line [" << LinesOnBoundaryCount << "|" << *(a->node) << " and " << *(b->node) << "." << endl;1835 void Tesselation::AddNewTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n) 1836 { 1837 Info FunctionInfo(__func__); 1838 DoLog(0) && (Log() << Verbose(0) << "Adding open line [" << LinesOnBoundaryCount << "|" << *(a->node) << " and " << *(b->node) << "." << endl); 1763 1839 BPS[0] = a; 1764 1840 BPS[1] = b; 1765 BLS[n] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount); 1841 BLS[n] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount); // this also adds the line to the local maps 1766 1842 // add line to global map 1767 1843 LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount, BLS[n])); … … 1770 1846 // also add to open lines 1771 1847 CandidateForTesselation *CFT = new CandidateForTesselation(BLS[n]); 1772 OpenLines.insert(pair< BoundaryLineSet *, CandidateForTesselation *> (BLS[n], CFT)); 1773 }; 1848 OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *> (BLS[n], CFT)); 1849 } 1850 ; 1851 1852 /** Uses an existing line for a new triangle. 1853 * Sets Tesselation::BLS[\a n] and removes the lines from Tesselation::OpenLines. 1854 * \param *FindLine the line to add 1855 * \param n index of the line to set in Tesselation::BLS 1856 */ 1857 void Tesselation::AddExistingTesselationTriangleLine(class BoundaryLineSet *Line, int n) 1858 { 1859 Info FunctionInfo(__func__); 1860 DoLog(0) && (Log() << Verbose(0) << "Using existing line " << *Line << endl); 1861 1862 // set endpoints and line 1863 BPS[0] = Line->endpoints[0]; 1864 BPS[1] = Line->endpoints[1]; 1865 BLS[n] = Line; 1866 // remove existing line from OpenLines 1867 CandidateMap::iterator CandidateLine = OpenLines.find(BLS[n]); 1868 if (CandidateLine != OpenLines.end()) { 1869 DoLog(1) && (Log() << Verbose(1) << " Removing line from OpenLines." << endl); 1870 delete (CandidateLine->second); 1871 OpenLines.erase(CandidateLine); 1872 } else { 1873 DoeLog(1) && (eLog() << Verbose(1) << "Line exists and is attached to less than two triangles, but not in OpenLines!" << endl); 1874 } 1875 } 1876 ; 1774 1877 1775 1878 /** Function adds triangle to global list. … … 1778 1881 void Tesselation::AddTesselationTriangle() 1779 1882 { 1780 1781 Log() << Verbose(1) << "Adding triangle to global TrianglesOnBoundary map." << endl;1883 Info FunctionInfo(__func__); 1884 DoLog(1) && (Log() << Verbose(1) << "Adding triangle to global TrianglesOnBoundary map." << endl); 1782 1885 1783 1886 // add triangle to global map … … 1789 1892 1790 1893 // NOTE: add triangle to local maps is done in constructor of BoundaryTriangleSet 1791 }; 1894 } 1895 ; 1792 1896 1793 1897 /** Function adds triangle to global list. … … 1797 1901 void Tesselation::AddTesselationTriangle(const int nr) 1798 1902 { 1799 1800 Log() << Verbose(0) << "Adding triangle to global TrianglesOnBoundary map." << endl;1903 Info FunctionInfo(__func__); 1904 DoLog(0) && (Log() << Verbose(0) << "Adding triangle to global TrianglesOnBoundary map." << endl); 1801 1905 1802 1906 // add triangle to global map … … 1807 1911 1808 1912 // NOTE: add triangle to local maps is done in constructor of BoundaryTriangleSet 1809 }; 1913 } 1914 ; 1810 1915 1811 1916 /** Removes a triangle from the tesselation. … … 1816 1921 void Tesselation::RemoveTesselationTriangle(class BoundaryTriangleSet *triangle) 1817 1922 { 1818 1923 Info FunctionInfo(__func__); 1819 1924 if (triangle == NULL) 1820 1925 return; 1821 1926 for (int i = 0; i < 3; i++) { 1822 1927 if (triangle->lines[i] != NULL) { 1823 Log() << Verbose(0) << "Removing triangle Nr." << triangle->Nr << " in line " << *triangle->lines[i] << "." << endl;1928 DoLog(0) && (Log() << Verbose(0) << "Removing triangle Nr." << triangle->Nr << " in line " << *triangle->lines[i] << "." << endl); 1824 1929 triangle->lines[i]->triangles.erase(triangle->Nr); 1825 1930 if (triangle->lines[i]->triangles.empty()) { 1826 Log() << Verbose(0) << *triangle->lines[i] << " is no more attached to any triangle, erasing." << endl;1827 1931 DoLog(0) && (Log() << Verbose(0) << *triangle->lines[i] << " is no more attached to any triangle, erasing." << endl); 1932 RemoveTesselationLine(triangle->lines[i]); 1828 1933 } else { 1829 Log() << Verbose(0) << *triangle->lines[i] << " is still attached to another triangle: ";1830 OpenLines.insert(pair< 1831 for (TriangleMap::iterator TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); TriangleRunner++)1832 Log() << Verbose(0) << "[" << (TriangleRunner->second)->Nr << "|" << *((TriangleRunner->second)->endpoints[0]) << ", " << *((TriangleRunner->second)->endpoints[1]) << ", " << *((TriangleRunner->second)->endpoints[2]) << "] \t";1833 Log() << Verbose(0) << endl;1834 // for (int j=0;j<2;j++) {1835 // Log() << Verbose(0) << "Lines of endpoint " << *(triangle->lines[i]->endpoints[j]) << ": ";1836 // for(LineMap::iterator LineRunner = triangle->lines[i]->endpoints[j]->lines.begin(); LineRunner != triangle->lines[i]->endpoints[j]->lines.end(); LineRunner++)1837 // Log() << Verbose(0) << "[" << *(LineRunner->second) << "] \t";1838 // Log() << Verbose(0) << endl;1839 // }1934 DoLog(0) && (Log() << Verbose(0) << *triangle->lines[i] << " is still attached to another triangle: "); 1935 OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *> (triangle->lines[i], NULL)); 1936 for (TriangleMap::iterator TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); TriangleRunner++) 1937 DoLog(0) && (Log() << Verbose(0) << "[" << (TriangleRunner->second)->Nr << "|" << *((TriangleRunner->second)->endpoints[0]) << ", " << *((TriangleRunner->second)->endpoints[1]) << ", " << *((TriangleRunner->second)->endpoints[2]) << "] \t"); 1938 DoLog(0) && (Log() << Verbose(0) << endl); 1939 // for (int j=0;j<2;j++) { 1940 // Log() << Verbose(0) << "Lines of endpoint " << *(triangle->lines[i]->endpoints[j]) << ": "; 1941 // for(LineMap::iterator LineRunner = triangle->lines[i]->endpoints[j]->lines.begin(); LineRunner != triangle->lines[i]->endpoints[j]->lines.end(); LineRunner++) 1942 // Log() << Verbose(0) << "[" << *(LineRunner->second) << "] \t"; 1943 // Log() << Verbose(0) << endl; 1944 // } 1840 1945 } 1841 triangle->lines[i] = NULL; 1946 triangle->lines[i] = NULL; // free'd or not: disconnect 1842 1947 } else 1843 eLog() << Verbose(1) << "This line " << i << " has already been free'd." << endl;1948 DoeLog(1) && (eLog() << Verbose(1) << "This line " << i << " has already been free'd." << endl); 1844 1949 } 1845 1950 1846 1951 if (TrianglesOnBoundary.erase(triangle->Nr)) 1847 Log() << Verbose(0) << "Removing triangle Nr. " << triangle->Nr << "." << endl; 1848 delete(triangle); 1849 }; 1952 DoLog(0) && (Log() << Verbose(0) << "Removing triangle Nr. " << triangle->Nr << "." << endl); 1953 delete (triangle); 1954 } 1955 ; 1850 1956 1851 1957 /** Removes a line from the tesselation. … … 1855 1961 void Tesselation::RemoveTesselationLine(class BoundaryLineSet *line) 1856 1962 { 1857 1963 Info FunctionInfo(__func__); 1858 1964 int Numbers[2]; 1859 1965 … … 1876 1982 for (LineMap::iterator Runner = erasor.first; Runner != erasor.second; Runner++) 1877 1983 if ((*Runner).second == line) { 1878 Log() << Verbose(0) << "Removing Line Nr. " << line->Nr << " in boundary point " << *line->endpoints[i] << "." << endl;1984 DoLog(0) && (Log() << Verbose(0) << "Removing Line Nr. " << line->Nr << " in boundary point " << *line->endpoints[i] << "." << endl); 1879 1985 line->endpoints[i]->lines.erase(Runner); 1880 1986 break; … … 1882 1988 } else { // there's just a single line left 1883 1989 if (line->endpoints[i]->lines.erase(line->Nr)) 1884 Log() << Verbose(0) << "Removing Line Nr. " << line->Nr << " in boundary point " << *line->endpoints[i] << "." << endl;1990 DoLog(0) && (Log() << Verbose(0) << "Removing Line Nr. " << line->Nr << " in boundary point " << *line->endpoints[i] << "." << endl); 1885 1991 } 1886 1992 if (line->endpoints[i]->lines.empty()) { 1887 Log() << Verbose(0) << *line->endpoints[i] << " has no more lines it's attached to, erasing." << endl;1993 DoLog(0) && (Log() << Verbose(0) << *line->endpoints[i] << " has no more lines it's attached to, erasing." << endl); 1888 1994 RemoveTesselationPoint(line->endpoints[i]); 1889 1995 } else { 1890 Log() << Verbose(0) << *line->endpoints[i] << " has still lines it's attached to: ";1891 for (LineMap::iterator LineRunner = line->endpoints[i]->lines.begin(); LineRunner != line->endpoints[i]->lines.end(); LineRunner++)1892 Log() << Verbose(0) << "[" << *(LineRunner->second) << "] \t";1893 Log() << Verbose(0) << endl;1996 DoLog(0) && (Log() << Verbose(0) << *line->endpoints[i] << " has still lines it's attached to: "); 1997 for (LineMap::iterator LineRunner = line->endpoints[i]->lines.begin(); LineRunner != line->endpoints[i]->lines.end(); LineRunner++) 1998 DoLog(0) && (Log() << Verbose(0) << "[" << *(LineRunner->second) << "] \t"); 1999 DoLog(0) && (Log() << Verbose(0) << endl); 1894 2000 } 1895 line->endpoints[i] = NULL; 2001 line->endpoints[i] = NULL; // free'd or not: disconnect 1896 2002 } else 1897 eLog() << Verbose(1) << "Endpoint " << i << " has already been free'd." << endl;2003 DoeLog(1) && (eLog() << Verbose(1) << "Endpoint " << i << " has already been free'd." << endl); 1898 2004 } 1899 2005 if (!line->triangles.empty()) 1900 eLog() << Verbose(2) << "Memory Leak! I " << *line << " am still connected to some triangles." << endl;2006 DoeLog(2) && (eLog() << Verbose(2) << "Memory Leak! I " << *line << " am still connected to some triangles." << endl); 1901 2007 1902 2008 if (LinesOnBoundary.erase(line->Nr)) 1903 Log() << Verbose(0) << "Removing line Nr. " << line->Nr << "." << endl; 1904 delete(line); 1905 }; 2009 DoLog(0) && (Log() << Verbose(0) << "Removing line Nr. " << line->Nr << "." << endl); 2010 delete (line); 2011 } 2012 ; 1906 2013 1907 2014 /** Removes a point from the tesselation. … … 1912 2019 void Tesselation::RemoveTesselationPoint(class BoundaryPointSet *point) 1913 2020 { 1914 2021 Info FunctionInfo(__func__); 1915 2022 if (point == NULL) 1916 2023 return; 1917 2024 if (PointsOnBoundary.erase(point->Nr)) 1918 Log() << Verbose(0) << "Removing point Nr. " << point->Nr << "." << endl; 1919 delete(point); 1920 }; 2025 DoLog(0) && (Log() << Verbose(0) << "Removing point Nr. " << point->Nr << "." << endl); 2026 delete (point); 2027 } 2028 ; 2029 2030 /** Checks validity of a given sphere of a candidate line. 2031 * \sa CandidateForTesselation::CheckValidity(), which is more evolved. 2032 * We check CandidateForTesselation::OtherOptCenter 2033 * \param &CandidateLine contains other degenerated candidates which we have to subtract as well 2034 * \param RADIUS radius of sphere 2035 * \param *LC LinkedCell structure with other atoms 2036 * \return true - candidate triangle is degenerated, false - candidate triangle is not degenerated 2037 */ 2038 bool Tesselation::CheckDegeneracy(CandidateForTesselation &CandidateLine, const double RADIUS, const LinkedCell *LC) const 2039 { 2040 Info FunctionInfo(__func__); 2041 2042 DoLog(1) && (Log() << Verbose(1) << "INFO: Checking whether sphere contains no others points ..." << endl); 2043 bool flag = true; 2044 2045 DoLog(1) && (Log() << Verbose(1) << "Check by: draw sphere {" << CandidateLine.OtherOptCenter[0] << " " << CandidateLine.OtherOptCenter[1] << " " << CandidateLine.OtherOptCenter[2] << "} radius " << RADIUS << " resolution 30" << endl); 2046 // get all points inside the sphere 2047 TesselPointList *ListofPoints = LC->GetPointsInsideSphere(RADIUS, &CandidateLine.OtherOptCenter); 2048 2049 DoLog(1) && (Log() << Verbose(1) << "The following atoms are inside sphere at " << CandidateLine.OtherOptCenter << ":" << endl); 2050 for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner) 2051 DoLog(1) && (Log() << Verbose(1) << " " << *(*Runner) << " with distance " << (*Runner)->node->distance(CandidateLine.OtherOptCenter) << "." << endl); 2052 2053 // remove triangles's endpoints 2054 for (int i = 0; i < 2; i++) 2055 ListofPoints->remove(CandidateLine.BaseLine->endpoints[i]->node); 2056 2057 // remove other candidates 2058 for (TesselPointList::const_iterator Runner = CandidateLine.pointlist.begin(); Runner != CandidateLine.pointlist.end(); ++Runner) 2059 ListofPoints->remove(*Runner); 2060 2061 // check for other points 2062 if (!ListofPoints->empty()) { 2063 DoLog(1) && (Log() << Verbose(1) << "CheckDegeneracy: There are still " << ListofPoints->size() << " points inside the sphere." << endl); 2064 flag = false; 2065 DoLog(1) && (Log() << Verbose(1) << "External atoms inside of sphere at " << CandidateLine.OtherOptCenter << ":" << endl); 2066 for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner) 2067 DoLog(1) && (Log() << Verbose(1) << " " << *(*Runner) << " with distance " << (*Runner)->node->distance(CandidateLine.OtherOptCenter) << "." << endl); 2068 } 2069 delete (ListofPoints); 2070 2071 return flag; 2072 } 2073 ; 1921 2074 1922 2075 /** Checks whether the triangle consisting of the three points is already present. … … 1931 2084 int Tesselation::CheckPresenceOfTriangle(TesselPoint *Candidates[3]) const 1932 2085 { 1933 2086 Info FunctionInfo(__func__); 1934 2087 int adjacentTriangleCount = 0; 1935 2088 class BoundaryPointSet *Points[3]; … … 1953 2106 for (; (FindLine != Points[i]->lines.end()) && (FindLine->first == Points[j]->node->nr); FindLine++) { 1954 2107 TriangleMap *triangles = &FindLine->second->triangles; 1955 Log() << Verbose(1) << "Current line is " << FindLine->first << ": " << *(FindLine->second) << " with triangles " << triangles << "." << endl;2108 DoLog(1) && (Log() << Verbose(1) << "Current line is " << FindLine->first << ": " << *(FindLine->second) << " with triangles " << triangles << "." << endl); 1956 2109 for (TriangleMap::const_iterator FindTriangle = triangles->begin(); FindTriangle != triangles->end(); FindTriangle++) { 1957 2110 if (FindTriangle->second->IsPresentTupel(Points)) { … … 1959 2112 } 1960 2113 } 1961 Log() << Verbose(1) << "end." << endl;2114 DoLog(1) && (Log() << Verbose(1) << "end." << endl); 1962 2115 } 1963 2116 // Only one of the triangle lines must be considered for the triangle count. … … 1969 2122 } 1970 2123 1971 Log() << Verbose(0) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl;2124 DoLog(0) && (Log() << Verbose(0) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl); 1972 2125 return adjacentTriangleCount; 1973 }; 2126 } 2127 ; 1974 2128 1975 2129 /** Checks whether the triangle consisting of the three points is already present. … … 1983 2137 class BoundaryTriangleSet * Tesselation::GetPresentTriangle(TesselPoint *Candidates[3]) 1984 2138 { 1985 2139 Info FunctionInfo(__func__); 1986 2140 class BoundaryTriangleSet *triangle = NULL; 1987 2141 class BoundaryPointSet *Points[3]; … … 2021 2175 2022 2176 return triangle; 2023 } ;2024 2177 } 2178 ; 2025 2179 2026 2180 /** Finds the starting triangle for FindNonConvexBorder(). … … 2031 2185 * \param RADIUS radius of virtual rolling sphere 2032 2186 * \param *LC LinkedCell structure with neighbouring TesselPoint's 2033 */ 2034 void Tesselation::FindStartingTriangle(const double RADIUS, const LinkedCell *LC) 2035 { 2036 Info FunctionInfo(__func__); 2187 * \return true - a starting triangle has been created, false - no valid triple of points found 2188 */ 2189 bool Tesselation::FindStartingTriangle(const double RADIUS, const LinkedCell *LC) 2190 { 2191 Info FunctionInfo(__func__); 2037 2192 int i = 0; 2038 2193 TesselPoint* MaxPoint[NDIM]; 2039 2194 TesselPoint* Temporary; 2040 2195 double maxCoordinate[NDIM]; 2041 BoundaryLineSet BaseLine;2196 BoundaryLineSet *BaseLine = NULL; 2042 2197 Vector helper; 2043 2198 Vector Chord; 2044 2199 Vector SearchDirection; 2045 Vector CircleCenter; 2200 Vector CircleCenter; // center of the circle, i.e. of the band of sphere's centers 2046 2201 Vector CirclePlaneNormal; // normal vector defining the plane this circle lives in 2047 2202 Vector SphereCenter; … … 2056 2211 2057 2212 // 1. searching topmost point with respect to each axis 2058 for (int i =0;i<NDIM;i++) { // each axis2059 LC->n[i] = LC->N[i] -1; // current axis is topmost cell2060 for (LC->n[(i +1)%NDIM]=0;LC->n[(i+1)%NDIM]<LC->N[(i+1)%NDIM];LC->n[(i+1)%NDIM]++)2061 for (LC->n[(i +2)%NDIM]=0;LC->n[(i+2)%NDIM]<LC->N[(i+2)%NDIM];LC->n[(i+2)%NDIM]++) {2062 const Linked Nodes *List = LC->GetCurrentCell();2213 for (int i = 0; i < NDIM; i++) { // each axis 2214 LC->n[i] = LC->N[i] - 1; // current axis is topmost cell 2215 for (LC->n[(i + 1) % NDIM] = 0; LC->n[(i + 1) % NDIM] < LC->N[(i + 1) % NDIM]; LC->n[(i + 1) % NDIM]++) 2216 for (LC->n[(i + 2) % NDIM] = 0; LC->n[(i + 2) % NDIM] < LC->N[(i + 2) % NDIM]; LC->n[(i + 2) % NDIM]++) { 2217 const LinkedCell::LinkedNodes *List = LC->GetCurrentCell(); 2063 2218 //Log() << Verbose(1) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 2064 2219 if (List != NULL) { 2065 for (Linked Nodes::const_iterator Runner = List->begin();Runner != List->end();Runner++) {2066 if ((*Runner)->node-> x[i]> maxCoordinate[i]) {2067 Log() << Verbose(1) << "New maximal for axis " << i << " node is " << *(*Runner) << " at " << *(*Runner)->node << "." << endl;2068 maxCoordinate[i] = (*Runner)->node-> x[i];2220 for (LinkedCell::LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 2221 if ((*Runner)->node->at(i) > maxCoordinate[i]) { 2222 DoLog(1) && (Log() << Verbose(1) << "New maximal for axis " << i << " node is " << *(*Runner) << " at " << *(*Runner)->node << "." << endl); 2223 maxCoordinate[i] = (*Runner)->node->at(i); 2069 2224 MaxPoint[i] = (*Runner); 2070 2225 } 2071 2226 } 2072 2227 } else { 2073 eLog() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << " is invalid!" << endl;2228 DoeLog(1) && (eLog() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << " is invalid!" << endl); 2074 2229 } 2075 2230 } 2076 2231 } 2077 2232 2078 Log() << Verbose(1) << "Found maximum coordinates: ";2079 for (int i =0;i<NDIM;i++)2080 Log() << Verbose(0) << i << ": " << *MaxPoint[i] << "\t";2081 Log() << Verbose(0) << endl;2233 DoLog(1) && (Log() << Verbose(1) << "Found maximum coordinates: "); 2234 for (int i = 0; i < NDIM; i++) 2235 DoLog(0) && (Log() << Verbose(0) << i << ": " << *MaxPoint[i] << "\t"); 2236 DoLog(0) && (Log() << Verbose(0) << endl); 2082 2237 2083 2238 BTS = NULL; 2084 for (int k =0;k<NDIM;k++) {2239 for (int k = 0; k < NDIM; k++) { 2085 2240 NormalVector.Zero(); 2086 NormalVector.x[k] = 1.; 2087 BaseLine.endpoints[0] = new BoundaryPointSet(MaxPoint[k]); 2088 Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine.endpoints[0]->node << "." << endl; 2241 NormalVector[k] = 1.; 2242 BaseLine = new BoundaryLineSet(); 2243 BaseLine->endpoints[0] = new BoundaryPointSet(MaxPoint[k]); 2244 DoLog(0) && (Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine->endpoints[0]->node << "." << endl); 2089 2245 2090 2246 double ShortestAngle; 2091 2247 ShortestAngle = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant. 2092 2248 2093 FindSecondPointForTesselation(BaseLine.endpoints[0]->node, NormalVector, Temporary, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_... 2094 if (Temporary == NULL) // have we found a second point? 2249 Temporary = NULL; 2250 FindSecondPointForTesselation(BaseLine->endpoints[0]->node, NormalVector, Temporary, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_... 2251 if (Temporary == NULL) { 2252 // have we found a second point? 2253 delete BaseLine; 2095 2254 continue; 2096 BaseLine.endpoints[1] = new BoundaryPointSet(Temporary); 2255 } 2256 BaseLine->endpoints[1] = new BoundaryPointSet(Temporary); 2097 2257 2098 2258 // construct center of circle 2099 CircleCenter.CopyVector(BaseLine.endpoints[0]->node->node); 2100 CircleCenter.AddVector(BaseLine.endpoints[1]->node->node); 2101 CircleCenter.Scale(0.5); 2259 CircleCenter = 0.5 * ((*BaseLine->endpoints[0]->node->node) + (*BaseLine->endpoints[1]->node->node)); 2102 2260 2103 2261 // construct normal vector of circle 2104 CirclePlaneNormal.CopyVector(BaseLine.endpoints[0]->node->node); 2105 CirclePlaneNormal.SubtractVector(BaseLine.endpoints[1]->node->node); 2262 CirclePlaneNormal = (*BaseLine->endpoints[0]->node->node) - (*BaseLine->endpoints[1]->node->node); 2106 2263 2107 2264 double radius = CirclePlaneNormal.NormSquared(); 2108 double CircleRadius = sqrt(RADIUS *RADIUS - radius/4.);2109 2110 NormalVector.ProjectOntoPlane( &CirclePlaneNormal);2265 double CircleRadius = sqrt(RADIUS * RADIUS - radius / 4.); 2266 2267 NormalVector.ProjectOntoPlane(CirclePlaneNormal); 2111 2268 NormalVector.Normalize(); 2112 ShortestAngle = 2.*M_PI; // This will indicate the quadrant. 2113 2114 SphereCenter.CopyVector(&NormalVector); 2115 SphereCenter.Scale(CircleRadius); 2116 SphereCenter.AddVector(&CircleCenter); 2269 ShortestAngle = 2. * M_PI; // This will indicate the quadrant. 2270 2271 SphereCenter = (CircleRadius * NormalVector) + CircleCenter; 2117 2272 // Now, NormalVector and SphereCenter are two orthonormalized vectors in the plane defined by CirclePlaneNormal (not normalized) 2118 2273 2119 2274 // look in one direction of baseline for initial candidate 2120 SearchDirection .MakeNormalVector(&CirclePlaneNormal, &NormalVector); // whether we look "left" first or "right" first is not important ...2275 SearchDirection = Plane(CirclePlaneNormal, NormalVector,0).getNormal(); // whether we look "left" first or "right" first is not important ... 2121 2276 2122 2277 // adding point 1 and point 2 and add the line between them 2123 Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine.endpoints[0]->node << "." << endl;2124 Log() << Verbose(0) << "Found second point is at " << *BaseLine.endpoints[1]->node << ".\n";2278 DoLog(0) && (Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine->endpoints[0]->node << "." << endl); 2279 DoLog(0) && (Log() << Verbose(0) << "Found second point is at " << *BaseLine->endpoints[1]->node << ".\n"); 2125 2280 2126 2281 //Log() << Verbose(1) << "INFO: OldSphereCenter is at " << helper << ".\n"; 2127 CandidateForTesselation OptCandidates( &BaseLine);2282 CandidateForTesselation OptCandidates(BaseLine); 2128 2283 FindThirdPointForTesselation(NormalVector, SearchDirection, SphereCenter, OptCandidates, NULL, RADIUS, LC); 2129 Log() << Verbose(0) << "List of third Points is:" << endl;2284 DoLog(0) && (Log() << Verbose(0) << "List of third Points is:" << endl); 2130 2285 for (TesselPointList::iterator it = OptCandidates.pointlist.begin(); it != OptCandidates.pointlist.end(); it++) { 2131 Log() << Verbose(0) << " " << *(*it) << endl; 2132 } 2133 2134 BTS = NULL; 2135 AddCandidateTriangle(OptCandidates); 2136 // delete(BaseLine.endpoints[0]); 2137 // delete(BaseLine.endpoints[1]); 2138 2139 if (BTS != NULL) // we have created one starting triangle 2286 DoLog(0) && (Log() << Verbose(0) << " " << *(*it) << endl); 2287 } 2288 if (!OptCandidates.pointlist.empty()) { 2289 BTS = NULL; 2290 AddCandidatePolygon(OptCandidates, RADIUS, LC); 2291 } else { 2292 delete BaseLine; 2293 continue; 2294 } 2295 2296 if (BTS != NULL) { // we have created one starting triangle 2297 delete BaseLine; 2140 2298 break; 2141 else {2299 } else { 2142 2300 // remove all candidates from the list and then the list itself 2143 2301 OptCandidates.pointlist.clear(); 2144 2302 } 2145 } 2146 }; 2303 delete BaseLine; 2304 } 2305 2306 return (BTS != NULL); 2307 } 2308 ; 2147 2309 2148 2310 /** Checks for a given baseline and a third point candidate whether baselines of the found triangle don't have even better candidates. … … 2215 2377 // if (fabs(OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { 2216 2378 // // rotated the wrong way! 2217 // eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl;2379 // DoeLog(1) && (eLog()<< Verbose(1) << "SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl); 2218 2380 // } 2219 2381 // … … 2272 2434 // } 2273 2435 // } else { 2274 // eLog() << Verbose(2) << "Baseline is connected to two triangles already?" << endl;2436 // DoeLog(2) && (eLog()<< Verbose(2) << "Baseline is connected to two triangles already?" << endl); 2275 2437 // } 2276 2438 // } else { … … 2279 2441 // } 2280 2442 // } else { 2281 // eLog() << Verbose(1) << "Could not find the TesselPoint " << *ThirdNode << "." << endl;2443 // DoeLog(1) && (eLog()<< Verbose(1) << "Could not find the TesselPoint " << *ThirdNode << "." << endl); 2282 2444 // } 2283 2445 // … … 2293 2455 * @param *LC LinkedCell structure with neighbouring points 2294 2456 */ 2295 bool Tesselation::FindNextSuitableTriangle(CandidateForTesselation &CandidateLine, BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC) 2296 { 2297 Info FunctionInfo(__func__); 2298 bool result = true; 2299 2457 bool Tesselation::FindNextSuitableTriangle(CandidateForTesselation &CandidateLine, const BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC) 2458 { 2459 Info FunctionInfo(__func__); 2300 2460 Vector CircleCenter; 2301 2461 Vector CirclePlaneNormal; … … 2303 2463 Vector SearchDirection; 2304 2464 Vector helper; 2305 TesselPoint *ThirdNode= NULL;2465 BoundaryPointSet *ThirdPoint = NULL; 2306 2466 LineMap::iterator testline; 2307 2467 double radius, CircleRadius; 2308 2468 2309 for (int i =0;i<3;i++)2310 if ((T.endpoints[i] ->node != CandidateLine.BaseLine->endpoints[0]->node) && (T.endpoints[i]->node != CandidateLine.BaseLine->endpoints[1]->node)) {2311 Third Node = T.endpoints[i]->node;2469 for (int i = 0; i < 3; i++) 2470 if ((T.endpoints[i] != CandidateLine.BaseLine->endpoints[0]) && (T.endpoints[i] != CandidateLine.BaseLine->endpoints[1])) { 2471 ThirdPoint = T.endpoints[i]; 2312 2472 break; 2313 2473 } 2314 Log() << Verbose(0) << "Current baseline is " << *CandidateLine.BaseLine << " with ThirdNode " << *ThirdNode << " of triangle " << T << "." << endl; 2474 DoLog(0) && (Log() << Verbose(0) << "Current baseline is " << *CandidateLine.BaseLine << " with ThirdPoint " << *ThirdPoint << " of triangle " << T << "." << endl); 2475 2476 CandidateLine.T = &T; 2315 2477 2316 2478 // construct center of circle 2317 CircleCenter.CopyVector(CandidateLine.BaseLine->endpoints[0]->node->node); 2318 CircleCenter.AddVector(CandidateLine.BaseLine->endpoints[1]->node->node); 2319 CircleCenter.Scale(0.5); 2479 CircleCenter = 0.5 * ((*CandidateLine.BaseLine->endpoints[0]->node->node) + 2480 (*CandidateLine.BaseLine->endpoints[1]->node->node)); 2320 2481 2321 2482 // construct normal vector of circle 2322 CirclePlaneNormal .CopyVector(CandidateLine.BaseLine->endpoints[0]->node->node);2323 CirclePlaneNormal.SubtractVector(CandidateLine.BaseLine->endpoints[1]->node->node);2483 CirclePlaneNormal = (*CandidateLine.BaseLine->endpoints[0]->node->node) - 2484 (*CandidateLine.BaseLine->endpoints[1]->node->node); 2324 2485 2325 2486 // calculate squared radius of circle 2326 radius = CirclePlaneNormal.ScalarProduct( &CirclePlaneNormal);2327 if (radius /4. < RADIUS*RADIUS) {2487 radius = CirclePlaneNormal.ScalarProduct(CirclePlaneNormal); 2488 if (radius / 4. < RADIUS * RADIUS) { 2328 2489 // construct relative sphere center with now known CircleCenter 2329 RelativeSphereCenter.CopyVector(&T.SphereCenter); 2330 RelativeSphereCenter.SubtractVector(&CircleCenter); 2331 2332 CircleRadius = RADIUS*RADIUS - radius/4.; 2490 RelativeSphereCenter = T.SphereCenter - CircleCenter; 2491 2492 CircleRadius = RADIUS * RADIUS - radius / 4.; 2333 2493 CirclePlaneNormal.Normalize(); 2334 Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;2335 2336 Log() << Verbose(1) << "INFO: OldSphereCenter is at " << T.SphereCenter << "." << endl;2494 DoLog(1) && (Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl); 2495 2496 DoLog(1) && (Log() << Verbose(1) << "INFO: OldSphereCenter is at " << T.SphereCenter << "." << endl); 2337 2497 2338 2498 // construct SearchDirection and an "outward pointer" 2339 SearchDirection.MakeNormalVector(&RelativeSphereCenter, &CirclePlaneNormal); 2340 helper.CopyVector(&CircleCenter); 2341 helper.SubtractVector(ThirdNode->node); 2342 if (helper.ScalarProduct(&SearchDirection) < -HULLEPSILON)// ohoh, SearchDirection points inwards! 2499 SearchDirection = Plane(RelativeSphereCenter, CirclePlaneNormal,0).getNormal(); 2500 helper = CircleCenter - (*ThirdPoint->node->node); 2501 if (helper.ScalarProduct(SearchDirection) < -HULLEPSILON)// ohoh, SearchDirection points inwards! 2343 2502 SearchDirection.Scale(-1.); 2344 Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl;2345 if (fabs(RelativeSphereCenter.ScalarProduct( &SearchDirection)) > HULLEPSILON) {2503 DoLog(1) && (Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl); 2504 if (fabs(RelativeSphereCenter.ScalarProduct(SearchDirection)) > HULLEPSILON) { 2346 2505 // rotated the wrong way! 2347 eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl;2506 DoeLog(1) && (eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl); 2348 2507 } 2349 2508 2350 2509 // add third point 2351 FindThirdPointForTesselation(T.NormalVector, SearchDirection, T.SphereCenter, CandidateLine, Third Node, RADIUS, LC);2510 FindThirdPointForTesselation(T.NormalVector, SearchDirection, T.SphereCenter, CandidateLine, ThirdPoint, RADIUS, LC); 2352 2511 2353 2512 } else { 2354 Log() << Verbose(0) << "Circumcircle for base line " << *CandidateLine.BaseLine << " and base triangle " << T << " is too big!" << endl;2513 DoLog(0) && (Log() << Verbose(0) << "Circumcircle for base line " << *CandidateLine.BaseLine << " and base triangle " << T << " is too big!" << endl); 2355 2514 } 2356 2515 2357 2516 if (CandidateLine.pointlist.empty()) { 2358 eLog() << Verbose(2) << "Could not find a suitable candidate." << endl;2517 DoeLog(2) && (eLog() << Verbose(2) << "Could not find a suitable candidate." << endl); 2359 2518 return false; 2360 2519 } 2361 Log() << Verbose(0) << "Third Points are: " << endl;2520 DoLog(0) && (Log() << Verbose(0) << "Third Points are: " << endl); 2362 2521 for (TesselPointList::iterator it = CandidateLine.pointlist.begin(); it != CandidateLine.pointlist.end(); ++it) { 2363 Log() << Verbose(0) << " " << *(*it) << endl;2522 DoLog(0) && (Log() << Verbose(0) << " " << *(*it) << endl); 2364 2523 } 2365 2524 2366 2525 return true; 2367 2368 // BoundaryLineSet *BaseRay = CandidateLine.BaseLine; 2369 // for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 2370 // Log() << Verbose(0) << "Third point candidate is " << *(*it)->point 2371 // << " with circumsphere's center at " << (*it)->OptCenter << "." << endl; 2372 // Log() << Verbose(0) << "Baseline is " << *BaseRay << endl; 2373 // 2374 // // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2) 2375 // TesselPoint *PointCandidates[3]; 2376 // PointCandidates[0] = (*it)->point; 2377 // PointCandidates[1] = BaseRay->endpoints[0]->node; 2378 // PointCandidates[2] = BaseRay->endpoints[1]->node; 2379 // int existentTrianglesCount = CheckPresenceOfTriangle(PointCandidates); 2380 // 2381 // BTS = NULL; 2382 // // check for present edges and whether we reach better candidates from them 2383 // //if (HasOtherBaselineBetterCandidate(BaseRay, (*it)->point, ShortestAngle, RADIUS, LC) ) { 2384 // if (0) { 2385 // result = false; 2386 // break; 2387 // } else { 2388 // // If there is no triangle, add it regularly. 2389 // if (existentTrianglesCount == 0) { 2390 // AddTesselationPoint((*it)->point, 0); 2391 // AddTesselationPoint(BaseRay->endpoints[0]->node, 1); 2392 // AddTesselationPoint(BaseRay->endpoints[1]->node, 2); 2393 // 2394 // if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const )TPS)) { 2395 // CandidateLine.point = (*it)->point; 2396 // CandidateLine.OptCenter.CopyVector(&((*it)->OptCenter)); 2397 // CandidateLine.OtherOptCenter.CopyVector(&((*it)->OtherOptCenter)); 2398 // CandidateLine.ShortestAngle = ShortestAngle; 2399 // } else { 2400 //// eLog() << Verbose(1) << "This triangle consisting of "; 2401 //// Log() << Verbose(0) << *(*it)->point << ", "; 2402 //// Log() << Verbose(0) << *BaseRay->endpoints[0]->node << " and "; 2403 //// Log() << Verbose(0) << *BaseRay->endpoints[1]->node << " "; 2404 //// Log() << Verbose(0) << "exists and is not added, as it 0x80000000006fc150(does not seem helpful!" << endl; 2405 // result = false; 2406 // } 2407 // } else if ((existentTrianglesCount >= 1) && (existentTrianglesCount <= 3)) { // If there is a planar region within the structure, we need this triangle a second time. 2408 // AddTesselationPoint((*it)->point, 0); 2409 // AddTesselationPoint(BaseRay->endpoints[0]->node, 1); 2410 // AddTesselationPoint(BaseRay->endpoints[1]->node, 2); 2411 // 2412 // // We demand that at most one new degenerate line is created and that this line also already exists (which has to be the case due to existentTrianglesCount == 1) 2413 // // i.e. at least one of the three lines must be present with TriangleCount <= 1 2414 // if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const)TPS) || CandidateLine.BaseLine->skipped) { 2415 // CandidateLine.point = (*it)->point; 2416 // CandidateLine.OptCenter.CopyVector(&(*it)->OptCenter); 2417 // CandidateLine.OtherOptCenter.CopyVector(&(*it)->OtherOptCenter); 2418 // CandidateLine.ShortestAngle = ShortestAngle+2.*M_PI; 2419 // 2420 // } else { 2421 //// eLog() << Verbose(1) << "This triangle consisting of " << *(*it)->point << ", " << *BaseRay->endpoints[0]->node << " and " << *BaseRay->endpoints[1]->node << " " << "exists and is not added, as it does not seem helpful!" << endl; 2422 // result = false; 2423 // } 2424 // } else { 2425 //// Log() << Verbose(1) << "This triangle consisting of "; 2426 //// Log() << Verbose(0) << *(*it)->point << ", "; 2427 //// Log() << Verbose(0) << *BaseRay->endpoints[0]->node << " and "; 2428 //// Log() << Verbose(0) << *BaseRay->endpoints[1]->node << " "; 2429 //// Log() << Verbose(0) << "is invalid!" << endl; 2430 // result = false; 2431 // } 2432 // } 2433 // 2434 // // set baseline to new ray from ref point (here endpoints[0]->node) to current candidate (here (*it)->point)) 2435 // BaseRay = BLS[0]; 2436 // if ((BTS != NULL) && (BTS->NormalVector.NormSquared() < MYEPSILON)) { 2437 // eLog() << Verbose(1) << "Triangle " << *BTS << " has zero normal vector!" << endl; 2438 // exit(255); 2439 // } 2440 // 2441 // } 2442 // 2443 // // remove all candidates from the list and then the list itself 2444 // class CandidateForTesselation *remover = NULL; 2445 // for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 2446 // remover = *it; 2447 // delete(remover); 2448 // } 2449 // delete(OptCandidates); 2450 return result; 2451 }; 2526 } 2527 ; 2528 2529 /** Walks through Tesselation::OpenLines() and finds candidates for newly created ones. 2530 * \param *&LCList atoms in LinkedCell list 2531 * \param RADIUS radius of the virtual sphere 2532 * \return true - for all open lines without candidates so far, a candidate has been found, 2533 * false - at least one open line without candidate still 2534 */ 2535 bool Tesselation::FindCandidatesforOpenLines(const double RADIUS, const LinkedCell *&LCList) 2536 { 2537 bool TesselationFailFlag = true; 2538 CandidateForTesselation *baseline = NULL; 2539 BoundaryTriangleSet *T = NULL; 2540 2541 for (CandidateMap::iterator Runner = OpenLines.begin(); Runner != OpenLines.end(); Runner++) { 2542 baseline = Runner->second; 2543 if (baseline->pointlist.empty()) { 2544 assert((baseline->BaseLine->triangles.size() == 1) && ("Open line without exactly one attached triangle")); 2545 T = (((baseline->BaseLine->triangles.begin()))->second); 2546 DoLog(1) && (Log() << Verbose(1) << "Finding best candidate for open line " << *baseline->BaseLine << " of triangle " << *T << endl); 2547 TesselationFailFlag = TesselationFailFlag && FindNextSuitableTriangle(*baseline, *T, RADIUS, LCList); //the line is there, so there is a triangle, but only one. 2548 } 2549 } 2550 return TesselationFailFlag; 2551 } 2552 ; 2452 2553 2453 2554 /** Adds the present line and candidate point from \a &CandidateLine to the Tesselation. 2454 2555 * \param CandidateLine triangle to add 2455 * \NOTE we need the copy operator here as the original CandidateForTesselation is removed in AddTesselationLine() 2456 */ 2457 void Tesselation::AddCandidateTriangle(CandidateForTesselation CandidateLine) 2458 { 2459 Info FunctionInfo(__func__); 2556 * \param RADIUS Radius of sphere 2557 * \param *LC LinkedCell structure 2558 * \NOTE we need the copy operator here as the original CandidateForTesselation is removed in 2559 * AddTesselationLine() in AddCandidateTriangle() 2560 */ 2561 void Tesselation::AddCandidatePolygon(CandidateForTesselation CandidateLine, const double RADIUS, const LinkedCell *LC) 2562 { 2563 Info FunctionInfo(__func__); 2460 2564 Vector Center; 2461 2565 TesselPoint * const TurningPoint = CandidateLine.BaseLine->endpoints[0]->node; 2566 TesselPointList::iterator Runner; 2567 TesselPointList::iterator Sprinter; 2462 2568 2463 2569 // fill the set of neighbours … … 2468 2574 TesselPointList *connectedClosestPoints = GetCircleOfSetOfPoints(&SetOfNeighbours, TurningPoint, CandidateLine.BaseLine->endpoints[1]->node->node); 2469 2575 2576 DoLog(0) && (Log() << Verbose(0) << "List of Candidates for Turning Point " << *TurningPoint << ":" << endl); 2577 for (TesselPointList::iterator TesselRunner = connectedClosestPoints->begin(); TesselRunner != connectedClosestPoints->end(); ++TesselRunner) 2578 DoLog(0) && (Log() << Verbose(0) << " " << **TesselRunner << endl); 2579 2470 2580 // go through all angle-sorted candidates (in degenerate n-nodes case we may have to add multiple triangles) 2471 Log() << Verbose(0) << "List of Candidates for Turning Point: " << *TurningPoint << "." << endl; 2472 for (TesselPointList::iterator TesselRunner = connectedClosestPoints->begin(); TesselRunner != connectedClosestPoints->end(); ++TesselRunner) 2473 Log() << Verbose(0) << **TesselRunner << endl; 2474 TesselPointList::iterator Runner = connectedClosestPoints->begin(); 2475 TesselPointList::iterator Sprinter = Runner; 2581 Runner = connectedClosestPoints->begin(); 2582 Sprinter = Runner; 2476 2583 Sprinter++; 2477 while(Sprinter != connectedClosestPoints->end()) { 2478 // add the points 2584 while (Sprinter != connectedClosestPoints->end()) { 2585 DoLog(0) && (Log() << Verbose(0) << "Current Runner is " << *(*Runner) << " and sprinter is " << *(*Sprinter) << "." << endl); 2586 2479 2587 AddTesselationPoint(TurningPoint, 0); 2480 AddTesselationPoint((*Runner), 1); 2481 AddTesselationPoint((*Sprinter), 2); 2482 2483 // add the lines 2484 AddTesselationLine(TPS[0], TPS[1], 0); 2485 AddTesselationLine(TPS[0], TPS[2], 1); 2486 AddTesselationLine(TPS[1], TPS[2], 2); 2487 2488 // add the triangles 2489 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2490 AddTesselationTriangle(); 2491 BTS->GetCenter(&Center); 2492 Center.SubtractVector(&CandidateLine.OptCenter); 2493 BTS->SphereCenter.CopyVector(&CandidateLine.OptCenter); 2494 BTS->GetNormalVector(Center); 2495 2496 Log() << Verbose(0) << "--> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << "." << endl; 2588 AddTesselationPoint(*Runner, 1); 2589 AddTesselationPoint(*Sprinter, 2); 2590 2591 AddCandidateTriangle(CandidateLine, Opt); 2592 2497 2593 Runner = Sprinter; 2498 2594 Sprinter++; 2499 Log() << Verbose(0) << "Current Runner is " << **Runner << "." << endl; 2500 if (Sprinter != connectedClosestPoints->end()) 2501 Log() << Verbose(0) << " There are still more triangles to add." << endl; 2502 } 2503 delete(connectedClosestPoints); 2595 if (Sprinter != connectedClosestPoints->end()) { 2596 // fill the internal open lines with its respective candidate (otherwise lines in degenerate case are not picked) 2597 FindDegeneratedCandidatesforOpenLines(*Sprinter, &CandidateLine.OptCenter); // Assume BTS contains last triangle 2598 DoLog(0) && (Log() << Verbose(0) << " There are still more triangles to add." << endl); 2599 } 2600 // pick candidates for other open lines as well 2601 FindCandidatesforOpenLines(RADIUS, LC); 2602 2603 // check whether we add a degenerate or a normal triangle 2604 if (CheckDegeneracy(CandidateLine, RADIUS, LC)) { 2605 // add normal and degenerate triangles 2606 DoLog(1) && (Log() << Verbose(1) << "Triangle of endpoints " << *TPS[0] << "," << *TPS[1] << " and " << *TPS[2] << " is degenerated, adding both sides." << endl); 2607 AddCandidateTriangle(CandidateLine, OtherOpt); 2608 2609 if (Sprinter != connectedClosestPoints->end()) { 2610 // fill the internal open lines with its respective candidate (otherwise lines in degenerate case are not picked) 2611 FindDegeneratedCandidatesforOpenLines(*Sprinter, &CandidateLine.OtherOptCenter); 2612 } 2613 // pick candidates for other open lines as well 2614 FindCandidatesforOpenLines(RADIUS, LC); 2615 } 2616 } 2617 delete (connectedClosestPoints); 2504 2618 }; 2619 2620 /** for polygons (multiple candidates for a baseline) sets internal edges to the correct next candidate. 2621 * \param *Sprinter next candidate to which internal open lines are set 2622 * \param *OptCenter OptCenter for this candidate 2623 */ 2624 void Tesselation::FindDegeneratedCandidatesforOpenLines(TesselPoint * const Sprinter, const Vector * const OptCenter) 2625 { 2626 Info FunctionInfo(__func__); 2627 2628 pair<LineMap::iterator, LineMap::iterator> FindPair = TPS[0]->lines.equal_range(TPS[2]->node->nr); 2629 for (LineMap::const_iterator FindLine = FindPair.first; FindLine != FindPair.second; FindLine++) { 2630 DoLog(1) && (Log() << Verbose(1) << "INFO: Checking line " << *(FindLine->second) << " ..." << endl); 2631 // If there is a line with less than two attached triangles, we don't need a new line. 2632 if (FindLine->second->triangles.size() == 1) { 2633 CandidateMap::iterator Finder = OpenLines.find(FindLine->second); 2634 if (!Finder->second->pointlist.empty()) 2635 DoLog(1) && (Log() << Verbose(1) << "INFO: line " << *(FindLine->second) << " is open with candidate " << **(Finder->second->pointlist.begin()) << "." << endl); 2636 else { 2637 DoLog(1) && (Log() << Verbose(1) << "INFO: line " << *(FindLine->second) << " is open with no candidate, setting to next Sprinter" << (*Sprinter) << endl); 2638 Finder->second->T = BTS; // is last triangle 2639 Finder->second->pointlist.push_back(Sprinter); 2640 Finder->second->ShortestAngle = 0.; 2641 Finder->second->OptCenter = *OptCenter; 2642 } 2643 } 2644 } 2645 }; 2646 2647 /** If a given \a *triangle is degenerated, this adds both sides. 2648 * i.e. the triangle with same BoundaryPointSet's but NormalVector in opposite direction. 2649 * Note that endpoints are stored in Tesselation::TPS 2650 * \param CandidateLine CanddiateForTesselation structure for the desired BoundaryLine 2651 * \param RADIUS radius of sphere 2652 * \param *LC pointer to LinkedCell structure 2653 */ 2654 void Tesselation::AddDegeneratedTriangle(CandidateForTesselation &CandidateLine, const double RADIUS, const LinkedCell *LC) 2655 { 2656 Info FunctionInfo(__func__); 2657 Vector Center; 2658 CandidateMap::const_iterator CandidateCheck = OpenLines.end(); 2659 BoundaryTriangleSet *triangle = NULL; 2660 2661 /// 1. Create or pick the lines for the first triangle 2662 DoLog(0) && (Log() << Verbose(0) << "INFO: Creating/Picking lines for first triangle ..." << endl); 2663 for (int i = 0; i < 3; i++) { 2664 BLS[i] = NULL; 2665 DoLog(0) && (Log() << Verbose(0) << "Current line is between " << *TPS[(i + 0) % 3] << " and " << *TPS[(i + 1) % 3] << ":" << endl); 2666 AddTesselationLine(&CandidateLine.OptCenter, TPS[(i + 2) % 3], TPS[(i + 0) % 3], TPS[(i + 1) % 3], i); 2667 } 2668 2669 /// 2. create the first triangle and NormalVector and so on 2670 DoLog(0) && (Log() << Verbose(0) << "INFO: Adding first triangle with center at " << CandidateLine.OptCenter << " ..." << endl); 2671 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2672 AddTesselationTriangle(); 2673 2674 // create normal vector 2675 BTS->GetCenter(&Center); 2676 Center -= CandidateLine.OptCenter; 2677 BTS->SphereCenter = CandidateLine.OptCenter; 2678 BTS->GetNormalVector(Center); 2679 // give some verbose output about the whole procedure 2680 if (CandidateLine.T != NULL) 2681 DoLog(0) && (Log() << Verbose(0) << "--> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << "." << endl); 2682 else 2683 DoLog(0) && (Log() << Verbose(0) << "--> New starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle." << endl); 2684 triangle = BTS; 2685 2686 /// 3. Gather candidates for each new line 2687 DoLog(0) && (Log() << Verbose(0) << "INFO: Adding candidates to new lines ..." << endl); 2688 for (int i = 0; i < 3; i++) { 2689 DoLog(0) && (Log() << Verbose(0) << "Current line is between " << *TPS[(i + 0) % 3] << " and " << *TPS[(i + 1) % 3] << ":" << endl); 2690 CandidateCheck = OpenLines.find(BLS[i]); 2691 if ((CandidateCheck != OpenLines.end()) && (CandidateCheck->second->pointlist.empty())) { 2692 if (CandidateCheck->second->T == NULL) 2693 CandidateCheck->second->T = triangle; 2694 FindNextSuitableTriangle(*(CandidateCheck->second), *CandidateCheck->second->T, RADIUS, LC); 2695 } 2696 } 2697 2698 /// 4. Create or pick the lines for the second triangle 2699 DoLog(0) && (Log() << Verbose(0) << "INFO: Creating/Picking lines for second triangle ..." << endl); 2700 for (int i = 0; i < 3; i++) { 2701 DoLog(0) && (Log() << Verbose(0) << "Current line is between " << *TPS[(i + 0) % 3] << " and " << *TPS[(i + 1) % 3] << ":" << endl); 2702 AddTesselationLine(&CandidateLine.OtherOptCenter, TPS[(i + 2) % 3], TPS[(i + 0) % 3], TPS[(i + 1) % 3], i); 2703 } 2704 2705 /// 5. create the second triangle and NormalVector and so on 2706 DoLog(0) && (Log() << Verbose(0) << "INFO: Adding second triangle with center at " << CandidateLine.OtherOptCenter << " ..." << endl); 2707 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2708 AddTesselationTriangle(); 2709 2710 BTS->SphereCenter = CandidateLine.OtherOptCenter; 2711 // create normal vector in other direction 2712 BTS->GetNormalVector(triangle->NormalVector); 2713 BTS->NormalVector.Scale(-1.); 2714 // give some verbose output about the whole procedure 2715 if (CandidateLine.T != NULL) 2716 DoLog(0) && (Log() << Verbose(0) << "--> New degenerate triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << "." << endl); 2717 else 2718 DoLog(0) && (Log() << Verbose(0) << "--> New degenerate starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle." << endl); 2719 2720 /// 6. Adding triangle to new lines 2721 DoLog(0) && (Log() << Verbose(0) << "INFO: Adding second triangles to new lines ..." << endl); 2722 for (int i = 0; i < 3; i++) { 2723 DoLog(0) && (Log() << Verbose(0) << "Current line is between " << *TPS[(i + 0) % 3] << " and " << *TPS[(i + 1) % 3] << ":" << endl); 2724 CandidateCheck = OpenLines.find(BLS[i]); 2725 if ((CandidateCheck != OpenLines.end()) && (CandidateCheck->second->pointlist.empty())) { 2726 if (CandidateCheck->second->T == NULL) 2727 CandidateCheck->second->T = BTS; 2728 } 2729 } 2730 } 2731 ; 2732 2733 /** Adds a triangle to the Tesselation structure from three given TesselPoint's. 2734 * Note that endpoints are in Tesselation::TPS. 2735 * \param CandidateLine CandidateForTesselation structure contains other information 2736 * \param type which opt center to add (i.e. which side) and thus which NormalVector to take 2737 */ 2738 void Tesselation::AddCandidateTriangle(CandidateForTesselation &CandidateLine, enum centers type) 2739 { 2740 Info FunctionInfo(__func__); 2741 Vector Center; 2742 Vector *OptCenter = (type == Opt) ? &CandidateLine.OptCenter : &CandidateLine.OtherOptCenter; 2743 2744 // add the lines 2745 AddTesselationLine(OptCenter, TPS[2], TPS[0], TPS[1], 0); 2746 AddTesselationLine(OptCenter, TPS[1], TPS[0], TPS[2], 1); 2747 AddTesselationLine(OptCenter, TPS[0], TPS[1], TPS[2], 2); 2748 2749 // add the triangles 2750 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2751 AddTesselationTriangle(); 2752 2753 // create normal vector 2754 BTS->GetCenter(&Center); 2755 Center.SubtractVector(*OptCenter); 2756 BTS->SphereCenter = *OptCenter; 2757 BTS->GetNormalVector(Center); 2758 2759 // give some verbose output about the whole procedure 2760 if (CandidateLine.T != NULL) 2761 DoLog(0) && (Log() << Verbose(0) << "--> New" << ((type == OtherOpt) ? " degenerate " : " ") << "triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << "." << endl); 2762 else 2763 DoLog(0) && (Log() << Verbose(0) << "--> New" << ((type == OtherOpt) ? " degenerate " : " ") << "starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle." << endl); 2764 } 2765 ; 2505 2766 2506 2767 /** Checks whether the quadragon of the two triangles connect to \a *Base is convex. … … 2513 2774 class BoundaryPointSet *Tesselation::IsConvexRectangle(class BoundaryLineSet *Base) 2514 2775 { 2515 2776 Info FunctionInfo(__func__); 2516 2777 class BoundaryPointSet *Spot = NULL; 2517 2778 class BoundaryLineSet *OtherBase; 2518 2779 Vector *ClosestPoint; 2519 2780 2520 int m =0;2521 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++)2522 for (int j =0;j<3;j++) // all of their endpoints and baselines2781 int m = 0; 2782 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 2783 for (int j = 0; j < 3; j++) // all of their endpoints and baselines 2523 2784 if (!Base->ContainsBoundaryPoint(runner->second->endpoints[j])) // and neither of its endpoints 2524 2785 BPS[m++] = runner->second->endpoints[j]; 2525 OtherBase = new class BoundaryLineSet(BPS, -1);2526 2527 Log() << Verbose(1) << "INFO: Current base line is " << *Base << "." << endl;2528 Log() << Verbose(1) << "INFO: Other base line is " << *OtherBase << "." << endl;2786 OtherBase = new class BoundaryLineSet(BPS, -1); 2787 2788 DoLog(1) && (Log() << Verbose(1) << "INFO: Current base line is " << *Base << "." << endl); 2789 DoLog(1) && (Log() << Verbose(1) << "INFO: Other base line is " << *OtherBase << "." << endl); 2529 2790 2530 2791 // get the closest point on each line to the other line … … 2532 2793 2533 2794 // delete the temporary other base line 2534 delete (OtherBase);2795 delete (OtherBase); 2535 2796 2536 2797 // get the distance vector from Base line to OtherBase line 2537 2798 Vector DistanceToIntersection[2], BaseLine; 2538 2799 double distance[2]; 2539 BaseLine.CopyVector(Base->endpoints[1]->node->node); 2540 BaseLine.SubtractVector(Base->endpoints[0]->node->node); 2541 for (int i=0;i<2;i++) { 2542 DistanceToIntersection[i].CopyVector(ClosestPoint); 2543 DistanceToIntersection[i].SubtractVector(Base->endpoints[i]->node->node); 2544 distance[i] = BaseLine.ScalarProduct(&DistanceToIntersection[i]); 2545 } 2546 delete(ClosestPoint); 2547 if ((distance[0] * distance[1]) > 0) { // have same sign? 2548 Log() << Verbose(1) << "REJECT: Both SKPs have same sign: " << distance[0] << " and " << distance[1] << ". " << *Base << "' rectangle is concave." << endl; 2800 BaseLine = (*Base->endpoints[1]->node->node) - (*Base->endpoints[0]->node->node); 2801 for (int i = 0; i < 2; i++) { 2802 DistanceToIntersection[i] = (*ClosestPoint) - (*Base->endpoints[i]->node->node); 2803 distance[i] = BaseLine.ScalarProduct(DistanceToIntersection[i]); 2804 } 2805 delete (ClosestPoint); 2806 if ((distance[0] * distance[1]) > 0) { // have same sign? 2807 DoLog(1) && (Log() << Verbose(1) << "REJECT: Both SKPs have same sign: " << distance[0] << " and " << distance[1] << ". " << *Base << "' rectangle is concave." << endl); 2549 2808 if (distance[0] < distance[1]) { 2550 2809 Spot = Base->endpoints[0]; … … 2553 2812 } 2554 2813 return Spot; 2555 } else { 2556 Log() << Verbose(0) << "ACCEPT: Rectangle of triangles of base line " << *Base << " is convex." << endl;2814 } else { // different sign, i.e. we are in between 2815 DoLog(0) && (Log() << Verbose(0) << "ACCEPT: Rectangle of triangles of base line " << *Base << " is convex." << endl); 2557 2816 return NULL; 2558 2817 } 2559 2818 2560 }; 2819 } 2820 ; 2561 2821 2562 2822 void Tesselation::PrintAllBoundaryPoints(ofstream *out) const 2563 2823 { 2564 2824 Info FunctionInfo(__func__); 2565 2825 // print all lines 2566 Log() << Verbose(0) << "Printing all boundary points for debugging:" << endl; 2567 for (PointMap::const_iterator PointRunner = PointsOnBoundary.begin();PointRunner != PointsOnBoundary.end(); PointRunner++) 2568 Log() << Verbose(0) << *(PointRunner->second) << endl; 2569 }; 2826 DoLog(0) && (Log() << Verbose(0) << "Printing all boundary points for debugging:" << endl); 2827 for (PointMap::const_iterator PointRunner = PointsOnBoundary.begin(); PointRunner != PointsOnBoundary.end(); PointRunner++) 2828 DoLog(0) && (Log() << Verbose(0) << *(PointRunner->second) << endl); 2829 } 2830 ; 2570 2831 2571 2832 void Tesselation::PrintAllBoundaryLines(ofstream *out) const 2572 2833 { 2573 2834 Info FunctionInfo(__func__); 2574 2835 // print all lines 2575 Log() << Verbose(0) << "Printing all boundary lines for debugging:" << endl;2836 DoLog(0) && (Log() << Verbose(0) << "Printing all boundary lines for debugging:" << endl); 2576 2837 for (LineMap::const_iterator LineRunner = LinesOnBoundary.begin(); LineRunner != LinesOnBoundary.end(); LineRunner++) 2577 Log() << Verbose(0) << *(LineRunner->second) << endl; 2578 }; 2838 DoLog(0) && (Log() << Verbose(0) << *(LineRunner->second) << endl); 2839 } 2840 ; 2579 2841 2580 2842 void Tesselation::PrintAllBoundaryTriangles(ofstream *out) const 2581 2843 { 2582 2844 Info FunctionInfo(__func__); 2583 2845 // print all triangles 2584 Log() << Verbose(0) << "Printing all boundary triangles for debugging:" << endl;2846 DoLog(0) && (Log() << Verbose(0) << "Printing all boundary triangles for debugging:" << endl); 2585 2847 for (TriangleMap::const_iterator TriangleRunner = TrianglesOnBoundary.begin(); TriangleRunner != TrianglesOnBoundary.end(); TriangleRunner++) 2586 Log() << Verbose(0) << *(TriangleRunner->second) << endl; 2587 }; 2848 DoLog(0) && (Log() << Verbose(0) << *(TriangleRunner->second) << endl); 2849 } 2850 ; 2588 2851 2589 2852 /** For a given boundary line \a *Base and its two triangles, picks the central baseline that is "higher". … … 2594 2857 double Tesselation::PickFarthestofTwoBaselines(class BoundaryLineSet *Base) 2595 2858 { 2596 2859 Info FunctionInfo(__func__); 2597 2860 class BoundaryLineSet *OtherBase; 2598 2861 Vector *ClosestPoint[2]; 2599 2862 double volume; 2600 2863 2601 int m =0;2602 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++)2603 for (int j =0;j<3;j++) // all of their endpoints and baselines2864 int m = 0; 2865 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 2866 for (int j = 0; j < 3; j++) // all of their endpoints and baselines 2604 2867 if (!Base->ContainsBoundaryPoint(runner->second->endpoints[j])) // and neither of its endpoints 2605 2868 BPS[m++] = runner->second->endpoints[j]; 2606 OtherBase = new class BoundaryLineSet(BPS, -1);2607 2608 Log() << Verbose(0) << "INFO: Current base line is " << *Base << "." << endl;2609 Log() << Verbose(0) << "INFO: Other base line is " << *OtherBase << "." << endl;2869 OtherBase = new class BoundaryLineSet(BPS, -1); 2870 2871 DoLog(0) && (Log() << Verbose(0) << "INFO: Current base line is " << *Base << "." << endl); 2872 DoLog(0) && (Log() << Verbose(0) << "INFO: Other base line is " << *OtherBase << "." << endl); 2610 2873 2611 2874 // get the closest point on each line to the other line … … 2614 2877 2615 2878 // get the distance vector from Base line to OtherBase line 2616 Vector Distance; 2617 Distance.CopyVector(ClosestPoint[1]); 2618 Distance.SubtractVector(ClosestPoint[0]); 2879 Vector Distance = (*ClosestPoint[1]) - (*ClosestPoint[0]); 2619 2880 2620 2881 // calculate volume … … 2622 2883 2623 2884 // delete the temporary other base line and the closest points 2624 delete (ClosestPoint[0]);2625 delete (ClosestPoint[1]);2626 delete (OtherBase);2885 delete (ClosestPoint[0]); 2886 delete (ClosestPoint[1]); 2887 delete (OtherBase); 2627 2888 2628 2889 if (Distance.NormSquared() < MYEPSILON) { // check for intersection 2629 Log() << Verbose(0) << "REJECT: Both lines have an intersection: Nothing to do." << endl;2890 DoLog(0) && (Log() << Verbose(0) << "REJECT: Both lines have an intersection: Nothing to do." << endl); 2630 2891 return false; 2631 2892 } else { // check for sign against BaseLineNormal … … 2633 2894 BaseLineNormal.Zero(); 2634 2895 if (Base->triangles.size() < 2) { 2635 eLog() << Verbose(1) << "Less than two triangles are attached to this baseline!" << endl;2896 DoeLog(1) && (eLog() << Verbose(1) << "Less than two triangles are attached to this baseline!" << endl); 2636 2897 return 0.; 2637 2898 } 2638 2899 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { 2639 Log() << Verbose(1) << "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << "." << endl;2640 BaseLineNormal .AddVector(&(runner->second->NormalVector));2641 } 2642 BaseLineNormal.Scale(1. /2.);2643 2644 if (Distance.ScalarProduct( &BaseLineNormal) > MYEPSILON) { // Distance points outwards, hence OtherBase higher than Base -> flip2645 Log() << Verbose(0) << "ACCEPT: Other base line would be higher: Flipping baseline." << endl;2900 DoLog(1) && (Log() << Verbose(1) << "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << "." << endl); 2901 BaseLineNormal += (runner->second->NormalVector); 2902 } 2903 BaseLineNormal.Scale(1. / 2.); 2904 2905 if (Distance.ScalarProduct(BaseLineNormal) > MYEPSILON) { // Distance points outwards, hence OtherBase higher than Base -> flip 2906 DoLog(0) && (Log() << Verbose(0) << "ACCEPT: Other base line would be higher: Flipping baseline." << endl); 2646 2907 // calculate volume summand as a general tetraeder 2647 2908 return volume; 2648 } else { 2649 Log() << Verbose(0) << "REJECT: Base line is higher: Nothing to do." << endl;2909 } else { // Base higher than OtherBase -> do nothing 2910 DoLog(0) && (Log() << Verbose(0) << "REJECT: Base line is higher: Nothing to do." << endl); 2650 2911 return 0.; 2651 2912 } 2652 2913 } 2653 }; 2914 } 2915 ; 2654 2916 2655 2917 /** For a given baseline and its two connected triangles, flips the baseline. … … 2662 2924 class BoundaryLineSet * Tesselation::FlipBaseline(class BoundaryLineSet *Base) 2663 2925 { 2664 2926 Info FunctionInfo(__func__); 2665 2927 class BoundaryLineSet *OldLines[4], *NewLine; 2666 2928 class BoundaryPointSet *OldPoints[2]; 2667 2929 Vector BaseLineNormal; 2668 2930 int OldTriangleNrs[2], OldBaseLineNr; 2669 int i, m;2931 int i, m; 2670 2932 2671 2933 // calculate NormalVector for later use 2672 2934 BaseLineNormal.Zero(); 2673 2935 if (Base->triangles.size() < 2) { 2674 eLog() << Verbose(1) << "Less than two triangles are attached to this baseline!" << endl;2936 DoeLog(1) && (eLog() << Verbose(1) << "Less than two triangles are attached to this baseline!" << endl); 2675 2937 return NULL; 2676 2938 } 2677 2939 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { 2678 Log() << Verbose(1) << "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << "." << endl;2679 BaseLineNormal .AddVector(&(runner->second->NormalVector));2680 } 2681 BaseLineNormal.Scale(-1. /2.); // has to point inside for BoundaryTriangleSet::GetNormalVector()2940 DoLog(1) && (Log() << Verbose(1) << "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << "." << endl); 2941 BaseLineNormal += (runner->second->NormalVector); 2942 } 2943 BaseLineNormal.Scale(-1. / 2.); // has to point inside for BoundaryTriangleSet::GetNormalVector() 2682 2944 2683 2945 // get the two triangles 2684 2946 // gather four endpoints and four lines 2685 for (int j =0;j<4;j++)2947 for (int j = 0; j < 4; j++) 2686 2948 OldLines[j] = NULL; 2687 for (int j =0;j<2;j++)2949 for (int j = 0; j < 2; j++) 2688 2950 OldPoints[j] = NULL; 2689 i =0;2690 m =0;2691 Log() << Verbose(0) << "The four old lines are: ";2692 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++)2693 for (int j =0;j<3;j++) // all of their endpoints and baselines2951 i = 0; 2952 m = 0; 2953 DoLog(0) && (Log() << Verbose(0) << "The four old lines are: "); 2954 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 2955 for (int j = 0; j < 3; j++) // all of their endpoints and baselines 2694 2956 if (runner->second->lines[j] != Base) { // pick not the central baseline 2695 2957 OldLines[i++] = runner->second->lines[j]; 2696 Log() << Verbose(0) << *runner->second->lines[j] << "\t";2958 DoLog(0) && (Log() << Verbose(0) << *runner->second->lines[j] << "\t"); 2697 2959 } 2698 Log() << Verbose(0) << endl;2699 Log() << Verbose(0) << "The two old points are: ";2700 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++)2701 for (int j =0;j<3;j++) // all of their endpoints and baselines2960 DoLog(0) && (Log() << Verbose(0) << endl); 2961 DoLog(0) && (Log() << Verbose(0) << "The two old points are: "); 2962 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 2963 for (int j = 0; j < 3; j++) // all of their endpoints and baselines 2702 2964 if (!Base->ContainsBoundaryPoint(runner->second->endpoints[j])) { // and neither of its endpoints 2703 2965 OldPoints[m++] = runner->second->endpoints[j]; 2704 Log() << Verbose(0) << *runner->second->endpoints[j] << "\t";2966 DoLog(0) && (Log() << Verbose(0) << *runner->second->endpoints[j] << "\t"); 2705 2967 } 2706 Log() << Verbose(0) << endl;2968 DoLog(0) && (Log() << Verbose(0) << endl); 2707 2969 2708 2970 // check whether everything is in place to create new lines and triangles 2709 if (i <4) {2710 eLog() << Verbose(1) << "We have not gathered enough baselines!" << endl;2971 if (i < 4) { 2972 DoeLog(1) && (eLog() << Verbose(1) << "We have not gathered enough baselines!" << endl); 2711 2973 return NULL; 2712 2974 } 2713 for (int j =0;j<4;j++)2975 for (int j = 0; j < 4; j++) 2714 2976 if (OldLines[j] == NULL) { 2715 eLog() << Verbose(1) << "We have not gathered enough baselines!" << endl;2977 DoeLog(1) && (eLog() << Verbose(1) << "We have not gathered enough baselines!" << endl); 2716 2978 return NULL; 2717 2979 } 2718 for (int j =0;j<2;j++)2980 for (int j = 0; j < 2; j++) 2719 2981 if (OldPoints[j] == NULL) { 2720 eLog() << Verbose(1) << "We have not gathered enough endpoints!" << endl;2982 DoeLog(1) && (eLog() << Verbose(1) << "We have not gathered enough endpoints!" << endl); 2721 2983 return NULL; 2722 2984 } 2723 2985 2724 2986 // remove triangles and baseline removes itself 2725 Log() << Verbose(0) << "INFO: Deleting baseline " << *Base << " from global list." << endl;2987 DoLog(0) && (Log() << Verbose(0) << "INFO: Deleting baseline " << *Base << " from global list." << endl); 2726 2988 OldBaseLineNr = Base->Nr; 2727 m =0;2728 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {2729 Log() << Verbose(0) << "INFO: Deleting triangle " << *(runner->second) << "." << endl;2989 m = 0; 2990 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { 2991 DoLog(0) && (Log() << Verbose(0) << "INFO: Deleting triangle " << *(runner->second) << "." << endl); 2730 2992 OldTriangleNrs[m++] = runner->second->Nr; 2731 2993 RemoveTesselationTriangle(runner->second); … … 2737 2999 NewLine = new class BoundaryLineSet(BPS, OldBaseLineNr); 2738 3000 LinesOnBoundary.insert(LinePair(OldBaseLineNr, NewLine)); // no need for check for unique insertion as NewLine is definitely a new one 2739 Log() << Verbose(0) << "INFO: Created new baseline " << *NewLine << "." << endl;3001 DoLog(0) && (Log() << Verbose(0) << "INFO: Created new baseline " << *NewLine << "." << endl); 2740 3002 2741 3003 // construct new triangles with flipped baseline 2742 i =-1;3004 i = -1; 2743 3005 if (OldLines[0]->IsConnectedTo(OldLines[2])) 2744 i =2;3006 i = 2; 2745 3007 if (OldLines[0]->IsConnectedTo(OldLines[3])) 2746 i =3;2747 if (i !=-1) {3008 i = 3; 3009 if (i != -1) { 2748 3010 BLS[0] = OldLines[0]; 2749 3011 BLS[1] = OldLines[i]; … … 2752 3014 BTS->GetNormalVector(BaseLineNormal); 2753 3015 AddTesselationTriangle(OldTriangleNrs[0]); 2754 Log() << Verbose(0) << "INFO: Created new triangle " << *BTS << "." << endl;2755 2756 BLS[0] = (i ==2 ? OldLines[3] : OldLines[2]);3016 DoLog(0) && (Log() << Verbose(0) << "INFO: Created new triangle " << *BTS << "." << endl); 3017 3018 BLS[0] = (i == 2 ? OldLines[3] : OldLines[2]); 2757 3019 BLS[1] = OldLines[1]; 2758 3020 BLS[2] = NewLine; … … 2760 3022 BTS->GetNormalVector(BaseLineNormal); 2761 3023 AddTesselationTriangle(OldTriangleNrs[1]); 2762 Log() << Verbose(0) << "INFO: Created new triangle " << *BTS << "." << endl;3024 DoLog(0) && (Log() << Verbose(0) << "INFO: Created new triangle " << *BTS << "." << endl); 2763 3025 } else { 2764 eLog() << Verbose(0) << "The four old lines do not connect, something's utterly wrong here!" << endl;3026 DoeLog(0) && (eLog() << Verbose(0) << "The four old lines do not connect, something's utterly wrong here!" << endl); 2765 3027 return NULL; 2766 3028 } 2767 3029 2768 3030 return NewLine; 2769 } ;2770 3031 } 3032 ; 2771 3033 2772 3034 /** Finds the second point of starting triangle. … … 2780 3042 void Tesselation::FindSecondPointForTesselation(TesselPoint* a, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, const LinkedCell *LC) 2781 3043 { 2782 3044 Info FunctionInfo(__func__); 2783 3045 Vector AngleCheck; 2784 3046 class TesselPoint* Candidate = NULL; … … 2789 3051 int Nupper[NDIM]; 2790 3052 2791 if (LC->SetIndexToNode(a)) { 2792 for (int i=0;i<NDIM;i++) // store indices of this cell3053 if (LC->SetIndexToNode(a)) { // get cell for the starting point 3054 for (int i = 0; i < NDIM; i++) // store indices of this cell 2793 3055 N[i] = LC->n[i]; 2794 3056 } else { 2795 eLog() << Verbose(1) << "Point " << *a << " is not found in cell " << LC->index << "." << endl;3057 DoeLog(1) && (eLog() << Verbose(1) << "Point " << *a << " is not found in cell " << LC->index << "." << endl); 2796 3058 return; 2797 3059 } 2798 3060 // then go through the current and all neighbouring cells and check the contained points for possible candidates 2799 for (int i=0;i<NDIM;i++) { 2800 Nlower[i] = ((N[i]-1) >= 0) ? N[i]-1 : 0; 2801 Nupper[i] = ((N[i]+1) < LC->N[i]) ? N[i]+1 : LC->N[i]-1; 2802 } 2803 Log() << Verbose(0) << "LC Intervals from [" << N[0] << "<->" << LC->N[0] << ", " << N[1] << "<->" << LC->N[1] << ", " << N[2] << "<->" << LC->N[2] << "] :" 2804 << " [" << Nlower[0] << "," << Nupper[0] << "], " << " [" << Nlower[1] << "," << Nupper[1] << "], " << " [" << Nlower[2] << "," << Nupper[2] << "], " << endl; 3061 for (int i = 0; i < NDIM; i++) { 3062 Nlower[i] = ((N[i] - 1) >= 0) ? N[i] - 1 : 0; 3063 Nupper[i] = ((N[i] + 1) < LC->N[i]) ? N[i] + 1 : LC->N[i] - 1; 3064 } 3065 DoLog(0) && (Log() << Verbose(0) << "LC Intervals from [" << N[0] << "<->" << LC->N[0] << ", " << N[1] << "<->" << LC->N[1] << ", " << N[2] << "<->" << LC->N[2] << "] :" << " [" << Nlower[0] << "," << Nupper[0] << "], " << " [" << Nlower[1] << "," << Nupper[1] << "], " << " [" << Nlower[2] << "," << Nupper[2] << "], " << endl); 2805 3066 2806 3067 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++) 2807 3068 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 2808 3069 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 2809 const Linked Nodes *List = LC->GetCurrentCell();3070 const LinkedCell::LinkedNodes *List = LC->GetCurrentCell(); 2810 3071 //Log() << Verbose(1) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 2811 3072 if (List != NULL) { 2812 for (Linked Nodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {3073 for (LinkedCell::LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 2813 3074 Candidate = (*Runner); 2814 3075 // check if we only have one unique point yet ... … … 2818 3079 double distance, scaleFactor; 2819 3080 2820 OrthogonalizedOben.CopyVector(&Oben); 2821 aCandidate.CopyVector(a->node); 2822 aCandidate.SubtractVector(Candidate->node); 2823 OrthogonalizedOben.ProjectOntoPlane(&aCandidate); 3081 OrthogonalizedOben = Oben; 3082 aCandidate = (*a->node) - (*Candidate->node); 3083 OrthogonalizedOben.ProjectOntoPlane(aCandidate); 2824 3084 OrthogonalizedOben.Normalize(); 2825 3085 distance = 0.5 * aCandidate.Norm(); … … 2827 3087 OrthogonalizedOben.Scale(scaleFactor); 2828 3088 2829 Center.CopyVector(Candidate->node); 2830 Center.AddVector(a->node); 2831 Center.Scale(0.5); 2832 Center.AddVector(&OrthogonalizedOben); 2833 2834 AngleCheck.CopyVector(&Center); 2835 AngleCheck.SubtractVector(a->node); 3089 Center = 0.5 * ((*Candidate->node) + (*a->node)); 3090 Center += OrthogonalizedOben; 3091 3092 AngleCheck = Center - (*a->node); 2836 3093 norm = aCandidate.Norm(); 2837 3094 // second point shall have smallest angle with respect to Oben vector 2838 if (norm < RADIUS *2.) {2839 angle = AngleCheck.Angle( &Oben);3095 if (norm < RADIUS * 2.) { 3096 angle = AngleCheck.Angle(Oben); 2840 3097 if (angle < Storage[0]) { 2841 3098 //Log() << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]); 2842 Log() << Verbose(1) << "Current candidate is " << *Candidate << ": Is a better candidate with distance " << norm << " and angle " << angle << " to oben " << Oben << ".\n";3099 DoLog(1) && (Log() << Verbose(1) << "Current candidate is " << *Candidate << ": Is a better candidate with distance " << norm << " and angle " << angle << " to oben " << Oben << ".\n"); 2843 3100 OptCandidate = Candidate; 2844 3101 Storage[0] = angle; … … 2855 3112 } 2856 3113 } else { 2857 Log() << Verbose(0) << "Linked cell list is empty." << endl;3114 DoLog(0) && (Log() << Verbose(0) << "Linked cell list is empty." << endl); 2858 3115 } 2859 3116 } 2860 } ;2861 3117 } 3118 ; 2862 3119 2863 3120 /** This recursive function finds a third point, to form a triangle with two given ones. … … 2887 3144 * @param OldSphereCenter center of sphere for base triangle, relative to center of BaseLine, giving null angle for the parameter circle 2888 3145 * @param CandidateLine CandidateForTesselation with the current base line and list of candidates and ShortestAngle 2889 * @param Third Nodethird point to avoid in search3146 * @param ThirdPoint third point to avoid in search 2890 3147 * @param RADIUS radius of sphere 2891 3148 * @param *LC LinkedCell structure with neighbouring points 2892 3149 */ 2893 void Tesselation::FindThirdPointForTesselation( Vector &NormalVector, Vector &SearchDirection, Vector &OldSphereCenter, CandidateForTesselation &CandidateLine, const class TesselPoint * const ThirdNode, const double RADIUS, const LinkedCell *LC) const2894 { 2895 2896 Vector CircleCenter; 3150 void Tesselation::FindThirdPointForTesselation(const Vector &NormalVector, const Vector &SearchDirection, const Vector &OldSphereCenter, CandidateForTesselation &CandidateLine, const class BoundaryPointSet * const ThirdPoint, const double RADIUS, const LinkedCell *LC) const 3151 { 3152 Info FunctionInfo(__func__); 3153 Vector CircleCenter; // center of the circle, i.e. of the band of sphere's centers 2897 3154 Vector CirclePlaneNormal; // normal vector defining the plane this circle lives in 2898 3155 Vector SphereCenter; 2899 Vector NewSphereCenter; 2900 Vector OtherNewSphereCenter; 2901 Vector NewNormalVector; 3156 Vector NewSphereCenter; // center of the sphere defined by the two points of BaseLine and the one of Candidate, first possibility 3157 Vector OtherNewSphereCenter; // center of the sphere defined by the two points of BaseLine and the one of Candidate, second possibility 3158 Vector NewNormalVector; // normal vector of the Candidate's triangle 2902 3159 Vector helper, OptCandidateCenter, OtherOptCandidateCenter; 2903 3160 Vector RelativeOldSphereCenter; … … 2910 3167 TesselPoint *Candidate = NULL; 2911 3168 2912 Log() << Verbose(1) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl; 3169 DoLog(1) && (Log() << Verbose(1) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl); 3170 3171 // copy old center 3172 CandidateLine.OldCenter = OldSphereCenter; 3173 CandidateLine.ThirdPoint = ThirdPoint; 3174 CandidateLine.pointlist.clear(); 2913 3175 2914 3176 // construct center of circle 2915 CircleCenter.CopyVector(CandidateLine.BaseLine->endpoints[0]->node->node); 2916 CircleCenter.AddVector(CandidateLine.BaseLine->endpoints[1]->node->node); 2917 CircleCenter.Scale(0.5); 3177 CircleCenter = 0.5 * ((*CandidateLine.BaseLine->endpoints[0]->node->node) + 3178 (*CandidateLine.BaseLine->endpoints[1]->node->node)); 2918 3179 2919 3180 // construct normal vector of circle 2920 CirclePlaneNormal.CopyVector(CandidateLine.BaseLine->endpoints[0]->node->node); 2921 CirclePlaneNormal.SubtractVector(CandidateLine.BaseLine->endpoints[1]->node->node); 2922 2923 RelativeOldSphereCenter.CopyVector(&OldSphereCenter); 2924 RelativeOldSphereCenter.SubtractVector(&CircleCenter); 2925 2926 // calculate squared radius TesselPoint *ThirdNode,f circle 2927 radius = CirclePlaneNormal.NormSquared()/4.; 2928 if (radius < RADIUS*RADIUS) { 2929 CircleRadius = RADIUS*RADIUS - radius; 3181 CirclePlaneNormal = (*CandidateLine.BaseLine->endpoints[0]->node->node) - 3182 (*CandidateLine.BaseLine->endpoints[1]->node->node); 3183 3184 RelativeOldSphereCenter = OldSphereCenter - CircleCenter; 3185 3186 // calculate squared radius TesselPoint *ThirdPoint,f circle 3187 radius = CirclePlaneNormal.NormSquared() / 4.; 3188 if (radius < RADIUS * RADIUS) { 3189 CircleRadius = RADIUS * RADIUS - radius; 2930 3190 CirclePlaneNormal.Normalize(); 2931 Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;3191 DoLog(1) && (Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl); 2932 3192 2933 3193 // test whether old center is on the band's plane 2934 if (fabs(RelativeOldSphereCenter.ScalarProduct( &CirclePlaneNormal)) > HULLEPSILON) {2935 eLog() << Verbose(1) << "Something's very wrong here: RelativeOldSphereCenter is not on the band's plane as desired by " << fabs(RelativeOldSphereCenter.ScalarProduct(&CirclePlaneNormal)) << "!" << endl;2936 RelativeOldSphereCenter.ProjectOntoPlane( &CirclePlaneNormal);3194 if (fabs(RelativeOldSphereCenter.ScalarProduct(CirclePlaneNormal)) > HULLEPSILON) { 3195 DoeLog(1) && (eLog() << Verbose(1) << "Something's very wrong here: RelativeOldSphereCenter is not on the band's plane as desired by " << fabs(RelativeOldSphereCenter.ScalarProduct(CirclePlaneNormal)) << "!" << endl); 3196 RelativeOldSphereCenter.ProjectOntoPlane(CirclePlaneNormal); 2937 3197 } 2938 3198 radius = RelativeOldSphereCenter.NormSquared(); 2939 3199 if (fabs(radius - CircleRadius) < HULLEPSILON) { 2940 Log() << Verbose(1) << "INFO: RelativeOldSphereCenter is at " << RelativeOldSphereCenter << "." << endl;3200 DoLog(1) && (Log() << Verbose(1) << "INFO: RelativeOldSphereCenter is at " << RelativeOldSphereCenter << "." << endl); 2941 3201 2942 3202 // check SearchDirection 2943 Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl;2944 if (fabs(RelativeOldSphereCenter.ScalarProduct( &SearchDirection)) > HULLEPSILON) {// rotated the wrong way!2945 eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are not orthogonal!" << endl;3203 DoLog(1) && (Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl); 3204 if (fabs(RelativeOldSphereCenter.ScalarProduct(SearchDirection)) > HULLEPSILON) { // rotated the wrong way! 3205 DoeLog(1) && (eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are not orthogonal!" << endl); 2946 3206 } 2947 3207 2948 3208 // get cell for the starting point 2949 3209 if (LC->SetIndexToVector(&CircleCenter)) { 2950 for (int i=0;i<NDIM;i++) // store indices of this cell2951 N[i] = LC->n[i];3210 for (int i = 0; i < NDIM; i++) // store indices of this cell 3211 N[i] = LC->n[i]; 2952 3212 //Log() << Verbose(1) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 2953 3213 } else { 2954 eLog() << Verbose(1) << "Vector " << CircleCenter << " is outside of LinkedCell's bounding box." << endl;3214 DoeLog(1) && (eLog() << Verbose(1) << "Vector " << CircleCenter << " is outside of LinkedCell's bounding box." << endl); 2955 3215 return; 2956 3216 } 2957 3217 // then go through the current and all neighbouring cells and check the contained points for possible candidates 2958 3218 //Log() << Verbose(1) << "LC Intervals:"; 2959 for (int i =0;i<NDIM;i++) {2960 Nlower[i] = ((N[i] -1) >= 0) ? N[i]-1 : 0;2961 Nupper[i] = ((N[i] +1) < LC->N[i]) ? N[i]+1 : LC->N[i]-1;3219 for (int i = 0; i < NDIM; i++) { 3220 Nlower[i] = ((N[i] - 1) >= 0) ? N[i] - 1 : 0; 3221 Nupper[i] = ((N[i] + 1) < LC->N[i]) ? N[i] + 1 : LC->N[i] - 1; 2962 3222 //Log() << Verbose(0) << " [" << Nlower[i] << "," << Nupper[i] << "] "; 2963 3223 } … … 2966 3226 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 2967 3227 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 2968 const Linked Nodes *List = LC->GetCurrentCell();3228 const LinkedCell::LinkedNodes *List = LC->GetCurrentCell(); 2969 3229 //Log() << Verbose(1) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 2970 3230 if (List != NULL) { 2971 for (Linked Nodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {3231 for (LinkedCell::LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 2972 3232 Candidate = (*Runner); 2973 3233 2974 3234 // check for three unique points 2975 Log() << Verbose(2) << "INFO: Current Candidate is " << *Candidate << " for BaseLine " << *CandidateLine.BaseLine << " with OldSphereCenter " << OldSphereCenter << "." << endl;2976 if ((Candidate != CandidateLine.BaseLine->endpoints[0]->node) && (Candidate != CandidateLine.BaseLine->endpoints[1]->node) ){3235 DoLog(2) && (Log() << Verbose(2) << "INFO: Current Candidate is " << *Candidate << " for BaseLine " << *CandidateLine.BaseLine << " with OldSphereCenter " << OldSphereCenter << "." << endl); 3236 if ((Candidate != CandidateLine.BaseLine->endpoints[0]->node) && (Candidate != CandidateLine.BaseLine->endpoints[1]->node)) { 2977 3237 2978 3238 // find center on the plane 2979 3239 GetCenterofCircumcircle(&NewPlaneCenter, *CandidateLine.BaseLine->endpoints[0]->node->node, *CandidateLine.BaseLine->endpoints[1]->node->node, *Candidate->node); 2980 Log() << Verbose(1) << "INFO: NewPlaneCenter is " << NewPlaneCenter << "." << endl; 2981 2982 if (NewNormalVector.MakeNormalVector(CandidateLine.BaseLine->endpoints[0]->node->node, CandidateLine.BaseLine->endpoints[1]->node->node, Candidate->node) 2983 && (fabs(NewNormalVector.NormSquared()) > HULLEPSILON) 2984 ) { 2985 Log() << Verbose(1) << "INFO: NewNormalVector is " << NewNormalVector << "." << endl; 2986 radius = CandidateLine.BaseLine->endpoints[0]->node->node->DistanceSquared(&NewPlaneCenter); 2987 Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 2988 Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl; 2989 Log() << Verbose(1) << "INFO: Radius of CircumCenterCircle is " << radius << "." << endl; 2990 if (radius < RADIUS*RADIUS) { 2991 otherradius = CandidateLine.BaseLine->endpoints[1]->node->node->DistanceSquared(&NewPlaneCenter); 2992 if (fabs(radius - otherradius) > HULLEPSILON) { 2993 eLog() << Verbose(1) << "Distance to center of circumcircle is not the same from each corner of the triangle: " << fabs(radius-otherradius) << endl; 2994 } 2995 // construct both new centers 2996 NewSphereCenter.CopyVector(&NewPlaneCenter); 2997 OtherNewSphereCenter.CopyVector(&NewPlaneCenter); 2998 helper.CopyVector(&NewNormalVector); 2999 helper.Scale(sqrt(RADIUS*RADIUS - radius)); 3000 Log() << Verbose(2) << "INFO: Distance of NewPlaneCenter " << NewPlaneCenter << " to either NewSphereCenter is " << helper.Norm() << " of vector " << helper << " with sphere radius " << RADIUS << "." << endl; 3001 NewSphereCenter.AddVector(&helper); 3002 Log() << Verbose(2) << "INFO: NewSphereCenter is at " << NewSphereCenter << "." << endl; 3003 // OtherNewSphereCenter is created by the same vector just in the other direction 3004 helper.Scale(-1.); 3005 OtherNewSphereCenter.AddVector(&helper); 3006 Log() << Verbose(2) << "INFO: OtherNewSphereCenter is at " << OtherNewSphereCenter << "." << endl; 3007 3008 alpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, NewSphereCenter, OldSphereCenter, NormalVector, SearchDirection); 3009 Otheralpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, OtherNewSphereCenter, OldSphereCenter, NormalVector, SearchDirection); 3010 alpha = min(alpha, Otheralpha); 3011 3012 // if there is a better candidate, drop the current list and add the new candidate 3013 // otherwise ignore the new candidate and keep the list 3014 if (CandidateLine.ShortestAngle > (alpha - HULLEPSILON)) { 3015 if (fabs(alpha - Otheralpha) > MYEPSILON) { 3016 CandidateLine.OptCenter.CopyVector(&NewSphereCenter); 3017 CandidateLine.OtherOptCenter.CopyVector(&OtherNewSphereCenter); 3240 DoLog(1) && (Log() << Verbose(1) << "INFO: NewPlaneCenter is " << NewPlaneCenter << "." << endl); 3241 3242 try { 3243 NewNormalVector = Plane(*(CandidateLine.BaseLine->endpoints[0]->node->node), 3244 *(CandidateLine.BaseLine->endpoints[1]->node->node), 3245 *(Candidate->node)).getNormal(); 3246 DoLog(1) && (Log() << Verbose(1) << "INFO: NewNormalVector is " << NewNormalVector << "." << endl); 3247 radius = CandidateLine.BaseLine->endpoints[0]->node->node->DistanceSquared(NewPlaneCenter); 3248 DoLog(1) && (Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl); 3249 DoLog(1) && (Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl); 3250 DoLog(1) && (Log() << Verbose(1) << "INFO: Radius of CircumCenterCircle is " << radius << "." << endl); 3251 if (radius < RADIUS * RADIUS) { 3252 otherradius = CandidateLine.BaseLine->endpoints[1]->node->node->DistanceSquared(NewPlaneCenter); 3253 if (fabs(radius - otherradius) < HULLEPSILON) { 3254 // construct both new centers 3255 NewSphereCenter = NewPlaneCenter; 3256 OtherNewSphereCenter= NewPlaneCenter; 3257 helper = NewNormalVector; 3258 helper.Scale(sqrt(RADIUS * RADIUS - radius)); 3259 DoLog(2) && (Log() << Verbose(2) << "INFO: Distance of NewPlaneCenter " << NewPlaneCenter << " to either NewSphereCenter is " << helper.Norm() << " of vector " << helper << " with sphere radius " << RADIUS << "." << endl); 3260 NewSphereCenter += helper; 3261 DoLog(2) && (Log() << Verbose(2) << "INFO: NewSphereCenter is at " << NewSphereCenter << "." << endl); 3262 // OtherNewSphereCenter is created by the same vector just in the other direction 3263 helper.Scale(-1.); 3264 OtherNewSphereCenter += helper; 3265 DoLog(2) && (Log() << Verbose(2) << "INFO: OtherNewSphereCenter is at " << OtherNewSphereCenter << "." << endl); 3266 alpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, NewSphereCenter, OldSphereCenter, NormalVector, SearchDirection); 3267 Otheralpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, OtherNewSphereCenter, OldSphereCenter, NormalVector, SearchDirection); 3268 if ((ThirdPoint != NULL) && (Candidate == ThirdPoint->node)) { // in that case only the other circlecenter is valid 3269 if (OldSphereCenter.DistanceSquared(NewSphereCenter) < OldSphereCenter.DistanceSquared(OtherNewSphereCenter)) 3270 alpha = Otheralpha; 3271 } else 3272 alpha = min(alpha, Otheralpha); 3273 // if there is a better candidate, drop the current list and add the new candidate 3274 // otherwise ignore the new candidate and keep the list 3275 if (CandidateLine.ShortestAngle > (alpha - HULLEPSILON)) { 3276 if (fabs(alpha - Otheralpha) > MYEPSILON) { 3277 CandidateLine.OptCenter = NewSphereCenter; 3278 CandidateLine.OtherOptCenter = OtherNewSphereCenter; 3279 } else { 3280 CandidateLine.OptCenter = OtherNewSphereCenter; 3281 CandidateLine.OtherOptCenter = NewSphereCenter; 3282 } 3283 // if there is an equal candidate, add it to the list without clearing the list 3284 if ((CandidateLine.ShortestAngle - HULLEPSILON) < alpha) { 3285 CandidateLine.pointlist.push_back(Candidate); 3286 DoLog(0) && (Log() << Verbose(0) << "ACCEPT: We have found an equally good candidate: " << *(Candidate) << " with " << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << "." << endl); 3287 } else { 3288 // remove all candidates from the list and then the list itself 3289 CandidateLine.pointlist.clear(); 3290 CandidateLine.pointlist.push_back(Candidate); 3291 DoLog(0) && (Log() << Verbose(0) << "ACCEPT: We have found a better candidate: " << *(Candidate) << " with " << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << "." << endl); 3292 } 3293 CandidateLine.ShortestAngle = alpha; 3294 DoLog(0) && (Log() << Verbose(0) << "INFO: There are " << CandidateLine.pointlist.size() << " candidates in the list now." << endl); 3018 3295 } else { 3019 CandidateLine.OptCenter.CopyVector(&OtherNewSphereCenter); 3020 CandidateLine.OtherOptCenter.CopyVector(&NewSphereCenter); 3296 if ((Candidate != NULL) && (CandidateLine.pointlist.begin() != CandidateLine.pointlist.end())) { 3297 DoLog(1) && (Log() << Verbose(1) << "REJECT: Old candidate " << *(*CandidateLine.pointlist.begin()) << " with " << CandidateLine.ShortestAngle << " is better than new one " << *Candidate << " with " << alpha << " ." << endl); 3298 } else { 3299 DoLog(1) && (Log() << Verbose(1) << "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected." << endl); 3300 } 3021 3301 } 3022 // if there is an equal candidate, add it to the list without clearing the list3023 if ((CandidateLine.ShortestAngle - HULLEPSILON) < alpha) {3024 CandidateLine.pointlist.push_back(Candidate);3025 Log() << Verbose(0) << "ACCEPT: We have found an equally good candidate: " << *(Candidate) << " with "3026 << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << "." << endl;3027 } else {3028 // remove all candidates from the list and then the list itself3029 CandidateLine.pointlist.clear();3030 CandidateLine.pointlist.push_back(Candidate);3031 Log() << Verbose(0) << "ACCEPT: We have found a better candidate: " << *(Candidate) << " with "3032 << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << "." << endl;3033 }3034 CandidateLine.ShortestAngle = alpha;3035 Log() << Verbose(0) << "INFO: There are " << CandidateLine.pointlist.size() << " candidates in the list now." << endl;3036 3302 } else { 3037 if ((Candidate != NULL) && (CandidateLine.pointlist.begin() != CandidateLine.pointlist.end())) { 3038 Log() << Verbose(1) << "REJECT: Old candidate " << *(Candidate) << " with " << CandidateLine.ShortestAngle << " is better than new one " << *Candidate << " with " << alpha << " ." << endl; 3039 } else { 3040 Log() << Verbose(1) << "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected." << endl; 3041 } 3303 DoLog(1) && (Log() << Verbose(1) << "REJECT: Distance to center of circumcircle is not the same from each corner of the triangle: " << fabs(radius - otherradius) << endl); 3042 3304 } 3043 3305 } else { 3044 Log() << Verbose(1) << "REJECT: NewSphereCenter " << NewSphereCenter << " for " << *Candidate << " is too far away: " << radius << "." << endl;3306 DoLog(1) && (Log() << Verbose(1) << "REJECT: NewSphereCenter " << NewSphereCenter << " for " << *Candidate << " is too far away: " << radius << "." << endl); 3045 3307 } 3046 } else { 3308 } 3309 catch (LinearDependenceException &excp){ 3310 Log() << Verbose(1) << excp; 3047 3311 Log() << Verbose(1) << "REJECT: Three points from " << *CandidateLine.BaseLine << " and Candidate " << *Candidate << " are linear-dependent." << endl; 3048 3312 } 3049 3313 } else { 3050 if (Third Node!= NULL) {3051 Log() << Verbose(1) << "REJECT: Base triangle " << *CandidateLine.BaseLine << " and " << *ThirdNode << " contains Candidate " << *Candidate << "." << endl;3314 if (ThirdPoint != NULL) { 3315 DoLog(1) && (Log() << Verbose(1) << "REJECT: Base triangle " << *CandidateLine.BaseLine << " and " << *ThirdPoint << " contains Candidate " << *Candidate << "." << endl); 3052 3316 } else { 3053 Log() << Verbose(1) << "REJECT: Base triangle " << *CandidateLine.BaseLine << " contains Candidate " << *Candidate << "." << endl;3317 DoLog(1) && (Log() << Verbose(1) << "REJECT: Base triangle " << *CandidateLine.BaseLine << " contains Candidate " << *Candidate << "." << endl); 3054 3318 } 3055 3319 } … … 3058 3322 } 3059 3323 } else { 3060 eLog() << Verbose(1) << "The projected center of the old sphere has radius " << radius << " instead of " << CircleRadius << "." << endl;3324 DoeLog(1) && (eLog() << Verbose(1) << "The projected center of the old sphere has radius " << radius << " instead of " << CircleRadius << "." << endl); 3061 3325 } 3062 3326 } else { 3063 if (Third Node!= NULL)3064 Log() << Verbose(1) << "Circumcircle for base line " << *CandidateLine.BaseLine << " and third node " << *ThirdNode << " is too big!" << endl;3327 if (ThirdPoint != NULL) 3328 DoLog(1) && (Log() << Verbose(1) << "Circumcircle for base line " << *CandidateLine.BaseLine << " and third node " << *ThirdPoint << " is too big!" << endl); 3065 3329 else 3066 Log() << Verbose(1) << "Circumcircle for base line " << *CandidateLine.BaseLine << " is too big!" << endl;3067 } 3068 3069 Log() << Verbose(1) << "INFO: Sorting candidate list ..." << endl;3330 DoLog(1) && (Log() << Verbose(1) << "Circumcircle for base line " << *CandidateLine.BaseLine << " is too big!" << endl); 3331 } 3332 3333 DoLog(1) && (Log() << Verbose(1) << "INFO: Sorting candidate list ..." << endl); 3070 3334 if (CandidateLine.pointlist.size() > 1) { 3071 3335 CandidateLine.pointlist.unique(); 3072 3336 CandidateLine.pointlist.sort(); //SortCandidates); 3073 3337 } 3074 }; 3338 3339 if ((!CandidateLine.pointlist.empty()) && (!CandidateLine.CheckValidity(RADIUS, LC))) { 3340 DoeLog(0) && (eLog() << Verbose(0) << "There were other points contained in the rolling sphere as well!" << endl); 3341 performCriticalExit(); 3342 } 3343 } 3344 ; 3075 3345 3076 3346 /** Finds the endpoint two lines are sharing. … … 3081 3351 class BoundaryPointSet *Tesselation::GetCommonEndpoint(const BoundaryLineSet * line1, const BoundaryLineSet * line2) const 3082 3352 { 3083 3353 Info FunctionInfo(__func__); 3084 3354 const BoundaryLineSet * lines[2] = { line1, line2 }; 3085 3355 class BoundaryPointSet *node = NULL; … … 3088 3358 for (int i = 0; i < 2; i++) 3089 3359 // for both lines 3090 for (int j = 0; j < 2; j++) 3091 { // for both endpoints 3092 OrderTest = OrderMap.insert(pair<int, class BoundaryPointSet *> ( 3093 lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j])); 3094 if (!OrderTest.second) 3095 { // if insertion fails, we have common endpoint 3096 node = OrderTest.first->second; 3097 Log() << Verbose(1) << "Common endpoint of lines " << *line1 3098 << " and " << *line2 << " is: " << *node << "." << endl; 3099 j = 2; 3100 i = 2; 3101 break; 3102 } 3360 for (int j = 0; j < 2; j++) { // for both endpoints 3361 OrderTest = OrderMap.insert(pair<int, class BoundaryPointSet *> (lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j])); 3362 if (!OrderTest.second) { // if insertion fails, we have common endpoint 3363 node = OrderTest.first->second; 3364 DoLog(1) && (Log() << Verbose(1) << "Common endpoint of lines " << *line1 << " and " << *line2 << " is: " << *node << "." << endl); 3365 j = 2; 3366 i = 2; 3367 break; 3103 3368 } 3369 } 3104 3370 return node; 3105 }; 3371 } 3372 ; 3106 3373 3107 3374 /** Finds the boundary points that are closest to a given Vector \a *x. … … 3117 3384 3118 3385 if (LinesOnBoundary.empty()) { 3119 eLog() << Verbose(1) << "There is no tesselation structure to compare the point with, please create one first." << endl;3386 DoeLog(1) && (eLog() << Verbose(1) << "There is no tesselation structure to compare the point with, please create one first." << endl); 3120 3387 return NULL; 3121 3388 } … … 3123 3390 // gather all points close to the desired one 3124 3391 LC->SetIndexToVector(x); // ignore status as we calculate bounds below sensibly 3125 for (int i=0;i<NDIM;i++) // store indices of this cell3392 for (int i = 0; i < NDIM; i++) // store indices of this cell 3126 3393 N[i] = LC->n[i]; 3127 Log() << Verbose(1) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 3128 3394 DoLog(1) && (Log() << Verbose(1) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl); 3129 3395 DistanceToPointMap * points = new DistanceToPointMap; 3130 3396 LC->GetNeighbourBounds(Nlower, Nupper); … … 3133 3399 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 3134 3400 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 3135 const Linked Nodes *List = LC->GetCurrentCell();3401 const LinkedCell::LinkedNodes *List = LC->GetCurrentCell(); 3136 3402 //Log() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 3137 3403 if (List != NULL) { 3138 for (Linked Nodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {3404 for (LinkedCell::LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 3139 3405 FindPoint = PointsOnBoundary.find((*Runner)->nr); 3140 3406 if (FindPoint != PointsOnBoundary.end()) { 3141 points->insert(DistanceToPointPair (FindPoint->second->node->node->DistanceSquared(x), FindPoint->second));3142 Log() << Verbose(1) << "INFO: Putting " << *FindPoint->second << " into the list." << endl;3407 points->insert(DistanceToPointPair(FindPoint->second->node->node->DistanceSquared(*x), FindPoint->second)); 3408 DoLog(1) && (Log() << Verbose(1) << "INFO: Putting " << *FindPoint->second << " into the list." << endl); 3143 3409 } 3144 3410 } 3145 3411 } else { 3146 eLog() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << " is invalid!" << endl;3412 DoeLog(1) && (eLog() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << " is invalid!" << endl); 3147 3413 } 3148 3414 } … … 3150 3416 // check whether we found some points 3151 3417 if (points->empty()) { 3152 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl;3153 delete (points);3418 DoeLog(1) && (eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl); 3419 delete (points); 3154 3420 return NULL; 3155 3421 } 3156 3422 return points; 3157 }; 3423 } 3424 ; 3158 3425 3159 3426 /** Finds the boundary line that is closest to a given Vector \a *x. … … 3165 3432 { 3166 3433 Info FunctionInfo(__func__); 3167 3168 3434 // get closest points 3169 DistanceToPointMap * points = FindClosestBoundaryPointsToVector(x, LC);3435 DistanceToPointMap * points = FindClosestBoundaryPointsToVector(x, LC); 3170 3436 if (points == NULL) { 3171 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl;3437 DoeLog(1) && (eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl); 3172 3438 return NULL; 3173 3439 } 3174 3440 3175 3441 // for each point, check its lines, remember closest 3176 Log() << Verbose(1) << "Finding closest BoundaryLine to " << *x << " ... " << endl;3442 DoLog(1) && (Log() << Verbose(1) << "Finding closest BoundaryLine to " << *x << " ... " << endl); 3177 3443 BoundaryLineSet *ClosestLine = NULL; 3178 3444 double MinDistance = -1.; … … 3183 3449 for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) { 3184 3450 // calculate closest point on line to desired point 3185 helper.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3186 helper.AddVector((LineRunner->second)->endpoints[1]->node->node); 3187 helper.Scale(0.5); 3188 Center.CopyVector(x); 3189 Center.SubtractVector(&helper); 3190 BaseLine.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3191 BaseLine.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3192 Center.ProjectOntoPlane(&BaseLine); 3451 helper = 0.5 * ((*(LineRunner->second)->endpoints[0]->node->node) + 3452 (*(LineRunner->second)->endpoints[1]->node->node)); 3453 Center = (*x) - helper; 3454 BaseLine = (*(LineRunner->second)->endpoints[0]->node->node) - 3455 (*(LineRunner->second)->endpoints[1]->node->node); 3456 Center.ProjectOntoPlane(BaseLine); 3193 3457 const double distance = Center.NormSquared(); 3194 3458 if ((ClosestLine == NULL) || (distance < MinDistance)) { 3195 3459 // additionally calculate intersection on line (whether it's on the line section or not) 3196 helper.CopyVector(x); 3197 helper.SubtractVector((LineRunner->second)->endpoints[0]->node->node); 3198 helper.SubtractVector(&Center); 3199 const double lengthA = helper.ScalarProduct(&BaseLine); 3200 helper.CopyVector(x); 3201 helper.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3202 helper.SubtractVector(&Center); 3203 const double lengthB = helper.ScalarProduct(&BaseLine); 3204 if (lengthB*lengthA < 0) { // if have different sign 3460 helper = (*x) - (*(LineRunner->second)->endpoints[0]->node->node) - Center; 3461 const double lengthA = helper.ScalarProduct(BaseLine); 3462 helper = (*x) - (*(LineRunner->second)->endpoints[1]->node->node) - Center; 3463 const double lengthB = helper.ScalarProduct(BaseLine); 3464 if (lengthB * lengthA < 0) { // if have different sign 3205 3465 ClosestLine = LineRunner->second; 3206 3466 MinDistance = distance; 3207 Log() << Verbose(1) << "ACCEPT: New closest line is " << *ClosestLine << " with projected distance " << MinDistance << "." << endl;3467 DoLog(1) && (Log() << Verbose(1) << "ACCEPT: New closest line is " << *ClosestLine << " with projected distance " << MinDistance << "." << endl); 3208 3468 } else { 3209 Log() << Verbose(1) << "REJECT: Intersection is outside of the line section: " << lengthA << " and " << lengthB << "." << endl;3469 DoLog(1) && (Log() << Verbose(1) << "REJECT: Intersection is outside of the line section: " << lengthA << " and " << lengthB << "." << endl); 3210 3470 } 3211 3471 } else { 3212 Log() << Verbose(1) << "REJECT: Point is too further away than present line: " << distance << " >> " << MinDistance << "." << endl;3472 DoLog(1) && (Log() << Verbose(1) << "REJECT: Point is too further away than present line: " << distance << " >> " << MinDistance << "." << endl); 3213 3473 } 3214 3474 } 3215 3475 } 3216 delete (points);3476 delete (points); 3217 3477 // check whether closest line is "too close" :), then it's inside 3218 3478 if (ClosestLine == NULL) { 3219 Log() << Verbose(0) << "Is the only point, no one else is closeby." << endl;3479 DoLog(0) && (Log() << Verbose(0) << "Is the only point, no one else is closeby." << endl); 3220 3480 return NULL; 3221 3481 } 3222 3482 return ClosestLine; 3223 } ;3224 3483 } 3484 ; 3225 3485 3226 3486 /** Finds the triangle that is closest to a given Vector \a *x. … … 3231 3491 TriangleList * Tesselation::FindClosestTrianglesToVector(const Vector *x, const LinkedCell* LC) const 3232 3492 { 3233 Info FunctionInfo(__func__); 3234 3235 // get closest points 3236 DistanceToPointMap * points = FindClosestBoundaryPointsToVector(x,LC); 3493 Info FunctionInfo(__func__); 3494 // get closest points 3495 DistanceToPointMap * points = FindClosestBoundaryPointsToVector(x, LC); 3237 3496 if (points == NULL) { 3238 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl;3497 DoeLog(1) && (eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl); 3239 3498 return NULL; 3240 3499 } 3241 3500 3242 3501 // for each point, check its lines, remember closest 3243 Log() << Verbose(1) << "Finding closest BoundaryTriangle to " << *x << " ... " << endl;3502 DoLog(1) && (Log() << Verbose(1) << "Finding closest BoundaryTriangle to " << *x << " ... " << endl); 3244 3503 LineSet ClosestLines; 3245 3504 double MinDistance = 1e+16; … … 3251 3510 for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) { 3252 3511 3253 BaseLine .CopyVector((LineRunner->second)->endpoints[0]->node->node);3254 BaseLine.SubtractVector((LineRunner->second)->endpoints[1]->node->node);3512 BaseLine = (*(LineRunner->second)->endpoints[0]->node->node) - 3513 (*(LineRunner->second)->endpoints[1]->node->node); 3255 3514 const double lengthBase = BaseLine.NormSquared(); 3256 3515 3257 BaseLineIntersection.CopyVector(x); 3258 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[0]->node->node); 3516 BaseLineIntersection = (*x) - (*(LineRunner->second)->endpoints[0]->node->node); 3259 3517 const double lengthEndA = BaseLineIntersection.NormSquared(); 3260 3518 3261 BaseLineIntersection.CopyVector(x); 3262 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3519 BaseLineIntersection = (*x) - (*(LineRunner->second)->endpoints[1]->node->node); 3263 3520 const double lengthEndB = BaseLineIntersection.NormSquared(); 3264 3521 3265 if ((lengthEndA > lengthBase) || (lengthEndB > lengthBase) || ((lengthEndA < MYEPSILON) || (lengthEndB < MYEPSILON))) { 3522 if ((lengthEndA > lengthBase) || (lengthEndB > lengthBase) || ((lengthEndA < MYEPSILON) || (lengthEndB < MYEPSILON))) { // intersection would be outside, take closer endpoint 3266 3523 const double lengthEnd = Min(lengthEndA, lengthEndB); 3267 3524 if (lengthEnd - MinDistance < -MYEPSILON) { // new best line … … 3269 3526 ClosestLines.insert(LineRunner->second); 3270 3527 MinDistance = lengthEnd; 3271 Log() << Verbose(1) << "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[0]->node << " is closer with " << lengthEnd << "." << endl;3272 } else if 3528 DoLog(1) && (Log() << Verbose(1) << "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[0]->node << " is closer with " << lengthEnd << "." << endl); 3529 } else if (fabs(lengthEnd - MinDistance) < MYEPSILON) { // additional best candidate 3273 3530 ClosestLines.insert(LineRunner->second); 3274 Log() << Verbose(1) << "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[1]->node << " is equally good with " << lengthEnd << "." << endl;3531 DoLog(1) && (Log() << Verbose(1) << "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[1]->node << " is equally good with " << lengthEnd << "." << endl); 3275 3532 } else { // line is worse 3276 Log() << Verbose(1) << "REJECT: Line " << *LineRunner->second << " to either endpoints is further away than present closest line candidate: " << lengthEndA << ", " << lengthEndB << ", and distance is longer than baseline:" << lengthBase << "." << endl;3533 DoLog(1) && (Log() << Verbose(1) << "REJECT: Line " << *LineRunner->second << " to either endpoints is further away than present closest line candidate: " << lengthEndA << ", " << lengthEndB << ", and distance is longer than baseline:" << lengthBase << "." << endl); 3277 3534 } 3278 3535 } else { // intersection is closer, calculate 3279 3536 // calculate closest point on line to desired point 3280 BaseLineIntersection.CopyVector(x); 3281 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3282 Center.CopyVector(&BaseLineIntersection); 3283 Center.ProjectOntoPlane(&BaseLine); 3284 BaseLineIntersection.SubtractVector(&Center); 3537 BaseLineIntersection = (*x) - (*(LineRunner->second)->endpoints[1]->node->node); 3538 Center = BaseLineIntersection; 3539 Center.ProjectOntoPlane(BaseLine); 3540 BaseLineIntersection -= Center; 3285 3541 const double distance = BaseLineIntersection.NormSquared(); 3286 3542 if (Center.NormSquared() > BaseLine.NormSquared()) { 3287 eLog() << Verbose(0) << "Algorithmic error: In second case we have intersection outside of baseline!" << endl;3543 DoeLog(0) && (eLog() << Verbose(0) << "Algorithmic error: In second case we have intersection outside of baseline!" << endl); 3288 3544 } 3289 3545 if ((ClosestLines.empty()) || (distance < MinDistance)) { 3290 3546 ClosestLines.insert(LineRunner->second); 3291 3547 MinDistance = distance; 3292 Log() << Verbose(1) << "ACCEPT: Intersection in between endpoints, new closest line " << *LineRunner->second << " is " << *ClosestLines.begin() << " with projected distance " << MinDistance << "." << endl;3548 DoLog(1) && (Log() << Verbose(1) << "ACCEPT: Intersection in between endpoints, new closest line " << *LineRunner->second << " is " << *ClosestLines.begin() << " with projected distance " << MinDistance << "." << endl); 3293 3549 } else { 3294 Log() << Verbose(2) << "REJECT: Point is further away from line " << *LineRunner->second << " than present closest line: " << distance << " >> " << MinDistance << "." << endl;3550 DoLog(2) && (Log() << Verbose(2) << "REJECT: Point is further away from line " << *LineRunner->second << " than present closest line: " << distance << " >> " << MinDistance << "." << endl); 3295 3551 } 3296 3552 } 3297 3553 } 3298 3554 } 3299 delete (points);3555 delete (points); 3300 3556 3301 3557 // check whether closest line is "too close" :), then it's inside 3302 3558 if (ClosestLines.empty()) { 3303 Log() << Verbose(0) << "Is the only point, no one else is closeby." << endl;3559 DoLog(0) && (Log() << Verbose(0) << "Is the only point, no one else is closeby." << endl); 3304 3560 return NULL; 3305 3561 } … … 3307 3563 for (LineSet::iterator LineRunner = ClosestLines.begin(); LineRunner != ClosestLines.end(); LineRunner++) 3308 3564 for (TriangleMap::iterator Runner = (*LineRunner)->triangles.begin(); Runner != (*LineRunner)->triangles.end(); Runner++) { 3309 candidates->push_back(Runner->second);3310 }3565 candidates->push_back(Runner->second); 3566 } 3311 3567 return candidates; 3312 }; 3568 } 3569 ; 3313 3570 3314 3571 /** Finds closest triangle to a point. … … 3316 3573 * \param *out output stream for debugging 3317 3574 * \param *x Vector to look from 3575 * \param &distance contains found distance on return 3318 3576 * \return list of BoundaryTriangleSet of nearest triangles or NULL. 3319 3577 */ 3320 3578 class BoundaryTriangleSet * Tesselation::FindClosestTriangleToVector(const Vector *x, const LinkedCell* LC) const 3321 3579 { 3322 3580 Info FunctionInfo(__func__); 3323 3581 class BoundaryTriangleSet *result = NULL; 3324 3582 TriangleList *triangles = FindClosestTrianglesToVector(x, LC); … … 3331 3589 3332 3590 // go through all and pick the one with the best alignment to x 3333 double MinAlignment = 2. *M_PI;3591 double MinAlignment = 2. * M_PI; 3334 3592 for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) { 3335 3593 (*Runner)->GetCenter(&Center); 3336 helper.CopyVector(x); 3337 helper.SubtractVector(&Center); 3338 const double Alignment = helper.Angle(&(*Runner)->NormalVector); 3594 helper = (*x) - Center; 3595 const double Alignment = helper.Angle((*Runner)->NormalVector); 3339 3596 if (Alignment < MinAlignment) { 3340 3597 result = *Runner; 3341 3598 MinAlignment = Alignment; 3342 Log() << Verbose(1) << "ACCEPT: Triangle " << *result << " is better aligned with " << MinAlignment << "." << endl;3599 DoLog(1) && (Log() << Verbose(1) << "ACCEPT: Triangle " << *result << " is better aligned with " << MinAlignment << "." << endl); 3343 3600 } else { 3344 Log() << Verbose(1) << "REJECT: Triangle " << *result << " is worse aligned with " << MinAlignment << "." << endl;3345 } 3346 } 3347 delete (triangles);3601 DoLog(1) && (Log() << Verbose(1) << "REJECT: Triangle " << *result << " is worse aligned with " << MinAlignment << "." << endl); 3602 } 3603 } 3604 delete (triangles); 3348 3605 3349 3606 return result; 3350 }; 3607 } 3608 ; 3351 3609 3352 3610 /** Checks whether the provided Vector is within the Tesselation structure. … … 3359 3617 bool Tesselation::IsInnerPoint(const Vector &Point, const LinkedCell* const LC) const 3360 3618 { 3361 return (GetDistanceSquaredToSurface(Point, LC) < MYEPSILON); 3362 } 3619 Info FunctionInfo(__func__); 3620 TriangleIntersectionList Intersections(&Point, this, LC); 3621 3622 return Intersections.IsInside(); 3623 } 3624 ; 3363 3625 3364 3626 /** Returns the distance to the surface given by the tesselation. … … 3390 3652 3391 3653 if (triangle == NULL) {// is boundary point or only point in point cloud? 3392 Log() << Verbose(1) << "No triangle given!" << endl;3654 DoLog(1) && (Log() << Verbose(1) << "No triangle given!" << endl); 3393 3655 return -1.; 3394 3656 } else { 3395 Log() << Verbose(1) << "INFO: Closest triangle found is " << *triangle << " with normal vector " << triangle->NormalVector << "." << endl;3657 DoLog(1) && (Log() << Verbose(1) << "INFO: Closest triangle found is " << *triangle << " with normal vector " << triangle->NormalVector << "." << endl); 3396 3658 } 3397 3659 3398 3660 triangle->GetCenter(&Center); 3399 Log() << Verbose(2) << "INFO: Central point of the triangle is " << Center << "." << endl; 3400 DistanceToCenter.CopyVector(&Center); 3401 DistanceToCenter.SubtractVector(&Point); 3402 Log() << Verbose(2) << "INFO: Vector from point to test to center is " << DistanceToCenter << "." << endl; 3661 DoLog(2) && (Log() << Verbose(2) << "INFO: Central point of the triangle is " << Center << "." << endl); 3662 DistanceToCenter = Center - Point; 3663 DoLog(2) && (Log() << Verbose(2) << "INFO: Vector from point to test to center is " << DistanceToCenter << "." << endl); 3403 3664 3404 3665 // check whether we are on boundary 3405 if (fabs(DistanceToCenter.ScalarProduct( &triangle->NormalVector)) < MYEPSILON) {3666 if (fabs(DistanceToCenter.ScalarProduct(triangle->NormalVector)) < MYEPSILON) { 3406 3667 // calculate whether inside of triangle 3407 DistanceToCenter.CopyVector(&Point); 3408 Center.CopyVector(&Point); 3409 Center.SubtractVector(&triangle->NormalVector); // points towards MolCenter 3410 DistanceToCenter.AddVector(&triangle->NormalVector); // points outside 3411 Log() << Verbose(1) << "INFO: Calling Intersection with " << Center << " and " << DistanceToCenter << "." << endl; 3668 DistanceToCenter = Point + triangle->NormalVector; // points outside 3669 Center = Point - triangle->NormalVector; // points towards MolCenter 3670 DoLog(1) && (Log() << Verbose(1) << "INFO: Calling Intersection with " << Center << " and " << DistanceToCenter << "." << endl); 3412 3671 if (triangle->GetIntersectionInsideTriangle(&Center, &DistanceToCenter, &Intersection)) { 3413 Log() << Verbose(1) << Point << " is inner point: sufficiently close to boundary, " << Intersection << "." << endl;3672 DoLog(1) && (Log() << Verbose(1) << Point << " is inner point: sufficiently close to boundary, " << Intersection << "." << endl); 3414 3673 return 0.; 3415 3674 } else { 3416 Log() << Verbose(1) << Point << " is NOT an inner point: on triangle plane but outside of triangle bounds." << endl;3675 DoLog(1) && (Log() << Verbose(1) << Point << " is NOT an inner point: on triangle plane but outside of triangle bounds." << endl); 3417 3676 return false; 3418 3677 } … … 3420 3679 // calculate smallest distance 3421 3680 distance = triangle->GetClosestPointInsideTriangle(&Point, &Intersection); 3422 Log() << Verbose(1) << "Closest point on triangle is " << Intersection << "." << endl;3681 DoLog(1) && (Log() << Verbose(1) << "Closest point on triangle is " << Intersection << "." << endl); 3423 3682 3424 3683 // then check direction to boundary 3425 if (DistanceToCenter.ScalarProduct( &triangle->NormalVector) > MYEPSILON) {3426 Log() << Verbose(1) << Point << " is an inner point, " << distance << " below surface." << endl;3684 if (DistanceToCenter.ScalarProduct(triangle->NormalVector) > MYEPSILON) { 3685 DoLog(1) && (Log() << Verbose(1) << Point << " is an inner point, " << distance << " below surface." << endl); 3427 3686 return -distance; 3428 3687 } else { 3429 Log() << Verbose(1) << Point << " is NOT an inner point, " << distance << " above surface." << endl;3688 DoLog(1) && (Log() << Verbose(1) << Point << " is NOT an inner point, " << distance << " above surface." << endl); 3430 3689 return +distance; 3431 3690 } 3432 3691 } 3433 }; 3434 3435 /** Calculates distance to a tesselated surface. 3692 } 3693 ; 3694 3695 /** Calculates minimum distance from \a&Point to a tesselated surface. 3436 3696 * Combines \sa FindClosestTrianglesToVector() and \sa GetDistanceSquaredToTriangle(). 3437 3697 * \param &Point point to calculate distance from … … 3439 3699 * \return distance squared to closest point on surface 3440 3700 */ 3441 double Tesselation::GetDistanceSquaredToSurface(const Vector &Point, const LinkedCell* const LC) const 3442 { 3443 BoundaryTriangleSet *triangle = FindClosestTriangleToVector(&Point, LC); 3444 const double distance = GetDistanceSquaredToTriangle(Point, triangle); 3445 return Min(distance, LC->RADIUS); 3446 }; 3701 double Tesselation::GetDistanceToSurface(const Vector &Point, const LinkedCell* const LC) const 3702 { 3703 Info FunctionInfo(__func__); 3704 TriangleIntersectionList Intersections(&Point, this, LC); 3705 3706 return Intersections.GetSmallestDistance(); 3707 } 3708 ; 3709 3710 /** Calculates minimum distance from \a&Point to a tesselated surface. 3711 * Combines \sa FindClosestTrianglesToVector() and \sa GetDistanceSquaredToTriangle(). 3712 * \param &Point point to calculate distance from 3713 * \param *LC needed for finding closest points fast 3714 * \return distance squared to closest point on surface 3715 */ 3716 BoundaryTriangleSet * Tesselation::GetClosestTriangleOnSurface(const Vector &Point, const LinkedCell* const LC) const 3717 { 3718 Info FunctionInfo(__func__); 3719 TriangleIntersectionList Intersections(&Point, this, LC); 3720 3721 return Intersections.GetClosestTriangle(); 3722 } 3723 ; 3447 3724 3448 3725 /** Gets all points connected to the provided point by triangulation lines. … … 3454 3731 TesselPointSet * Tesselation::GetAllConnectedPoints(const TesselPoint* const Point) const 3455 3732 { 3456 3457 3733 Info FunctionInfo(__func__); 3734 TesselPointSet *connectedPoints = new TesselPointSet; 3458 3735 class BoundaryPointSet *ReferencePoint = NULL; 3459 3736 TesselPoint* current; 3460 3737 bool takePoint = false; 3461 3462 3738 // find the respective boundary point 3463 3739 PointMap::const_iterator PointRunner = PointsOnBoundary.find(Point->nr); … … 3465 3741 ReferencePoint = PointRunner->second; 3466 3742 } else { 3467 eLog() << Verbose(2) << "GetAllConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl;3743 DoeLog(2) && (eLog() << Verbose(2) << "GetAllConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl); 3468 3744 ReferencePoint = NULL; 3469 3745 } … … 3471 3747 // little trick so that we look just through lines connect to the BoundaryPoint 3472 3748 // OR fall-back to look through all lines if there is no such BoundaryPoint 3473 const LineMap *Lines;; 3749 const LineMap *Lines; 3750 ; 3474 3751 if (ReferencePoint != NULL) 3475 3752 Lines = &(ReferencePoint->lines); … … 3478 3755 LineMap::const_iterator findLines = Lines->begin(); 3479 3756 while (findLines != Lines->end()) { 3480 takePoint = false;3481 3482 if (findLines->second->endpoints[0]->Nr == Point->nr) {3483 takePoint = true;3484 current = findLines->second->endpoints[1]->node;3485 } else if (findLines->second->endpoints[1]->Nr == Point->nr) {3486 takePoint = true;3487 current = findLines->second->endpoints[0]->node;3488 }3489 3490 if (takePoint) {3491 Log() << Verbose(1) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is enlisted." << endl;3492 connectedPoints->insert(current);3493 }3494 3495 findLines++;3757 takePoint = false; 3758 3759 if (findLines->second->endpoints[0]->Nr == Point->nr) { 3760 takePoint = true; 3761 current = findLines->second->endpoints[1]->node; 3762 } else if (findLines->second->endpoints[1]->Nr == Point->nr) { 3763 takePoint = true; 3764 current = findLines->second->endpoints[0]->node; 3765 } 3766 3767 if (takePoint) { 3768 DoLog(1) && (Log() << Verbose(1) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is enlisted." << endl); 3769 connectedPoints->insert(current); 3770 } 3771 3772 findLines++; 3496 3773 } 3497 3774 3498 3775 if (connectedPoints->empty()) { // if have not found any points 3499 eLog() << Verbose(1) << "We have not found any connected points to " << *Point<< "." << endl;3776 DoeLog(1) && (eLog() << Verbose(1) << "We have not found any connected points to " << *Point << "." << endl); 3500 3777 return NULL; 3501 3778 } 3502 3779 3503 3780 return connectedPoints; 3504 } ;3505 3781 } 3782 ; 3506 3783 3507 3784 /** Gets all points connected to the provided point by triangulation lines, ordered such that we have the circle round the point. … … 3519 3796 TesselPointList * Tesselation::GetCircleOfConnectedTriangles(TesselPointSet *SetOfNeighbours, const TesselPoint* const Point, const Vector * const Reference) const 3520 3797 { 3521 3798 Info FunctionInfo(__func__); 3522 3799 map<double, TesselPoint*> anglesOfPoints; 3523 3800 TesselPointList *connectedCircle = new TesselPointList; … … 3526 3803 Vector OrthogonalVector; 3527 3804 Vector helper; 3528 const TesselPoint * const TrianglePoints[3] = { Point, NULL, NULL};3805 const TesselPoint * const TrianglePoints[3] = { Point, NULL, NULL }; 3529 3806 TriangleList *triangles = NULL; 3530 3807 3531 3808 if (SetOfNeighbours == NULL) { 3532 eLog() << Verbose(2) << "Could not find any connected points!" << endl;3533 delete (connectedCircle);3809 DoeLog(2) && (eLog() << Verbose(2) << "Could not find any connected points!" << endl); 3810 delete (connectedCircle); 3534 3811 return NULL; 3535 3812 } … … 3539 3816 if ((triangles != NULL) && (!triangles->empty())) { 3540 3817 for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) 3541 PlaneNormal .AddVector(&(*Runner)->NormalVector);3818 PlaneNormal += (*Runner)->NormalVector; 3542 3819 } else { 3543 eLog() << Verbose(0) << "Could not find any triangles for point " << *Point << "." << endl;3820 DoeLog(0) && (eLog() << Verbose(0) << "Could not find any triangles for point " << *Point << "." << endl); 3544 3821 performCriticalExit(); 3545 3822 } 3546 PlaneNormal.Scale(1.0 /triangles->size());3547 Log() << Verbose(1) << "INFO: Calculated PlaneNormal of all circle points is " << PlaneNormal << "." << endl;3823 PlaneNormal.Scale(1.0 / triangles->size()); 3824 DoLog(1) && (Log() << Verbose(1) << "INFO: Calculated PlaneNormal of all circle points is " << PlaneNormal << "." << endl); 3548 3825 PlaneNormal.Normalize(); 3549 3826 3550 3827 // construct one orthogonal vector 3551 3828 if (Reference != NULL) { 3552 AngleZero.CopyVector(Reference); 3553 AngleZero.SubtractVector(Point->node); 3554 AngleZero.ProjectOntoPlane(&PlaneNormal); 3555 } 3556 if ((Reference == NULL) || (AngleZero.NormSquared() < MYEPSILON )) { 3557 Log() << Verbose(1) << "Using alternatively " << *(*SetOfNeighbours->begin())->node << " as angle 0 referencer." << endl; 3558 AngleZero.CopyVector((*SetOfNeighbours->begin())->node); 3559 AngleZero.SubtractVector(Point->node); 3560 AngleZero.ProjectOntoPlane(&PlaneNormal); 3829 AngleZero = (*Reference) - (*Point->node); 3830 AngleZero.ProjectOntoPlane(PlaneNormal); 3831 } 3832 if ((Reference == NULL) || (AngleZero.NormSquared() < MYEPSILON)) { 3833 DoLog(1) && (Log() << Verbose(1) << "Using alternatively " << *(*SetOfNeighbours->begin())->node << " as angle 0 referencer." << endl); 3834 AngleZero = (*(*SetOfNeighbours->begin())->node) - (*Point->node); 3835 AngleZero.ProjectOntoPlane(PlaneNormal); 3561 3836 if (AngleZero.NormSquared() < MYEPSILON) { 3562 eLog() << Verbose(0) << "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!" << endl;3837 DoeLog(0) && (eLog() << Verbose(0) << "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!" << endl); 3563 3838 performCriticalExit(); 3564 3839 } 3565 3840 } 3566 Log() << Verbose(1) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl;3841 DoLog(1) && (Log() << Verbose(1) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl); 3567 3842 if (AngleZero.NormSquared() > MYEPSILON) 3568 OrthogonalVector .MakeNormalVector(&PlaneNormal, &AngleZero);3843 OrthogonalVector = Plane(PlaneNormal, AngleZero,0).getNormal(); 3569 3844 else 3570 OrthogonalVector.MakeNormal Vector(&PlaneNormal);3571 Log() << Verbose(1) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl;3845 OrthogonalVector.MakeNormalTo(PlaneNormal); 3846 DoLog(1) && (Log() << Verbose(1) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl); 3572 3847 3573 3848 // go through all connected points and calculate angle 3574 3849 for (TesselPointSet::iterator listRunner = SetOfNeighbours->begin(); listRunner != SetOfNeighbours->end(); listRunner++) { 3575 helper.CopyVector((*listRunner)->node); 3576 helper.SubtractVector(Point->node); 3577 helper.ProjectOntoPlane(&PlaneNormal); 3850 helper = (*(*listRunner)->node) - (*Point->node); 3851 helper.ProjectOntoPlane(PlaneNormal); 3578 3852 double angle = GetAngle(helper, AngleZero, OrthogonalVector); 3579 Log() << Verbose(0) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl;3580 anglesOfPoints.insert(pair<double, TesselPoint*> (angle, (*listRunner)));3581 } 3582 3583 for (map<double, TesselPoint*>::iterator AngleRunner = anglesOfPoints.begin(); AngleRunner != anglesOfPoints.end(); AngleRunner++) {3853 DoLog(0) && (Log() << Verbose(0) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl); 3854 anglesOfPoints.insert(pair<double, TesselPoint*> (angle, (*listRunner))); 3855 } 3856 3857 for (map<double, TesselPoint*>::iterator AngleRunner = anglesOfPoints.begin(); AngleRunner != anglesOfPoints.end(); AngleRunner++) { 3584 3858 connectedCircle->push_back(AngleRunner->second); 3585 3859 } … … 3611 3885 3612 3886 if (SetOfNeighbours == NULL) { 3613 eLog() << Verbose(2) << "Could not find any connected points!" << endl;3614 delete (connectedCircle);3887 DoeLog(2) && (eLog() << Verbose(2) << "Could not find any connected points!" << endl); 3888 delete (connectedCircle); 3615 3889 return NULL; 3616 3890 } … … 3623 3897 } 3624 3898 3625 Log() << Verbose(1) << "INFO: Point is " << *Point << " and Reference is " << *Reference << "." << endl;3899 DoLog(1) && (Log() << Verbose(1) << "INFO: Point is " << *Point << " and Reference is " << *Reference << "." << endl); 3626 3900 // calculate central point 3627 3628 3901 TesselPointSet::const_iterator TesselA = SetOfNeighbours->begin(); 3629 3902 TesselPointSet::const_iterator TesselB = SetOfNeighbours->begin(); … … 3634 3907 int counter = 0; 3635 3908 while (TesselC != SetOfNeighbours->end()) { 3636 helper.MakeNormalVector((*TesselA)->node, (*TesselB)->node, (*TesselC)->node); 3637 Log() << Verbose(0) << "Making normal vector out of " << *(*TesselA) << ", " << *(*TesselB) << " and " << *(*TesselC) << ":" << helper << endl; 3909 helper = Plane(*((*TesselA)->node), 3910 *((*TesselB)->node), 3911 *((*TesselC)->node)).getNormal(); 3912 DoLog(0) && (Log() << Verbose(0) << "Making normal vector out of " << *(*TesselA) << ", " << *(*TesselB) << " and " << *(*TesselC) << ":" << helper << endl); 3638 3913 counter++; 3639 3914 TesselA++; 3640 3915 TesselB++; 3641 3916 TesselC++; 3642 PlaneNormal .AddVector(&helper);3917 PlaneNormal += helper; 3643 3918 } 3644 3919 //Log() << Verbose(0) << "Summed vectors " << center << "; number of points " << connectedPoints.size() 3645 3920 // << "; scale factor " << counter; 3646 PlaneNormal.Scale(1.0 /(double)counter);3647 // Log() << Verbose(1) << "INFO: Calculated center of all circle points is " << center << "." << endl;3648 //3649 // // projection plane of the circle is at the closes Point and normal is pointing away from center of all circle points3650 // PlaneNormal.CopyVector(Point->node);3651 // PlaneNormal.SubtractVector(¢er);3652 // PlaneNormal.Normalize();3653 Log() << Verbose(1) << "INFO: Calculated plane normal of circle is " << PlaneNormal << "." << endl;3921 PlaneNormal.Scale(1.0 / (double) counter); 3922 // Log() << Verbose(1) << "INFO: Calculated center of all circle points is " << center << "." << endl; 3923 // 3924 // // projection plane of the circle is at the closes Point and normal is pointing away from center of all circle points 3925 // PlaneNormal.CopyVector(Point->node); 3926 // PlaneNormal.SubtractVector(¢er); 3927 // PlaneNormal.Normalize(); 3928 DoLog(1) && (Log() << Verbose(1) << "INFO: Calculated plane normal of circle is " << PlaneNormal << "." << endl); 3654 3929 3655 3930 // construct one orthogonal vector 3656 3931 if (Reference != NULL) { 3657 AngleZero.CopyVector(Reference); 3658 AngleZero.SubtractVector(Point->node); 3659 AngleZero.ProjectOntoPlane(&PlaneNormal); 3932 AngleZero = (*Reference) - (*Point->node); 3933 AngleZero.ProjectOntoPlane(PlaneNormal); 3660 3934 } 3661 3935 if ((Reference == NULL) || (AngleZero.NormSquared() < MYEPSILON )) { 3662 Log() << Verbose(1) << "Using alternatively " << *(*SetOfNeighbours->begin())->node << " as angle 0 referencer." << endl; 3663 AngleZero.CopyVector((*SetOfNeighbours->begin())->node); 3664 AngleZero.SubtractVector(Point->node); 3665 AngleZero.ProjectOntoPlane(&PlaneNormal); 3936 DoLog(1) && (Log() << Verbose(1) << "Using alternatively " << *(*SetOfNeighbours->begin())->node << " as angle 0 referencer." << endl); 3937 AngleZero = (*(*SetOfNeighbours->begin())->node) - (*Point->node); 3938 AngleZero.ProjectOntoPlane(PlaneNormal); 3666 3939 if (AngleZero.NormSquared() < MYEPSILON) { 3667 eLog() << Verbose(0) << "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!" << endl;3940 DoeLog(0) && (eLog() << Verbose(0) << "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!" << endl); 3668 3941 performCriticalExit(); 3669 3942 } 3670 3943 } 3671 Log() << Verbose(1) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl;3944 DoLog(1) && (Log() << Verbose(1) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl); 3672 3945 if (AngleZero.NormSquared() > MYEPSILON) 3673 OrthogonalVector .MakeNormalVector(&PlaneNormal, &AngleZero);3946 OrthogonalVector = Plane(PlaneNormal, AngleZero,0).getNormal(); 3674 3947 else 3675 OrthogonalVector.MakeNormal Vector(&PlaneNormal);3676 Log() << Verbose(1) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl;3948 OrthogonalVector.MakeNormalTo(PlaneNormal); 3949 DoLog(1) && (Log() << Verbose(1) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl); 3677 3950 3678 3951 // go through all connected points and calculate angle 3679 pair <map<double, TesselPoint*>::iterator, bool> InserterTest;3952 pair<map<double, TesselPoint*>::iterator, bool> InserterTest; 3680 3953 for (TesselPointSet::iterator listRunner = SetOfNeighbours->begin(); listRunner != SetOfNeighbours->end(); listRunner++) { 3681 helper.CopyVector((*listRunner)->node); 3682 helper.SubtractVector(Point->node); 3683 helper.ProjectOntoPlane(&PlaneNormal); 3954 helper = (*(*listRunner)->node) - (*Point->node); 3955 helper.ProjectOntoPlane(PlaneNormal); 3684 3956 double angle = GetAngle(helper, AngleZero, OrthogonalVector); 3685 3957 if (angle > M_PI) // the correction is of no use here (and not desired) 3686 angle = 2. *M_PI - angle;3687 Log() << Verbose(0) << "INFO: Calculated angle between " << helper << " and " << AngleZero << " is " << angle << " for point " << **listRunner << "." << endl;3688 InserterTest = anglesOfPoints.insert(pair<double, TesselPoint*> (angle, (*listRunner)));3958 angle = 2. * M_PI - angle; 3959 DoLog(0) && (Log() << Verbose(0) << "INFO: Calculated angle between " << helper << " and " << AngleZero << " is " << angle << " for point " << **listRunner << "." << endl); 3960 InserterTest = anglesOfPoints.insert(pair<double, TesselPoint*> (angle, (*listRunner))); 3689 3961 if (!InserterTest.second) { 3690 eLog() << Verbose(0) << "GetCircleOfSetOfPoints() got two atoms with same angle: " << *((InserterTest.first)->second) << " and " << (*listRunner) << endl;3962 DoeLog(0) && (eLog() << Verbose(0) << "GetCircleOfSetOfPoints() got two atoms with same angle: " << *((InserterTest.first)->second) << " and " << (*listRunner) << endl); 3691 3963 performCriticalExit(); 3692 3964 } 3693 3965 } 3694 3966 3695 for (map<double, TesselPoint*>::iterator AngleRunner = anglesOfPoints.begin(); AngleRunner != anglesOfPoints.end(); AngleRunner++) {3967 for (map<double, TesselPoint*>::iterator AngleRunner = anglesOfPoints.begin(); AngleRunner != anglesOfPoints.end(); AngleRunner++) { 3696 3968 connectedCircle->push_back(AngleRunner->second); 3697 3969 } … … 3708 3980 ListOfTesselPointList * Tesselation::GetPathsOfConnectedPoints(const TesselPoint* const Point) const 3709 3981 { 3710 3982 Info FunctionInfo(__func__); 3711 3983 map<double, TesselPoint*> anglesOfPoints; 3712 list< TesselPointList *> *ListOfPaths = new list< TesselPointList *>;3984 list<TesselPointList *> *ListOfPaths = new list<TesselPointList *> ; 3713 3985 TesselPointList *connectedPath = NULL; 3714 3986 Vector center; … … 3722 3994 class BoundaryLineSet *CurrentLine = NULL; 3723 3995 class BoundaryLineSet *StartLine = NULL; 3724 3725 3996 // find the respective boundary point 3726 3997 PointMap::const_iterator PointRunner = PointsOnBoundary.find(Point->nr); … … 3728 3999 ReferencePoint = PointRunner->second; 3729 4000 } else { 3730 eLog() << Verbose(1) << "GetPathOfConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl;4001 DoeLog(1) && (eLog() << Verbose(1) << "GetPathOfConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl); 3731 4002 return NULL; 3732 4003 } 3733 4004 3734 map 3735 map 3736 map 3737 map 4005 map<class BoundaryLineSet *, bool> TouchedLine; 4006 map<class BoundaryTriangleSet *, bool> TouchedTriangle; 4007 map<class BoundaryLineSet *, bool>::iterator LineRunner; 4008 map<class BoundaryTriangleSet *, bool>::iterator TriangleRunner; 3738 4009 for (LineMap::iterator Runner = ReferencePoint->lines.begin(); Runner != ReferencePoint->lines.end(); Runner++) { 3739 TouchedLine.insert( pair <class BoundaryLineSet *, bool>(Runner->second, false));4010 TouchedLine.insert(pair<class BoundaryLineSet *, bool> (Runner->second, false)); 3740 4011 for (TriangleMap::iterator Sprinter = Runner->second->triangles.begin(); Sprinter != Runner->second->triangles.end(); Sprinter++) 3741 TouchedTriangle.insert( pair <class BoundaryTriangleSet *, bool>(Sprinter->second, false));4012 TouchedTriangle.insert(pair<class BoundaryTriangleSet *, bool> (Sprinter->second, false)); 3742 4013 } 3743 4014 if (!ReferencePoint->lines.empty()) { … … 3745 4016 LineRunner = TouchedLine.find(runner->second); 3746 4017 if (LineRunner == TouchedLine.end()) { 3747 eLog() << Verbose(1) << "I could not find " << *runner->second << " in the touched list." << endl;4018 DoeLog(1) && (eLog() << Verbose(1) << "I could not find " << *runner->second << " in the touched list." << endl); 3748 4019 } else if (!LineRunner->second) { 3749 4020 LineRunner->second = true; … … 3753 4024 StartLine = CurrentLine; 3754 4025 CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint); 3755 Log() << Verbose(1)<< "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << "." << endl;4026 DoLog(1) && (Log() << Verbose(1) << "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << "." << endl); 3756 4027 do { 3757 4028 // push current one 3758 Log() << Verbose(1) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl;4029 DoLog(1) && (Log() << Verbose(1) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl); 3759 4030 connectedPath->push_back(CurrentPoint->node); 3760 4031 3761 4032 // find next triangle 3762 4033 for (TriangleMap::iterator Runner = CurrentLine->triangles.begin(); Runner != CurrentLine->triangles.end(); Runner++) { 3763 Log() << Verbose(1) << "INFO: Inspecting triangle " << *Runner->second << "." << endl;4034 DoLog(1) && (Log() << Verbose(1) << "INFO: Inspecting triangle " << *Runner->second << "." << endl); 3764 4035 if ((Runner->second != triangle)) { // look for first triangle not equal to old one 3765 4036 triangle = Runner->second; … … 3768 4039 if (!TriangleRunner->second) { 3769 4040 TriangleRunner->second = true; 3770 Log() << Verbose(1) << "INFO: Connecting triangle is " << *triangle << "." << endl;4041 DoLog(1) && (Log() << Verbose(1) << "INFO: Connecting triangle is " << *triangle << "." << endl); 3771 4042 break; 3772 4043 } else { 3773 Log() << Verbose(1) << "INFO: Skipping " << *triangle << ", as we have already visited it." << endl;4044 DoLog(1) && (Log() << Verbose(1) << "INFO: Skipping " << *triangle << ", as we have already visited it." << endl); 3774 4045 triangle = NULL; 3775 4046 } 3776 4047 } else { 3777 eLog() << Verbose(1) << "I could not find " << *triangle << " in the touched list." << endl;4048 DoeLog(1) && (eLog() << Verbose(1) << "I could not find " << *triangle << " in the touched list." << endl); 3778 4049 triangle = NULL; 3779 4050 } … … 3783 4054 break; 3784 4055 // find next line 3785 for (int i =0;i<3;i++) {4056 for (int i = 0; i < 3; i++) { 3786 4057 if ((triangle->lines[i] != CurrentLine) && (triangle->lines[i]->ContainsBoundaryPoint(ReferencePoint))) { // not the current line and still containing Point 3787 4058 CurrentLine = triangle->lines[i]; 3788 Log() << Verbose(1) << "INFO: Connecting line is " << *CurrentLine << "." << endl;4059 DoLog(1) && (Log() << Verbose(1) << "INFO: Connecting line is " << *CurrentLine << "." << endl); 3789 4060 break; 3790 4061 } … … 3792 4063 LineRunner = TouchedLine.find(CurrentLine); 3793 4064 if (LineRunner == TouchedLine.end()) 3794 eLog() << Verbose(1) << "I could not find " << *CurrentLine << " in the touched list." << endl;4065 DoeLog(1) && (eLog() << Verbose(1) << "I could not find " << *CurrentLine << " in the touched list." << endl); 3795 4066 else 3796 4067 LineRunner->second = true; … … 3800 4071 } while (CurrentLine != StartLine); 3801 4072 // last point is missing, as it's on start line 3802 Log() << Verbose(1) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl;4073 DoLog(1) && (Log() << Verbose(1) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl); 3803 4074 if (StartLine->GetOtherEndpoint(ReferencePoint)->node != connectedPath->back()) 3804 4075 connectedPath->push_back(StartLine->GetOtherEndpoint(ReferencePoint)->node); … … 3806 4077 ListOfPaths->push_back(connectedPath); 3807 4078 } else { 3808 Log() << Verbose(1) << "INFO: Skipping " << *runner->second << ", as we have already visited it." << endl;4079 DoLog(1) && (Log() << Verbose(1) << "INFO: Skipping " << *runner->second << ", as we have already visited it." << endl); 3809 4080 } 3810 4081 } 3811 4082 } else { 3812 eLog() << Verbose(1) << "There are no lines attached to " << *ReferencePoint << "." << endl;4083 DoeLog(1) && (eLog() << Verbose(1) << "There are no lines attached to " << *ReferencePoint << "." << endl); 3813 4084 } 3814 4085 … … 3824 4095 ListOfTesselPointList * Tesselation::GetClosedPathsOfConnectedPoints(const TesselPoint* const Point) const 3825 4096 { 3826 4097 Info FunctionInfo(__func__); 3827 4098 list<TesselPointList *> *ListofPaths = GetPathsOfConnectedPoints(Point); 3828 list<TesselPointList *> *ListofClosedPaths = new list<TesselPointList *> ;4099 list<TesselPointList *> *ListofClosedPaths = new list<TesselPointList *> ; 3829 4100 TesselPointList *connectedPath = NULL; 3830 4101 TesselPointList *newPath = NULL; 3831 4102 int count = 0; 3832 3833 3834 4103 TesselPointList::iterator CircleRunner; 3835 4104 TesselPointList::iterator CircleStart; 3836 4105 3837 for (list<TesselPointList *>::iterator ListRunner = ListofPaths->begin(); ListRunner != ListofPaths->end(); ListRunner++) {4106 for (list<TesselPointList *>::iterator ListRunner = ListofPaths->begin(); ListRunner != ListofPaths->end(); ListRunner++) { 3838 4107 connectedPath = *ListRunner; 3839 4108 3840 Log() << Verbose(1) << "INFO: Current path is " << connectedPath << "." << endl;4109 DoLog(1) && (Log() << Verbose(1) << "INFO: Current path is " << connectedPath << "." << endl); 3841 4110 3842 4111 // go through list, look for reappearance of starting Point and count 3843 4112 CircleStart = connectedPath->begin(); 3844 3845 4113 // go through list, look for reappearance of starting Point and create list 3846 4114 TesselPointList::iterator Marker = CircleStart; … … 3848 4116 if ((*CircleRunner == *CircleStart) && (CircleRunner != CircleStart)) { // is not the very first point 3849 4117 // we have a closed circle from Marker to new Marker 3850 Log() << Verbose(1) << count+1 << ". closed path consists of: ";4118 DoLog(1) && (Log() << Verbose(1) << count + 1 << ". closed path consists of: "); 3851 4119 newPath = new TesselPointList; 3852 4120 TesselPointList::iterator CircleSprinter = Marker; 3853 4121 for (; CircleSprinter != CircleRunner; CircleSprinter++) { 3854 4122 newPath->push_back(*CircleSprinter); 3855 Log() << Verbose(0) << (**CircleSprinter) << " <-> ";4123 DoLog(0) && (Log() << Verbose(0) << (**CircleSprinter) << " <-> "); 3856 4124 } 3857 Log() << Verbose(0) << ".." << endl;4125 DoLog(0) && (Log() << Verbose(0) << ".." << endl); 3858 4126 count++; 3859 4127 Marker = CircleRunner; … … 3864 4132 } 3865 4133 } 3866 Log() << Verbose(1) << "INFO: " << count << " closed additional path(s) have been created." << endl;4134 DoLog(1) && (Log() << Verbose(1) << "INFO: " << count << " closed additional path(s) have been created." << endl); 3867 4135 3868 4136 // delete list of paths … … 3870 4138 connectedPath = *(ListofPaths->begin()); 3871 4139 ListofPaths->remove(connectedPath); 3872 delete (connectedPath);3873 } 3874 delete (ListofPaths);4140 delete (connectedPath); 4141 } 4142 delete (ListofPaths); 3875 4143 3876 4144 // exit 3877 4145 return ListofClosedPaths; 3878 } ;3879 4146 } 4147 ; 3880 4148 3881 4149 /** Gets all belonging triangles for a given BoundaryPointSet. … … 3886 4154 TriangleSet *Tesselation::GetAllTriangles(const BoundaryPointSet * const Point) const 3887 4155 { 3888 3889 4156 Info FunctionInfo(__func__); 4157 TriangleSet *connectedTriangles = new TriangleSet; 3890 4158 3891 4159 if (Point == NULL) { 3892 eLog() << Verbose(1) << "Point given is NULL." << endl;4160 DoeLog(1) && (eLog() << Verbose(1) << "Point given is NULL." << endl); 3893 4161 } else { 3894 4162 // go through its lines and insert all triangles 3895 4163 for (LineMap::const_iterator LineRunner = Point->lines.begin(); LineRunner != Point->lines.end(); LineRunner++) 3896 4164 for (TriangleMap::iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) { 3897 connectedTriangles->insert(TriangleRunner->second);3898 }4165 connectedTriangles->insert(TriangleRunner->second); 4166 } 3899 4167 } 3900 4168 3901 4169 return connectedTriangles; 3902 } ;3903 4170 } 4171 ; 3904 4172 3905 4173 /** Removes a boundary point from the envelope while keeping it closed. … … 3914 4182 * \return volume added to the volume inside the tesselated surface by the removal 3915 4183 */ 3916 double Tesselation::RemovePointFromTesselatedSurface(class BoundaryPointSet *point) { 4184 double Tesselation::RemovePointFromTesselatedSurface(class BoundaryPointSet *point) 4185 { 3917 4186 class BoundaryLineSet *line = NULL; 3918 4187 class BoundaryTriangleSet *triangle = NULL; … … 3922 4191 3923 4192 if (point == NULL) { 3924 eLog() << Verbose(1) << "Cannot remove the point " << point << ", it's NULL!" << endl;4193 DoeLog(1) && (eLog() << Verbose(1) << "Cannot remove the point " << point << ", it's NULL!" << endl); 3925 4194 return 0.; 3926 4195 } else 3927 Log() << Verbose(0) << "Removing point " << *point << " from tesselated boundary ..." << endl;4196 DoLog(0) && (Log() << Verbose(0) << "Removing point " << *point << " from tesselated boundary ..." << endl); 3928 4197 3929 4198 // copy old location for the volume 3930 OldPoint .CopyVector(point->node->node);4199 OldPoint = (*point->node->node); 3931 4200 3932 4201 // get list of connected points 3933 4202 if (point->lines.empty()) { 3934 eLog() << Verbose(1) << "Cannot remove the point " << *point << ", it's connected to no lines!" << endl;4203 DoeLog(1) && (eLog() << Verbose(1) << "Cannot remove the point " << *point << ", it's connected to no lines!" << endl); 3935 4204 return 0.; 3936 4205 } … … 3941 4210 // gather all triangles 3942 4211 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) 3943 count +=LineRunner->second->triangles.size();4212 count += LineRunner->second->triangles.size(); 3944 4213 TriangleMap Candidates; 3945 4214 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) { … … 3947 4216 for (TriangleMap::iterator TriangleRunner = line->triangles.begin(); TriangleRunner != line->triangles.end(); TriangleRunner++) { 3948 4217 triangle = TriangleRunner->second; 3949 Candidates.insert( TrianglePair (triangle->Nr, triangle));4218 Candidates.insert(TrianglePair(triangle->Nr, triangle)); 3950 4219 } 3951 4220 } 3952 4221 3953 4222 // remove all triangles 3954 count =0;4223 count = 0; 3955 4224 NormalVector.Zero(); 3956 4225 for (TriangleMap::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) { 3957 Log() << Verbose(1) << "INFO: Removing triangle " << *(Runner->second) << "." << endl;3958 NormalVector .SubtractVector(&Runner->second->NormalVector); // has to point inward4226 DoLog(1) && (Log() << Verbose(1) << "INFO: Removing triangle " << *(Runner->second) << "." << endl); 4227 NormalVector -= Runner->second->NormalVector; // has to point inward 3959 4228 RemoveTesselationTriangle(Runner->second); 3960 4229 count++; 3961 4230 } 3962 Log() << Verbose(1) << count << " triangles were removed." << endl;4231 DoLog(1) && (Log() << Verbose(1) << count << " triangles were removed." << endl); 3963 4232 3964 4233 list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin(); … … 3969 4238 double smallestangle; 3970 4239 Vector Point, Reference, OrthogonalVector; 3971 if (count > 2) { 4240 if (count > 2) { // less than three triangles, then nothing will be created 3972 4241 class TesselPoint *TriangleCandidates[3]; 3973 4242 count = 0; 3974 for ( ; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) {// go through all closed paths4243 for (; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths 3975 4244 if (ListAdvance != ListOfClosedPaths->end()) 3976 4245 ListAdvance++; 3977 4246 3978 4247 connectedPath = *ListRunner; 3979 3980 4248 // re-create all triangles by going through connected points list 3981 4249 LineList NewLines; 3982 for (; !connectedPath->empty();) {4250 for (; !connectedPath->empty();) { 3983 4251 // search middle node with widest angle to next neighbours 3984 4252 EndNode = connectedPath->end(); 3985 4253 smallestangle = 0.; 3986 4254 for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) { 3987 Log() << Verbose(1) << "INFO: MiddleNode is " << **MiddleNode << "." << endl;4255 DoLog(1) && (Log() << Verbose(1) << "INFO: MiddleNode is " << **MiddleNode << "." << endl); 3988 4256 // construct vectors to next and previous neighbour 3989 4257 StartNode = MiddleNode; … … 3992 4260 StartNode--; 3993 4261 //Log() << Verbose(3) << "INFO: StartNode is " << **StartNode << "." << endl; 3994 Point.CopyVector((*StartNode)->node); 3995 Point.SubtractVector((*MiddleNode)->node); 4262 Point = (*(*StartNode)->node) - (*(*MiddleNode)->node); 3996 4263 StartNode = MiddleNode; 3997 4264 StartNode++; … … 3999 4266 StartNode = connectedPath->begin(); 4000 4267 //Log() << Verbose(3) << "INFO: EndNode is " << **StartNode << "." << endl; 4001 Reference.CopyVector((*StartNode)->node); 4002 Reference.SubtractVector((*MiddleNode)->node); 4003 OrthogonalVector.CopyVector((*MiddleNode)->node); 4004 OrthogonalVector.SubtractVector(&OldPoint); 4005 OrthogonalVector.MakeNormalVector(&Reference); 4268 Reference = (*(*StartNode)->node) - (*(*MiddleNode)->node); 4269 OrthogonalVector = (*(*MiddleNode)->node) - OldPoint; 4270 OrthogonalVector.MakeNormalTo(Reference); 4006 4271 angle = GetAngle(Point, Reference, OrthogonalVector); 4007 4272 //if (angle < M_PI) // no wrong-sided triangles, please? 4008 if(fabs(angle - M_PI) < fabs(smallestangle - M_PI)) {// get straightest angle (i.e. construct those triangles with smallest area first)4009 4010 4011 4273 if (fabs(angle - M_PI) < fabs(smallestangle - M_PI)) { // get straightest angle (i.e. construct those triangles with smallest area first) 4274 smallestangle = angle; 4275 EndNode = MiddleNode; 4276 } 4012 4277 } 4013 4278 MiddleNode = EndNode; 4014 4279 if (MiddleNode == connectedPath->end()) { 4015 eLog() << Verbose(0) << "CRITICAL: Could not find a smallest angle!" << endl;4280 DoeLog(0) && (eLog() << Verbose(0) << "CRITICAL: Could not find a smallest angle!" << endl); 4016 4281 performCriticalExit(); 4017 4282 } … … 4023 4288 if (EndNode == connectedPath->end()) 4024 4289 EndNode = connectedPath->begin(); 4025 Log() << Verbose(2) << "INFO: StartNode is " << **StartNode << "." << endl;4026 Log() << Verbose(2) << "INFO: MiddleNode is " << **MiddleNode << "." << endl;4027 Log() << Verbose(2) << "INFO: EndNode is " << **EndNode << "." << endl;4028 Log() << Verbose(1) << "INFO: Attempting to create triangle " << (*StartNode)->Name << ", " << (*MiddleNode)->Name << " and " << (*EndNode)->Name << "." << endl;4290 DoLog(2) && (Log() << Verbose(2) << "INFO: StartNode is " << **StartNode << "." << endl); 4291 DoLog(2) && (Log() << Verbose(2) << "INFO: MiddleNode is " << **MiddleNode << "." << endl); 4292 DoLog(2) && (Log() << Verbose(2) << "INFO: EndNode is " << **EndNode << "." << endl); 4293 DoLog(1) && (Log() << Verbose(1) << "INFO: Attempting to create triangle " << (*StartNode)->getName() << ", " << (*MiddleNode)->getName() << " and " << (*EndNode)->getName() << "." << endl); 4029 4294 TriangleCandidates[0] = *StartNode; 4030 4295 TriangleCandidates[1] = *MiddleNode; … … 4032 4297 triangle = GetPresentTriangle(TriangleCandidates); 4033 4298 if (triangle != NULL) { 4034 eLog() << Verbose(0) << "New triangle already present, skipping!" << endl;4299 DoeLog(0) && (eLog() << Verbose(0) << "New triangle already present, skipping!" << endl); 4035 4300 StartNode++; 4036 4301 MiddleNode++; … … 4044 4309 continue; 4045 4310 } 4046 Log() << Verbose(3) << "Adding new triangle points."<< endl;4311 DoLog(3) && (Log() << Verbose(3) << "Adding new triangle points." << endl); 4047 4312 AddTesselationPoint(*StartNode, 0); 4048 4313 AddTesselationPoint(*MiddleNode, 1); 4049 4314 AddTesselationPoint(*EndNode, 2); 4050 Log() << Verbose(3) << "Adding new triangle lines."<< endl;4051 AddTesselationLine( TPS[0], TPS[1], 0);4052 AddTesselationLine( TPS[0], TPS[2], 1);4315 DoLog(3) && (Log() << Verbose(3) << "Adding new triangle lines." << endl); 4316 AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0); 4317 AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1); 4053 4318 NewLines.push_back(BLS[1]); 4054 AddTesselationLine( TPS[1], TPS[2], 2);4319 AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2); 4055 4320 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 4056 4321 BTS->GetNormalVector(NormalVector); … … 4063 4328 // prepare nodes for next triangle 4064 4329 StartNode = EndNode; 4065 Log() << Verbose(2) << "Removing " << **MiddleNode << " from closed path, remaining points: " << connectedPath->size() << "." << endl;4330 DoLog(2) && (Log() << Verbose(2) << "Removing " << **MiddleNode << " from closed path, remaining points: " << connectedPath->size() << "." << endl); 4066 4331 connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles) 4067 4332 if (connectedPath->size() == 2) { // we are done … … 4070 4335 break; 4071 4336 } else if (connectedPath->size() < 2) { // something's gone wrong! 4072 eLog() << Verbose(0) << "CRITICAL: There are only two endpoints left!" << endl;4337 DoeLog(0) && (eLog() << Verbose(0) << "CRITICAL: There are only two endpoints left!" << endl); 4073 4338 performCriticalExit(); 4074 4339 } else { … … 4090 4355 do { 4091 4356 maxgain = 0; 4092 for (LineList::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) {4357 for (LineList::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) { 4093 4358 tmp = PickFarthestofTwoBaselines(*Runner); 4094 4359 if (maxgain < tmp) { … … 4099 4364 if (maxgain != 0) { 4100 4365 volume += maxgain; 4101 Log() << Verbose(1) << "Flipping baseline with highest volume" << **Candidate << "." << endl;4366 DoLog(1) && (Log() << Verbose(1) << "Flipping baseline with highest volume" << **Candidate << "." << endl); 4102 4367 OtherBase = FlipBaseline(*Candidate); 4103 4368 NewLines.erase(Candidate); … … 4108 4373 4109 4374 ListOfClosedPaths->remove(connectedPath); 4110 delete (connectedPath);4111 } 4112 Log() << Verbose(0) << count << " triangles were created." << endl;4375 delete (connectedPath); 4376 } 4377 DoLog(0) && (Log() << Verbose(0) << count << " triangles were created." << endl); 4113 4378 } else { 4114 4379 while (!ListOfClosedPaths->empty()) { … … 4116 4381 connectedPath = *ListRunner; 4117 4382 ListOfClosedPaths->remove(connectedPath); 4118 delete (connectedPath);4119 } 4120 Log() << Verbose(0) << "No need to create any triangles." << endl;4121 } 4122 delete (ListOfClosedPaths);4123 4124 Log() << Verbose(0) << "Removed volume is " << volume << "." << endl;4383 delete (connectedPath); 4384 } 4385 DoLog(0) && (Log() << Verbose(0) << "No need to create any triangles." << endl); 4386 } 4387 delete (ListOfClosedPaths); 4388 4389 DoLog(0) && (Log() << Verbose(0) << "Removed volume is " << volume << "." << endl); 4125 4390 4126 4391 return volume; 4127 }; 4128 4129 4392 } 4393 ; 4130 4394 4131 4395 /** … … 4139 4403 TriangleList *Tesselation::FindTriangles(const TesselPoint* const Points[3]) const 4140 4404 { 4141 4142 4405 Info FunctionInfo(__func__); 4406 TriangleList *result = new TriangleList; 4143 4407 LineMap::const_iterator FindLine; 4144 4408 TriangleMap::const_iterator FindTriangle; … … 4164 4428 for (int i = 0; i < 3; i++) { 4165 4429 if (TrianglePoints[i] != NULL) { 4166 for (int j = i +1; j < 3; j++) {4430 for (int j = i + 1; j < 3; j++) { 4167 4431 if (TrianglePoints[j] != NULL) { 4168 4432 for (FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->nr); // is a multimap! 4169 (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->nr); 4170 FindLine++) { 4171 for (FindTriangle = FindLine->second->triangles.begin(); 4172 FindTriangle != FindLine->second->triangles.end(); 4173 FindTriangle++) { 4433 (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->nr); FindLine++) { 4434 for (FindTriangle = FindLine->second->triangles.begin(); FindTriangle != FindLine->second->triangles.end(); FindTriangle++) { 4174 4435 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { 4175 4436 result->push_back(FindTriangle->second); … … 4186 4447 case 1: // copy all triangles of the respective line 4187 4448 { 4188 int i =0;4449 int i = 0; 4189 4450 for (; i < 3; i++) 4190 4451 if (TrianglePoints[i] == NULL) 4191 4452 break; 4192 for (FindLine = TrianglePoints[(i+1)%3]->lines.find(TrianglePoints[(i+2)%3]->node->nr); // is a multimap! 4193 (FindLine != TrianglePoints[(i+1)%3]->lines.end()) && (FindLine->first == TrianglePoints[(i+2)%3]->node->nr); 4194 FindLine++) { 4195 for (FindTriangle = FindLine->second->triangles.begin(); 4196 FindTriangle != FindLine->second->triangles.end(); 4197 FindTriangle++) { 4453 for (FindLine = TrianglePoints[(i + 1) % 3]->lines.find(TrianglePoints[(i + 2) % 3]->node->nr); // is a multimap! 4454 (FindLine != TrianglePoints[(i + 1) % 3]->lines.end()) && (FindLine->first == TrianglePoints[(i + 2) % 3]->node->nr); FindLine++) { 4455 for (FindTriangle = FindLine->second->triangles.begin(); FindTriangle != FindLine->second->triangles.end(); FindTriangle++) { 4198 4456 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { 4199 4457 result->push_back(FindTriangle->second); … … 4205 4463 case 2: // copy all triangles of the respective point 4206 4464 { 4207 int i =0;4465 int i = 0; 4208 4466 for (; i < 3; i++) 4209 4467 if (TrianglePoints[i] != NULL) … … 4223 4481 } 4224 4482 default: 4225 eLog() << Verbose(0) << "Number of wildcards is greater than 3, cannot happen!" << endl;4483 DoeLog(0) && (eLog() << Verbose(0) << "Number of wildcards is greater than 3, cannot happen!" << endl); 4226 4484 performCriticalExit(); 4227 4485 break; … … 4231 4489 } 4232 4490 4233 struct BoundaryLineSetCompare { 4234 bool operator() (const BoundaryLineSet * const a, const BoundaryLineSet * const b) { 4491 struct BoundaryLineSetCompare 4492 { 4493 bool operator()(const BoundaryLineSet * const a, const BoundaryLineSet * const b) 4494 { 4235 4495 int lowerNra = -1; 4236 4496 int lowerNrb = -1; … … 4250 4510 else if (a->endpoints[lowerNra] > b->endpoints[lowerNrb]) 4251 4511 return false; 4252 else { 4253 if (a->endpoints[(lowerNra+1)%2] < b->endpoints[(lowerNrb+1)%2])4254 return true;4255 else if (a->endpoints[(lowerNra+1)%2] > b->endpoints[(lowerNrb+1)%2])4256 return false;4512 else { // both lower-numbered endpoints are the same ... 4513 if (a->endpoints[(lowerNra + 1) % 2] < b->endpoints[(lowerNrb + 1) % 2]) 4514 return true; 4515 else if (a->endpoints[(lowerNra + 1) % 2] > b->endpoints[(lowerNrb + 1) % 2]) 4516 return false; 4257 4517 } 4258 4518 return false; 4259 }; 4519 } 4520 ; 4260 4521 }; 4261 4522 … … 4270 4531 IndexToIndex * Tesselation::FindAllDegeneratedLines() 4271 4532 { 4272 4273 4533 Info FunctionInfo(__func__); 4534 UniqueLines AllLines; 4274 4535 IndexToIndex * DegeneratedLines = new IndexToIndex; 4275 4536 4276 4537 // sanity check 4277 4538 if (LinesOnBoundary.empty()) { 4278 eLog() << Verbose(2) << "FindAllDegeneratedTriangles() was called without any tesselation structure.";4539 DoeLog(2) && (eLog() << Verbose(2) << "FindAllDegeneratedTriangles() was called without any tesselation structure."); 4279 4540 return DegeneratedLines; 4280 4541 } 4281 4282 4542 LineMap::iterator LineRunner1; 4283 pair< 4543 pair<UniqueLines::iterator, bool> tester; 4284 4544 for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) { 4285 tester = AllLines.insert( LineRunner1->second);4545 tester = AllLines.insert(LineRunner1->second); 4286 4546 if (!tester.second) { // found degenerated line 4287 DegeneratedLines->insert ( pair<int, int> (LineRunner1->second->Nr, (*tester.first)->Nr));4288 DegeneratedLines->insert ( pair<int, int> ((*tester.first)->Nr, LineRunner1->second->Nr));4547 DegeneratedLines->insert(pair<int, int> (LineRunner1->second->Nr, (*tester.first)->Nr)); 4548 DegeneratedLines->insert(pair<int, int> ((*tester.first)->Nr, LineRunner1->second->Nr)); 4289 4549 } 4290 4550 } … … 4292 4552 AllLines.clear(); 4293 4553 4294 Log() << Verbose(0) << "FindAllDegeneratedLines() found " << DegeneratedLines->size() << " lines." << endl;4554 DoLog(0) && (Log() << Verbose(0) << "FindAllDegeneratedLines() found " << DegeneratedLines->size() << " lines." << endl); 4295 4555 IndexToIndex::iterator it; 4296 4556 for (it = DegeneratedLines->begin(); it != DegeneratedLines->end(); it++) { … … 4298 4558 const LineMap::const_iterator Line2 = LinesOnBoundary.find((*it).second); 4299 4559 if (Line1 != LinesOnBoundary.end() && Line2 != LinesOnBoundary.end()) 4300 Log() << Verbose(0) << *Line1->second << " => " << *Line2->second << endl;4560 DoLog(0) && (Log() << Verbose(0) << *Line1->second << " => " << *Line2->second << endl); 4301 4561 else 4302 eLog() << Verbose(1) << "Either " << (*it).first << " or " << (*it).second << " are not in LinesOnBoundary!" << endl;4562 DoeLog(1) && (eLog() << Verbose(1) << "Either " << (*it).first << " or " << (*it).second << " are not in LinesOnBoundary!" << endl); 4303 4563 } 4304 4564 … … 4314 4574 IndexToIndex * Tesselation::FindAllDegeneratedTriangles() 4315 4575 { 4316 4576 Info FunctionInfo(__func__); 4317 4577 IndexToIndex * DegeneratedLines = FindAllDegeneratedLines(); 4318 4578 IndexToIndex * DegeneratedTriangles = new IndexToIndex; 4319 4320 4579 TriangleMap::iterator TriangleRunner1, TriangleRunner2; 4321 4580 LineMap::iterator Liner; … … 4332 4591 for (TriangleRunner1 = line1->triangles.begin(); TriangleRunner1 != line1->triangles.end(); ++TriangleRunner1) { 4333 4592 for (TriangleRunner2 = line2->triangles.begin(); TriangleRunner2 != line2->triangles.end(); ++TriangleRunner2) { 4334 if ((TriangleRunner1->second != TriangleRunner2->second) 4335 && (TriangleRunner1->second->IsPresentTupel(TriangleRunner2->second))) { 4336 DegeneratedTriangles->insert( pair<int, int> (TriangleRunner1->second->Nr, TriangleRunner2->second->Nr) ); 4337 DegeneratedTriangles->insert( pair<int, int> (TriangleRunner2->second->Nr, TriangleRunner1->second->Nr) ); 4593 if ((TriangleRunner1->second != TriangleRunner2->second) && (TriangleRunner1->second->IsPresentTupel(TriangleRunner2->second))) { 4594 DegeneratedTriangles->insert(pair<int, int> (TriangleRunner1->second->Nr, TriangleRunner2->second->Nr)); 4595 DegeneratedTriangles->insert(pair<int, int> (TriangleRunner2->second->Nr, TriangleRunner1->second->Nr)); 4338 4596 } 4339 4597 } 4340 4598 } 4341 4599 } 4342 delete (DegeneratedLines);4343 4344 Log() << Verbose(0) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles->size() << " triangles:" << endl;4600 delete (DegeneratedLines); 4601 4602 DoLog(0) && (Log() << Verbose(0) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles->size() << " triangles:" << endl); 4345 4603 IndexToIndex::iterator it; 4346 4604 for (it = DegeneratedTriangles->begin(); it != DegeneratedTriangles->end(); it++) 4347 Log() << Verbose(0) << (*it).first << " => " << (*it).second << endl;4605 DoLog(0) && (Log() << Verbose(0) << (*it).first << " => " << (*it).second << endl); 4348 4606 4349 4607 return DegeneratedTriangles; … … 4356 4614 void Tesselation::RemoveDegeneratedTriangles() 4357 4615 { 4358 4616 Info FunctionInfo(__func__); 4359 4617 IndexToIndex * DegeneratedTriangles = FindAllDegeneratedTriangles(); 4360 4618 TriangleMap::iterator finder; 4361 4619 BoundaryTriangleSet *triangle = NULL, *partnerTriangle = NULL; 4362 int count = 0; 4363 4364 for (IndexToIndex::iterator TriangleKeyRunner = DegeneratedTriangles->begin(); 4365 TriangleKeyRunner != DegeneratedTriangles->end(); ++TriangleKeyRunner 4366 ) { 4620 int count = 0; 4621 4622 for (IndexToIndex::iterator TriangleKeyRunner = DegeneratedTriangles->begin(); TriangleKeyRunner != DegeneratedTriangles->end(); ++TriangleKeyRunner) { 4367 4623 finder = TrianglesOnBoundary.find(TriangleKeyRunner->first); 4368 4624 if (finder != TrianglesOnBoundary.end()) … … 4381 4637 trianglesShareLine = trianglesShareLine || triangle->lines[i] == partnerTriangle->lines[j]; 4382 4638 4383 if (trianglesShareLine 4384 && (triangle->endpoints[1]->LinesCount > 2) 4385 && (triangle->endpoints[2]->LinesCount > 2) 4386 && (triangle->endpoints[0]->LinesCount > 2) 4387 ) { 4639 if (trianglesShareLine && (triangle->endpoints[1]->LinesCount > 2) && (triangle->endpoints[2]->LinesCount > 2) && (triangle->endpoints[0]->LinesCount > 2)) { 4388 4640 // check whether we have to fix lines 4389 4641 BoundaryTriangleSet *Othertriangle = NULL; … … 4405 4657 // the line of triangle receives the degenerated ones 4406 4658 triangle->lines[i]->triangles.erase(Othertriangle->Nr); 4407 triangle->lines[i]->triangles.insert( TrianglePair( partnerTriangle->Nr, partnerTriangle));4408 for (int k =0;k<3;k++)4659 triangle->lines[i]->triangles.insert(TrianglePair(partnerTriangle->Nr, partnerTriangle)); 4660 for (int k = 0; k < 3; k++) 4409 4661 if (triangle->lines[i] == Othertriangle->lines[k]) { 4410 4662 Othertriangle->lines[k] = partnerTriangle->lines[j]; … … 4412 4664 } 4413 4665 // the line of partnerTriangle receives the non-degenerated ones 4414 partnerTriangle->lines[j]->triangles.erase( 4415 partnerTriangle->lines[j]->triangles.insert( TrianglePair( Othertriangle->Nr, Othertriangle));4666 partnerTriangle->lines[j]->triangles.erase(partnerTriangle->Nr); 4667 partnerTriangle->lines[j]->triangles.insert(TrianglePair(Othertriangle->Nr, Othertriangle)); 4416 4668 partnerTriangle->lines[j] = triangle->lines[i]; 4417 4669 } … … 4419 4671 // erase the pair 4420 4672 count += (int) DegeneratedTriangles->erase(triangle->Nr); 4421 Log() << Verbose(0) << "RemoveDegeneratedTriangles() removes triangle " << *triangle << "." << endl;4673 DoLog(0) && (Log() << Verbose(0) << "RemoveDegeneratedTriangles() removes triangle " << *triangle << "." << endl); 4422 4674 RemoveTesselationTriangle(triangle); 4423 4675 count += (int) DegeneratedTriangles->erase(partnerTriangle->Nr); 4424 Log() << Verbose(0) << "RemoveDegeneratedTriangles() removes triangle " << *partnerTriangle << "." << endl;4676 DoLog(0) && (Log() << Verbose(0) << "RemoveDegeneratedTriangles() removes triangle " << *partnerTriangle << "." << endl); 4425 4677 RemoveTesselationTriangle(partnerTriangle); 4426 4678 } else { 4427 Log() << Verbose(0) << "RemoveDegeneratedTriangles() does not remove triangle " << *triangle 4428 << " and its partner " << *partnerTriangle << " because it is essential for at" 4429 << " least one of the endpoints to be kept in the tesselation structure." << endl; 4430 } 4431 } 4432 delete(DegeneratedTriangles); 4679 DoLog(0) && (Log() << Verbose(0) << "RemoveDegeneratedTriangles() does not remove triangle " << *triangle << " and its partner " << *partnerTriangle << " because it is essential for at" << " least one of the endpoints to be kept in the tesselation structure." << endl); 4680 } 4681 } 4682 delete (DegeneratedTriangles); 4433 4683 if (count > 0) 4434 4684 LastTriangle = NULL; 4435 4685 4436 Log() << Verbose(0) << "RemoveDegeneratedTriangles() removed " << count << " triangles:" << endl;4686 DoLog(0) && (Log() << Verbose(0) << "RemoveDegeneratedTriangles() removed " << count << " triangles:" << endl); 4437 4687 } 4438 4688 … … 4447 4697 void Tesselation::AddBoundaryPointByDegeneratedTriangle(class TesselPoint *point, LinkedCell *LC) 4448 4698 { 4449 4699 Info FunctionInfo(__func__); 4450 4700 // find nearest boundary point 4451 4701 class TesselPoint *BackupPoint = NULL; … … 4460 4710 NearestBoundaryPoint = PointRunner->second; 4461 4711 } else { 4462 eLog() << Verbose(1) << "I cannot find the boundary point." << endl;4712 DoeLog(1) && (eLog() << Verbose(1) << "I cannot find the boundary point." << endl); 4463 4713 return; 4464 4714 } 4465 Log() << Verbose(0) << "Nearest point on boundary is " << NearestPoint->Name << "." << endl;4715 DoLog(0) && (Log() << Verbose(0) << "Nearest point on boundary is " << NearestPoint->getName() << "." << endl); 4466 4716 4467 4717 // go through its lines and find the best one to split … … 4471 4721 class BoundaryLineSet *BestLine = NULL; 4472 4722 for (LineMap::iterator Runner = NearestBoundaryPoint->lines.begin(); Runner != NearestBoundaryPoint->lines.end(); Runner++) { 4473 BaseLine.CopyVector(Runner->second->endpoints[0]->node->node); 4474 BaseLine.SubtractVector(Runner->second->endpoints[1]->node->node); 4475 CenterToPoint.CopyVector(Runner->second->endpoints[0]->node->node); 4476 CenterToPoint.AddVector(Runner->second->endpoints[1]->node->node); 4477 CenterToPoint.Scale(0.5); 4478 CenterToPoint.SubtractVector(point->node); 4479 angle = CenterToPoint.Angle(&BaseLine); 4723 BaseLine = (*Runner->second->endpoints[0]->node->node) - 4724 (*Runner->second->endpoints[1]->node->node); 4725 CenterToPoint = 0.5 * ((*Runner->second->endpoints[0]->node->node) + 4726 (*Runner->second->endpoints[1]->node->node)); 4727 CenterToPoint -= (*point->node); 4728 angle = CenterToPoint.Angle(BaseLine); 4480 4729 if (fabs(angle - M_PI/2.) < fabs(BestAngle - M_PI/2.)) { 4481 4730 BestAngle = angle; … … 4488 4737 BestLine->triangles.erase(TempTriangle->Nr); 4489 4738 int nr = -1; 4490 for (int i =0;i<3; i++) {4739 for (int i = 0; i < 3; i++) { 4491 4740 if (TempTriangle->lines[i] == BestLine) { 4492 4741 nr = i; … … 4496 4745 4497 4746 // create new triangle to connect point (connects automatically with the missing spot of the chosen line) 4498 Log() << Verbose(2) << "Adding new triangle points."<< endl;4747 DoLog(2) && (Log() << Verbose(2) << "Adding new triangle points." << endl); 4499 4748 AddTesselationPoint((BestLine->endpoints[0]->node), 0); 4500 4749 AddTesselationPoint((BestLine->endpoints[1]->node), 1); 4501 4750 AddTesselationPoint(point, 2); 4502 Log() << Verbose(2) << "Adding new triangle lines."<< endl;4503 AddTesselationLine( TPS[0], TPS[1], 0);4504 AddTesselationLine( TPS[0], TPS[2], 1);4505 AddTesselationLine( TPS[1], TPS[2], 2);4751 DoLog(2) && (Log() << Verbose(2) << "Adding new triangle lines." << endl); 4752 AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0); 4753 AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1); 4754 AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2); 4506 4755 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 4507 4756 BTS->GetNormalVector(TempTriangle->NormalVector); 4508 4757 BTS->NormalVector.Scale(-1.); 4509 Log() << Verbose(1) << "INFO: NormalVector of new triangle is " << BTS->NormalVector << "." << endl;4758 DoLog(1) && (Log() << Verbose(1) << "INFO: NormalVector of new triangle is " << BTS->NormalVector << "." << endl); 4510 4759 AddTesselationTriangle(); 4511 4760 4512 4761 // create other side of this triangle and close both new sides of the first created triangle 4513 Log() << Verbose(2) << "Adding new triangle points."<< endl;4762 DoLog(2) && (Log() << Verbose(2) << "Adding new triangle points." << endl); 4514 4763 AddTesselationPoint((BestLine->endpoints[0]->node), 0); 4515 4764 AddTesselationPoint((BestLine->endpoints[1]->node), 1); 4516 4765 AddTesselationPoint(point, 2); 4517 Log() << Verbose(2) << "Adding new triangle lines."<< endl;4518 AddTesselationLine( TPS[0], TPS[1], 0);4519 AddTesselationLine( TPS[0], TPS[2], 1);4520 AddTesselationLine( TPS[1], TPS[2], 2);4766 DoLog(2) && (Log() << Verbose(2) << "Adding new triangle lines." << endl); 4767 AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0); 4768 AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1); 4769 AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2); 4521 4770 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 4522 4771 BTS->GetNormalVector(TempTriangle->NormalVector); 4523 Log() << Verbose(1) << "INFO: NormalVector of other new triangle is " << BTS->NormalVector << "." << endl;4772 DoLog(1) && (Log() << Verbose(1) << "INFO: NormalVector of other new triangle is " << BTS->NormalVector << "." << endl); 4524 4773 AddTesselationTriangle(); 4525 4774 4526 4775 // add removed triangle to the last open line of the second triangle 4527 for (int i =0;i<3;i++) { // look for the same line as BestLine (only it's its degenerated companion)4776 for (int i = 0; i < 3; i++) { // look for the same line as BestLine (only it's its degenerated companion) 4528 4777 if ((BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[0])) && (BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[1]))) { 4529 if (BestLine == BTS->lines[i]) {4530 eLog() << Verbose(0) << "BestLine is same as found line, something's wrong here!" << endl;4778 if (BestLine == BTS->lines[i]) { 4779 DoeLog(0) && (eLog() << Verbose(0) << "BestLine is same as found line, something's wrong here!" << endl); 4531 4780 performCriticalExit(); 4532 4781 } 4533 BTS->lines[i]->triangles.insert( pair<int, class BoundaryTriangleSet *> (TempTriangle->Nr, TempTriangle));4782 BTS->lines[i]->triangles.insert(pair<int, class BoundaryTriangleSet *> (TempTriangle->Nr, TempTriangle)); 4534 4783 TempTriangle->lines[nr] = BTS->lines[i]; 4535 4784 break; 4536 4785 } 4537 4786 } 4538 }; 4787 } 4788 ; 4539 4789 4540 4790 /** Writes the envelope to file. … … 4545 4795 void Tesselation::Output(const char *filename, const PointCloud * const cloud) 4546 4796 { 4547 4797 Info FunctionInfo(__func__); 4548 4798 ofstream *tempstream = NULL; 4549 4799 string NameofTempFile; 4550 char NumberName[255];4800 string NumberName; 4551 4801 4552 4802 if (LastTriangle != NULL) { 4553 sprintf(NumberName, "-%04d-%s_%s_%s", (int)TrianglesOnBoundary.size(), LastTriangle->endpoints[0]->node->Name, LastTriangle->endpoints[1]->node->Name, LastTriangle->endpoints[2]->node->Name); 4803 stringstream sstr; 4804 sstr << "-"<< TrianglesOnBoundary.size() << "-" << LastTriangle->endpoints[0]->node->getName() << "_" << LastTriangle->endpoints[1]->node->getName() << "_" << LastTriangle->endpoints[2]->node->getName(); 4805 NumberName = sstr.str(); 4554 4806 if (DoTecplotOutput) { 4555 4807 string NameofTempFile(filename); 4556 4808 NameofTempFile.append(NumberName); 4557 for (size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos))4558 NameofTempFile.erase(npos, 1);4809 for (size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos)) 4810 NameofTempFile.erase(npos, 1); 4559 4811 NameofTempFile.append(TecplotSuffix); 4560 Log() << Verbose(0) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";4812 DoLog(0) && (Log() << Verbose(0) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"); 4561 4813 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 4562 4814 WriteTecplotFile(tempstream, this, cloud, TriangleFilesWritten); 4563 4815 tempstream->close(); 4564 4816 tempstream->flush(); 4565 delete (tempstream);4817 delete (tempstream); 4566 4818 } 4567 4819 … … 4569 4821 string NameofTempFile(filename); 4570 4822 NameofTempFile.append(NumberName); 4571 for (size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos))4572 NameofTempFile.erase(npos, 1);4823 for (size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos)) 4824 NameofTempFile.erase(npos, 1); 4573 4825 NameofTempFile.append(Raster3DSuffix); 4574 Log() << Verbose(0) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";4826 DoLog(0) && (Log() << Verbose(0) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"); 4575 4827 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 4576 4828 WriteRaster3dFile(tempstream, this, cloud); … … 4578 4830 tempstream->close(); 4579 4831 tempstream->flush(); 4580 delete (tempstream);4832 delete (tempstream); 4581 4833 } 4582 4834 } 4583 4835 if (DoTecplotOutput || DoRaster3DOutput) 4584 4836 TriangleFilesWritten++; 4585 }; 4586 4587 struct BoundaryPolygonSetCompare { 4588 bool operator()(const BoundaryPolygonSet * s1, const BoundaryPolygonSet * s2) const { 4837 } 4838 ; 4839 4840 struct BoundaryPolygonSetCompare 4841 { 4842 bool operator()(const BoundaryPolygonSet * s1, const BoundaryPolygonSet * s2) const 4843 { 4589 4844 if (s1->endpoints.size() < s2->endpoints.size()) 4590 4845 return true; … … 4615 4870 { 4616 4871 Info FunctionInfo(__func__); 4617 4618 4872 /// 2. Go through all BoundaryPointSet's, check their triangles' NormalVector 4619 4873 IndexToIndex *DegeneratedTriangles = FindAllDegeneratedTriangles(); 4620 set <BoundaryPointSet *> EndpointCandidateList;4621 pair < set < BoundaryPointSet *>::iterator, bool> InsertionTester;4622 pair < map < int, Vector *>::iterator, bool> TriangleInsertionTester;4874 set<BoundaryPointSet *> EndpointCandidateList; 4875 pair<set<BoundaryPointSet *>::iterator, bool> InsertionTester; 4876 pair<map<int, Vector *>::iterator, bool> TriangleInsertionTester; 4623 4877 for (PointMap::const_iterator Runner = PointsOnBoundary.begin(); Runner != PointsOnBoundary.end(); Runner++) { 4624 Log() << Verbose(0) << "Current point is " << *Runner->second << "." << endl;4625 map <int, Vector *> TriangleVectors;4878 DoLog(0) && (Log() << Verbose(0) << "Current point is " << *Runner->second << "." << endl); 4879 map<int, Vector *> TriangleVectors; 4626 4880 // gather all NormalVectors 4627 Log() << Verbose(1) << "Gathering triangles ..." << endl;4881 DoLog(1) && (Log() << Verbose(1) << "Gathering triangles ..." << endl); 4628 4882 for (LineMap::const_iterator LineRunner = (Runner->second)->lines.begin(); LineRunner != (Runner->second)->lines.end(); LineRunner++) 4629 4883 for (TriangleMap::const_iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) { 4630 4884 if (DegeneratedTriangles->find(TriangleRunner->second->Nr) == DegeneratedTriangles->end()) { 4631 TriangleInsertionTester = TriangleVectors.insert( pair< int, Vector *> ((TriangleRunner->second)->Nr, &((TriangleRunner->second)->NormalVector)));4885 TriangleInsertionTester = TriangleVectors.insert(pair<int, Vector *> ((TriangleRunner->second)->Nr, &((TriangleRunner->second)->NormalVector))); 4632 4886 if (TriangleInsertionTester.second) 4633 Log() << Verbose(1) << " Adding triangle " << *(TriangleRunner->second) << " to triangles to check-list." << endl;4887 DoLog(1) && (Log() << Verbose(1) << " Adding triangle " << *(TriangleRunner->second) << " to triangles to check-list." << endl); 4634 4888 } else { 4635 Log() << Verbose(1) << " NOT adding triangle " << *(TriangleRunner->second) << " as it's a simply degenerated one." << endl;4889 DoLog(1) && (Log() << Verbose(1) << " NOT adding triangle " << *(TriangleRunner->second) << " as it's a simply degenerated one." << endl); 4636 4890 } 4637 4891 } 4638 4892 // check whether there are two that are parallel 4639 Log() << Verbose(1) << "Finding two parallel triangles ..." << endl;4640 for (map <int, Vector *>::iterator VectorWalker = TriangleVectors.begin(); VectorWalker != TriangleVectors.end(); VectorWalker++)4641 for (map <int, Vector *>::iterator VectorRunner = VectorWalker; VectorRunner != TriangleVectors.end(); VectorRunner++)4893 DoLog(1) && (Log() << Verbose(1) << "Finding two parallel triangles ..." << endl); 4894 for (map<int, Vector *>::iterator VectorWalker = TriangleVectors.begin(); VectorWalker != TriangleVectors.end(); VectorWalker++) 4895 for (map<int, Vector *>::iterator VectorRunner = VectorWalker; VectorRunner != TriangleVectors.end(); VectorRunner++) 4642 4896 if (VectorWalker != VectorRunner) { // skip equals 4643 const double SCP = VectorWalker->second->ScalarProduct( VectorRunner->second);// ScalarProduct should result in -1. for degenerated triangles4644 Log() << Verbose(1) << "Checking " << *VectorWalker->second<< " against " << *VectorRunner->second << ": " << SCP << endl;4897 const double SCP = VectorWalker->second->ScalarProduct(*VectorRunner->second); // ScalarProduct should result in -1. for degenerated triangles 4898 DoLog(1) && (Log() << Verbose(1) << "Checking " << *VectorWalker->second << " against " << *VectorRunner->second << ": " << SCP << endl); 4645 4899 if (fabs(SCP + 1.) < ParallelEpsilon) { 4646 4900 InsertionTester = EndpointCandidateList.insert((Runner->second)); 4647 4901 if (InsertionTester.second) 4648 Log() << Verbose(0) << " Adding " << *Runner->second << " to endpoint candidate list." << endl;4902 DoLog(0) && (Log() << Verbose(0) << " Adding " << *Runner->second << " to endpoint candidate list." << endl); 4649 4903 // and break out of both loops 4650 4904 VectorWalker = TriangleVectors.end(); … … 4661 4915 BoundaryPointSet *OtherWalker = NULL; 4662 4916 BoundaryPolygonSet *Current = NULL; 4663 stack 4917 stack<BoundaryPointSet*> ToCheckConnecteds; 4664 4918 while (!EndpointCandidateList.empty()) { 4665 4919 Walker = *(EndpointCandidateList.begin()); 4666 if (Current == NULL) { 4667 Log() << Verbose(0) << "Starting new polygon set at point " << *Walker << endl;4920 if (Current == NULL) { // create a new polygon with current candidate 4921 DoLog(0) && (Log() << Verbose(0) << "Starting new polygon set at point " << *Walker << endl); 4668 4922 Current = new BoundaryPolygonSet; 4669 4923 Current->endpoints.insert(Walker); … … 4678 4932 for (LineMap::const_iterator LineWalker = Walker->lines.begin(); LineWalker != Walker->lines.end(); LineWalker++) { 4679 4933 OtherWalker = (LineWalker->second)->GetOtherEndpoint(Walker); 4680 Log() << Verbose(1) << "Checking " << *OtherWalker << endl;4681 set <BoundaryPointSet *>::iterator Finder = EndpointCandidateList.find(OtherWalker);4682 if (Finder != EndpointCandidateList.end()) { 4683 Log() << Verbose(1) << " Adding to polygon." << endl;4934 DoLog(1) && (Log() << Verbose(1) << "Checking " << *OtherWalker << endl); 4935 set<BoundaryPointSet *>::iterator Finder = EndpointCandidateList.find(OtherWalker); 4936 if (Finder != EndpointCandidateList.end()) { // found a connected partner 4937 DoLog(1) && (Log() << Verbose(1) << " Adding to polygon." << endl); 4684 4938 Current->endpoints.insert(OtherWalker); 4685 EndpointCandidateList.erase(Finder); 4686 ToCheckConnecteds.push(OtherWalker); 4939 EndpointCandidateList.erase(Finder); // remove from candidates 4940 ToCheckConnecteds.push(OtherWalker); // but check its partners too 4687 4941 } else { 4688 Log() << Verbose(1) << " is not connected to " << *Walker << endl;4942 DoLog(1) && (Log() << Verbose(1) << " is not connected to " << *Walker << endl); 4689 4943 } 4690 4944 } 4691 4945 } 4692 4946 4693 Log() << Verbose(0) << "Final polygon is " << *Current << endl;4947 DoLog(0) && (Log() << Verbose(0) << "Final polygon is " << *Current << endl); 4694 4948 ListofDegeneratedPolygons.insert(Current); 4695 4949 Current = NULL; … … 4698 4952 const int counter = ListofDegeneratedPolygons.size(); 4699 4953 4700 Log() << Verbose(0) << "The following " << counter << " degenerated polygons have been found: " << endl;4954 DoLog(0) && (Log() << Verbose(0) << "The following " << counter << " degenerated polygons have been found: " << endl); 4701 4955 for (UniquePolygonSet::iterator PolygonRunner = ListofDegeneratedPolygons.begin(); PolygonRunner != ListofDegeneratedPolygons.end(); PolygonRunner++) 4702 Log() << Verbose(0) << " " << **PolygonRunner << endl;4956 DoLog(0) && (Log() << Verbose(0) << " " << **PolygonRunner << endl); 4703 4957 4704 4958 /// 4. Go through all these degenerated polygons 4705 4959 for (UniquePolygonSet::iterator PolygonRunner = ListofDegeneratedPolygons.begin(); PolygonRunner != ListofDegeneratedPolygons.end(); PolygonRunner++) { 4706 stack 4960 stack<int> TriangleNrs; 4707 4961 Vector NormalVector; 4708 4962 /// 4a. Gather all triangles of this polygon … … 4711 4965 // check whether number is bigger than 2, otherwise it's just a simply degenerated one and nothing to do. 4712 4966 if (T->size() == 2) { 4713 Log() << Verbose(1) << " Skipping degenerated polygon, is just a (already simply degenerated) triangle." << endl;4714 delete (T);4967 DoLog(1) && (Log() << Verbose(1) << " Skipping degenerated polygon, is just a (already simply degenerated) triangle." << endl); 4968 delete (T); 4715 4969 continue; 4716 4970 } … … 4721 4975 // connections to either polygon ... 4722 4976 if (T->size() % 2 != 0) { 4723 eLog() << Verbose(0) << " degenerated polygon contains an odd number of triangles, probably contains bridging non-degenerated ones, too!" << endl;4977 DoeLog(0) && (eLog() << Verbose(0) << " degenerated polygon contains an odd number of triangles, probably contains bridging non-degenerated ones, too!" << endl); 4724 4978 performCriticalExit(); 4725 4979 } 4726 4727 TriangleSet::iterator TriangleWalker = T->begin(); // is the inner iterator 4980 TriangleSet::iterator TriangleWalker = T->begin(); // is the inner iterator 4728 4981 /// 4a. Get NormalVector for one side (this is "front") 4729 NormalVector .CopyVector(&(*TriangleWalker)->NormalVector);4730 Log() << Verbose(1) << "\"front\" defining triangle is " << **TriangleWalker << " and Normal vector of \"front\" side is " << NormalVector << endl;4982 NormalVector = (*TriangleWalker)->NormalVector; 4983 DoLog(1) && (Log() << Verbose(1) << "\"front\" defining triangle is " << **TriangleWalker << " and Normal vector of \"front\" side is " << NormalVector << endl); 4731 4984 TriangleWalker++; 4732 4985 TriangleSet::iterator TriangleSprinter = TriangleWalker; // is the inner advanced iterator … … 4737 4990 triangle = *TriangleWalker; 4738 4991 TriangleSprinter++; 4739 Log() << Verbose(1) << "Current triangle to test for removal: " << *triangle << endl;4740 if (triangle->NormalVector.ScalarProduct( &NormalVector) < 0) { // if from other side, then delete and remove from list4741 Log() << Verbose(1) << " Removing ... " << endl;4992 DoLog(1) && (Log() << Verbose(1) << "Current triangle to test for removal: " << *triangle << endl); 4993 if (triangle->NormalVector.ScalarProduct(NormalVector) < 0) { // if from other side, then delete and remove from list 4994 DoLog(1) && (Log() << Verbose(1) << " Removing ... " << endl); 4742 4995 TriangleNrs.push(triangle->Nr); 4743 4996 T->erase(TriangleWalker); 4744 4997 RemoveTesselationTriangle(triangle); 4745 4998 } else 4746 Log() << Verbose(1) << " Keeping ... " << endl;4999 DoLog(1) && (Log() << Verbose(1) << " Keeping ... " << endl); 4747 5000 } 4748 5001 /// 4c. Copy all "front" triangles but with inverse NormalVector 4749 5002 TriangleWalker = T->begin(); 4750 while (TriangleWalker != T->end()) { 4751 Log() << Verbose(1) << " Re-creating triangle " << **TriangleWalker << " with NormalVector " << (*TriangleWalker)->NormalVector << endl;5003 while (TriangleWalker != T->end()) { // go through all front triangles 5004 DoLog(1) && (Log() << Verbose(1) << " Re-creating triangle " << **TriangleWalker << " with NormalVector " << (*TriangleWalker)->NormalVector << endl); 4752 5005 for (int i = 0; i < 3; i++) 4753 5006 AddTesselationPoint((*TriangleWalker)->endpoints[i]->node, i); 4754 AddTesselationLine( TPS[0], TPS[1], 0);4755 AddTesselationLine( TPS[0], TPS[2], 1);4756 AddTesselationLine( TPS[1], TPS[2], 2);5007 AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0); 5008 AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1); 5009 AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2); 4757 5010 if (TriangleNrs.empty()) 4758 eLog() << Verbose(0) << "No more free triangle numbers!" << endl;5011 DoeLog(0) && (eLog() << Verbose(0) << "No more free triangle numbers!" << endl); 4759 5012 BTS = new BoundaryTriangleSet(BLS, TriangleNrs.top()); // copy triangle ... 4760 5013 AddTesselationTriangle(); // ... and add 4761 5014 TriangleNrs.pop(); 4762 BTS->NormalVector.CopyVector(&(*TriangleWalker)->NormalVector); 4763 BTS->NormalVector.Scale(-1.); 5015 BTS->NormalVector = -1 * (*TriangleWalker)->NormalVector; 4764 5016 TriangleWalker++; 4765 5017 } 4766 5018 if (!TriangleNrs.empty()) { 4767 eLog() << Verbose(0) << "There have been less triangles created than removed!" << endl; 4768 } 4769 delete(T); // remove the triangleset 4770 } 4771 5019 DoeLog(0) && (eLog() << Verbose(0) << "There have been less triangles created than removed!" << endl); 5020 } 5021 delete (T); // remove the triangleset 5022 } 4772 5023 IndexToIndex * SimplyDegeneratedTriangles = FindAllDegeneratedTriangles(); 4773 Log() << Verbose(0) << "Final list of simply degenerated triangles found, containing " << SimplyDegeneratedTriangles->size() << " triangles:" << endl;5024 DoLog(0) && (Log() << Verbose(0) << "Final list of simply degenerated triangles found, containing " << SimplyDegeneratedTriangles->size() << " triangles:" << endl); 4774 5025 IndexToIndex::iterator it; 4775 5026 for (it = SimplyDegeneratedTriangles->begin(); it != SimplyDegeneratedTriangles->end(); it++) 4776 Log() << Verbose(0) << (*it).first << " => " << (*it).second << endl; 4777 delete(SimplyDegeneratedTriangles); 4778 5027 DoLog(0) && (Log() << Verbose(0) << (*it).first << " => " << (*it).second << endl); 5028 delete (SimplyDegeneratedTriangles); 4779 5029 /// 5. exit 4780 5030 UniquePolygonSet::iterator PolygonRunner; 4781 5031 while (!ListofDegeneratedPolygons.empty()) { 4782 5032 PolygonRunner = ListofDegeneratedPolygons.begin(); 4783 delete (*PolygonRunner);5033 delete (*PolygonRunner); 4784 5034 ListofDegeneratedPolygons.erase(PolygonRunner); 4785 5035 } 4786 5036 4787 5037 return counter; 4788 }; 5038 } 5039 ;
Note:
See TracChangeset
for help on using the changeset viewer.