Changeset b8d1aeb for src/tesselation.cpp
- Timestamp:
- Feb 2, 2010, 11:38:06 AM (16 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, Candidate_v1.7.0, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
- Children:
- 7ba324
- Parents:
- 9fe36b (diff), 2ededc2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 edited
-
src/tesselation.cpp (modified) (198 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/tesselation.cpp
r9fe36b rb8d1aeb 9 9 10 10 #include "helpers.hpp" 11 #include "info.hpp" 11 12 #include "linkedcell.hpp" 12 13 #include "log.hpp" … … 22 23 /** Constructor of BoundaryPointSet. 23 24 */ 24 BoundaryPointSet::BoundaryPointSet() 25 { 26 LinesCount = 0; 27 Nr = -1; 28 value = 0.; 25 BoundaryPointSet::BoundaryPointSet() : 26 LinesCount(0), 27 value(0.), 28 Nr(-1) 29 { 30 Info FunctionInfo(__func__); 31 Log() << Verbose(1) << "Adding noname." << endl; 29 32 }; 30 33 … … 32 35 * \param *Walker TesselPoint this boundary point represents 33 36 */ 34 BoundaryPointSet::BoundaryPointSet(TesselPoint * Walker) 35 { 36 node = Walker; 37 LinesCount = 0; 38 Nr = Walker->nr; 39 value = 0.; 37 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; 40 45 }; 41 46 … … 46 51 BoundaryPointSet::~BoundaryPointSet() 47 52 { 48 //Log() << Verbose(5) << "Erasing point nr. " << Nr << "." << endl; 53 Info FunctionInfo(__func__); 54 //Log() << Verbose(0) << "Erasing point nr. " << Nr << "." << endl; 49 55 if (!lines.empty()) 50 56 eLog() << Verbose(2) << "Memory Leak! I " << *this << " am still connected to some lines." << endl; … … 55 61 * \param *line line to add 56 62 */ 57 void BoundaryPointSet::AddLine(class BoundaryLineSet *line) 58 { 59 Log() << Verbose(6) << "Adding " << *this << " to line " << *line << "." 63 void BoundaryPointSet::AddLine(BoundaryLineSet * const line) 64 { 65 Info FunctionInfo(__func__); 66 Log() << Verbose(1) << "Adding " << *this << " to line " << *line << "." 60 67 << endl; 61 68 if (line->endpoints[0] == this) … … 85 92 /** Constructor of BoundaryLineSet. 86 93 */ 87 BoundaryLineSet::BoundaryLineSet() 88 { 94 BoundaryLineSet::BoundaryLineSet() : 95 Nr(-1) 96 { 97 Info FunctionInfo(__func__); 89 98 for (int i = 0; i < 2; i++) 90 99 endpoints[i] = NULL; 91 Nr = -1;92 100 }; 93 101 … … 97 105 * \param number number of the list 98 106 */ 99 BoundaryLineSet::BoundaryLineSet(class BoundaryPointSet *Point[2], const int number) 100 { 107 BoundaryLineSet::BoundaryLineSet(BoundaryPointSet * const Point[2], const int number) 108 { 109 Info FunctionInfo(__func__); 101 110 // set number 102 111 Nr = number; … … 106 115 Point[0]->AddLine(this); //Taken out, to check whether we can avoid unwanted double adding. 107 116 Point[1]->AddLine(this); // 117 // set skipped to false 118 skipped = false; 108 119 // clear triangles list 109 Log() << Verbose(5) << "New Line with endpoints " << *this << "." << endl; 120 Log() << Verbose(0) << "New Line with endpoints " << *this << "." << endl; 121 }; 122 123 /** Constructor of BoundaryLineSet with two endpoints. 124 * Adds line automatically to each endpoints' LineMap 125 * \param *Point1 first boundary point 126 * \param *Point2 second boundary point 127 * \param number number of the list 128 */ 129 BoundaryLineSet::BoundaryLineSet(BoundaryPointSet * const Point1, BoundaryPointSet * const Point2, const int number) 130 { 131 Info FunctionInfo(__func__); 132 // set number 133 Nr = number; 134 // set endpoints in ascending order 135 SetEndpointsOrdered(endpoints, Point1, Point2); 136 // add this line to the hash maps of both endpoints 137 Point1->AddLine(this); //Taken out, to check whether we can avoid unwanted double adding. 138 Point2->AddLine(this); // 139 // set skipped to false 140 skipped = false; 141 // clear triangles list 142 Log() << Verbose(0) << "New Line with endpoints " << *this << "." << endl; 110 143 }; 111 144 … … 116 149 BoundaryLineSet::~BoundaryLineSet() 117 150 { 151 Info FunctionInfo(__func__); 118 152 int Numbers[2]; 119 153 … … 134 168 for (LineMap::iterator Runner = erasor.first; Runner != erasor.second; Runner++) 135 169 if ((*Runner).second == this) { 136 //Log() << Verbose( 5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;170 //Log() << Verbose(0) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 137 171 endpoints[i]->lines.erase(Runner); 138 172 break; … … 140 174 } else { // there's just a single line left 141 175 if (endpoints[i]->lines.erase(Nr)) { 142 //Log() << Verbose( 5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;176 //Log() << Verbose(0) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 143 177 } 144 178 } 145 179 if (endpoints[i]->lines.empty()) { 146 //Log() << Verbose( 5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;180 //Log() << Verbose(0) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl; 147 181 if (endpoints[i] != NULL) { 148 182 delete(endpoints[i]); … … 159 193 * \param *triangle to add 160 194 */ 161 void BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle) 162 { 163 Log() << Verbose(6) << "Add " << triangle->Nr << " to line " << *this << "." << endl; 195 void BoundaryLineSet::AddTriangle(BoundaryTriangleSet * const triangle) 196 { 197 Info FunctionInfo(__func__); 198 Log() << Verbose(0) << "Add " << triangle->Nr << " to line " << *this << "." << endl; 164 199 triangles.insert(TrianglePair(triangle->Nr, triangle)); 165 200 }; … … 169 204 * \return true - common endpoint present, false - not connected 170 205 */ 171 bool BoundaryLineSet::IsConnectedTo(class BoundaryLineSet *line) 172 { 206 bool BoundaryLineSet::IsConnectedTo(const BoundaryLineSet * const line) const 207 { 208 Info FunctionInfo(__func__); 173 209 if ((endpoints[0] == line->endpoints[0]) || (endpoints[1] == line->endpoints[0]) || (endpoints[0] == line->endpoints[1]) || (endpoints[1] == line->endpoints[1])) 174 210 return true; … … 183 219 * \return true - triangles are convex, false - concave or less than two triangles connected 184 220 */ 185 bool BoundaryLineSet::CheckConvexityCriterion() 186 { 221 bool BoundaryLineSet::CheckConvexityCriterion() const 222 { 223 Info FunctionInfo(__func__); 187 224 Vector BaseLineCenter, BaseLineNormal, BaseLine, helper[2], NormalCheck; 188 225 // get the two triangles 189 226 if (triangles.size() != 2) { 190 eLog() << Verbose( 1) << "Baseline " << *this << " is connected to less than two triangles, Tesselation incomplete!" << endl;227 eLog() << Verbose(0) << "Baseline " << *this << " is connected to less than two triangles, Tesselation incomplete!" << endl; 191 228 return true; 192 229 } 193 230 // check normal vectors 194 231 // have a normal vector on the base line pointing outwards 195 //Log() << Verbose( 3) << "INFO: " << *this << " has vectors at " << *(endpoints[0]->node->node) << " and at " << *(endpoints[1]->node->node) << "." << endl;232 //Log() << Verbose(0) << "INFO: " << *this << " has vectors at " << *(endpoints[0]->node->node) << " and at " << *(endpoints[1]->node->node) << "." << endl; 196 233 BaseLineCenter.CopyVector(endpoints[0]->node->node); 197 234 BaseLineCenter.AddVector(endpoints[1]->node->node); … … 199 236 BaseLine.CopyVector(endpoints[0]->node->node); 200 237 BaseLine.SubtractVector(endpoints[1]->node->node); 201 //Log() << Verbose( 3) << "INFO: Baseline is " << BaseLine << " and its center is at " << BaseLineCenter << "." << endl;238 //Log() << Verbose(0) << "INFO: Baseline is " << BaseLine << " and its center is at " << BaseLineCenter << "." << endl; 202 239 203 240 BaseLineNormal.Zero(); … … 206 243 int i=0; 207 244 class BoundaryPointSet *node = NULL; 208 for(TriangleMap:: iterator runner = triangles.begin(); runner != triangles.end(); runner++) {209 //Log() << Verbose( 3) << "INFO: NormalVector of " << *(runner->second) << " is " << runner->second->NormalVector << "." << endl;245 for(TriangleMap::const_iterator runner = triangles.begin(); runner != triangles.end(); runner++) { 246 //Log() << Verbose(0) << "INFO: NormalVector of " << *(runner->second) << " is " << runner->second->NormalVector << "." << endl; 210 247 NormalCheck.AddVector(&runner->second->NormalVector); 211 248 NormalCheck.Scale(sign); … … 214 251 BaseLineNormal.CopyVector(&runner->second->NormalVector); // yes, copy second on top of first 215 252 else { 216 Log() << Verbose(1) << "CRITICAL: Triangle " << *runner->second << " has zero normal vector!" << endl; 217 exit(255); 253 eLog() << Verbose(0) << "Triangle " << *runner->second << " has zero normal vector!" << endl; 218 254 } 219 255 node = runner->second->GetThirdEndpoint(this); 220 256 if (node != NULL) { 221 //Log() << Verbose( 3) << "INFO: Third node for triangle " << *(runner->second) << " is " << *node << " at " << *(node->node->node) << "." << endl;257 //Log() << Verbose(0) << "INFO: Third node for triangle " << *(runner->second) << " is " << *node << " at " << *(node->node->node) << "." << endl; 222 258 helper[i].CopyVector(node->node->node); 223 259 helper[i].SubtractVector(&BaseLineCenter); 224 260 helper[i].MakeNormalVector(&BaseLine); // we want to compare the triangle's heights' angles! 225 //Log() << Verbose( 4) << "INFO: Height vector with respect to baseline is " << helper[i] << "." << endl;261 //Log() << Verbose(0) << "INFO: Height vector with respect to baseline is " << helper[i] << "." << endl; 226 262 i++; 227 263 } else { 228 //eLog() << Verbose(1) << "I cannot find third node in triangle, something's wrong." << endl;264 eLog() << Verbose(1) << "I cannot find third node in triangle, something's wrong." << endl; 229 265 return true; 230 266 } 231 267 } 232 //Log() << Verbose( 3) << "INFO: BaselineNormal is " << BaseLineNormal << "." << endl;268 //Log() << Verbose(0) << "INFO: BaselineNormal is " << BaseLineNormal << "." << endl; 233 269 if (NormalCheck.NormSquared() < MYEPSILON) { 234 Log() << Verbose( 3) << "ACCEPT: Normalvectors of both triangles are the same: convex." << endl;270 Log() << Verbose(0) << "ACCEPT: Normalvectors of both triangles are the same: convex." << endl; 235 271 return true; 236 272 } … … 238 274 double angle = GetAngle(helper[0], helper[1], BaseLineNormal); 239 275 if ((angle - M_PI) > -MYEPSILON) { 240 Log() << Verbose( 3) << "ACCEPT: Angle is greater than pi: convex." << endl;276 Log() << Verbose(0) << "ACCEPT: Angle is greater than pi: convex." << endl; 241 277 return true; 242 278 } else { 243 Log() << Verbose( 3) << "REJECT: Angle is less than pi: concave." << endl;279 Log() << Verbose(0) << "REJECT: Angle is less than pi: concave." << endl; 244 280 return false; 245 281 } … … 250 286 * \return true - point is of the line, false - is not 251 287 */ 252 bool BoundaryLineSet::ContainsBoundaryPoint(class BoundaryPointSet *point) 253 { 288 bool BoundaryLineSet::ContainsBoundaryPoint(const BoundaryPointSet * const point) const 289 { 290 Info FunctionInfo(__func__); 254 291 for(int i=0;i<2;i++) 255 292 if (point == endpoints[i]) … … 262 299 * \return NULL - if endpoint not contained in BoundaryLineSet, or pointer to BoundaryPointSet otherwise 263 300 */ 264 class BoundaryPointSet *BoundaryLineSet::GetOtherEndpoint(class BoundaryPointSet *point) 265 { 301 class BoundaryPointSet *BoundaryLineSet::GetOtherEndpoint(const BoundaryPointSet * const point) const 302 { 303 Info FunctionInfo(__func__); 266 304 if (endpoints[0] == point) 267 305 return endpoints[1]; … … 286 324 /** Constructor for BoundaryTriangleSet. 287 325 */ 288 BoundaryTriangleSet::BoundaryTriangleSet() 289 { 326 BoundaryTriangleSet::BoundaryTriangleSet() : 327 Nr(-1) 328 { 329 Info FunctionInfo(__func__); 290 330 for (int i = 0; i < 3; i++) 291 331 { … … 293 333 lines[i] = NULL; 294 334 } 295 Nr = -1;296 335 }; 297 336 … … 300 339 * \param number number of triangle 301 340 */ 302 BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet *line[3], int number) 303 { 341 BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet * const line[3], const int number) : 342 Nr(number) 343 { 344 Info FunctionInfo(__func__); 304 345 // set number 305 Nr = number;306 346 // set lines 307 Log() << Verbose(5) << "New triangle " << Nr << ":" << endl; 308 for (int i = 0; i < 3; i++) 309 { 310 lines[i] = line[i]; 311 lines[i]->AddTriangle(this); 312 } 347 for (int i = 0; i < 3; i++) { 348 lines[i] = line[i]; 349 lines[i]->AddTriangle(this); 350 } 313 351 // get ascending order of endpoints 314 map<int, class BoundaryPointSet *>OrderMap;352 PointMap OrderMap; 315 353 for (int i = 0; i < 3; i++) 316 354 // for all three lines 317 for (int j = 0; j < 2; j++) 318 { // for both endpoints 319 OrderMap.insert(pair<int, class BoundaryPointSet *> ( 320 line[i]->endpoints[j]->Nr, line[i]->endpoints[j])); 321 // and we don't care whether insertion fails 322 } 355 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])); 358 // and we don't care whether insertion fails 359 } 323 360 // set endpoints 324 361 int Counter = 0; 325 Log() << Verbose(6) << " with end points "; 326 for (map<int, class BoundaryPointSet *>::iterator runner = OrderMap.begin(); runner 327 != OrderMap.end(); runner++) 328 { 329 endpoints[Counter] = runner->second; 330 Log() << Verbose(0) << " " << *endpoints[Counter]; 331 Counter++; 332 } 333 if (Counter < 3) 334 { 335 eLog() << Verbose(0) << "ERROR! We have a triangle with only two distinct endpoints!" << endl; 336 performCriticalExit(); 337 } 338 Log() << Verbose(0) << "." << endl; 362 Log() << Verbose(0) << "New triangle " << Nr << " with end points: " << endl; 363 for (PointMap::iterator runner = OrderMap.begin(); runner != OrderMap.end(); runner++) { 364 endpoints[Counter] = runner->second; 365 Log() << Verbose(0) << " " << *endpoints[Counter] << endl; 366 Counter++; 367 } 368 if (Counter < 3) { 369 eLog() << Verbose(0) << "We have a triangle with only two distinct endpoints!" << endl; 370 performCriticalExit(); 371 } 339 372 }; 340 373 … … 345 378 BoundaryTriangleSet::~BoundaryTriangleSet() 346 379 { 380 Info FunctionInfo(__func__); 347 381 for (int i = 0; i < 3; i++) { 348 382 if (lines[i] != NULL) { 349 383 if (lines[i]->triangles.erase(Nr)) { 350 //Log() << Verbose( 5) << "Triangle Nr." << Nr << " erased in line " << *lines[i] << "." << endl;384 //Log() << Verbose(0) << "Triangle Nr." << Nr << " erased in line " << *lines[i] << "." << endl; 351 385 } 352 386 if (lines[i]->triangles.empty()) { 353 //Log() << Verbose( 5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;387 //Log() << Verbose(0) << *lines[i] << " is no more attached to any triangle, erasing." << endl; 354 388 delete (lines[i]); 355 389 lines[i] = NULL; … … 357 391 } 358 392 } 359 //Log() << Verbose( 5) << "Erasing triangle Nr." << Nr << " itself." << endl;393 //Log() << Verbose(0) << "Erasing triangle Nr." << Nr << " itself." << endl; 360 394 }; 361 395 … … 364 398 * \param &OtherVector direction vector to make normal vector unique. 365 399 */ 366 void BoundaryTriangleSet::GetNormalVector(Vector &OtherVector) 367 { 400 void BoundaryTriangleSet::GetNormalVector(const Vector &OtherVector) 401 { 402 Info FunctionInfo(__func__); 368 403 // get normal vector 369 404 NormalVector.MakeNormalVector(endpoints[0]->node->node, endpoints[1]->node->node, endpoints[2]->node->node); … … 372 407 if (NormalVector.ScalarProduct(&OtherVector) > 0.) 373 408 NormalVector.Scale(-1.); 374 }; 375 376 /** Finds the point on the triangle \a *BTS the line defined by \a *MolCenter and \a *x crosses through. 409 Log() << Verbose(1) << "Normal Vector is " << NormalVector << "." << endl; 410 }; 411 412 /** Finds the point on the triangle \a *BTS through which the line defined by \a *MolCenter and \a *x crosses. 377 413 * We call Vector::GetIntersectionWithPlane() to receive the intersection point with the plane 378 * Th is we test if it's really on the plane and whether it's inside the triangle on the plane or not.414 * Thus we test if it's really on the plane and whether it's inside the triangle on the plane or not. 379 415 * The latter is done as follows: We calculate the cross point of one of the triangle's baseline with the line 380 416 * given by the intersection and the third basepoint. Then, we check whether it's on the baseline (i.e. between … … 386 422 * \return true - \a *Intersection contains intersection on plane defined by triangle, false - zero vector if outside of triangle. 387 423 */ 388 bool BoundaryTriangleSet::GetIntersectionInsideTriangle(Vector *MolCenter, Vector *x, Vector *Intersection) 389 { 424 bool BoundaryTriangleSet::GetIntersectionInsideTriangle(const Vector * const MolCenter, const Vector * const x, Vector * const Intersection) const 425 { 426 Info FunctionInfo(__func__); 390 427 Vector CrossPoint; 391 428 Vector helper; 392 429 393 430 if (!Intersection->GetIntersectionWithPlane(&NormalVector, endpoints[0]->node->node, MolCenter, x)) { 394 Log() << Verbose(1) << "Alas! Intersection with plane failed - at least numerically - the intersection is not on the plane!" << endl;431 eLog() << Verbose(1) << "Alas! Intersection with plane failed - at least numerically - the intersection is not on the plane!" << endl; 395 432 return false; 396 433 } 397 434 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; 441 return true; 442 } else if (Intersection->DistanceSquared(endpoints[1]->node->node) < MYEPSILON) { 443 Log() << Verbose(1) << "Intersection coindices with second endpoint." << endl; 444 return true; 445 } else if (Intersection->DistanceSquared(endpoints[2]->node->node) < MYEPSILON) { 446 Log() << Verbose(1) << "Intersection coindices with third endpoint." << endl; 447 return true; 448 } 398 449 // Calculate cross point between one baseline and the line from the third endpoint to intersection 399 450 int i=0; … … 402 453 helper.CopyVector(endpoints[(i+1)%3]->node->node); 403 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; 458 if ((s < -MYEPSILON) || ((s-1.) > MYEPSILON)) { 459 Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << "outside of triangle." << endl; 460 i=4; 461 break; 462 } 463 i++; 404 464 } else 405 i++;406 if (i>2)407 465 break; 408 } while ( CrossPoint.NormSquared() < MYEPSILON);466 } while (i<3); 409 467 if (i==3) { 410 eLog() << Verbose(1) << "Could not find any cross points, something's utterly wrong here!" << endl; 411 exit(255); 412 } 413 CrossPoint.SubtractVector(endpoints[i%3]->node->node); // cross point was returned as absolute vector 414 415 // check whether intersection is inside or not by comparing length of intersection and length of cross point 416 if ((CrossPoint.NormSquared() - helper.NormSquared()) < MYEPSILON) { // inside 468 Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << " inside of triangle." << endl; 417 469 return true; 418 } else { // outside!419 Intersection->Zero();470 } else { 471 Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << " outside of triangle." << endl; 420 472 return false; 421 473 } 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 478 * Thus we test if it's really on the plane and whether it's inside the triangle on the plane or not. 479 * The latter is done as follows: We calculate the cross point of one of the triangle's baseline with the line 480 * given by the intersection and the third basepoint. Then, we check whether it's on the baseline (i.e. between 481 * the first two basepoints) or not. 482 * \param *x point 483 * \param *ClosestPoint desired closest point inside triangle to \a *x, is absolute vector 484 * \return Distance squared between \a *x and closest point inside triangle 485 */ 486 double BoundaryTriangleSet::GetClosestPointInsideTriangle(const Vector * const x, Vector * const ClosestPoint) const 487 { 488 Info FunctionInfo(__func__); 489 Vector Direction; 490 491 // 1. get intersection with plane 492 Log() << Verbose(1) << "INFO: Looking for closest point of triangle " << *this << " to " << *x << "." << endl; 493 GetCenter(&Direction); 494 if (!ClosestPoint->GetIntersectionWithPlane(&NormalVector, endpoints[0]->node->node, x, &Direction)) { 495 ClosestPoint->CopyVector(x); 496 } 497 498 // 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; 508 509 // Calculate cross point between one baseline and the desired point such that distance is shortest 510 double ShortestDistance = -1.; 511 bool InsideFlag = false; 512 Vector CrossDirection[3]; 513 Vector CrossPoint[3]; 514 Vector helper; 515 for (int i=0;i<3;i++) { 516 // 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); 519 // 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; 526 if ((s >= -MYEPSILON) && ((s-1.) <= MYEPSILON)) { 527 CrossPoint[i].AddVector(endpoints[i%3]->node->node); // make cross point absolute again 528 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); 530 if ((ShortestDistance < 0.) || (ShortestDistance > distance)) { 531 ShortestDistance = distance; 532 ClosestPoint->CopyVector(&CrossPoint[i]); 533 } 534 } else 535 CrossPoint[i].Zero(); 536 } 537 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 542 InsideFlag = false; 543 } 544 if (InsideFlag) { 545 ClosestPoint->CopyVector(&InPlane); 546 ShortestDistance = InPlane.DistanceSquared(x); 547 } else { // also check endnodes 548 for (int i=0;i<3;i++) { 549 const double distance = x->DistanceSquared(endpoints[i]->node->node); 550 if ((ShortestDistance < 0.) || (ShortestDistance > distance)) { 551 ShortestDistance = distance; 552 ClosestPoint->CopyVector(endpoints[i]->node->node); 553 } 554 } 555 } 556 Log() << Verbose(1) << "INFO: Closest Point is " << *ClosestPoint << " with shortest squared distance is " << ShortestDistance << "." << endl; 557 return ShortestDistance; 422 558 }; 423 559 … … 426 562 * \return true - line is of the triangle, false - is not 427 563 */ 428 bool BoundaryTriangleSet::ContainsBoundaryLine(class BoundaryLineSet *line) 429 { 564 bool BoundaryTriangleSet::ContainsBoundaryLine(const BoundaryLineSet * const line) const 565 { 566 Info FunctionInfo(__func__); 430 567 for(int i=0;i<3;i++) 431 568 if (line == lines[i]) … … 438 575 * \return true - point is of the triangle, false - is not 439 576 */ 440 bool BoundaryTriangleSet::ContainsBoundaryPoint(class BoundaryPointSet *point) 441 { 577 bool BoundaryTriangleSet::ContainsBoundaryPoint(const BoundaryPointSet * const point) const 578 { 579 Info FunctionInfo(__func__); 442 580 for(int i=0;i<3;i++) 443 581 if (point == endpoints[i]) … … 450 588 * \return true - point is of the triangle, false - is not 451 589 */ 452 bool BoundaryTriangleSet::ContainsBoundaryPoint(class TesselPoint *point) 453 { 590 bool BoundaryTriangleSet::ContainsBoundaryPoint(const TesselPoint * const point) const 591 { 592 Info FunctionInfo(__func__); 454 593 for(int i=0;i<3;i++) 455 594 if (point == endpoints[i]->node) … … 462 601 * \return true - is the very triangle, false - is not 463 602 */ 464 bool BoundaryTriangleSet::IsPresentTupel(class BoundaryPointSet *Points[3]) 465 { 603 bool BoundaryTriangleSet::IsPresentTupel(const BoundaryPointSet * const Points[3]) const 604 { 605 Info FunctionInfo(__func__); 606 Log() << Verbose(1) << "INFO: Checking " << Points[0] << "," << Points[1] << "," << Points[2] << " against " << endpoints[0] << "," << endpoints[1] << "," << endpoints[2] << "." << endl; 466 607 return (((endpoints[0] == Points[0]) 467 608 || (endpoints[0] == Points[1]) … … 483 624 * \return true - is the very triangle, false - is not 484 625 */ 485 bool BoundaryTriangleSet::IsPresentTupel(class BoundaryTriangleSet *T) 486 { 626 bool BoundaryTriangleSet::IsPresentTupel(const BoundaryTriangleSet * const T) const 627 { 628 Info FunctionInfo(__func__); 487 629 return (((endpoints[0] == T->endpoints[0]) 488 630 || (endpoints[0] == T->endpoints[1]) … … 504 646 * \return pointer third endpoint or NULL if line does not belong to triangle. 505 647 */ 506 class BoundaryPointSet *BoundaryTriangleSet::GetThirdEndpoint(class BoundaryLineSet *line) 507 { 648 class BoundaryPointSet *BoundaryTriangleSet::GetThirdEndpoint(const BoundaryLineSet * const line) const 649 { 650 Info FunctionInfo(__func__); 508 651 // sanity check 509 652 if (!ContainsBoundaryLine(line)) … … 520 663 * \param *center central point on return. 521 664 */ 522 void BoundaryTriangleSet::GetCenter(Vector *center) 523 { 665 void BoundaryTriangleSet::GetCenter(Vector * const center) const 666 { 667 Info FunctionInfo(__func__); 524 668 center->Zero(); 525 669 for(int i=0;i<3;i++) 526 670 center->AddVector(endpoints[i]->node->node); 527 671 center->Scale(1./3.); 672 Log() << Verbose(1) << "INFO: Center is at " << *center << "." << endl; 528 673 } 529 674 … … 534 679 ostream &operator <<(ostream &ost, const BoundaryTriangleSet &a) 535 680 { 536 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << "," 537 << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "," << a.endpoints[2]->node->Name << " at " << *a.endpoints[2]->node->node << "]"; 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 << "]"; 538 684 return ost; 539 685 }; 540 686 687 // ======================================== Polygons on Boundary ================================= 688 689 /** Constructor for BoundaryPolygonSet. 690 */ 691 BoundaryPolygonSet::BoundaryPolygonSet() : 692 Nr(-1) 693 { 694 Info FunctionInfo(__func__); 695 }; 696 697 /** Destructor of BoundaryPolygonSet. 698 * Just clears endpoints. 699 * \note When removing triangles from a class Tesselation, use RemoveTesselationTriangle() 700 */ 701 BoundaryPolygonSet::~BoundaryPolygonSet() 702 { 703 Info FunctionInfo(__func__); 704 endpoints.clear(); 705 Log() << Verbose(1) << "Erasing polygon Nr." << Nr << " itself." << endl; 706 }; 707 708 /** Calculates the normal vector for this triangle. 709 * Is made unique by comparison with \a OtherVector to point in the other direction. 710 * \param &OtherVector direction vector to make normal vector unique. 711 * \return allocated vector in normal direction 712 */ 713 Vector * BoundaryPolygonSet::GetNormalVector(const Vector &OtherVector) const 714 { 715 Info FunctionInfo(__func__); 716 // get normal vector 717 Vector TemporaryNormal; 718 Vector *TotalNormal = new Vector; 719 PointSet::const_iterator Runner[3]; 720 for (int i=0;i<3; i++) { 721 Runner[i] = endpoints.begin(); 722 for (int j = 0; j<i; j++) { // go as much further 723 Runner[i]++; 724 if (Runner[i] == endpoints.end()) { 725 eLog() << Verbose(0) << "There are less than three endpoints in the polygon!" << endl; 726 performCriticalExit(); 727 } 728 } 729 } 730 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 735 Runner[i]++; 736 TotalNormal->AddVector(&TemporaryNormal); 737 } 738 TotalNormal->Scale(1./(double)counter); 739 740 // make it always point inward (any offset vector onto plane projected onto normal vector suffices) 741 if (TotalNormal->ScalarProduct(&OtherVector) > 0.) 742 TotalNormal->Scale(-1.); 743 Log() << Verbose(1) << "Normal Vector is " << *TotalNormal << "." << endl; 744 745 return TotalNormal; 746 }; 747 748 /** Calculates the center point of the triangle. 749 * Is third of the sum of all endpoints. 750 * \param *center central point on return. 751 */ 752 void BoundaryPolygonSet::GetCenter(Vector * const center) const 753 { 754 Info FunctionInfo(__func__); 755 center->Zero(); 756 int counter = 0; 757 for(PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) { 758 center->AddVector((*Runner)->node->node); 759 counter++; 760 } 761 center->Scale(1./(double)counter); 762 Log() << Verbose(1) << "Center is at " << *center << "." << endl; 763 } 764 765 /** Checks whether the polygons contains all three endpoints of the triangle. 766 * \param *triangle triangle to test 767 * \return true - triangle is contained polygon, false - is not 768 */ 769 bool BoundaryPolygonSet::ContainsBoundaryTriangle(const BoundaryTriangleSet * const triangle) const 770 { 771 Info FunctionInfo(__func__); 772 return ContainsPresentTupel(triangle->endpoints, 3); 773 }; 774 775 /** Checks whether the polygons contains both endpoints of the line. 776 * \param *line line to test 777 * \return true - line is of the triangle, false - is not 778 */ 779 bool BoundaryPolygonSet::ContainsBoundaryLine(const BoundaryLineSet * const line) const 780 { 781 Info FunctionInfo(__func__); 782 return ContainsPresentTupel(line->endpoints, 2); 783 }; 784 785 /** Checks whether point is any of the three endpoints this triangle contains. 786 * \param *point point to test 787 * \return true - point is of the triangle, false - is not 788 */ 789 bool BoundaryPolygonSet::ContainsBoundaryPoint(const BoundaryPointSet * const point) const 790 { 791 Info FunctionInfo(__func__); 792 for(PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) { 793 Log() << Verbose(0) << "Checking against " << **Runner << endl; 794 if (point == (*Runner)) { 795 Log() << Verbose(0) << " Contained." << endl; 796 return true; 797 } 798 } 799 Log() << Verbose(0) << " Not contained." << endl; 800 return false; 801 }; 802 803 /** Checks whether point is any of the three endpoints this triangle contains. 804 * \param *point TesselPoint to test 805 * \return true - point is of the triangle, false - is not 806 */ 807 bool BoundaryPolygonSet::ContainsBoundaryPoint(const TesselPoint * const point) const 808 { 809 Info FunctionInfo(__func__); 810 for(PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) 811 if (point == (*Runner)->node) { 812 Log() << Verbose(0) << " Contained." << endl; 813 return true; 814 } 815 Log() << Verbose(0) << " Not contained." << endl; 816 return false; 817 }; 818 819 /** Checks whether given array of \a *Points coincide with polygons's endpoints. 820 * \param **Points pointer to an array of BoundaryPointSet 821 * \param dim dimension of array 822 * \return true - set of points is contained in polygon, false - is not 823 */ 824 bool BoundaryPolygonSet::ContainsPresentTupel(const BoundaryPointSet * const * Points, const int dim) const 825 { 826 Info FunctionInfo(__func__); 827 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; 831 if (ContainsBoundaryPoint(Points[i])) { 832 counter++; 833 } 834 } 835 836 if (counter == dim) 837 return true; 838 else 839 return false; 840 }; 841 842 /** Checks whether given PointList coincide with polygons's endpoints. 843 * \param &endpoints PointList 844 * \return true - set of points is contained in polygon, false - is not 845 */ 846 bool BoundaryPolygonSet::ContainsPresentTupel(const PointSet &endpoints) const 847 { 848 Info FunctionInfo(__func__); 849 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; 853 if (ContainsBoundaryPoint(*Runner)) 854 counter++; 855 } 856 857 if (counter == endpoints.size()) 858 return true; 859 else 860 return false; 861 }; 862 863 /** Checks whether given set of \a *Points coincide with polygons's endpoints. 864 * \param *P pointer to BoundaryPolygonSet 865 * \return true - is the very triangle, false - is not 866 */ 867 bool BoundaryPolygonSet::ContainsPresentTupel(const BoundaryPolygonSet * const P) const 868 { 869 return ContainsPresentTupel((const PointSet)P->endpoints); 870 }; 871 872 /** Gathers all the endpoints' triangles in a unique set. 873 * \return set of all triangles 874 */ 875 TriangleSet * BoundaryPolygonSet::GetAllContainedTrianglesFromEndpoints() const 876 { 877 Info FunctionInfo(__func__); 878 pair <TriangleSet::iterator, bool> Tester; 879 TriangleSet *triangles = new TriangleSet; 880 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++) { 884 //Log() << Verbose(0) << " Testing triangle " << *(Sprinter->second) << endl; 885 if (ContainsBoundaryTriangle(Sprinter->second)) { 886 Tester = triangles->insert(Sprinter->second); 887 if (Tester.second) 888 Log() << Verbose(0) << "Adding triangle " << *(Sprinter->second) << endl; 889 } 890 } 891 892 Log() << Verbose(1) << "The Polygon of " << endpoints.size() << " endpoints has " << triangles->size() << " unique triangles in total." << endl; 893 return triangles; 894 }; 895 896 /** Fills the endpoints of this polygon from the triangles attached to \a *line. 897 * \param *line lines with triangles attached 898 * \return true - polygon contains endpoints, false - line was NULL 899 */ 900 bool BoundaryPolygonSet::FillPolygonFromTrianglesOfLine(const BoundaryLineSet * const line) 901 { 902 Info FunctionInfo(__func__); 903 pair <PointSet::iterator, bool> Tester; 904 if (line == NULL) 905 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++) { 909 Tester = endpoints.insert((Runner->second)->endpoints[i]); 910 if (Tester.second) 911 Log() << Verbose(1) << " Inserting endpoint " << *((Runner->second)->endpoints[i]) << endl; 912 } 913 } 914 915 return true; 916 }; 917 918 /** output operator for BoundaryPolygonSet. 919 * \param &ost output stream 920 * \param &a boundary polygon 921 */ 922 ostream &operator <<(ostream &ost, const BoundaryPolygonSet &a) 923 { 924 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<< "]"; 932 return ost; 933 }; 934 541 935 // =========================================================== class TESSELPOINT =========================================== 542 936 … … 545 939 TesselPoint::TesselPoint() 546 940 { 941 //Info FunctionInfo(__func__); 547 942 node = NULL; 548 943 nr = -1; … … 554 949 TesselPoint::~TesselPoint() 555 950 { 951 //Info FunctionInfo(__func__); 556 952 }; 557 953 … … 568 964 ostream & TesselPoint::operator << (ostream &ost) 569 965 { 570 ost << "[" << (Name) << "|" << this << "]"; 966 Info FunctionInfo(__func__); 967 ost << "[" << (nr) << "|" << this << "]"; 571 968 return ost; 572 969 }; … … 579 976 PointCloud::PointCloud() 580 977 { 581 978 //Info FunctionInfo(__func__); 582 979 }; 583 980 … … 586 983 PointCloud::~PointCloud() 587 984 { 588 985 //Info FunctionInfo(__func__); 589 986 }; 590 987 … … 593 990 /** Constructor of class CandidateForTesselation. 594 991 */ 595 CandidateForTesselation::CandidateForTesselation(TesselPoint *candidate, BoundaryLineSet* line, Vector OptCandidateCenter, Vector OtherOptCandidateCenter) { 596 point = candidate; 597 BaseLine = line; 992 CandidateForTesselation::CandidateForTesselation (BoundaryLineSet* line) : 993 BaseLine(line), 994 ShortestAngle(2.*M_PI), 995 OtherShortestAngle(2.*M_PI) 996 { 997 Info FunctionInfo(__func__); 998 }; 999 1000 1001 /** Constructor of class CandidateForTesselation. 1002 */ 1003 CandidateForTesselation::CandidateForTesselation (TesselPoint *candidate, BoundaryLineSet* line, Vector OptCandidateCenter, Vector OtherOptCandidateCenter) : 1004 BaseLine(line), 1005 ShortestAngle(2.*M_PI), 1006 OtherShortestAngle(2.*M_PI) 1007 { 1008 Info FunctionInfo(__func__); 598 1009 OptCenter.CopyVector(&OptCandidateCenter); 599 1010 OtherOptCenter.CopyVector(&OtherOptCandidateCenter); … … 603 1014 */ 604 1015 CandidateForTesselation::~CandidateForTesselation() { 605 point = NULL;606 1016 BaseLine = NULL; 607 1017 }; 608 1018 1019 /** output operator for CandidateForTesselation. 1020 * \param &ost output stream 1021 * \param &a boundary line 1022 */ 1023 ostream & operator <<(ostream &ost, const CandidateForTesselation &a) 1024 { 1025 ost << "[" << a.BaseLine->Nr << "|" << a.BaseLine->endpoints[0]->node->Name << "," << a.BaseLine->endpoints[1]->node->Name << "] with "; 1026 if (a.pointlist.empty()) 1027 ost << "no candidate."; 1028 else { 1029 ost << "candidate"; 1030 if (a.pointlist.size() != 1) 1031 ost << "s "; 1032 else 1033 ost << " "; 1034 for (TesselPointList::const_iterator Runner = a.pointlist.begin(); Runner != a.pointlist.end(); Runner++) 1035 ost << *(*Runner) << " "; 1036 ost << " at angle " << (a.ShortestAngle)<< "."; 1037 } 1038 1039 return ost; 1040 }; 1041 1042 609 1043 // =========================================================== class TESSELATION =========================================== 610 1044 611 1045 /** Constructor of class Tesselation. 612 1046 */ 613 Tesselation::Tesselation() 614 { 615 PointsOnBoundaryCount = 0; 616 LinesOnBoundaryCount = 0; 617 TrianglesOnBoundaryCount = 0; 618 InternalPointer = PointsOnBoundary.begin(); 619 LastTriangle = NULL; 620 TriangleFilesWritten = 0; 1047 Tesselation::Tesselation() : 1048 PointsOnBoundaryCount(0), 1049 LinesOnBoundaryCount(0), 1050 TrianglesOnBoundaryCount(0), 1051 LastTriangle(NULL), 1052 TriangleFilesWritten(0), 1053 InternalPointer(PointsOnBoundary.begin()) 1054 { 1055 Info FunctionInfo(__func__); 621 1056 } 622 1057 ; … … 627 1062 Tesselation::~Tesselation() 628 1063 { 629 Log() << Verbose(1) << "Free'ing TesselStruct ... " << endl; 1064 Info FunctionInfo(__func__); 1065 Log() << Verbose(0) << "Free'ing TesselStruct ... " << endl; 630 1066 for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) { 631 1067 if (runner->second != NULL) { … … 635 1071 eLog() << Verbose(1) << "The triangle " << runner->first << " has already been free'd." << endl; 636 1072 } 637 Log() << Verbose( 1) << "This envelope was written to file " << TriangleFilesWritten << " times(s)." << endl;1073 Log() << Verbose(0) << "This envelope was written to file " << TriangleFilesWritten << " times(s)." << endl; 638 1074 } 639 1075 ; … … 644 1080 Vector * Tesselation::GetCenter(ofstream *out) const 645 1081 { 1082 Info FunctionInfo(__func__); 646 1083 Vector *Center = new Vector(0.,0.,0.); 647 1084 int num=0; … … 659 1096 TesselPoint * Tesselation::GetPoint() const 660 1097 { 1098 Info FunctionInfo(__func__); 661 1099 return (InternalPointer->second->node); 662 1100 }; … … 667 1105 TesselPoint * Tesselation::GetTerminalPoint() const 668 1106 { 1107 Info FunctionInfo(__func__); 669 1108 PointMap::const_iterator Runner = PointsOnBoundary.end(); 670 1109 Runner--; … … 677 1116 void Tesselation::GoToNext() const 678 1117 { 1118 Info FunctionInfo(__func__); 679 1119 if (InternalPointer != PointsOnBoundary.end()) 680 1120 InternalPointer++; … … 686 1126 void Tesselation::GoToPrevious() const 687 1127 { 1128 Info FunctionInfo(__func__); 688 1129 if (InternalPointer != PointsOnBoundary.begin()) 689 1130 InternalPointer--; … … 695 1136 void Tesselation::GoToFirst() const 696 1137 { 1138 Info FunctionInfo(__func__); 697 1139 InternalPointer = PointsOnBoundary.begin(); 698 1140 }; … … 703 1145 void Tesselation::GoToLast() const 704 1146 { 1147 Info FunctionInfo(__func__); 705 1148 InternalPointer = PointsOnBoundary.end(); 706 1149 InternalPointer--; … … 712 1155 bool Tesselation::IsEmpty() const 713 1156 { 1157 Info FunctionInfo(__func__); 714 1158 return (PointsOnBoundary.empty()); 715 1159 }; … … 720 1164 bool Tesselation::IsEnd() const 721 1165 { 1166 Info FunctionInfo(__func__); 722 1167 return (InternalPointer == PointsOnBoundary.end()); 723 1168 }; … … 729 1174 * \param PointsOnBoundary set of boundary points defining the convex envelope of the cluster 730 1175 */ 731 void 732 Tesselation::GuessStartingTriangle() 733 { 1176 void Tesselation::GuessStartingTriangle() 1177 { 1178 Info FunctionInfo(__func__); 734 1179 // 4b. create a starting triangle 735 1180 // 4b1. create all distances … … 778 1223 baseline->second.first->second->node->node, 779 1224 baseline->second.second->second->node->node); 780 Log() << Verbose(2) << "Plane vector of candidate triangle is "; 781 PlaneVector.Output(); 782 Log() << Verbose(0) << endl; 1225 Log() << Verbose(2) << "Plane vector of candidate triangle is " << PlaneVector << endl; 783 1226 // 4. loop over all points 784 1227 double sign = 0.; … … 796 1239 if (fabs(distance) < 1e-4) // we need to have a small epsilon around 0 which is still ok 797 1240 continue; 798 Log() << Verbose(3) << "Projection of " << checker->second->node->Name 799 << " yields distance of " << distance << "." << endl; 1241 Log() << Verbose(2) << "Projection of " << checker->second->node->Name << " yields distance of " << distance << "." << endl; 800 1242 tmp = distance / fabs(distance); 801 1243 // 4b. Any have different sign to than before? (i.e. would lie outside convex hull with this starting triangle) … … 850 1292 if (checker == PointsOnBoundary.end()) 851 1293 { 852 Log() << Verbose( 0) << "Looks like we have a candidate!" << endl;1294 Log() << Verbose(2) << "Looks like we have a candidate!" << endl; 853 1295 break; 854 1296 } … … 880 1322 else 881 1323 { 882 Log() << Verbose(1) << "No starting triangle found." << endl; 883 exit(255); 1324 eLog() << Verbose(0) << "No starting triangle found." << endl; 884 1325 } 885 1326 } … … 901 1342 void Tesselation::TesselateOnBoundary(const PointCloud * const cloud) 902 1343 { 1344 Info FunctionInfo(__func__); 903 1345 bool flag; 904 1346 PointMap::iterator winner; … … 919 1361 // get peak point with respect to this base line's only triangle 920 1362 BTS = baseline->second->triangles.begin()->second; // there is only one triangle so far 921 Log() << Verbose( 2) << "Current baseline is between " << *(baseline->second) << "." << endl;1363 Log() << Verbose(0) << "Current baseline is between " << *(baseline->second) << "." << endl; 922 1364 for (int i = 0; i < 3; i++) 923 1365 if ((BTS->endpoints[i] != baseline->second->endpoints[0]) && (BTS->endpoints[i] != baseline->second->endpoints[1])) 924 1366 peak = BTS->endpoints[i]; 925 Log() << Verbose( 3) << " and has peak " << *peak << "." << endl;1367 Log() << Verbose(1) << " and has peak " << *peak << "." << endl; 926 1368 927 1369 // prepare some auxiliary vectors … … 938 1380 CenterVector.AddVector(BTS->endpoints[i]->node->node); 939 1381 CenterVector.Scale(1. / 3.); 940 Log() << Verbose( 4) << "CenterVector of base triangle is " << CenterVector << endl;1382 Log() << Verbose(2) << "CenterVector of base triangle is " << CenterVector << endl; 941 1383 942 1384 // normal vector of triangle … … 945 1387 BTS->GetNormalVector(NormalVector); 946 1388 NormalVector.CopyVector(&BTS->NormalVector); 947 Log() << Verbose( 4) << "NormalVector of base triangle is " << NormalVector << endl;1389 Log() << Verbose(2) << "NormalVector of base triangle is " << NormalVector << endl; 948 1390 949 1391 // vector in propagation direction (out of triangle) … … 952 1394 TempVector.CopyVector(&CenterVector); 953 1395 TempVector.SubtractVector(baseline->second->endpoints[0]->node->node); // TempVector is vector on triangle plane pointing from one baseline egde towards center! 954 //Log() << Verbose( 2) << "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << "." << endl;1396 //Log() << Verbose(0) << "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << "." << endl; 955 1397 if (PropagationVector.ScalarProduct(&TempVector) > 0) // make sure normal propagation vector points outward from baseline 956 1398 PropagationVector.Scale(-1.); 957 Log() << Verbose( 4) << "PropagationVector of base triangle is " << PropagationVector << endl;1399 Log() << Verbose(2) << "PropagationVector of base triangle is " << PropagationVector << endl; 958 1400 winner = PointsOnBoundary.end(); 959 1401 … … 961 1403 for (PointMap::iterator target = PointsOnBoundary.begin(); target != PointsOnBoundary.end(); target++) { 962 1404 if ((target->second != baseline->second->endpoints[0]) && (target->second != baseline->second->endpoints[1])) { // don't take the same endpoints 963 Log() << Verbose( 3) << "Target point is " << *(target->second) << ":" << endl;1405 Log() << Verbose(1) << "Target point is " << *(target->second) << ":" << endl; 964 1406 965 1407 // first check direction, so that triangles don't intersect … … 968 1410 VirtualNormalVector.ProjectOntoPlane(&NormalVector); 969 1411 TempAngle = VirtualNormalVector.Angle(&PropagationVector); 970 Log() << Verbose( 4) << "VirtualNormalVector is " << VirtualNormalVector << " and PropagationVector is " << PropagationVector << "." << endl;1412 Log() << Verbose(2) << "VirtualNormalVector is " << VirtualNormalVector << " and PropagationVector is " << PropagationVector << "." << endl; 971 1413 if (TempAngle > (M_PI/2.)) { // no bends bigger than Pi/2 (90 degrees) 972 Log() << Verbose( 4) << "Angle on triangle plane between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", bad direction!" << endl;1414 Log() << Verbose(2) << "Angle on triangle plane between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", bad direction!" << endl; 973 1415 continue; 974 1416 } else 975 Log() << Verbose( 4) << "Angle on triangle plane between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", good direction!" << endl;1417 Log() << Verbose(2) << "Angle on triangle plane between propagation direction and base line to " << *(target->second) << " is " << TempAngle << ", good direction!" << endl; 976 1418 977 1419 // check first and second endpoint (if any connecting line goes to target has at least not more than 1 triangle) … … 979 1421 LineChecker[1] = baseline->second->endpoints[1]->lines.find(target->first); 980 1422 if (((LineChecker[0] != baseline->second->endpoints[0]->lines.end()) && (LineChecker[0]->second->triangles.size() == 2))) { 981 Log() << Verbose( 4) << *(baseline->second->endpoints[0]) << " has line " << *(LineChecker[0]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[0]->second->triangles.size() << " triangles." << endl;1423 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; 982 1424 continue; 983 1425 } 984 1426 if (((LineChecker[1] != baseline->second->endpoints[1]->lines.end()) && (LineChecker[1]->second->triangles.size() == 2))) { 985 Log() << Verbose( 4) << *(baseline->second->endpoints[1]) << " has line " << *(LineChecker[1]->second) << " to " << *(target->second) << " as endpoint with " << LineChecker[1]->second->triangles.size() << " triangles." << endl;1427 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; 986 1428 continue; 987 1429 } … … 1000 1442 helper.ProjectOntoPlane(&TempVector); 1001 1443 if (fabs(helper.NormSquared()) < MYEPSILON) { 1002 Log() << Verbose( 4) << "Chosen set of vectors is linear dependent." << endl;1444 Log() << Verbose(2) << "Chosen set of vectors is linear dependent." << endl; 1003 1445 continue; 1004 1446 } … … 1017 1459 // calculate angle 1018 1460 TempAngle = NormalVector.Angle(&VirtualNormalVector); 1019 Log() << Verbose( 4) << "NormalVector is " << VirtualNormalVector << " and the angle is " << TempAngle << "." << endl;1461 Log() << Verbose(2) << "NormalVector is " << VirtualNormalVector << " and the angle is " << TempAngle << "." << endl; 1020 1462 if ((SmallestAngle - TempAngle) > MYEPSILON) { // set to new possible winner 1021 1463 SmallestAngle = TempAngle; 1022 1464 winner = target; 1023 Log() << Verbose( 4) << "New winner " << *winner->second->node << " due to smaller angle between normal vectors." << endl;1465 Log() << Verbose(2) << "New winner " << *winner->second->node << " due to smaller angle between normal vectors." << endl; 1024 1466 } else if (fabs(SmallestAngle - TempAngle) < MYEPSILON) { // check the angle to propagation, both possible targets are in one plane! (their normals have same angle) 1025 1467 // hence, check the angles to some normal direction from our base line but in this common plane of both targets... … … 1039 1481 SmallestAngle = TempAngle; 1040 1482 winner = target; 1041 Log() << Verbose( 4) << "New winner " << *winner->second->node << " due to smaller angle " << TempAngle << " to propagation direction." << endl;1483 Log() << Verbose(2) << "New winner " << *winner->second->node << " due to smaller angle " << TempAngle << " to propagation direction." << endl; 1042 1484 } else 1043 Log() << Verbose( 4) << "Keeping old winner " << *winner->second->node << " due to smaller angle to propagation direction." << endl;1485 Log() << Verbose(2) << "Keeping old winner " << *winner->second->node << " due to smaller angle to propagation direction." << endl; 1044 1486 } else 1045 Log() << Verbose( 4) << "Keeping old winner " << *winner->second->node << " due to smaller angle between normal vectors." << endl;1487 Log() << Verbose(2) << "Keeping old winner " << *winner->second->node << " due to smaller angle between normal vectors." << endl; 1046 1488 } 1047 1489 } // end of loop over all boundary points … … 1049 1491 // 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 1050 1492 if (winner != PointsOnBoundary.end()) { 1051 Log() << Verbose( 2) << "Winning target point is " << *(winner->second) << " with angle " << SmallestAngle << "." << endl;1493 Log() << Verbose(0) << "Winning target point is " << *(winner->second) << " with angle " << SmallestAngle << "." << endl; 1052 1494 // create the lins of not yet present 1053 1495 BLS[0] = baseline->second; … … 1079 1521 TrianglesOnBoundaryCount++; 1080 1522 } else { 1081 Log() << Verbose(1) << "I could not determine a winner for this baseline " << *(baseline->second) << "." << endl;1523 eLog() << Verbose(2) << "I could not determine a winner for this baseline " << *(baseline->second) << "." << endl; 1082 1524 } 1083 1525 1084 1526 // 5d. If the set of lines is not yet empty, go to 5. and continue 1085 1527 } else 1086 Log() << Verbose( 2) << "Baseline candidate " << *(baseline->second) << " has a triangle count of " << baseline->second->triangles.size() << "." << endl;1528 Log() << Verbose(0) << "Baseline candidate " << *(baseline->second) << " has a triangle count of " << baseline->second->triangles.size() << "." << endl; 1087 1529 } while (flag); 1088 1530 … … 1099 1541 bool Tesselation::InsertStraddlingPoints(const PointCloud *cloud, const LinkedCell *LC) 1100 1542 { 1543 Info FunctionInfo(__func__); 1101 1544 Vector Intersection, Normal; 1102 1545 TesselPoint *Walker = NULL; 1103 1546 Vector *Center = cloud->GetCenter(); 1104 list<BoundaryTriangleSet*>*triangles = NULL;1547 TriangleList *triangles = NULL; 1105 1548 bool AddFlag = false; 1106 1549 LinkedCell *BoundaryPoints = NULL; 1107 1108 Log() << Verbose(1) << "Begin of InsertStraddlingPoints" << endl;1109 1550 1110 1551 cloud->GoToFirst(); … … 1117 1558 } 1118 1559 Walker = cloud->GetPoint(); 1119 Log() << Verbose( 2) << "Current point is " << *Walker << "." << endl;1560 Log() << Verbose(0) << "Current point is " << *Walker << "." << endl; 1120 1561 // get the next triangle 1121 triangles = FindClosestTrianglesTo Point(Walker->node, BoundaryPoints);1562 triangles = FindClosestTrianglesToVector(Walker->node, BoundaryPoints); 1122 1563 BTS = triangles->front(); 1123 1564 if ((triangles == NULL) || (BTS->ContainsBoundaryPoint(Walker))) { 1124 Log() << Verbose( 2) << "No triangles found, probably a tesselation point itself." << endl;1565 Log() << Verbose(0) << "No triangles found, probably a tesselation point itself." << endl; 1125 1566 cloud->GoToNext(); 1126 1567 continue; 1127 1568 } else { 1128 1569 } 1129 Log() << Verbose( 2) << "Closest triangle is " << *BTS << "." << endl;1570 Log() << Verbose(0) << "Closest triangle is " << *BTS << "." << endl; 1130 1571 // get the intersection point 1131 1572 if (BTS->GetIntersectionInsideTriangle(Center, Walker->node, &Intersection)) { 1132 Log() << Verbose( 2) << "We have an intersection at " << Intersection << "." << endl;1573 Log() << Verbose(0) << "We have an intersection at " << Intersection << "." << endl; 1133 1574 // we have the intersection, check whether in- or outside of boundary 1134 1575 if ((Center->DistanceSquared(Walker->node) - Center->DistanceSquared(&Intersection)) < -MYEPSILON) { 1135 1576 // inside, next! 1136 Log() << Verbose( 2) << *Walker << " is inside wrt triangle " << *BTS << "." << endl;1577 Log() << Verbose(0) << *Walker << " is inside wrt triangle " << *BTS << "." << endl; 1137 1578 } else { 1138 1579 // outside! 1139 Log() << Verbose( 2) << *Walker << " is outside wrt triangle " << *BTS << "." << endl;1580 Log() << Verbose(0) << *Walker << " is outside wrt triangle " << *BTS << "." << endl; 1140 1581 class BoundaryLineSet *OldLines[3], *NewLines[3]; 1141 1582 class BoundaryPointSet *OldPoints[3], *NewPoint; … … 1147 1588 Normal.CopyVector(&BTS->NormalVector); 1148 1589 // add Walker to boundary points 1149 Log() << Verbose( 2) << "Adding " << *Walker << " to BoundaryPoints." << endl;1590 Log() << Verbose(0) << "Adding " << *Walker << " to BoundaryPoints." << endl; 1150 1591 AddFlag = true; 1151 1592 if (AddBoundaryPoint(Walker,0)) … … 1154 1595 continue; 1155 1596 // remove triangle 1156 Log() << Verbose( 2) << "Erasing triangle " << *BTS << "." << endl;1597 Log() << Verbose(0) << "Erasing triangle " << *BTS << "." << endl; 1157 1598 TrianglesOnBoundary.erase(BTS->Nr); 1158 1599 delete(BTS); … … 1162 1603 BPS[1] = OldPoints[i]; 1163 1604 NewLines[i] = new class BoundaryLineSet(BPS, LinesOnBoundaryCount); 1164 Log() << Verbose( 3) << "Creating new line " << *NewLines[i] << "." << endl;1605 Log() << Verbose(1) << "Creating new line " << *NewLines[i] << "." << endl; 1165 1606 LinesOnBoundary.insert(LinePair(LinesOnBoundaryCount, NewLines[i])); // no need for check for unique insertion as BPS[0] is definitely a new one 1166 1607 LinesOnBoundaryCount++; … … 1173 1614 if (NewLines[j]->IsConnectedTo(BLS[0])) { 1174 1615 if (n>2) { 1175 Log() << Verbose(1) << BLS[0] << " connects to all of the new lines?!" << endl;1616 eLog() << Verbose(2) << BLS[0] << " connects to all of the new lines?!" << endl; 1176 1617 return false; 1177 1618 } else … … 1184 1625 BTS->GetNormalVector(Normal); 1185 1626 Normal.Scale(-1.); 1186 Log() << Verbose( 2) << "Created new triangle " << *BTS << "." << endl;1627 Log() << Verbose(0) << "Created new triangle " << *BTS << "." << endl; 1187 1628 TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS)); 1188 1629 TrianglesOnBoundaryCount++; … … 1198 1639 // exit 1199 1640 delete(Center); 1200 Log() << Verbose(1) << "End of InsertStraddlingPoints" << endl;1201 1641 return true; 1202 1642 }; … … 1209 1649 bool Tesselation::AddBoundaryPoint(TesselPoint * Walker, const int n) 1210 1650 { 1651 Info FunctionInfo(__func__); 1211 1652 PointTestPair InsertUnique; 1212 1653 BPS[n] = new class BoundaryPointSet(Walker); … … 1230 1671 void Tesselation::AddTesselationPoint(TesselPoint* Candidate, const int n) 1231 1672 { 1673 Info FunctionInfo(__func__); 1232 1674 PointTestPair InsertUnique; 1233 1675 TPS[n] = new class BoundaryPointSet(Candidate); … … 1237 1679 } else { 1238 1680 delete TPS[n]; 1239 Log() << Verbose( 4) << "Node " << *((InsertUnique.first)->second->node) << " is already present in PointsOnBoundary." << endl;1681 Log() << Verbose(0) << "Node " << *((InsertUnique.first)->second->node) << " is already present in PointsOnBoundary." << endl; 1240 1682 TPS[n] = (InsertUnique.first)->second; 1241 1683 } … … 1250 1692 void Tesselation::SetTesselationPoint(TesselPoint* Candidate, const int n) const 1251 1693 { 1694 Info FunctionInfo(__func__); 1252 1695 PointMap::const_iterator FindPoint = PointsOnBoundary.find(Candidate->nr); 1253 1696 if (FindPoint != PointsOnBoundary.end()) … … 1267 1710 bool insertNewLine = true; 1268 1711 1269 if (a->lines.find(b->node->nr) != a->lines.end()) { 1270 LineMap::iterator FindLine = a->lines.find(b->node->nr); 1712 LineMap::iterator FindLine = a->lines.find(b->node->nr); 1713 if (FindLine != a->lines.end()) { 1714 Log() << Verbose(1) << "INFO: There is at least one line between " << *a << " and " << *b << ": " << *(FindLine->second) << "." << endl; 1715 1271 1716 pair<LineMap::iterator,LineMap::iterator> FindPair; 1272 1717 FindPair = a->lines.equal_range(b->node->nr); 1273 Log() << Verbose(5) << "INFO: There is at least one line between " << *a << " and " << *b << ": " << *(FindLine->second) << "." << endl;1274 1718 1275 1719 for (FindLine = FindPair.first; FindLine != FindPair.second; FindLine++) { … … 1277 1721 if (FindLine->second->triangles.size() < 2) { 1278 1722 insertNewLine = false; 1279 Log() << Verbose( 4) << "Using existing line " << *FindLine->second << endl;1723 Log() << Verbose(0) << "Using existing line " << *FindLine->second << endl; 1280 1724 1281 1725 BPS[0] = FindLine->second->endpoints[0]; 1282 1726 BPS[1] = FindLine->second->endpoints[1]; 1283 1727 BLS[n] = FindLine->second; 1728 1729 // remove existing line from OpenLines 1730 CandidateMap::iterator CandidateLine = OpenLines.find(BLS[n]); 1731 if (CandidateLine != OpenLines.end()) { 1732 Log() << Verbose(1) << " Removing line from OpenLines." << endl; 1733 delete(CandidateLine->second); 1734 OpenLines.erase(CandidateLine); 1735 } else { 1736 eLog() << Verbose(1) << "Line exists and is attached to less than two triangles, but not in OpenLines!" << endl; 1737 } 1284 1738 1285 1739 break; … … 1304 1758 void Tesselation::AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n) 1305 1759 { 1306 Log() << Verbose(4) << "Adding line [" << LinesOnBoundaryCount << "|" << *(a->node) << " and " << *(b->node) << "." << endl; 1760 Info FunctionInfo(__func__); 1761 Log() << Verbose(0) << "Adding open line [" << LinesOnBoundaryCount << "|" << *(a->node) << " and " << *(b->node) << "." << endl; 1307 1762 BPS[0] = a; 1308 1763 BPS[1] = b; … … 1312 1767 // increase counter 1313 1768 LinesOnBoundaryCount++; 1769 // also add to open lines 1770 CandidateForTesselation *CFT = new CandidateForTesselation(BLS[n]); 1771 OpenLines.insert(pair< BoundaryLineSet *, CandidateForTesselation *> (BLS[n], CFT)); 1314 1772 }; 1315 1773 … … 1319 1777 void Tesselation::AddTesselationTriangle() 1320 1778 { 1779 Info FunctionInfo(__func__); 1321 1780 Log() << Verbose(1) << "Adding triangle to global TrianglesOnBoundary map." << endl; 1322 1781 … … 1337 1796 void Tesselation::AddTesselationTriangle(const int nr) 1338 1797 { 1339 Log() << Verbose(1) << "Adding triangle to global TrianglesOnBoundary map." << endl; 1798 Info FunctionInfo(__func__); 1799 Log() << Verbose(0) << "Adding triangle to global TrianglesOnBoundary map." << endl; 1340 1800 1341 1801 // add triangle to global map … … 1355 1815 void Tesselation::RemoveTesselationTriangle(class BoundaryTriangleSet *triangle) 1356 1816 { 1817 Info FunctionInfo(__func__); 1357 1818 if (triangle == NULL) 1358 1819 return; 1359 1820 for (int i = 0; i < 3; i++) { 1360 1821 if (triangle->lines[i] != NULL) { 1361 Log() << Verbose( 5) << "Removing triangle Nr." << triangle->Nr << " in line " << *triangle->lines[i] << "." << endl;1822 Log() << Verbose(0) << "Removing triangle Nr." << triangle->Nr << " in line " << *triangle->lines[i] << "." << endl; 1362 1823 triangle->lines[i]->triangles.erase(triangle->Nr); 1363 1824 if (triangle->lines[i]->triangles.empty()) { 1364 Log() << Verbose( 5) << *triangle->lines[i] << " is no more attached to any triangle, erasing." << endl;1825 Log() << Verbose(0) << *triangle->lines[i] << " is no more attached to any triangle, erasing." << endl; 1365 1826 RemoveTesselationLine(triangle->lines[i]); 1366 1827 } else { 1367 Log() << Verbose(5) << *triangle->lines[i] << " is still attached to another triangle: "; 1828 Log() << Verbose(0) << *triangle->lines[i] << " is still attached to another triangle: "; 1829 OpenLines.insert(pair< BoundaryLineSet *, CandidateForTesselation *> (triangle->lines[i], NULL)); 1368 1830 for(TriangleMap::iterator TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); TriangleRunner++) 1369 1831 Log() << Verbose(0) << "[" << (TriangleRunner->second)->Nr << "|" << *((TriangleRunner->second)->endpoints[0]) << ", " << *((TriangleRunner->second)->endpoints[1]) << ", " << *((TriangleRunner->second)->endpoints[2]) << "] \t"; 1370 1832 Log() << Verbose(0) << endl; 1371 1833 // for (int j=0;j<2;j++) { 1372 // Log() << Verbose( 5) << "Lines of endpoint " << *(triangle->lines[i]->endpoints[j]) << ": ";1834 // Log() << Verbose(0) << "Lines of endpoint " << *(triangle->lines[i]->endpoints[j]) << ": "; 1373 1835 // for(LineMap::iterator LineRunner = triangle->lines[i]->endpoints[j]->lines.begin(); LineRunner != triangle->lines[i]->endpoints[j]->lines.end(); LineRunner++) 1374 1836 // Log() << Verbose(0) << "[" << *(LineRunner->second) << "] \t"; … … 1382 1844 1383 1845 if (TrianglesOnBoundary.erase(triangle->Nr)) 1384 Log() << Verbose( 5) << "Removing triangle Nr. " << triangle->Nr << "." << endl;1846 Log() << Verbose(0) << "Removing triangle Nr. " << triangle->Nr << "." << endl; 1385 1847 delete(triangle); 1386 1848 }; … … 1392 1854 void Tesselation::RemoveTesselationLine(class BoundaryLineSet *line) 1393 1855 { 1856 Info FunctionInfo(__func__); 1394 1857 int Numbers[2]; 1395 1858 … … 1412 1875 for (LineMap::iterator Runner = erasor.first; Runner != erasor.second; Runner++) 1413 1876 if ((*Runner).second == line) { 1414 Log() << Verbose( 5) << "Removing Line Nr. " << line->Nr << " in boundary point " << *line->endpoints[i] << "." << endl;1877 Log() << Verbose(0) << "Removing Line Nr. " << line->Nr << " in boundary point " << *line->endpoints[i] << "." << endl; 1415 1878 line->endpoints[i]->lines.erase(Runner); 1416 1879 break; … … 1418 1881 } else { // there's just a single line left 1419 1882 if (line->endpoints[i]->lines.erase(line->Nr)) 1420 Log() << Verbose( 5) << "Removing Line Nr. " << line->Nr << " in boundary point " << *line->endpoints[i] << "." << endl;1883 Log() << Verbose(0) << "Removing Line Nr. " << line->Nr << " in boundary point " << *line->endpoints[i] << "." << endl; 1421 1884 } 1422 1885 if (line->endpoints[i]->lines.empty()) { 1423 Log() << Verbose( 5) << *line->endpoints[i] << " has no more lines it's attached to, erasing." << endl;1886 Log() << Verbose(0) << *line->endpoints[i] << " has no more lines it's attached to, erasing." << endl; 1424 1887 RemoveTesselationPoint(line->endpoints[i]); 1425 1888 } else { 1426 Log() << Verbose( 5) << *line->endpoints[i] << " has still lines it's attached to: ";1889 Log() << Verbose(0) << *line->endpoints[i] << " has still lines it's attached to: "; 1427 1890 for(LineMap::iterator LineRunner = line->endpoints[i]->lines.begin(); LineRunner != line->endpoints[i]->lines.end(); LineRunner++) 1428 1891 Log() << Verbose(0) << "[" << *(LineRunner->second) << "] \t"; … … 1437 1900 1438 1901 if (LinesOnBoundary.erase(line->Nr)) 1439 Log() << Verbose( 5) << "Removing line Nr. " << line->Nr << "." << endl;1902 Log() << Verbose(0) << "Removing line Nr. " << line->Nr << "." << endl; 1440 1903 delete(line); 1441 1904 }; … … 1448 1911 void Tesselation::RemoveTesselationPoint(class BoundaryPointSet *point) 1449 1912 { 1913 Info FunctionInfo(__func__); 1450 1914 if (point == NULL) 1451 1915 return; 1452 1916 if (PointsOnBoundary.erase(point->Nr)) 1453 Log() << Verbose( 5) << "Removing point Nr. " << point->Nr << "." << endl;1917 Log() << Verbose(0) << "Removing point Nr. " << point->Nr << "." << endl; 1454 1918 delete(point); 1455 1919 }; … … 1466 1930 int Tesselation::CheckPresenceOfTriangle(TesselPoint *Candidates[3]) const 1467 1931 { 1932 Info FunctionInfo(__func__); 1468 1933 int adjacentTriangleCount = 0; 1469 1934 class BoundaryPointSet *Points[3]; 1470 1935 1471 Log() << Verbose(2) << "Begin of CheckPresenceOfTriangle" << endl;1472 1936 // builds a triangle point set (Points) of the end points 1473 1937 for (int i = 0; i < 3; i++) { … … 1488 1952 for (; (FindLine != Points[i]->lines.end()) && (FindLine->first == Points[j]->node->nr); FindLine++) { 1489 1953 TriangleMap *triangles = &FindLine->second->triangles; 1490 Log() << Verbose( 3) << "Current line is " << FindLine->first << ": " << *(FindLine->second) << " with triangles " << triangles << "." << endl;1954 Log() << Verbose(1) << "Current line is " << FindLine->first << ": " << *(FindLine->second) << " with triangles " << triangles << "." << endl; 1491 1955 for (TriangleMap::const_iterator FindTriangle = triangles->begin(); FindTriangle != triangles->end(); FindTriangle++) { 1492 1956 if (FindTriangle->second->IsPresentTupel(Points)) { … … 1494 1958 } 1495 1959 } 1496 Log() << Verbose( 3) << "end." << endl;1960 Log() << Verbose(1) << "end." << endl; 1497 1961 } 1498 1962 // Only one of the triangle lines must be considered for the triangle count. 1499 //Log() << Verbose( 2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl;1963 //Log() << Verbose(0) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl; 1500 1964 //return adjacentTriangleCount; 1501 1965 } … … 1504 1968 } 1505 1969 1506 Log() << Verbose(2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl; 1507 Log() << Verbose(2) << "End of CheckPresenceOfTriangle" << endl; 1970 Log() << Verbose(0) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl; 1508 1971 return adjacentTriangleCount; 1509 1972 }; … … 1519 1982 class BoundaryTriangleSet * Tesselation::GetPresentTriangle(TesselPoint *Candidates[3]) 1520 1983 { 1984 Info FunctionInfo(__func__); 1521 1985 class BoundaryTriangleSet *triangle = NULL; 1522 1986 class BoundaryPointSet *Points[3]; … … 1548 2012 } 1549 2013 // Only one of the triangle lines must be considered for the triangle count. 1550 //Log() << Verbose( 2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl;2014 //Log() << Verbose(0) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl; 1551 2015 //return adjacentTriangleCount; 1552 2016 } … … 1569 2033 void Tesselation::FindStartingTriangle(const double RADIUS, const LinkedCell *LC) 1570 2034 { 1571 Log() << Verbose(1) << "Begin of FindStartingTriangle\n";2035 Info FunctionInfo(__func__); 1572 2036 int i = 0; 1573 TesselPoint* FirstPoint = NULL;1574 TesselPoint* SecondPoint = NULL;1575 2037 TesselPoint* MaxPoint[NDIM]; 2038 TesselPoint* Temporary; 1576 2039 double maxCoordinate[NDIM]; 1577 Vector Oben;2040 BoundaryLineSet BaseLine; 1578 2041 Vector helper; 1579 2042 Vector Chord; 1580 2043 Vector SearchDirection; 1581 1582 Oben.Zero(); 2044 Vector CircleCenter; // center of the circle, i.e. of the band of sphere's centers 2045 Vector CirclePlaneNormal; // normal vector defining the plane this circle lives in 2046 Vector SphereCenter; 2047 Vector NormalVector; 2048 2049 NormalVector.Zero(); 1583 2050 1584 2051 for (i = 0; i < 3; i++) { … … 1593 2060 for (LC->n[(i+2)%NDIM]=0;LC->n[(i+2)%NDIM]<LC->N[(i+2)%NDIM];LC->n[(i+2)%NDIM]++) { 1594 2061 const LinkedNodes *List = LC->GetCurrentCell(); 1595 //Log() << Verbose( 2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;2062 //Log() << Verbose(1) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 1596 2063 if (List != NULL) { 1597 2064 for (LinkedNodes::const_iterator Runner = List->begin();Runner != List->end();Runner++) { 1598 2065 if ((*Runner)->node->x[i] > maxCoordinate[i]) { 1599 Log() << Verbose( 2) << "New maximal for axis " << i << " node is " << *(*Runner) << " at " << *(*Runner)->node << "." << endl;2066 Log() << Verbose(1) << "New maximal for axis " << i << " node is " << *(*Runner) << " at " << *(*Runner)->node << "." << endl; 1600 2067 maxCoordinate[i] = (*Runner)->node->x[i]; 1601 2068 MaxPoint[i] = (*Runner); … … 1608 2075 } 1609 2076 1610 Log() << Verbose( 2) << "Found maximum coordinates: ";2077 Log() << Verbose(1) << "Found maximum coordinates: "; 1611 2078 for (int i=0;i<NDIM;i++) 1612 2079 Log() << Verbose(0) << i << ": " << *MaxPoint[i] << "\t"; … … 1614 2081 1615 2082 BTS = NULL; 1616 CandidateList *OptCandidates = new CandidateList();1617 2083 for (int k=0;k<NDIM;k++) { 1618 Oben.Zero();1619 Oben.x[k] = 1.;1620 FirstPoint = MaxPoint[k];1621 Log() << Verbose( 1) << "Coordinates of start node at " << *FirstPoint->node << "." << endl;2084 NormalVector.Zero(); 2085 NormalVector.x[k] = 1.; 2086 BaseLine.endpoints[0] = new BoundaryPointSet(MaxPoint[k]); 2087 Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine.endpoints[0]->node << "." << endl; 1622 2088 1623 2089 double ShortestAngle; 1624 TesselPoint* OptCandidate = NULL;1625 2090 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. 1626 2091 1627 FindSecondPointForTesselation(FirstPoint, Oben, OptCandidate, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_... 1628 SecondPoint = OptCandidate; 1629 if (SecondPoint == NULL) // have we found a second point? 2092 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_... 2093 if (Temporary == NULL) // have we found a second point? 1630 2094 continue; 1631 1632 helper.CopyVector(FirstPoint->node); 1633 helper.SubtractVector(SecondPoint->node); 1634 helper.Normalize(); 1635 Oben.ProjectOntoPlane(&helper); 1636 Oben.Normalize(); 1637 helper.VectorProduct(&Oben); 2095 BaseLine.endpoints[1] = new BoundaryPointSet(Temporary); 2096 2097 // construct center of circle 2098 CircleCenter.CopyVector(BaseLine.endpoints[0]->node->node); 2099 CircleCenter.AddVector(BaseLine.endpoints[1]->node->node); 2100 CircleCenter.Scale(0.5); 2101 2102 // construct normal vector of circle 2103 CirclePlaneNormal.CopyVector(BaseLine.endpoints[0]->node->node); 2104 CirclePlaneNormal.SubtractVector(BaseLine.endpoints[1]->node->node); 2105 2106 double radius = CirclePlaneNormal.NormSquared(); 2107 double CircleRadius = sqrt(RADIUS*RADIUS - radius/4.); 2108 2109 NormalVector.ProjectOntoPlane(&CirclePlaneNormal); 2110 NormalVector.Normalize(); 1638 2111 ShortestAngle = 2.*M_PI; // This will indicate the quadrant. 1639 2112 1640 Chord.CopyVector(FirstPoint->node); // bring into calling function 1641 Chord.SubtractVector(SecondPoint->node); 1642 double radius = Chord.ScalarProduct(&Chord); 1643 double CircleRadius = sqrt(RADIUS*RADIUS - radius/4.); 1644 helper.CopyVector(&Oben); 1645 helper.Scale(CircleRadius); 1646 // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized) 2113 SphereCenter.CopyVector(&NormalVector); 2114 SphereCenter.Scale(CircleRadius); 2115 SphereCenter.AddVector(&CircleCenter); 2116 // Now, NormalVector and SphereCenter are two orthonormalized vectors in the plane defined by CirclePlaneNormal (not normalized) 1647 2117 1648 2118 // look in one direction of baseline for initial candidate 1649 SearchDirection.MakeNormalVector(&C hord, &Oben); // whether we look "left" first or "right" first is not important ...2119 SearchDirection.MakeNormalVector(&CirclePlaneNormal, &NormalVector); // whether we look "left" first or "right" first is not important ... 1650 2120 1651 2121 // adding point 1 and point 2 and add the line between them 1652 Log() << Verbose(1) << "Coordinates of start node at " << *FirstPoint->node << "." << endl; 1653 AddTesselationPoint(FirstPoint, 0); 1654 Log() << Verbose(1) << "Found second point is at " << *SecondPoint->node << ".\n"; 1655 AddTesselationPoint(SecondPoint, 1); 1656 AddTesselationLine(TPS[0], TPS[1], 0); 1657 1658 //Log() << Verbose(2) << "INFO: OldSphereCenter is at " << helper << ".\n"; 1659 FindThirdPointForTesselation(Oben, SearchDirection, helper, BLS[0], NULL, *&OptCandidates, &ShortestAngle, RADIUS, LC); 1660 Log() << Verbose(1) << "List of third Points is "; 1661 for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 1662 Log() << Verbose(0) << " " << *(*it)->point; 1663 } 1664 Log() << Verbose(0) << endl; 1665 1666 for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 1667 // add third triangle point 1668 AddTesselationPoint((*it)->point, 2); 1669 // add the second and third line 1670 AddTesselationLine(TPS[1], TPS[2], 1); 1671 AddTesselationLine(TPS[0], TPS[2], 2); 1672 // ... and triangles to the Maps of the Tesselation class 1673 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 1674 AddTesselationTriangle(); 1675 // ... and calculate its normal vector (with correct orientation) 1676 (*it)->OptCenter.Scale(-1.); 1677 Log() << Verbose(2) << "Anti-Oben is currently " << (*it)->OptCenter << "." << endl; 1678 BTS->GetNormalVector((*it)->OptCenter); // vector to compare with should point inwards 1679 Log() << Verbose(0) << "==> Found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " 1680 << *(*it)->point << " with normal vector " << BTS->NormalVector << ".\n"; 1681 1682 // if we do not reach the end with the next step of iteration, we need to setup a new first line 1683 if (it != OptCandidates->end()--) { 1684 FirstPoint = (*it)->BaseLine->endpoints[0]->node; 1685 SecondPoint = (*it)->point; 1686 // adding point 1 and point 2 and the line between them 1687 AddTesselationPoint(FirstPoint, 0); 1688 AddTesselationPoint(SecondPoint, 1); 1689 AddTesselationLine(TPS[0], TPS[1], 0); 1690 } 1691 Log() << Verbose(2) << "Projection is " << BTS->NormalVector.ScalarProduct(&Oben) << "." << endl; 1692 } 2122 Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine.endpoints[0]->node << "." << endl; 2123 Log() << Verbose(0) << "Found second point is at " << *BaseLine.endpoints[1]->node << ".\n"; 2124 2125 //Log() << Verbose(1) << "INFO: OldSphereCenter is at " << helper << ".\n"; 2126 CandidateForTesselation OptCandidates(&BaseLine); 2127 FindThirdPointForTesselation(NormalVector, SearchDirection, SphereCenter, OptCandidates, NULL, RADIUS, LC); 2128 Log() << Verbose(0) << "List of third Points is:" << endl; 2129 for (TesselPointList::iterator it = OptCandidates.pointlist.begin(); it != OptCandidates.pointlist.end(); it++) { 2130 Log() << Verbose(0) << " " << *(*it) << endl; 2131 } 2132 2133 BTS = NULL; 2134 AddCandidateTriangle(OptCandidates); 2135 // delete(BaseLine.endpoints[0]); 2136 // delete(BaseLine.endpoints[1]); 2137 1693 2138 if (BTS != NULL) // we have created one starting triangle 1694 2139 break; 1695 2140 else { 1696 2141 // remove all candidates from the list and then the list itself 1697 class CandidateForTesselation *remover = NULL; 1698 for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 1699 remover = *it; 1700 delete(remover); 1701 } 1702 OptCandidates->clear(); 1703 } 1704 } 1705 1706 // remove all candidates from the list and then the list itself 1707 class CandidateForTesselation *remover = NULL; 1708 for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 1709 remover = *it; 1710 delete(remover); 1711 } 1712 delete(OptCandidates); 1713 Log() << Verbose(1) << "End of FindStartingTriangle\n"; 2142 OptCandidates.pointlist.clear(); 2143 } 2144 } 1714 2145 }; 1715 2146 1716 2147 /** Checks for a given baseline and a third point candidate whether baselines of the found triangle don't have even better candidates. 1717 2148 * This is supposed to prevent early closing of the tesselation. 1718 * \param *BaseRay baseline, i.e. not \a *OptCandidate2149 * \param CandidateLine CandidateForTesselation with baseline and shortestangle , i.e. not \a *OptCandidate 1719 2150 * \param *ThirdNode third point in triangle, not in BoundaryLineSet::endpoints 1720 * \param ShortestAngle path length on this circle band for the current \a *ThirdNode1721 2151 * \param RADIUS radius of sphere 1722 2152 * \param *LC LinkedCell structure 1723 2153 * \return true - there is a better candidate (smaller angle than \a ShortestAngle), false - no better TesselPoint candidate found 1724 2154 */ 1725 bool Tesselation::HasOtherBaselineBetterCandidate(const BoundaryLineSet * const BaseRay, const TesselPoint * const ThirdNode, double ShortestAngle, double RADIUS, const LinkedCell * const LC) const 1726 { 1727 bool result = false; 1728 Vector CircleCenter; 1729 Vector CirclePlaneNormal; 1730 Vector OldSphereCenter; 1731 Vector SearchDirection; 1732 Vector helper; 1733 TesselPoint *OtherOptCandidate = NULL; 1734 double OtherShortestAngle = 2.*M_PI; // This will indicate the quadrant. 1735 double radius, CircleRadius; 1736 BoundaryLineSet *Line = NULL; 1737 BoundaryTriangleSet *T = NULL; 1738 1739 Log() << Verbose(1) << "Begin of HasOtherBaselineBetterCandidate" << endl; 1740 1741 // check both other lines 1742 PointMap::const_iterator FindPoint = PointsOnBoundary.find(ThirdNode->nr); 1743 if (FindPoint != PointsOnBoundary.end()) { 1744 for (int i=0;i<2;i++) { 1745 LineMap::const_iterator FindLine = (FindPoint->second)->lines.find(BaseRay->endpoints[0]->node->nr); 1746 if (FindLine != (FindPoint->second)->lines.end()) { 1747 Line = FindLine->second; 1748 Log() << Verbose(1) << "Found line " << *Line << "." << endl; 1749 if (Line->triangles.size() == 1) { 1750 T = Line->triangles.begin()->second; 1751 // construct center of circle 1752 CircleCenter.CopyVector(Line->endpoints[0]->node->node); 1753 CircleCenter.AddVector(Line->endpoints[1]->node->node); 1754 CircleCenter.Scale(0.5); 1755 1756 // construct normal vector of circle 1757 CirclePlaneNormal.CopyVector(Line->endpoints[0]->node->node); 1758 CirclePlaneNormal.SubtractVector(Line->endpoints[1]->node->node); 1759 1760 // calculate squared radius of circle 1761 radius = CirclePlaneNormal.ScalarProduct(&CirclePlaneNormal); 1762 if (radius/4. < RADIUS*RADIUS) { 1763 CircleRadius = RADIUS*RADIUS - radius/4.; 1764 CirclePlaneNormal.Normalize(); 1765 //Log() << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 1766 1767 // construct old center 1768 GetCenterofCircumcircle(&OldSphereCenter, *T->endpoints[0]->node->node, *T->endpoints[1]->node->node, *T->endpoints[2]->node->node); 1769 helper.CopyVector(&T->NormalVector); // normal vector ensures that this is correct center of the two possible ones 1770 radius = Line->endpoints[0]->node->node->DistanceSquared(&OldSphereCenter); 1771 helper.Scale(sqrt(RADIUS*RADIUS - radius)); 1772 OldSphereCenter.AddVector(&helper); 1773 OldSphereCenter.SubtractVector(&CircleCenter); 1774 //Log() << Verbose(2) << "INFO: OldSphereCenter is at " << OldSphereCenter << "." << endl; 1775 1776 // construct SearchDirection 1777 SearchDirection.MakeNormalVector(&T->NormalVector, &CirclePlaneNormal); 1778 helper.CopyVector(Line->endpoints[0]->node->node); 1779 helper.SubtractVector(ThirdNode->node); 1780 if (helper.ScalarProduct(&SearchDirection) < -HULLEPSILON)// ohoh, SearchDirection points inwards! 1781 SearchDirection.Scale(-1.); 1782 SearchDirection.ProjectOntoPlane(&OldSphereCenter); 1783 SearchDirection.Normalize(); 1784 Log() << Verbose(2) << "INFO: SearchDirection is " << SearchDirection << "." << endl; 1785 if (fabs(OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { 1786 // rotated the wrong way! 1787 eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl; 1788 } 1789 1790 // add third point 1791 CandidateList *OptCandidates = new CandidateList(); 1792 FindThirdPointForTesselation(T->NormalVector, SearchDirection, OldSphereCenter, Line, ThirdNode, OptCandidates, &OtherShortestAngle, RADIUS, LC); 1793 for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 1794 if (((*it)->point == BaseRay->endpoints[0]->node) || ((*it)->point == BaseRay->endpoints[1]->node)) // skip if it's the same triangle than suggested 1795 continue; 1796 Log() << Verbose(1) << " Third point candidate is " << *(*it)->point 1797 << " with circumsphere's center at " << (*it)->OptCenter << "." << endl; 1798 Log() << Verbose(1) << " Baseline is " << *BaseRay << endl; 1799 1800 // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2) 1801 TesselPoint *PointCandidates[3]; 1802 PointCandidates[0] = (*it)->point; 1803 PointCandidates[1] = BaseRay->endpoints[0]->node; 1804 PointCandidates[2] = BaseRay->endpoints[1]->node; 1805 bool check=false; 1806 int existentTrianglesCount = CheckPresenceOfTriangle(PointCandidates); 1807 // If there is no triangle, add it regularly. 1808 if (existentTrianglesCount == 0) { 1809 SetTesselationPoint((*it)->point, 0); 1810 SetTesselationPoint(BaseRay->endpoints[0]->node, 1); 1811 SetTesselationPoint(BaseRay->endpoints[1]->node, 2); 1812 1813 if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const )TPS)) { 1814 OtherOptCandidate = (*it)->point; 1815 check = true; 1816 } 1817 } else if ((existentTrianglesCount >= 1) && (existentTrianglesCount <= 3)) { // If there is a planar region within the structure, we need this triangle a second time. 1818 SetTesselationPoint((*it)->point, 0); 1819 SetTesselationPoint(BaseRay->endpoints[0]->node, 1); 1820 SetTesselationPoint(BaseRay->endpoints[1]->node, 2); 1821 1822 // 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) 1823 // i.e. at least one of the three lines must be present with TriangleCount <= 1 1824 if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const)TPS)) { 1825 OtherOptCandidate = (*it)->point; 1826 check = true; 1827 } 1828 } 1829 1830 if (check) { 1831 if (ShortestAngle > OtherShortestAngle) { 1832 Log() << Verbose(1) << "There is a better candidate than " << *ThirdNode << " with " << ShortestAngle << " from baseline " << *Line << ": " << *OtherOptCandidate << " with " << OtherShortestAngle << "." << endl; 1833 result = true; 1834 break; 1835 } 1836 } 1837 } 1838 delete(OptCandidates); 1839 if (result) 1840 break; 1841 } else { 1842 Log() << Verbose(1) << "Circumcircle for base line " << *Line << " and base triangle " << T << " is too big!" << endl; 1843 } 1844 } else { 1845 eLog() << Verbose(2) << "Baseline is connected to two triangles already?" << endl; 1846 } 1847 } else { 1848 Log() << Verbose(2) << "No present baseline between " << BaseRay->endpoints[0] << " and candidate " << *ThirdNode << "." << endl; 1849 } 1850 } 1851 } else { 1852 eLog() << Verbose(1) << "Could not find the TesselPoint " << *ThirdNode << "." << endl; 1853 } 1854 1855 Log() << Verbose(1) << "End of HasOtherBaselineBetterCandidate" << endl; 1856 1857 return result; 1858 }; 2155 //bool Tesselation::HasOtherBaselineBetterCandidate(CandidateForTesselation &CandidateLine, const TesselPoint * const ThirdNode, double RADIUS, const LinkedCell * const LC) const 2156 //{ 2157 // Info FunctionInfo(__func__); 2158 // bool result = false; 2159 // Vector CircleCenter; 2160 // Vector CirclePlaneNormal; 2161 // Vector OldSphereCenter; 2162 // Vector SearchDirection; 2163 // Vector helper; 2164 // TesselPoint *OtherOptCandidate = NULL; 2165 // double OtherShortestAngle = 2.*M_PI; // This will indicate the quadrant. 2166 // double radius, CircleRadius; 2167 // BoundaryLineSet *Line = NULL; 2168 // BoundaryTriangleSet *T = NULL; 2169 // 2170 // // check both other lines 2171 // PointMap::const_iterator FindPoint = PointsOnBoundary.find(ThirdNode->nr); 2172 // if (FindPoint != PointsOnBoundary.end()) { 2173 // for (int i=0;i<2;i++) { 2174 // LineMap::const_iterator FindLine = (FindPoint->second)->lines.find(BaseRay->endpoints[0]->node->nr); 2175 // if (FindLine != (FindPoint->second)->lines.end()) { 2176 // Line = FindLine->second; 2177 // Log() << Verbose(0) << "Found line " << *Line << "." << endl; 2178 // if (Line->triangles.size() == 1) { 2179 // T = Line->triangles.begin()->second; 2180 // // construct center of circle 2181 // CircleCenter.CopyVector(Line->endpoints[0]->node->node); 2182 // CircleCenter.AddVector(Line->endpoints[1]->node->node); 2183 // CircleCenter.Scale(0.5); 2184 // 2185 // // construct normal vector of circle 2186 // CirclePlaneNormal.CopyVector(Line->endpoints[0]->node->node); 2187 // CirclePlaneNormal.SubtractVector(Line->endpoints[1]->node->node); 2188 // 2189 // // calculate squared radius of circle 2190 // radius = CirclePlaneNormal.ScalarProduct(&CirclePlaneNormal); 2191 // if (radius/4. < RADIUS*RADIUS) { 2192 // CircleRadius = RADIUS*RADIUS - radius/4.; 2193 // CirclePlaneNormal.Normalize(); 2194 // //Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 2195 // 2196 // // construct old center 2197 // GetCenterofCircumcircle(&OldSphereCenter, *T->endpoints[0]->node->node, *T->endpoints[1]->node->node, *T->endpoints[2]->node->node); 2198 // helper.CopyVector(&T->NormalVector); // normal vector ensures that this is correct center of the two possible ones 2199 // radius = Line->endpoints[0]->node->node->DistanceSquared(&OldSphereCenter); 2200 // helper.Scale(sqrt(RADIUS*RADIUS - radius)); 2201 // OldSphereCenter.AddVector(&helper); 2202 // OldSphereCenter.SubtractVector(&CircleCenter); 2203 // //Log() << Verbose(1) << "INFO: OldSphereCenter is at " << OldSphereCenter << "." << endl; 2204 // 2205 // // construct SearchDirection 2206 // SearchDirection.MakeNormalVector(&T->NormalVector, &CirclePlaneNormal); 2207 // helper.CopyVector(Line->endpoints[0]->node->node); 2208 // helper.SubtractVector(ThirdNode->node); 2209 // if (helper.ScalarProduct(&SearchDirection) < -HULLEPSILON)// ohoh, SearchDirection points inwards! 2210 // SearchDirection.Scale(-1.); 2211 // SearchDirection.ProjectOntoPlane(&OldSphereCenter); 2212 // SearchDirection.Normalize(); 2213 // Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl; 2214 // if (fabs(OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { 2215 // // rotated the wrong way! 2216 // eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl; 2217 // } 2218 // 2219 // // add third point 2220 // FindThirdPointForTesselation(T->NormalVector, SearchDirection, OldSphereCenter, OptCandidates, ThirdNode, RADIUS, LC); 2221 // for (TesselPointList::iterator it = OptCandidates.pointlist.begin(); it != OptCandidates.pointlist.end(); ++it) { 2222 // if (((*it) == BaseRay->endpoints[0]->node) || ((*it) == BaseRay->endpoints[1]->node)) // skip if it's the same triangle than suggested 2223 // continue; 2224 // Log() << Verbose(0) << " Third point candidate is " << (*it) 2225 // << " with circumsphere's center at " << (*it)->OptCenter << "." << endl; 2226 // Log() << Verbose(0) << " Baseline is " << *BaseRay << endl; 2227 // 2228 // // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2) 2229 // TesselPoint *PointCandidates[3]; 2230 // PointCandidates[0] = (*it); 2231 // PointCandidates[1] = BaseRay->endpoints[0]->node; 2232 // PointCandidates[2] = BaseRay->endpoints[1]->node; 2233 // bool check=false; 2234 // int existentTrianglesCount = CheckPresenceOfTriangle(PointCandidates); 2235 // // If there is no triangle, add it regularly. 2236 // if (existentTrianglesCount == 0) { 2237 // SetTesselationPoint((*it), 0); 2238 // SetTesselationPoint(BaseRay->endpoints[0]->node, 1); 2239 // SetTesselationPoint(BaseRay->endpoints[1]->node, 2); 2240 // 2241 // if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const )TPS)) { 2242 // OtherOptCandidate = (*it); 2243 // check = true; 2244 // } 2245 // } else if ((existentTrianglesCount >= 1) && (existentTrianglesCount <= 3)) { // If there is a planar region within the structure, we need this triangle a second time. 2246 // SetTesselationPoint((*it), 0); 2247 // SetTesselationPoint(BaseRay->endpoints[0]->node, 1); 2248 // SetTesselationPoint(BaseRay->endpoints[1]->node, 2); 2249 // 2250 // // 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) 2251 // // i.e. at least one of the three lines must be present with TriangleCount <= 1 2252 // if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const)TPS)) { 2253 // OtherOptCandidate = (*it); 2254 // check = true; 2255 // } 2256 // } 2257 // 2258 // if (check) { 2259 // if (ShortestAngle > OtherShortestAngle) { 2260 // Log() << Verbose(0) << "There is a better candidate than " << *ThirdNode << " with " << ShortestAngle << " from baseline " << *Line << ": " << *OtherOptCandidate << " with " << OtherShortestAngle << "." << endl; 2261 // result = true; 2262 // break; 2263 // } 2264 // } 2265 // } 2266 // delete(OptCandidates); 2267 // if (result) 2268 // break; 2269 // } else { 2270 // Log() << Verbose(0) << "Circumcircle for base line " << *Line << " and base triangle " << T << " is too big!" << endl; 2271 // } 2272 // } else { 2273 // eLog() << Verbose(2) << "Baseline is connected to two triangles already?" << endl; 2274 // } 2275 // } else { 2276 // Log() << Verbose(1) << "No present baseline between " << BaseRay->endpoints[0] << " and candidate " << *ThirdNode << "." << endl; 2277 // } 2278 // } 2279 // } else { 2280 // eLog() << Verbose(1) << "Could not find the TesselPoint " << *ThirdNode << "." << endl; 2281 // } 2282 // 2283 // return result; 2284 //}; 1859 2285 1860 2286 /** This function finds a triangle to a line, adjacent to an existing one. 1861 2287 * @param out output stream for debugging 1862 * @param Line currentbaseline to search from2288 * @param CandidateLine current cadndiate baseline to search from 1863 2289 * @param T current triangle which \a Line is edge of 1864 2290 * @param RADIUS radius of the rolling ball … … 1866 2292 * @param *LC LinkedCell structure with neighbouring points 1867 2293 */ 1868 bool Tesselation::FindNextSuitableTriangle( BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC)1869 { 1870 Log() << Verbose(0) << "Begin of FindNextSuitableTriangle\n";2294 bool Tesselation::FindNextSuitableTriangle(CandidateForTesselation &CandidateLine, BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC) 2295 { 2296 Info FunctionInfo(__func__); 1871 2297 bool result = true; 1872 CandidateList *OptCandidates = new CandidateList();1873 2298 1874 2299 Vector CircleCenter; 1875 2300 Vector CirclePlaneNormal; 1876 Vector OldSphereCenter;2301 Vector RelativeSphereCenter; 1877 2302 Vector SearchDirection; 1878 2303 Vector helper; 1879 2304 TesselPoint *ThirdNode = NULL; 1880 2305 LineMap::iterator testline; 1881 double ShortestAngle = 2.*M_PI; // This will indicate the quadrant.1882 2306 double radius, CircleRadius; 1883 2307 1884 Log() << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;1885 2308 for (int i=0;i<3;i++) 1886 if ((T.endpoints[i]->node != Line.endpoints[0]->node) && (T.endpoints[i]->node != Line.endpoints[1]->node))2309 if ((T.endpoints[i]->node != CandidateLine.BaseLine->endpoints[0]->node) && (T.endpoints[i]->node != CandidateLine.BaseLine->endpoints[1]->node)) { 1887 2310 ThirdNode = T.endpoints[i]->node; 2311 break; 2312 } 2313 Log() << Verbose(0) << "Current baseline is " << *CandidateLine.BaseLine << " with ThirdNode " << *ThirdNode << " of triangle " << T << "." << endl; 1888 2314 1889 2315 // construct center of circle 1890 CircleCenter.CopyVector( Line.endpoints[0]->node->node);1891 CircleCenter.AddVector( Line.endpoints[1]->node->node);2316 CircleCenter.CopyVector(CandidateLine.BaseLine->endpoints[0]->node->node); 2317 CircleCenter.AddVector(CandidateLine.BaseLine->endpoints[1]->node->node); 1892 2318 CircleCenter.Scale(0.5); 1893 2319 1894 2320 // construct normal vector of circle 1895 CirclePlaneNormal.CopyVector( Line.endpoints[0]->node->node);1896 CirclePlaneNormal.SubtractVector( Line.endpoints[1]->node->node);2321 CirclePlaneNormal.CopyVector(CandidateLine.BaseLine->endpoints[0]->node->node); 2322 CirclePlaneNormal.SubtractVector(CandidateLine.BaseLine->endpoints[1]->node->node); 1897 2323 1898 2324 // calculate squared radius of circle 1899 2325 radius = CirclePlaneNormal.ScalarProduct(&CirclePlaneNormal); 1900 2326 if (radius/4. < RADIUS*RADIUS) { 2327 // construct relative sphere center with now known CircleCenter 2328 RelativeSphereCenter.CopyVector(&T.SphereCenter); 2329 RelativeSphereCenter.SubtractVector(&CircleCenter); 2330 1901 2331 CircleRadius = RADIUS*RADIUS - radius/4.; 1902 2332 CirclePlaneNormal.Normalize(); 1903 //Log() << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 1904 1905 // construct old center 1906 GetCenterofCircumcircle(&OldSphereCenter, *T.endpoints[0]->node->node, *T.endpoints[1]->node->node, *T.endpoints[2]->node->node); 1907 helper.CopyVector(&T.NormalVector); // normal vector ensures that this is correct center of the two possible ones 1908 radius = Line.endpoints[0]->node->node->DistanceSquared(&OldSphereCenter); 1909 helper.Scale(sqrt(RADIUS*RADIUS - radius)); 1910 OldSphereCenter.AddVector(&helper); 1911 OldSphereCenter.SubtractVector(&CircleCenter); 1912 //Log() << Verbose(2) << "INFO: OldSphereCenter is at " << OldSphereCenter << "." << endl; 1913 1914 // construct SearchDirection 1915 SearchDirection.MakeNormalVector(&T.NormalVector, &CirclePlaneNormal); 1916 helper.CopyVector(Line.endpoints[0]->node->node); 2333 Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 2334 2335 Log() << Verbose(1) << "INFO: OldSphereCenter is at " << T.SphereCenter << "." << endl; 2336 2337 // construct SearchDirection and an "outward pointer" 2338 SearchDirection.MakeNormalVector(&RelativeSphereCenter, &CirclePlaneNormal); 2339 helper.CopyVector(&CircleCenter); 1917 2340 helper.SubtractVector(ThirdNode->node); 1918 2341 if (helper.ScalarProduct(&SearchDirection) < -HULLEPSILON)// ohoh, SearchDirection points inwards! 1919 2342 SearchDirection.Scale(-1.); 1920 SearchDirection.ProjectOntoPlane(&OldSphereCenter); 1921 SearchDirection.Normalize(); 1922 Log() << Verbose(2) << "INFO: SearchDirection is " << SearchDirection << "." << endl; 1923 if (fabs(OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { 2343 Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl; 2344 if (fabs(RelativeSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { 1924 2345 // rotated the wrong way! 1925 2346 eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl; … … 1927 2348 1928 2349 // add third point 1929 FindThirdPointForTesselation(T.NormalVector, SearchDirection, OldSphereCenter, &Line, ThirdNode, OptCandidates, &ShortestAngle, RADIUS, LC);2350 FindThirdPointForTesselation(T.NormalVector, SearchDirection, T.SphereCenter, CandidateLine, ThirdNode, RADIUS, LC); 1930 2351 1931 2352 } else { 1932 Log() << Verbose( 1) << "Circumcircle for base line " <<Line << " and base triangle " << T << " is too big!" << endl;1933 } 1934 1935 if ( OptCandidates->begin() == OptCandidates->end()) {2353 Log() << Verbose(0) << "Circumcircle for base line " << *CandidateLine.BaseLine << " and base triangle " << T << " is too big!" << endl; 2354 } 2355 2356 if (CandidateLine.pointlist.empty()) { 1936 2357 eLog() << Verbose(2) << "Could not find a suitable candidate." << endl; 1937 2358 return false; 1938 2359 } 1939 Log() << Verbose(1) << "Third Points are "; 1940 for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 1941 Log() << Verbose(1) << " " << *(*it)->point << endl; 1942 } 1943 1944 BoundaryLineSet *BaseRay = &Line; 1945 for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 1946 Log() << Verbose(1) << " Third point candidate is " << *(*it)->point 1947 << " with circumsphere's center at " << (*it)->OptCenter << "." << endl; 1948 Log() << Verbose(1) << " Baseline is " << *BaseRay << endl; 1949 1950 // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2) 1951 TesselPoint *PointCandidates[3]; 1952 PointCandidates[0] = (*it)->point; 1953 PointCandidates[1] = BaseRay->endpoints[0]->node; 1954 PointCandidates[2] = BaseRay->endpoints[1]->node; 1955 int existentTrianglesCount = CheckPresenceOfTriangle(PointCandidates); 1956 1957 BTS = NULL; 1958 // check for present edges and whether we reach better candidates from them 1959 if (HasOtherBaselineBetterCandidate(BaseRay, (*it)->point, ShortestAngle, RADIUS, LC) ) { 1960 result = false; 1961 break; 1962 } else { 1963 // If there is no triangle, add it regularly. 1964 if (existentTrianglesCount == 0) { 1965 AddTesselationPoint((*it)->point, 0); 1966 AddTesselationPoint(BaseRay->endpoints[0]->node, 1); 1967 AddTesselationPoint(BaseRay->endpoints[1]->node, 2); 1968 1969 if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const )TPS)) { 1970 AddTesselationLine(TPS[0], TPS[1], 0); 1971 AddTesselationLine(TPS[0], TPS[2], 1); 1972 AddTesselationLine(TPS[1], TPS[2], 2); 1973 1974 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 1975 AddTesselationTriangle(); 1976 (*it)->OptCenter.Scale(-1.); 1977 BTS->GetNormalVector((*it)->OptCenter); 1978 (*it)->OptCenter.Scale(-1.); 1979 1980 Log() << Verbose(0) << "--> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector 1981 << " for this triangle ... " << endl; 1982 //Log() << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << *BaseRay << "." << endl; 1983 } else { 1984 eLog() << Verbose(2) << "This triangle consisting of "; 1985 Log() << Verbose(0) << *(*it)->point << ", "; 1986 Log() << Verbose(0) << *BaseRay->endpoints[0]->node << " and "; 1987 Log() << Verbose(0) << *BaseRay->endpoints[1]->node << " "; 1988 Log() << Verbose(0) << "exists and is not added, as it does not seem helpful!" << endl; 1989 result = false; 1990 } 1991 } else if ((existentTrianglesCount >= 1) && (existentTrianglesCount <= 3)) { // If there is a planar region within the structure, we need this triangle a second time. 1992 AddTesselationPoint((*it)->point, 0); 1993 AddTesselationPoint(BaseRay->endpoints[0]->node, 1); 1994 AddTesselationPoint(BaseRay->endpoints[1]->node, 2); 1995 1996 // 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) 1997 // i.e. at least one of the three lines must be present with TriangleCount <= 1 1998 if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const)TPS)) { 1999 AddTesselationLine(TPS[0], TPS[1], 0); 2000 AddTesselationLine(TPS[0], TPS[2], 1); 2001 AddTesselationLine(TPS[1], TPS[2], 2); 2002 2003 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2004 AddTesselationTriangle(); // add to global map 2005 2006 (*it)->OtherOptCenter.Scale(-1.); 2007 BTS->GetNormalVector((*it)->OtherOptCenter); 2008 (*it)->OtherOptCenter.Scale(-1.); 2009 2010 eLog() << Verbose(2) << "--> WARNING: Special new triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl; 2011 Log() << Verbose(1) << "We have "<< BaseRay->triangles.size() << " for line " << BaseRay << "." << endl; 2012 } else { 2013 eLog() << Verbose(2) << "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; 2014 result = false; 2015 } 2016 } else { 2017 Log() << Verbose(1) << "This triangle consisting of "; 2018 Log() << Verbose(0) << *(*it)->point << ", "; 2019 Log() << Verbose(0) << *BaseRay->endpoints[0]->node << " and "; 2020 Log() << Verbose(0) << *BaseRay->endpoints[1]->node << " "; 2021 Log() << Verbose(0) << "is invalid!" << endl; 2022 result = false; 2023 } 2024 } 2025 2026 // set baseline to new ray from ref point (here endpoints[0]->node) to current candidate (here (*it)->point)) 2027 BaseRay = BLS[0]; 2028 if ((BTS != NULL) && (BTS->NormalVector.NormSquared() < MYEPSILON)) { 2029 eLog() << Verbose(1) << "Triangle " << *BTS << " has zero normal vector!" << endl; 2030 exit(255); 2031 } 2032 2033 } 2034 2035 // remove all candidates from the list and then the list itself 2036 class CandidateForTesselation *remover = NULL; 2037 for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 2038 remover = *it; 2039 delete(remover); 2040 } 2041 delete(OptCandidates); 2042 Log() << Verbose(0) << "End of FindNextSuitableTriangle\n"; 2360 Log() << Verbose(0) << "Third Points are: " << endl; 2361 for (TesselPointList::iterator it = CandidateLine.pointlist.begin(); it != CandidateLine.pointlist.end(); ++it) { 2362 Log() << Verbose(0) << " " << *(*it) << endl; 2363 } 2364 2365 return true; 2366 2367 // BoundaryLineSet *BaseRay = CandidateLine.BaseLine; 2368 // for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 2369 // Log() << Verbose(0) << "Third point candidate is " << *(*it)->point 2370 // << " with circumsphere's center at " << (*it)->OptCenter << "." << endl; 2371 // Log() << Verbose(0) << "Baseline is " << *BaseRay << endl; 2372 // 2373 // // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2) 2374 // TesselPoint *PointCandidates[3]; 2375 // PointCandidates[0] = (*it)->point; 2376 // PointCandidates[1] = BaseRay->endpoints[0]->node; 2377 // PointCandidates[2] = BaseRay->endpoints[1]->node; 2378 // int existentTrianglesCount = CheckPresenceOfTriangle(PointCandidates); 2379 // 2380 // BTS = NULL; 2381 // // check for present edges and whether we reach better candidates from them 2382 // //if (HasOtherBaselineBetterCandidate(BaseRay, (*it)->point, ShortestAngle, RADIUS, LC) ) { 2383 // if (0) { 2384 // result = false; 2385 // break; 2386 // } else { 2387 // // If there is no triangle, add it regularly. 2388 // if (existentTrianglesCount == 0) { 2389 // AddTesselationPoint((*it)->point, 0); 2390 // AddTesselationPoint(BaseRay->endpoints[0]->node, 1); 2391 // AddTesselationPoint(BaseRay->endpoints[1]->node, 2); 2392 // 2393 // if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const )TPS)) { 2394 // CandidateLine.point = (*it)->point; 2395 // CandidateLine.OptCenter.CopyVector(&((*it)->OptCenter)); 2396 // CandidateLine.OtherOptCenter.CopyVector(&((*it)->OtherOptCenter)); 2397 // CandidateLine.ShortestAngle = ShortestAngle; 2398 // } else { 2399 //// eLog() << Verbose(1) << "This triangle consisting of "; 2400 //// Log() << Verbose(0) << *(*it)->point << ", "; 2401 //// Log() << Verbose(0) << *BaseRay->endpoints[0]->node << " and "; 2402 //// Log() << Verbose(0) << *BaseRay->endpoints[1]->node << " "; 2403 //// Log() << Verbose(0) << "exists and is not added, as it 0x80000000006fc150(does not seem helpful!" << endl; 2404 // result = false; 2405 // } 2406 // } else if ((existentTrianglesCount >= 1) && (existentTrianglesCount <= 3)) { // If there is a planar region within the structure, we need this triangle a second time. 2407 // AddTesselationPoint((*it)->point, 0); 2408 // AddTesselationPoint(BaseRay->endpoints[0]->node, 1); 2409 // AddTesselationPoint(BaseRay->endpoints[1]->node, 2); 2410 // 2411 // // 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) 2412 // // i.e. at least one of the three lines must be present with TriangleCount <= 1 2413 // if (CheckLineCriteriaForDegeneratedTriangle((const BoundaryPointSet ** const)TPS) || CandidateLine.BaseLine->skipped) { 2414 // CandidateLine.point = (*it)->point; 2415 // CandidateLine.OptCenter.CopyVector(&(*it)->OptCenter); 2416 // CandidateLine.OtherOptCenter.CopyVector(&(*it)->OtherOptCenter); 2417 // CandidateLine.ShortestAngle = ShortestAngle+2.*M_PI; 2418 // 2419 // } else { 2420 //// 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; 2421 // result = false; 2422 // } 2423 // } else { 2424 //// Log() << Verbose(1) << "This triangle consisting of "; 2425 //// Log() << Verbose(0) << *(*it)->point << ", "; 2426 //// Log() << Verbose(0) << *BaseRay->endpoints[0]->node << " and "; 2427 //// Log() << Verbose(0) << *BaseRay->endpoints[1]->node << " "; 2428 //// Log() << Verbose(0) << "is invalid!" << endl; 2429 // result = false; 2430 // } 2431 // } 2432 // 2433 // // set baseline to new ray from ref point (here endpoints[0]->node) to current candidate (here (*it)->point)) 2434 // BaseRay = BLS[0]; 2435 // if ((BTS != NULL) && (BTS->NormalVector.NormSquared() < MYEPSILON)) { 2436 // eLog() << Verbose(1) << "Triangle " << *BTS << " has zero normal vector!" << endl; 2437 // exit(255); 2438 // } 2439 // 2440 // } 2441 // 2442 // // remove all candidates from the list and then the list itself 2443 // class CandidateForTesselation *remover = NULL; 2444 // for (CandidateList::iterator it = OptCandidates->begin(); it != OptCandidates->end(); ++it) { 2445 // remover = *it; 2446 // delete(remover); 2447 // } 2448 // delete(OptCandidates); 2043 2449 return result; 2450 }; 2451 2452 /** Adds the present line and candidate point from \a &CandidateLine to the Tesselation. 2453 * \param CandidateLine triangle to add 2454 * \NOTE we need the copy operator here as the original CandidateForTesselation is removed in AddTesselationLine() 2455 */ 2456 void Tesselation::AddCandidateTriangle(CandidateForTesselation CandidateLine) 2457 { 2458 Info FunctionInfo(__func__); 2459 Vector Center; 2460 TesselPoint * const TurningPoint = CandidateLine.BaseLine->endpoints[0]->node; 2461 2462 // fill the set of neighbours 2463 TesselPointSet SetOfNeighbours; 2464 SetOfNeighbours.insert(CandidateLine.BaseLine->endpoints[1]->node); 2465 for (TesselPointList::iterator Runner = CandidateLine.pointlist.begin(); Runner != CandidateLine.pointlist.end(); Runner++) 2466 SetOfNeighbours.insert(*Runner); 2467 TesselPointList *connectedClosestPoints = GetCircleOfSetOfPoints(&SetOfNeighbours, TurningPoint, CandidateLine.BaseLine->endpoints[1]->node->node); 2468 2469 // go through all angle-sorted candidates (in degenerate n-nodes case we may have to add multiple triangles) 2470 Log() << Verbose(0) << "List of Candidates for Turning Point: " << *TurningPoint << "." << endl; 2471 for (TesselPointList::iterator TesselRunner = connectedClosestPoints->begin(); TesselRunner != connectedClosestPoints->end(); ++TesselRunner) 2472 Log() << Verbose(0) << **TesselRunner << endl; 2473 TesselPointList::iterator Runner = connectedClosestPoints->begin(); 2474 TesselPointList::iterator Sprinter = Runner; 2475 Sprinter++; 2476 while(Sprinter != connectedClosestPoints->end()) { 2477 // add the points 2478 AddTesselationPoint(TurningPoint, 0); 2479 AddTesselationPoint((*Runner), 1); 2480 AddTesselationPoint((*Sprinter), 2); 2481 2482 // add the lines 2483 AddTesselationLine(TPS[0], TPS[1], 0); 2484 AddTesselationLine(TPS[0], TPS[2], 1); 2485 AddTesselationLine(TPS[1], TPS[2], 2); 2486 2487 // add the triangles 2488 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2489 AddTesselationTriangle(); 2490 BTS->GetCenter(&Center); 2491 Center.SubtractVector(&CandidateLine.OptCenter); 2492 BTS->SphereCenter.CopyVector(&CandidateLine.OptCenter); 2493 BTS->GetNormalVector(Center); 2494 2495 Log() << Verbose(0) << "--> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << "." << endl; 2496 Runner = Sprinter; 2497 Sprinter++; 2498 Log() << Verbose(0) << "Current Runner is " << **Runner << "." << endl; 2499 if (Sprinter != connectedClosestPoints->end()) 2500 Log() << Verbose(0) << " There are still more triangles to add." << endl; 2501 } 2502 delete(connectedClosestPoints); 2044 2503 }; 2045 2504 … … 2053 2512 class BoundaryPointSet *Tesselation::IsConvexRectangle(class BoundaryLineSet *Base) 2054 2513 { 2514 Info FunctionInfo(__func__); 2055 2515 class BoundaryPointSet *Spot = NULL; 2056 2516 class BoundaryLineSet *OtherBase; … … 2064 2524 OtherBase = new class BoundaryLineSet(BPS,-1); 2065 2525 2066 Log() << Verbose( 3) << "INFO: Current base line is " << *Base << "." << endl;2067 Log() << Verbose( 3) << "INFO: Other base line is " << *OtherBase << "." << endl;2526 Log() << Verbose(1) << "INFO: Current base line is " << *Base << "." << endl; 2527 Log() << Verbose(1) << "INFO: Other base line is " << *OtherBase << "." << endl; 2068 2528 2069 2529 // get the closest point on each line to the other line … … 2085 2545 delete(ClosestPoint); 2086 2546 if ((distance[0] * distance[1]) > 0) { // have same sign? 2087 Log() << Verbose( 3) << "REJECT: Both SKPs have same sign: " << distance[0] << " and " << distance[1] << ". " << *Base << "' rectangle is concave." << endl;2547 Log() << Verbose(1) << "REJECT: Both SKPs have same sign: " << distance[0] << " and " << distance[1] << ". " << *Base << "' rectangle is concave." << endl; 2088 2548 if (distance[0] < distance[1]) { 2089 2549 Spot = Base->endpoints[0]; … … 2093 2553 return Spot; 2094 2554 } else { // different sign, i.e. we are in between 2095 Log() << Verbose( 3) << "ACCEPT: Rectangle of triangles of base line " << *Base << " is convex." << endl;2555 Log() << Verbose(0) << "ACCEPT: Rectangle of triangles of base line " << *Base << " is convex." << endl; 2096 2556 return NULL; 2097 2557 } … … 2101 2561 void Tesselation::PrintAllBoundaryPoints(ofstream *out) const 2102 2562 { 2563 Info FunctionInfo(__func__); 2103 2564 // print all lines 2104 Log() << Verbose( 1) << "Printing all boundary points for debugging:" << endl;2565 Log() << Verbose(0) << "Printing all boundary points for debugging:" << endl; 2105 2566 for (PointMap::const_iterator PointRunner = PointsOnBoundary.begin();PointRunner != PointsOnBoundary.end(); PointRunner++) 2106 Log() << Verbose( 2) << *(PointRunner->second) << endl;2567 Log() << Verbose(0) << *(PointRunner->second) << endl; 2107 2568 }; 2108 2569 2109 2570 void Tesselation::PrintAllBoundaryLines(ofstream *out) const 2110 2571 { 2572 Info FunctionInfo(__func__); 2111 2573 // print all lines 2112 Log() << Verbose( 1) << "Printing all boundary lines for debugging:" << endl;2574 Log() << Verbose(0) << "Printing all boundary lines for debugging:" << endl; 2113 2575 for (LineMap::const_iterator LineRunner = LinesOnBoundary.begin(); LineRunner != LinesOnBoundary.end(); LineRunner++) 2114 Log() << Verbose( 2) << *(LineRunner->second) << endl;2576 Log() << Verbose(0) << *(LineRunner->second) << endl; 2115 2577 }; 2116 2578 2117 2579 void Tesselation::PrintAllBoundaryTriangles(ofstream *out) const 2118 2580 { 2581 Info FunctionInfo(__func__); 2119 2582 // print all triangles 2120 Log() << Verbose( 1) << "Printing all boundary triangles for debugging:" << endl;2583 Log() << Verbose(0) << "Printing all boundary triangles for debugging:" << endl; 2121 2584 for (TriangleMap::const_iterator TriangleRunner = TrianglesOnBoundary.begin(); TriangleRunner != TrianglesOnBoundary.end(); TriangleRunner++) 2122 Log() << Verbose( 2) << *(TriangleRunner->second) << endl;2585 Log() << Verbose(0) << *(TriangleRunner->second) << endl; 2123 2586 }; 2124 2587 … … 2130 2593 double Tesselation::PickFarthestofTwoBaselines(class BoundaryLineSet *Base) 2131 2594 { 2595 Info FunctionInfo(__func__); 2132 2596 class BoundaryLineSet *OtherBase; 2133 2597 Vector *ClosestPoint[2]; … … 2141 2605 OtherBase = new class BoundaryLineSet(BPS,-1); 2142 2606 2143 Log() << Verbose( 3) << "INFO: Current base line is " << *Base << "." << endl;2144 Log() << Verbose( 3) << "INFO: Other base line is " << *OtherBase << "." << endl;2607 Log() << Verbose(0) << "INFO: Current base line is " << *Base << "." << endl; 2608 Log() << Verbose(0) << "INFO: Other base line is " << *OtherBase << "." << endl; 2145 2609 2146 2610 // get the closest point on each line to the other line … … 2162 2626 2163 2627 if (Distance.NormSquared() < MYEPSILON) { // check for intersection 2164 Log() << Verbose( 3) << "REJECT: Both lines have an intersection: Nothing to do." << endl;2628 Log() << Verbose(0) << "REJECT: Both lines have an intersection: Nothing to do." << endl; 2165 2629 return false; 2166 2630 } else { // check for sign against BaseLineNormal … … 2172 2636 } 2173 2637 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { 2174 Log() << Verbose( 4) << "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << "." << endl;2638 Log() << Verbose(1) << "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << "." << endl; 2175 2639 BaseLineNormal.AddVector(&(runner->second->NormalVector)); 2176 2640 } … … 2178 2642 2179 2643 if (Distance.ScalarProduct(&BaseLineNormal) > MYEPSILON) { // Distance points outwards, hence OtherBase higher than Base -> flip 2180 Log() << Verbose( 2) << "ACCEPT: Other base line would be higher: Flipping baseline." << endl;2644 Log() << Verbose(0) << "ACCEPT: Other base line would be higher: Flipping baseline." << endl; 2181 2645 // calculate volume summand as a general tetraeder 2182 2646 return volume; 2183 2647 } else { // Base higher than OtherBase -> do nothing 2184 Log() << Verbose( 2) << "REJECT: Base line is higher: Nothing to do." << endl;2648 Log() << Verbose(0) << "REJECT: Base line is higher: Nothing to do." << endl; 2185 2649 return 0.; 2186 2650 } … … 2197 2661 class BoundaryLineSet * Tesselation::FlipBaseline(class BoundaryLineSet *Base) 2198 2662 { 2663 Info FunctionInfo(__func__); 2199 2664 class BoundaryLineSet *OldLines[4], *NewLine; 2200 2665 class BoundaryPointSet *OldPoints[2]; … … 2203 2668 int i,m; 2204 2669 2205 Log() << Verbose(1) << "Begin of FlipBaseline" << endl;2206 2207 2670 // calculate NormalVector for later use 2208 2671 BaseLineNormal.Zero(); … … 2212 2675 } 2213 2676 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { 2214 Log() << Verbose( 4) << "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << "." << endl;2677 Log() << Verbose(1) << "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << "." << endl; 2215 2678 BaseLineNormal.AddVector(&(runner->second->NormalVector)); 2216 2679 } … … 2225 2688 i=0; 2226 2689 m=0; 2227 Log() << Verbose( 3) << "The four old lines are: ";2690 Log() << Verbose(0) << "The four old lines are: "; 2228 2691 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 2229 2692 for (int j=0;j<3;j++) // all of their endpoints and baselines … … 2233 2696 } 2234 2697 Log() << Verbose(0) << endl; 2235 Log() << Verbose( 3) << "The two old points are: ";2698 Log() << Verbose(0) << "The two old points are: "; 2236 2699 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 2237 2700 for (int j=0;j<3;j++) // all of their endpoints and baselines … … 2259 2722 2260 2723 // remove triangles and baseline removes itself 2261 Log() << Verbose( 3) << "INFO: Deleting baseline " << *Base << " from global list." << endl;2724 Log() << Verbose(0) << "INFO: Deleting baseline " << *Base << " from global list." << endl; 2262 2725 OldBaseLineNr = Base->Nr; 2263 2726 m=0; 2264 2727 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { 2265 Log() << Verbose( 3) << "INFO: Deleting triangle " << *(runner->second) << "." << endl;2728 Log() << Verbose(0) << "INFO: Deleting triangle " << *(runner->second) << "." << endl; 2266 2729 OldTriangleNrs[m++] = runner->second->Nr; 2267 2730 RemoveTesselationTriangle(runner->second); … … 2273 2736 NewLine = new class BoundaryLineSet(BPS, OldBaseLineNr); 2274 2737 LinesOnBoundary.insert(LinePair(OldBaseLineNr, NewLine)); // no need for check for unique insertion as NewLine is definitely a new one 2275 Log() << Verbose( 3) << "INFO: Created new baseline " << *NewLine << "." << endl;2738 Log() << Verbose(0) << "INFO: Created new baseline " << *NewLine << "." << endl; 2276 2739 2277 2740 // construct new triangles with flipped baseline … … 2288 2751 BTS->GetNormalVector(BaseLineNormal); 2289 2752 AddTesselationTriangle(OldTriangleNrs[0]); 2290 Log() << Verbose( 3) << "INFO: Created new triangle " << *BTS << "." << endl;2753 Log() << Verbose(0) << "INFO: Created new triangle " << *BTS << "." << endl; 2291 2754 2292 2755 BLS[0] = (i==2 ? OldLines[3] : OldLines[2]); … … 2296 2759 BTS->GetNormalVector(BaseLineNormal); 2297 2760 AddTesselationTriangle(OldTriangleNrs[1]); 2298 Log() << Verbose( 3) << "INFO: Created new triangle " << *BTS << "." << endl;2761 Log() << Verbose(0) << "INFO: Created new triangle " << *BTS << "." << endl; 2299 2762 } else { 2300 Log() << Verbose(1) << "The four old lines do not connect, something's utterly wrong here!" << endl;2763 eLog() << Verbose(0) << "The four old lines do not connect, something's utterly wrong here!" << endl; 2301 2764 return NULL; 2302 2765 } 2303 2766 2304 Log() << Verbose(1) << "End of FlipBaseline" << endl;2305 2767 return NewLine; 2306 2768 }; … … 2317 2779 void Tesselation::FindSecondPointForTesselation(TesselPoint* a, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, const LinkedCell *LC) 2318 2780 { 2319 Log() << Verbose(2) << "Begin of FindSecondPointForTesselation" << endl;2781 Info FunctionInfo(__func__); 2320 2782 Vector AngleCheck; 2321 2783 class TesselPoint* Candidate = NULL; … … 2338 2800 Nupper[i] = ((N[i]+1) < LC->N[i]) ? N[i]+1 : LC->N[i]-1; 2339 2801 } 2340 Log() << Verbose( 3) << "LC Intervals from [" << N[0] << "<->" << LC->N[0] << ", " << N[1] << "<->" << LC->N[1] << ", " << N[2] << "<->" << LC->N[2] << "] :"2802 Log() << Verbose(0) << "LC Intervals from [" << N[0] << "<->" << LC->N[0] << ", " << N[1] << "<->" << LC->N[1] << ", " << N[2] << "<->" << LC->N[2] << "] :" 2341 2803 << " [" << Nlower[0] << "," << Nupper[0] << "], " << " [" << Nlower[1] << "," << Nupper[1] << "], " << " [" << Nlower[2] << "," << Nupper[2] << "], " << endl; 2342 2804 … … 2345 2807 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 2346 2808 const LinkedNodes *List = LC->GetCurrentCell(); 2347 //Log() << Verbose( 2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;2809 //Log() << Verbose(1) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 2348 2810 if (List != NULL) { 2349 2811 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { … … 2376 2838 angle = AngleCheck.Angle(&Oben); 2377 2839 if (angle < Storage[0]) { 2378 //Log() << Verbose( 3) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);2379 Log() << Verbose( 3) << "Current candidate is " << *Candidate << ": Is a better candidate with distance " << norm << " and angle " << angle << " to oben " << Oben << ".\n";2840 //Log() << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]); 2841 Log() << Verbose(1) << "Current candidate is " << *Candidate << ": Is a better candidate with distance " << norm << " and angle " << angle << " to oben " << Oben << ".\n"; 2380 2842 OptCandidate = Candidate; 2381 2843 Storage[0] = angle; 2382 //Log() << Verbose( 3) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);2844 //Log() << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]); 2383 2845 } else { 2384 //Log() << Verbose( 3) << "Current candidate is " << *Candidate << ": Looses with angle " << angle << " to a better candidate " << *OptCandidate << endl;2846 //Log() << Verbose(1) << "Current candidate is " << *Candidate << ": Looses with angle " << angle << " to a better candidate " << *OptCandidate << endl; 2385 2847 } 2386 2848 } else { 2387 //Log() << Verbose( 3) << "Current candidate is " << *Candidate << ": Refused due to Radius " << norm << endl;2849 //Log() << Verbose(1) << "Current candidate is " << *Candidate << ": Refused due to Radius " << norm << endl; 2388 2850 } 2389 2851 } else { 2390 //Log() << Verbose( 3) << "Current candidate is " << *Candidate << ": Candidate is equal to first endpoint." << *a << "." << endl;2852 //Log() << Verbose(1) << "Current candidate is " << *Candidate << ": Candidate is equal to first endpoint." << *a << "." << endl; 2391 2853 } 2392 2854 } 2393 2855 } else { 2394 Log() << Verbose( 3) << "Linked cell list is empty." << endl;2856 Log() << Verbose(0) << "Linked cell list is empty." << endl; 2395 2857 } 2396 2858 } 2397 Log() << Verbose(2) << "End of FindSecondPointForTesselation" << endl;2398 2859 }; 2399 2860 … … 2424 2885 * @param SearchDirection general direction where to search for the next point, relative to center of BaseLine 2425 2886 * @param OldSphereCenter center of sphere for base triangle, relative to center of BaseLine, giving null angle for the parameter circle 2426 * @param BaseLine BoundaryLineSet with the current base line2887 * @param CandidateLine CandidateForTesselation with the current base line and list of candidates and ShortestAngle 2427 2888 * @param ThirdNode third point to avoid in search 2428 * @param candidates list of equally good candidates to return2429 * @param ShortestAngle the current path length on this circle band for the current OptCandidate2430 2889 * @param RADIUS radius of sphere 2431 2890 * @param *LC LinkedCell structure with neighbouring points 2432 2891 */ 2433 void Tesselation::FindThirdPointForTesselation(Vector &NormalVector, Vector &SearchDirection, Vector &OldSphereCenter, class BoundaryLineSet *BaseLine, const class TesselPoint * const ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, const LinkedCell *LC) const 2434 { 2892 void Tesselation::FindThirdPointForTesselation(Vector &NormalVector, Vector &SearchDirection, Vector &OldSphereCenter, CandidateForTesselation &CandidateLine, const class TesselPoint * const ThirdNode, const double RADIUS, const LinkedCell *LC) const 2893 { 2894 Info FunctionInfo(__func__); 2435 2895 Vector CircleCenter; // center of the circle, i.e. of the band of sphere's centers 2436 2896 Vector CirclePlaneNormal; // normal vector defining the plane this circle lives in … … 2440 2900 Vector NewNormalVector; // normal vector of the Candidate's triangle 2441 2901 Vector helper, OptCandidateCenter, OtherOptCandidateCenter; 2902 Vector RelativeOldSphereCenter; 2903 Vector NewPlaneCenter; 2442 2904 double CircleRadius; // radius of this circle 2443 2905 double radius; 2906 double otherradius; 2444 2907 double alpha, Otheralpha; // angles (i.e. parameter for the circle). 2445 2908 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 2446 2909 TesselPoint *Candidate = NULL; 2447 CandidateForTesselation *optCandidate = NULL; 2448 2449 Log() << Verbose(1) << "Begin of FindThirdPointForTesselation" << endl; 2450 2451 Log() << Verbose(2) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl; 2910 2911 Log() << Verbose(1) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl; 2452 2912 2453 2913 // construct center of circle 2454 CircleCenter.CopyVector( BaseLine->endpoints[0]->node->node);2455 CircleCenter.AddVector( BaseLine->endpoints[1]->node->node);2914 CircleCenter.CopyVector(CandidateLine.BaseLine->endpoints[0]->node->node); 2915 CircleCenter.AddVector(CandidateLine.BaseLine->endpoints[1]->node->node); 2456 2916 CircleCenter.Scale(0.5); 2457 2917 2458 2918 // construct normal vector of circle 2459 CirclePlaneNormal.CopyVector(BaseLine->endpoints[0]->node->node); 2460 CirclePlaneNormal.SubtractVector(BaseLine->endpoints[1]->node->node); 2919 CirclePlaneNormal.CopyVector(CandidateLine.BaseLine->endpoints[0]->node->node); 2920 CirclePlaneNormal.SubtractVector(CandidateLine.BaseLine->endpoints[1]->node->node); 2921 2922 RelativeOldSphereCenter.CopyVector(&OldSphereCenter); 2923 RelativeOldSphereCenter.SubtractVector(&CircleCenter); 2461 2924 2462 2925 // calculate squared radius TesselPoint *ThirdNode,f circle 2463 radius = CirclePlaneNormal. ScalarProduct(&CirclePlaneNormal);2464 if (radius /4.< RADIUS*RADIUS) {2465 CircleRadius = RADIUS*RADIUS - radius /4.;2926 radius = CirclePlaneNormal.NormSquared()/4.; 2927 if (radius < RADIUS*RADIUS) { 2928 CircleRadius = RADIUS*RADIUS - radius; 2466 2929 CirclePlaneNormal.Normalize(); 2467 //Log() << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;2930 Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 2468 2931 2469 2932 // test whether old center is on the band's plane 2470 if (fabs( OldSphereCenter.ScalarProduct(&CirclePlaneNormal)) > HULLEPSILON) {2471 eLog() << Verbose(1) << "Something's very wrong here: OldSphereCenter is not on the band's plane as desired by " << fabs(OldSphereCenter.ScalarProduct(&CirclePlaneNormal)) << "!" << endl;2472 OldSphereCenter.ProjectOntoPlane(&CirclePlaneNormal);2473 } 2474 radius = OldSphereCenter.ScalarProduct(&OldSphereCenter);2933 if (fabs(RelativeOldSphereCenter.ScalarProduct(&CirclePlaneNormal)) > HULLEPSILON) { 2934 eLog() << Verbose(1) << "Something's very wrong here: RelativeOldSphereCenter is not on the band's plane as desired by " << fabs(RelativeOldSphereCenter.ScalarProduct(&CirclePlaneNormal)) << "!" << endl; 2935 RelativeOldSphereCenter.ProjectOntoPlane(&CirclePlaneNormal); 2936 } 2937 radius = RelativeOldSphereCenter.NormSquared(); 2475 2938 if (fabs(radius - CircleRadius) < HULLEPSILON) { 2476 //Log() << Verbose(2) << "INFO: OldSphereCenter is at " <<OldSphereCenter << "." << endl;2939 Log() << Verbose(1) << "INFO: RelativeOldSphereCenter is at " << RelativeOldSphereCenter << "." << endl; 2477 2940 2478 2941 // check SearchDirection 2479 //Log() << Verbose(2) << "INFO: SearchDirection is " << SearchDirection << "." << endl;2480 if (fabs( OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { // rotated the wrong way!2942 Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl; 2943 if (fabs(RelativeOldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { // rotated the wrong way! 2481 2944 eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are not orthogonal!" << endl; 2482 2945 } … … 2486 2949 for(int i=0;i<NDIM;i++) // store indices of this cell 2487 2950 N[i] = LC->n[i]; 2488 //Log() << Verbose( 2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;2951 //Log() << Verbose(1) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 2489 2952 } else { 2490 2953 eLog() << Verbose(1) << "Vector " << CircleCenter << " is outside of LinkedCell's bounding box." << endl; … … 2492 2955 } 2493 2956 // then go through the current and all neighbouring cells and check the contained points for possible candidates 2494 //Log() << Verbose( 2) << "LC Intervals:";2957 //Log() << Verbose(1) << "LC Intervals:"; 2495 2958 for (int i=0;i<NDIM;i++) { 2496 2959 Nlower[i] = ((N[i]-1) >= 0) ? N[i]-1 : 0; … … 2503 2966 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 2504 2967 const LinkedNodes *List = LC->GetCurrentCell(); 2505 //Log() << Verbose( 2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;2968 //Log() << Verbose(1) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 2506 2969 if (List != NULL) { 2507 2970 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { … … 2509 2972 2510 2973 // check for three unique points 2511 //Log() << Verbose(2) << "INFO: Current Candidate is " << *Candidate << " at " << Candidate->node<< "." << endl;2512 if ((Candidate != BaseLine->endpoints[0]->node) && (Candidate !=BaseLine->endpoints[1]->node) ){2513 2514 // construct both new centers2515 GetCenterofCircumcircle(&New SphereCenter, *BaseLine->endpoints[0]->node->node, *BaseLine->endpoints[1]->node->node, *Candidate->node);2516 OtherNewSphereCenter.CopyVector(&NewSphereCenter);2517 2518 if ( (NewNormalVector.MakeNormalVector(BaseLine->endpoints[0]->node->node, BaseLine->endpoints[1]->node->node, Candidate->node))2519 && (fabs(NewNormalVector. ScalarProduct(&NewNormalVector)) > HULLEPSILON)2974 Log() << Verbose(2) << "INFO: Current Candidate is " << *Candidate << " for BaseLine " << *CandidateLine.BaseLine << " with OldSphereCenter " << OldSphereCenter << "." << endl; 2975 if ((Candidate != CandidateLine.BaseLine->endpoints[0]->node) && (Candidate != CandidateLine.BaseLine->endpoints[1]->node) ){ 2976 2977 // find center on the plane 2978 GetCenterofCircumcircle(&NewPlaneCenter, *CandidateLine.BaseLine->endpoints[0]->node->node, *CandidateLine.BaseLine->endpoints[1]->node->node, *Candidate->node); 2979 Log() << Verbose(1) << "INFO: NewPlaneCenter is " << NewPlaneCenter << "." << endl; 2980 2981 if (NewNormalVector.MakeNormalVector(CandidateLine.BaseLine->endpoints[0]->node->node, CandidateLine.BaseLine->endpoints[1]->node->node, Candidate->node) 2982 && (fabs(NewNormalVector.NormSquared()) > HULLEPSILON) 2520 2983 ) { 2521 helper.CopyVector(&NewNormalVector); 2522 //Log() << Verbose(2) << "INFO: NewNormalVector is " << NewNormalVector << "." << endl; 2523 radius = BaseLine->endpoints[0]->node->node->DistanceSquared(&NewSphereCenter); 2984 Log() << Verbose(1) << "INFO: NewNormalVector is " << NewNormalVector << "." << endl; 2985 radius = CandidateLine.BaseLine->endpoints[0]->node->node->DistanceSquared(&NewPlaneCenter); 2986 Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 2987 Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl; 2988 Log() << Verbose(1) << "INFO: Radius of CircumCenterCircle is " << radius << "." << endl; 2524 2989 if (radius < RADIUS*RADIUS) { 2990 otherradius = CandidateLine.BaseLine->endpoints[1]->node->node->DistanceSquared(&NewPlaneCenter); 2991 if (fabs(radius - otherradius) > HULLEPSILON) { 2992 eLog() << Verbose(1) << "Distance to center of circumcircle is not the same from each corner of the triangle: " << fabs(radius-otherradius) << endl; 2993 } 2994 // construct both new centers 2995 NewSphereCenter.CopyVector(&NewPlaneCenter); 2996 OtherNewSphereCenter.CopyVector(&NewPlaneCenter); 2997 helper.CopyVector(&NewNormalVector); 2525 2998 helper.Scale(sqrt(RADIUS*RADIUS - radius)); 2526 //Log() << Verbose(2) << "INFO: Distance of NewCircleCenter to NewSphereCenter is " << helper.Norm()<< " with sphere radius " << RADIUS << "." << endl;2999 Log() << Verbose(2) << "INFO: Distance of NewPlaneCenter " << NewPlaneCenter << " to either NewSphereCenter is " << helper.Norm() << " of vector " << helper << " with sphere radius " << RADIUS << "." << endl; 2527 3000 NewSphereCenter.AddVector(&helper); 2528 NewSphereCenter.SubtractVector(&CircleCenter); 2529 //Log() << Verbose(2) << "INFO: NewSphereCenter is at " << NewSphereCenter << "." << endl; 2530 3001 Log() << Verbose(2) << "INFO: NewSphereCenter is at " << NewSphereCenter << "." << endl; 2531 3002 // OtherNewSphereCenter is created by the same vector just in the other direction 2532 3003 helper.Scale(-1.); 2533 3004 OtherNewSphereCenter.AddVector(&helper); 2534 OtherNewSphereCenter.SubtractVector(&CircleCenter); 2535 //Log() << Verbose(2) << "INFO: OtherNewSphereCenter is at " << OtherNewSphereCenter << "." << endl; 3005 Log() << Verbose(2) << "INFO: OtherNewSphereCenter is at " << OtherNewSphereCenter << "." << endl; 2536 3006 2537 3007 alpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, NewSphereCenter, OldSphereCenter, NormalVector, SearchDirection); 2538 3008 Otheralpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, OtherNewSphereCenter, OldSphereCenter, NormalVector, SearchDirection); 2539 3009 alpha = min(alpha, Otheralpha); 3010 2540 3011 // if there is a better candidate, drop the current list and add the new candidate 2541 3012 // otherwise ignore the new candidate and keep the list 2542 if (*ShortestAngle > (alpha - HULLEPSILON)) { 2543 optCandidate = new CandidateForTesselation(Candidate, BaseLine, OptCandidateCenter, OtherOptCandidateCenter); 3013 if (CandidateLine.ShortestAngle > (alpha - HULLEPSILON)) { 2544 3014 if (fabs(alpha - Otheralpha) > MYEPSILON) { 2545 optCandidate->OptCenter.CopyVector(&NewSphereCenter);2546 optCandidate->OtherOptCenter.CopyVector(&OtherNewSphereCenter);3015 CandidateLine.OptCenter.CopyVector(&NewSphereCenter); 3016 CandidateLine.OtherOptCenter.CopyVector(&OtherNewSphereCenter); 2547 3017 } else { 2548 optCandidate->OptCenter.CopyVector(&OtherNewSphereCenter);2549 optCandidate->OtherOptCenter.CopyVector(&NewSphereCenter);3018 CandidateLine.OptCenter.CopyVector(&OtherNewSphereCenter); 3019 CandidateLine.OtherOptCenter.CopyVector(&NewSphereCenter); 2550 3020 } 2551 3021 // if there is an equal candidate, add it to the list without clearing the list 2552 if (( *ShortestAngle - HULLEPSILON) < alpha) {2553 candidates->push_back(optCandidate);2554 Log() << Verbose( 2) << "ACCEPT: We have found an equally good candidate: " << *(optCandidate->point) << " with "2555 << alpha << " and circumsphere's center at " << optCandidate->OptCenter << "." << endl;3022 if ((CandidateLine.ShortestAngle - HULLEPSILON) < alpha) { 3023 CandidateLine.pointlist.push_back(Candidate); 3024 Log() << Verbose(0) << "ACCEPT: We have found an equally good candidate: " << *(Candidate) << " with " 3025 << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << "." << endl; 2556 3026 } else { 2557 3027 // remove all candidates from the list and then the list itself 2558 class CandidateForTesselation *remover = NULL; 2559 for (CandidateList::iterator it = candidates->begin(); it != candidates->end(); ++it) { 2560 remover = *it; 2561 delete(remover); 2562 } 2563 candidates->clear(); 2564 candidates->push_back(optCandidate); 2565 Log() << Verbose(2) << "ACCEPT: We have found a better candidate: " << *(optCandidate->point) << " with " 2566 << alpha << " and circumsphere's center at " << optCandidate->OptCenter << "." << endl; 3028 CandidateLine.pointlist.clear(); 3029 CandidateLine.pointlist.push_back(Candidate); 3030 Log() << Verbose(0) << "ACCEPT: We have found a better candidate: " << *(Candidate) << " with " 3031 << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << "." << endl; 2567 3032 } 2568 *ShortestAngle = alpha;2569 //Log() << Verbose(2) << "INFO: There are " << candidates->size() << " candidates in the list now." << endl;3033 CandidateLine.ShortestAngle = alpha; 3034 Log() << Verbose(0) << "INFO: There are " << CandidateLine.pointlist.size() << " candidates in the list now." << endl; 2570 3035 } else { 2571 if (( optCandidate != NULL) && (optCandidate->point != NULL)) {2572 //Log() << Verbose(2) << "REJECT: Old candidate " << *(optCandidate->point) << " with " << *ShortestAngle << " is better than new one " << *Candidate << " with " << alpha << " ." << endl;3036 if ((Candidate != NULL) && (CandidateLine.pointlist.begin() != CandidateLine.pointlist.end())) { 3037 Log() << Verbose(1) << "REJECT: Old candidate " << *(Candidate) << " with " << CandidateLine.ShortestAngle << " is better than new one " << *Candidate << " with " << alpha << " ." << endl; 2573 3038 } else { 2574 //Log() << Verbose(2) << "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected." << endl;3039 Log() << Verbose(1) << "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected." << endl; 2575 3040 } 2576 3041 } 2577 2578 3042 } else { 2579 //Log() << Verbose(2) << "REJECT: NewSphereCenter " << NewSphereCenter << " for " << *Candidate << " is too far away: " << radius << "." << endl;3043 Log() << Verbose(1) << "REJECT: NewSphereCenter " << NewSphereCenter << " for " << *Candidate << " is too far away: " << radius << "." << endl; 2580 3044 } 2581 3045 } else { 2582 //Log() << Verbose(2) << "REJECT: Three points from " << *BaseLine << " and Candidate " << *Candidate << " are linear-dependent." << endl;3046 Log() << Verbose(1) << "REJECT: Three points from " << *CandidateLine.BaseLine << " and Candidate " << *Candidate << " are linear-dependent." << endl; 2583 3047 } 2584 3048 } else { 2585 3049 if (ThirdNode != NULL) { 2586 //Log() << Verbose(2) << "REJECT: Base triangle " << *BaseLine << " and " << *ThirdNode << " contains Candidate " << *Candidate << "." << endl;3050 Log() << Verbose(1) << "REJECT: Base triangle " << *CandidateLine.BaseLine << " and " << *ThirdNode << " contains Candidate " << *Candidate << "." << endl; 2587 3051 } else { 2588 //Log() << Verbose(2) << "REJECT: Base triangle " << *BaseLine << " contains Candidate " << *Candidate << "." << endl;3052 Log() << Verbose(1) << "REJECT: Base triangle " << *CandidateLine.BaseLine << " contains Candidate " << *Candidate << "." << endl; 2589 3053 } 2590 3054 } … … 2597 3061 } else { 2598 3062 if (ThirdNode != NULL) 2599 Log() << Verbose( 2) << "Circumcircle for base line " << *BaseLine << " and third node " << *ThirdNode << " is too big!" << endl;3063 Log() << Verbose(1) << "Circumcircle for base line " << *CandidateLine.BaseLine << " and third node " << *ThirdNode << " is too big!" << endl; 2600 3064 else 2601 Log() << Verbose(2) << "Circumcircle for base line " << *BaseLine << " is too big!" << endl; 2602 } 2603 2604 //Log() << Verbose(2) << "INFO: Sorting candidate list ..." << endl; 2605 if (candidates->size() > 1) { 2606 candidates->unique(); 2607 candidates->sort(SortCandidates); 2608 } 2609 2610 Log() << Verbose(1) << "End of FindThirdPointForTesselation" << endl; 3065 Log() << Verbose(1) << "Circumcircle for base line " << *CandidateLine.BaseLine << " is too big!" << endl; 3066 } 3067 3068 Log() << Verbose(1) << "INFO: Sorting candidate list ..." << endl; 3069 if (CandidateLine.pointlist.size() > 1) { 3070 CandidateLine.pointlist.unique(); 3071 CandidateLine.pointlist.sort(); //SortCandidates); 3072 } 2611 3073 }; 2612 3074 … … 2618 3080 class BoundaryPointSet *Tesselation::GetCommonEndpoint(const BoundaryLineSet * line1, const BoundaryLineSet * line2) const 2619 3081 { 3082 Info FunctionInfo(__func__); 2620 3083 const BoundaryLineSet * lines[2] = { line1, line2 }; 2621 3084 class BoundaryPointSet *node = NULL; 2622 map<int, class BoundaryPointSet *>OrderMap;2623 pair<map<int, class BoundaryPointSet *>::iterator, bool>OrderTest;3085 PointMap OrderMap; 3086 PointTestPair OrderTest; 2624 3087 for (int i = 0; i < 2; i++) 2625 3088 // for both lines … … 2631 3094 { // if insertion fails, we have common endpoint 2632 3095 node = OrderTest.first->second; 2633 Log() << Verbose( 5) << "Common endpoint of lines " << *line13096 Log() << Verbose(1) << "Common endpoint of lines " << *line1 2634 3097 << " and " << *line2 << " is: " << *node << "." << endl; 2635 3098 j = 2; … … 2641 3104 }; 2642 3105 3106 /** Finds the boundary points that are closest to a given Vector \a *x. 3107 * \param *out output stream for debugging 3108 * \param *x Vector to look from 3109 * \return map of BoundaryPointSet of closest points sorted by squared distance or NULL. 3110 */ 3111 DistanceToPointMap * Tesselation::FindClosestBoundaryPointsToVector(const Vector *x, const LinkedCell* LC) const 3112 { 3113 Info FunctionInfo(__func__); 3114 PointMap::const_iterator FindPoint; 3115 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 3116 3117 if (LinesOnBoundary.empty()) { 3118 eLog() << Verbose(1) << "There is no tesselation structure to compare the point with, please create one first." << endl; 3119 return NULL; 3120 } 3121 3122 // gather all points close to the desired one 3123 LC->SetIndexToVector(x); // ignore status as we calculate bounds below sensibly 3124 for(int i=0;i<NDIM;i++) // store indices of this cell 3125 N[i] = LC->n[i]; 3126 Log() << Verbose(1) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 3127 3128 DistanceToPointMap * points = new DistanceToPointMap; 3129 LC->GetNeighbourBounds(Nlower, Nupper); 3130 //Log() << Verbose(1) << endl; 3131 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++) 3132 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 3133 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 3134 const LinkedNodes *List = LC->GetCurrentCell(); 3135 //Log() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 3136 if (List != NULL) { 3137 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 3138 FindPoint = PointsOnBoundary.find((*Runner)->nr); 3139 if (FindPoint != PointsOnBoundary.end()) { 3140 points->insert(DistanceToPointPair (FindPoint->second->node->node->DistanceSquared(x), FindPoint->second) ); 3141 Log() << Verbose(1) << "INFO: Putting " << *FindPoint->second << " into the list." << endl; 3142 } 3143 } 3144 } else { 3145 eLog() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << " is invalid!" << endl; 3146 } 3147 } 3148 3149 // check whether we found some points 3150 if (points->empty()) { 3151 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl; 3152 delete(points); 3153 return NULL; 3154 } 3155 return points; 3156 }; 3157 3158 /** Finds the boundary line that is closest to a given Vector \a *x. 3159 * \param *out output stream for debugging 3160 * \param *x Vector to look from 3161 * \return closest BoundaryLineSet or NULL in degenerate case. 3162 */ 3163 BoundaryLineSet * Tesselation::FindClosestBoundaryLineToVector(const Vector *x, const LinkedCell* LC) const 3164 { 3165 Info FunctionInfo(__func__); 3166 3167 // get closest points 3168 DistanceToPointMap * points = FindClosestBoundaryPointsToVector(x,LC); 3169 if (points == NULL) { 3170 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl; 3171 return NULL; 3172 } 3173 3174 // for each point, check its lines, remember closest 3175 Log() << Verbose(1) << "Finding closest BoundaryLine to " << *x << " ... " << endl; 3176 BoundaryLineSet *ClosestLine = NULL; 3177 double MinDistance = -1.; 3178 Vector helper; 3179 Vector Center; 3180 Vector BaseLine; 3181 for (DistanceToPointMap::iterator Runner = points->begin(); Runner != points->end(); Runner++) { 3182 for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) { 3183 // calculate closest point on line to desired point 3184 helper.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3185 helper.AddVector((LineRunner->second)->endpoints[1]->node->node); 3186 helper.Scale(0.5); 3187 Center.CopyVector(x); 3188 Center.SubtractVector(&helper); 3189 BaseLine.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3190 BaseLine.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3191 Center.ProjectOntoPlane(&BaseLine); 3192 const double distance = Center.NormSquared(); 3193 if ((ClosestLine == NULL) || (distance < MinDistance)) { 3194 // additionally calculate intersection on line (whether it's on the line section or not) 3195 helper.CopyVector(x); 3196 helper.SubtractVector((LineRunner->second)->endpoints[0]->node->node); 3197 helper.SubtractVector(&Center); 3198 const double lengthA = helper.ScalarProduct(&BaseLine); 3199 helper.CopyVector(x); 3200 helper.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3201 helper.SubtractVector(&Center); 3202 const double lengthB = helper.ScalarProduct(&BaseLine); 3203 if (lengthB*lengthA < 0) { // if have different sign 3204 ClosestLine = LineRunner->second; 3205 MinDistance = distance; 3206 Log() << Verbose(1) << "ACCEPT: New closest line is " << *ClosestLine << " with projected distance " << MinDistance << "." << endl; 3207 } else { 3208 Log() << Verbose(1) << "REJECT: Intersection is outside of the line section: " << lengthA << " and " << lengthB << "." << endl; 3209 } 3210 } else { 3211 Log() << Verbose(1) << "REJECT: Point is too further away than present line: " << distance << " >> " << MinDistance << "." << endl; 3212 } 3213 } 3214 } 3215 delete(points); 3216 // check whether closest line is "too close" :), then it's inside 3217 if (ClosestLine == NULL) { 3218 Log() << Verbose(0) << "Is the only point, no one else is closeby." << endl; 3219 return NULL; 3220 } 3221 return ClosestLine; 3222 }; 3223 3224 2643 3225 /** Finds the triangle that is closest to a given Vector \a *x. 2644 3226 * \param *out output stream for debugging 2645 3227 * \param *x Vector to look from 2646 * \return list of BoundaryTriangleSet of nearest triangles or NULL in degenerate case.2647 */ 2648 list<BoundaryTriangleSet*> * Tesselation::FindClosestTrianglesToPoint(const Vector *x, const LinkedCell* LC) const2649 { 2650 TesselPoint *trianglePoints[3];2651 TesselPoint *SecondPoint = NULL; 2652 list<BoundaryTriangleSet*> *triangles = NULL; 2653 2654 if ( LinesOnBoundary.empty()) {2655 Log() << Verbose(0) << "Error: There is no tesselation structure to compare the point with, please create one first.";3228 * \return BoundaryTriangleSet of nearest triangle or NULL. 3229 */ 3230 TriangleList * Tesselation::FindClosestTrianglesToVector(const Vector *x, const LinkedCell* LC) const 3231 { 3232 Info FunctionInfo(__func__); 3233 3234 // get closest points 3235 DistanceToPointMap * points = FindClosestBoundaryPointsToVector(x,LC); 3236 if (points == NULL) { 3237 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl; 2656 3238 return NULL; 2657 3239 } 2658 Log() << Verbose(1) << "Finding closest Tesselpoint to " << *x << " ... " << endl; 2659 trianglePoints[0] = FindClosestPoint(x, SecondPoint, LC); 2660 2661 // check whether closest point is "too close" :), then it's inside 2662 if (trianglePoints[0] == NULL) { 2663 Log() << Verbose(2) << "Is the only point, no one else is closeby." << endl; 3240 3241 // for each point, check its lines, remember closest 3242 Log() << Verbose(1) << "Finding closest BoundaryTriangle to " << *x << " ... " << endl; 3243 LineSet ClosestLines; 3244 double MinDistance = 1e+16; 3245 Vector BaseLineIntersection; 3246 Vector Center; 3247 Vector BaseLine; 3248 Vector BaseLineCenter; 3249 for (DistanceToPointMap::iterator Runner = points->begin(); Runner != points->end(); Runner++) { 3250 for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) { 3251 3252 BaseLine.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3253 BaseLine.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3254 const double lengthBase = BaseLine.NormSquared(); 3255 3256 BaseLineIntersection.CopyVector(x); 3257 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[0]->node->node); 3258 const double lengthEndA = BaseLineIntersection.NormSquared(); 3259 3260 BaseLineIntersection.CopyVector(x); 3261 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3262 const double lengthEndB = BaseLineIntersection.NormSquared(); 3263 3264 if ((lengthEndA > lengthBase) || (lengthEndB > lengthBase) || ((lengthEndA < MYEPSILON) || (lengthEndB < MYEPSILON))) { // intersection would be outside, take closer endpoint 3265 const double lengthEnd = Min(lengthEndA, lengthEndB); 3266 if (lengthEnd - MinDistance < -MYEPSILON) { // new best line 3267 ClosestLines.clear(); 3268 ClosestLines.insert(LineRunner->second); 3269 MinDistance = lengthEnd; 3270 Log() << Verbose(1) << "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[0]->node << " is closer with " << lengthEnd << "." << endl; 3271 } else if (fabs(lengthEnd - MinDistance) < MYEPSILON) { // additional best candidate 3272 ClosestLines.insert(LineRunner->second); 3273 Log() << Verbose(1) << "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[1]->node << " is equally good with " << lengthEnd << "." << endl; 3274 } else { // line is worse 3275 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; 3276 } 3277 } else { // intersection is closer, calculate 3278 // calculate closest point on line to desired point 3279 BaseLineIntersection.CopyVector(x); 3280 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3281 Center.CopyVector(&BaseLineIntersection); 3282 Center.ProjectOntoPlane(&BaseLine); 3283 BaseLineIntersection.SubtractVector(&Center); 3284 const double distance = BaseLineIntersection.NormSquared(); 3285 if (Center.NormSquared() > BaseLine.NormSquared()) { 3286 eLog() << Verbose(0) << "Algorithmic error: In second case we have intersection outside of baseline!" << endl; 3287 } 3288 if ((ClosestLines.empty()) || (distance < MinDistance)) { 3289 ClosestLines.insert(LineRunner->second); 3290 MinDistance = distance; 3291 Log() << Verbose(1) << "ACCEPT: Intersection in between endpoints, new closest line " << *LineRunner->second << " is " << *ClosestLines.begin() << " with projected distance " << MinDistance << "." << endl; 3292 } else { 3293 Log() << Verbose(2) << "REJECT: Point is further away from line " << *LineRunner->second << " than present closest line: " << distance << " >> " << MinDistance << "." << endl; 3294 } 3295 } 3296 } 3297 } 3298 delete(points); 3299 3300 // check whether closest line is "too close" :), then it's inside 3301 if (ClosestLines.empty()) { 3302 Log() << Verbose(0) << "Is the only point, no one else is closeby." << endl; 2664 3303 return NULL; 2665 3304 } 2666 if (trianglePoints[0]->node->DistanceSquared(x) < MYEPSILON) { 2667 Log() << Verbose(3) << "Point is right on a tesselation point, no nearest triangle." << endl; 2668 PointMap::const_iterator PointRunner = PointsOnBoundary.find(trianglePoints[0]->nr); 2669 triangles = new list<BoundaryTriangleSet*>; 2670 if (PointRunner != PointsOnBoundary.end()) { 2671 for(LineMap::iterator LineRunner = PointRunner->second->lines.begin(); LineRunner != PointRunner->second->lines.end(); LineRunner++) 2672 for(TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++) 2673 triangles->push_back(TriangleRunner->second); 2674 triangles->sort(); 2675 triangles->unique(); 2676 } else { 2677 PointRunner = PointsOnBoundary.find(SecondPoint->nr); 2678 trianglePoints[0] = SecondPoint; 2679 if (PointRunner != PointsOnBoundary.end()) { 2680 for(LineMap::iterator LineRunner = PointRunner->second->lines.begin(); LineRunner != PointRunner->second->lines.end(); LineRunner++) 2681 for(TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++) 2682 triangles->push_back(TriangleRunner->second); 2683 triangles->sort(); 2684 triangles->unique(); 2685 } else { 2686 eLog() << Verbose(1) << "I cannot find a boundary point to the tessel point " << *trianglePoints[0] << "." << endl; 2687 return NULL; 2688 } 2689 } 2690 } else { 2691 list<TesselPoint*> *connectedClosestPoints = GetCircleOfConnectedPoints(trianglePoints[0], x); 2692 if (connectedClosestPoints != NULL) { 2693 trianglePoints[1] = connectedClosestPoints->front(); 2694 trianglePoints[2] = connectedClosestPoints->back(); 2695 for (int i=0;i<3;i++) { 2696 if (trianglePoints[i] == NULL) { 2697 eLog() << Verbose(1) << "IsInnerPoint encounters serious error, point " << i << " not found." << endl; 2698 } 2699 //Log() << Verbose(2) << "List of triangle points:" << endl; 2700 //Log() << Verbose(3) << *trianglePoints[i] << endl; 2701 } 2702 2703 triangles = FindTriangles(trianglePoints); 2704 Log() << Verbose(2) << "List of possible triangles:" << endl; 2705 for(list<BoundaryTriangleSet*>::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) 2706 Log() << Verbose(3) << **Runner << endl; 2707 2708 delete(connectedClosestPoints); 2709 } else { 2710 triangles = NULL; 2711 Log() << Verbose(1) << "There is no circle of connected points!" << endl; 2712 } 2713 } 2714 2715 if ((triangles == NULL) || (triangles->empty())) { 2716 eLog() << Verbose(1) << "There is no nearest triangle. Please check the tesselation structure."; 2717 delete(triangles); 2718 return NULL; 2719 } else 2720 return triangles; 3305 TriangleList * candidates = new TriangleList; 3306 for (LineSet::iterator LineRunner = ClosestLines.begin(); LineRunner != ClosestLines.end(); LineRunner++) 3307 for (TriangleMap::iterator Runner = (*LineRunner)->triangles.begin(); Runner != (*LineRunner)->triangles.end(); Runner++) { 3308 candidates->push_back(Runner->second); 3309 } 3310 return candidates; 2721 3311 }; 2722 3312 … … 2727 3317 * \return list of BoundaryTriangleSet of nearest triangles or NULL. 2728 3318 */ 2729 class BoundaryTriangleSet * Tesselation::FindClosestTriangleToPoint(const Vector *x, const LinkedCell* LC) const 2730 { 3319 class BoundaryTriangleSet * Tesselation::FindClosestTriangleToVector(const Vector *x, const LinkedCell* LC) const 3320 { 3321 Info FunctionInfo(__func__); 2731 3322 class BoundaryTriangleSet *result = NULL; 2732 list<BoundaryTriangleSet*> *triangles = FindClosestTrianglesToPoint(x, LC); 3323 TriangleList *triangles = FindClosestTrianglesToVector(x, LC); 3324 TriangleList candidates; 2733 3325 Vector Center; 2734 2735 if (triangles == NULL) 3326 Vector helper; 3327 3328 if ((triangles == NULL) || (triangles->empty())) 2736 3329 return NULL; 2737 3330 2738 if (triangles->size() == 1) { // there is no degenerate case 2739 result = triangles->front(); 2740 Log() << Verbose(2) << "Normal Vector of this triangle is " << result->NormalVector << "." << endl; 2741 } else { 2742 result = triangles->front(); 2743 result->GetCenter(&Center); 2744 Center.SubtractVector(x); 2745 Log() << Verbose(2) << "Normal Vector of this front side is " << result->NormalVector << "." << endl; 2746 if (Center.ScalarProduct(&result->NormalVector) < 0) { 2747 result = triangles->back(); 2748 Log() << Verbose(2) << "Normal Vector of this back side is " << result->NormalVector << "." << endl; 2749 if (Center.ScalarProduct(&result->NormalVector) < 0) { 2750 eLog() << Verbose(1) << "Front and back side yield NormalVector in wrong direction!" << endl; 2751 } 3331 // go through all and pick the one with the best alignment to x 3332 double MinAlignment = 2.*M_PI; 3333 for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) { 3334 (*Runner)->GetCenter(&Center); 3335 helper.CopyVector(x); 3336 helper.SubtractVector(&Center); 3337 const double Alignment = helper.Angle(&(*Runner)->NormalVector); 3338 if (Alignment < MinAlignment) { 3339 result = *Runner; 3340 MinAlignment = Alignment; 3341 Log() << Verbose(1) << "ACCEPT: Triangle " << *result << " is better aligned with " << MinAlignment << "." << endl; 3342 } else { 3343 Log() << Verbose(1) << "REJECT: Triangle " << *result << " is worse aligned with " << MinAlignment << "." << endl; 2752 3344 } 2753 3345 } 2754 3346 delete(triangles); 3347 2755 3348 return result; 2756 3349 }; 2757 3350 2758 /** Checks whether the provided Vector is within the tesselation structure. 3351 /** Checks whether the provided Vector is within the Tesselation structure. 3352 * Basically calls Tesselation::GetDistanceToSurface() and checks the sign of the return value. 3353 * @param point of which to check the position 3354 * @param *LC LinkedCell structure 3355 * 3356 * @return true if the point is inside the Tesselation structure, false otherwise 3357 */ 3358 bool Tesselation::IsInnerPoint(const Vector &Point, const LinkedCell* const LC) const 3359 { 3360 return (GetDistanceSquaredToSurface(Point, LC) < MYEPSILON); 3361 } 3362 3363 /** Returns the distance to the surface given by the tesselation. 3364 * Calls FindClosestTriangleToVector() and checks whether the resulting triangle's BoundaryTriangleSet#NormalVector points 3365 * towards or away from the given \a &Point. Additionally, we check whether it's normal to the normal vector, i.e. on the 3366 * closest triangle's plane. Then, we have to check whether \a Point is inside the triangle or not to determine whether it's 3367 * an inside or outside point. This is done by calling BoundaryTriangleSet::GetIntersectionInsideTriangle(). 3368 * In the end we additionally find the point on the triangle who was smallest distance to \a Point: 3369 * -# Separate distance from point to center in vector in NormalDirection and on the triangle plane. 3370 * -# Check whether vector on triangle plane points inside the triangle or crosses triangle bounds. 3371 * -# If inside, take it to calculate closest distance 3372 * -# If not, take intersection with BoundaryLine as distance 3373 * 3374 * @note distance is squared despite it still contains a sign to determine in-/outside! 2759 3375 * 2760 3376 * @param point of which to check the position 2761 3377 * @param *LC LinkedCell structure 2762 3378 * 2763 * @return true if the point is inside the tesselation structure, false otherwise2764 */ 2765 bool Tesselation::IsInnerPoint(const Vector &Point, const LinkedCell* const LC) const2766 { 2767 class BoundaryTriangleSet *result = FindClosestTriangleToPoint(&Point, LC);3379 * @return >0 if outside, ==0 if on surface, <0 if inside 3380 */ 3381 double Tesselation::GetDistanceSquaredToTriangle(const Vector &Point, const BoundaryTriangleSet* const triangle) const 3382 { 3383 Info FunctionInfo(__func__); 2768 3384 Vector Center; 2769 2770 if (result == NULL) {// is boundary point or only point in point cloud? 2771 Log() << Verbose(1) << Point << " is the only point in vicinity." << endl; 2772 return false; 2773 } 2774 2775 result->GetCenter(&Center); 2776 Log() << Verbose(3) << "INFO: Central point of the triangle is " << Center << "." << endl; 2777 Center.SubtractVector(&Point); 2778 Log() << Verbose(3) << "INFO: Vector from center to point to test is " << Center << "." << endl; 2779 if (Center.ScalarProduct(&result->NormalVector) > -MYEPSILON) { 2780 Log() << Verbose(1) << Point << " is an inner point." << endl; 2781 return true; 3385 Vector helper; 3386 Vector DistanceToCenter; 3387 Vector Intersection; 3388 double distance = 0.; 3389 3390 if (triangle == NULL) {// is boundary point or only point in point cloud? 3391 Log() << Verbose(1) << "No triangle given!" << endl; 3392 return -1.; 2782 3393 } else { 2783 Log() << Verbose(1) << Point << " is NOT an inner point." << endl; 2784 return false; 2785 } 2786 } 2787 2788 /** Checks whether the provided TesselPoint is within the tesselation structure. 2789 * 2790 * @param *Point of which to check the position 2791 * @param *LC Linked Cell structure 2792 * 2793 * @return true if the point is inside the tesselation structure, false otherwise 2794 */ 2795 bool Tesselation::IsInnerPoint(const TesselPoint * const Point, const LinkedCell* const LC) const 2796 { 2797 return IsInnerPoint(*(Point->node), LC); 2798 } 3394 Log() << Verbose(1) << "INFO: Closest triangle found is " << *triangle << " with normal vector " << triangle->NormalVector << "." << endl; 3395 } 3396 3397 triangle->GetCenter(&Center); 3398 Log() << Verbose(2) << "INFO: Central point of the triangle is " << Center << "." << endl; 3399 DistanceToCenter.CopyVector(&Center); 3400 DistanceToCenter.SubtractVector(&Point); 3401 Log() << Verbose(2) << "INFO: Vector from point to test to center is " << DistanceToCenter << "." << endl; 3402 3403 // check whether we are on boundary 3404 if (fabs(DistanceToCenter.ScalarProduct(&triangle->NormalVector)) < MYEPSILON) { 3405 // calculate whether inside of triangle 3406 DistanceToCenter.CopyVector(&Point); 3407 Center.CopyVector(&Point); 3408 Center.SubtractVector(&triangle->NormalVector); // points towards MolCenter 3409 DistanceToCenter.AddVector(&triangle->NormalVector); // points outside 3410 Log() << Verbose(1) << "INFO: Calling Intersection with " << Center << " and " << DistanceToCenter << "." << endl; 3411 if (triangle->GetIntersectionInsideTriangle(&Center, &DistanceToCenter, &Intersection)) { 3412 Log() << Verbose(1) << Point << " is inner point: sufficiently close to boundary, " << Intersection << "." << endl; 3413 return 0.; 3414 } else { 3415 Log() << Verbose(1) << Point << " is NOT an inner point: on triangle plane but outside of triangle bounds." << endl; 3416 return false; 3417 } 3418 } else { 3419 // calculate smallest distance 3420 distance = triangle->GetClosestPointInsideTriangle(&Point, &Intersection); 3421 Log() << Verbose(1) << "Closest point on triangle is " << Intersection << "." << endl; 3422 3423 // then check direction to boundary 3424 if (DistanceToCenter.ScalarProduct(&triangle->NormalVector) > MYEPSILON) { 3425 Log() << Verbose(1) << Point << " is an inner point, " << distance << " below surface." << endl; 3426 return -distance; 3427 } else { 3428 Log() << Verbose(1) << Point << " is NOT an inner point, " << distance << " above surface." << endl; 3429 return +distance; 3430 } 3431 } 3432 }; 3433 3434 /** Calculates distance to a tesselated surface. 3435 * Combines \sa FindClosestTrianglesToVector() and \sa GetDistanceSquaredToTriangle(). 3436 * \param &Point point to calculate distance from 3437 * \param *LC needed for finding closest points fast 3438 * \return distance squared to closest point on surface 3439 */ 3440 double Tesselation::GetDistanceSquaredToSurface(const Vector &Point, const LinkedCell* const LC) const 3441 { 3442 BoundaryTriangleSet *triangle = FindClosestTriangleToVector(&Point, LC); 3443 const double distance = GetDistanceSquaredToTriangle(Point, triangle); 3444 return Min(distance, LC->RADIUS); 3445 }; 2799 3446 2800 3447 /** Gets all points connected to the provided point by triangulation lines. … … 2804 3451 * @return set of the all points linked to the provided one 2805 3452 */ 2806 set<TesselPoint*> * Tesselation::GetAllConnectedPoints(const TesselPoint* const Point) const 2807 { 2808 set<TesselPoint*> *connectedPoints = new set<TesselPoint*>; 3453 TesselPointSet * Tesselation::GetAllConnectedPoints(const TesselPoint* const Point) const 3454 { 3455 Info FunctionInfo(__func__); 3456 TesselPointSet *connectedPoints = new TesselPointSet; 2809 3457 class BoundaryPointSet *ReferencePoint = NULL; 2810 3458 TesselPoint* current; 2811 3459 bool takePoint = false; 2812 2813 Log() << Verbose(3) << "Begin of GetAllConnectedPoints" << endl;2814 3460 2815 3461 // find the respective boundary point … … 2818 3464 ReferencePoint = PointRunner->second; 2819 3465 } else { 2820 Log() << Verbose(2) << "GetAllConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl;3466 eLog() << Verbose(2) << "GetAllConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl; 2821 3467 ReferencePoint = NULL; 2822 3468 } … … 2842 3488 2843 3489 if (takePoint) { 2844 Log() << Verbose( 5) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is enlisted." << endl;3490 Log() << Verbose(1) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is enlisted." << endl; 2845 3491 connectedPoints->insert(current); 2846 3492 } … … 2849 3495 } 2850 3496 2851 if (connectedPoints-> size() == 0) { // if have not found any points3497 if (connectedPoints->empty()) { // if have not found any points 2852 3498 eLog() << Verbose(1) << "We have not found any connected points to " << *Point<< "." << endl; 2853 3499 return NULL; 2854 3500 } 2855 3501 2856 Log() << Verbose(3) << "End of GetAllConnectedPoints" << endl;2857 3502 return connectedPoints; 2858 3503 }; … … 2866 3511 * 2867 3512 * @param *out output stream for debugging 3513 * @param *SetOfNeighbours all points for which the angle should be calculated 2868 3514 * @param *Point of which get all connected points 2869 3515 * @param *Reference Reference vector for zero angle or NULL for no preference 2870 3516 * @return list of the all points linked to the provided one 2871 3517 */ 2872 list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(const TesselPoint* const Point, const Vector * const Reference) const 2873 { 3518 TesselPointList * Tesselation::GetCircleOfConnectedTriangles(TesselPointSet *SetOfNeighbours, const TesselPoint* const Point, const Vector * const Reference) const 3519 { 3520 Info FunctionInfo(__func__); 2874 3521 map<double, TesselPoint*> anglesOfPoints; 2875 set<TesselPoint*> *connectedPoints = GetAllConnectedPoints(Point); 2876 list<TesselPoint*> *connectedCircle = new list<TesselPoint*>; 3522 TesselPointList *connectedCircle = new TesselPointList; 3523 Vector PlaneNormal; 3524 Vector AngleZero; 3525 Vector OrthogonalVector; 3526 Vector helper; 3527 const TesselPoint * const TrianglePoints[3] = {Point, NULL, NULL}; 3528 TriangleList *triangles = NULL; 3529 3530 if (SetOfNeighbours == NULL) { 3531 eLog() << Verbose(2) << "Could not find any connected points!" << endl; 3532 delete(connectedCircle); 3533 return NULL; 3534 } 3535 3536 // calculate central point 3537 triangles = FindTriangles(TrianglePoints); 3538 if ((triangles != NULL) && (!triangles->empty())) { 3539 for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) 3540 PlaneNormal.AddVector(&(*Runner)->NormalVector); 3541 } else { 3542 eLog() << Verbose(0) << "Could not find any triangles for point " << *Point << "." << endl; 3543 performCriticalExit(); 3544 } 3545 PlaneNormal.Scale(1.0/triangles->size()); 3546 Log() << Verbose(1) << "INFO: Calculated PlaneNormal of all circle points is " << PlaneNormal << "." << endl; 3547 PlaneNormal.Normalize(); 3548 3549 // construct one orthogonal vector 3550 if (Reference != NULL) { 3551 AngleZero.CopyVector(Reference); 3552 AngleZero.SubtractVector(Point->node); 3553 AngleZero.ProjectOntoPlane(&PlaneNormal); 3554 } 3555 if ((Reference == NULL) || (AngleZero.NormSquared() < MYEPSILON )) { 3556 Log() << Verbose(1) << "Using alternatively " << *(*SetOfNeighbours->begin())->node << " as angle 0 referencer." << endl; 3557 AngleZero.CopyVector((*SetOfNeighbours->begin())->node); 3558 AngleZero.SubtractVector(Point->node); 3559 AngleZero.ProjectOntoPlane(&PlaneNormal); 3560 if (AngleZero.NormSquared() < MYEPSILON) { 3561 eLog() << Verbose(0) << "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!" << endl; 3562 performCriticalExit(); 3563 } 3564 } 3565 Log() << Verbose(1) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl; 3566 if (AngleZero.NormSquared() > MYEPSILON) 3567 OrthogonalVector.MakeNormalVector(&PlaneNormal, &AngleZero); 3568 else 3569 OrthogonalVector.MakeNormalVector(&PlaneNormal); 3570 Log() << Verbose(1) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl; 3571 3572 // go through all connected points and calculate angle 3573 for (TesselPointSet::iterator listRunner = SetOfNeighbours->begin(); listRunner != SetOfNeighbours->end(); listRunner++) { 3574 helper.CopyVector((*listRunner)->node); 3575 helper.SubtractVector(Point->node); 3576 helper.ProjectOntoPlane(&PlaneNormal); 3577 double angle = GetAngle(helper, AngleZero, OrthogonalVector); 3578 Log() << Verbose(0) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl; 3579 anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner))); 3580 } 3581 3582 for(map<double, TesselPoint*>::iterator AngleRunner = anglesOfPoints.begin(); AngleRunner != anglesOfPoints.end(); AngleRunner++) { 3583 connectedCircle->push_back(AngleRunner->second); 3584 } 3585 3586 return connectedCircle; 3587 } 3588 3589 /** Gets all points connected to the provided point by triangulation lines, ordered such that we have the circle round the point. 3590 * Maps them down onto the plane designated by the axis \a *Point and \a *Reference. The center of all points 3591 * connected in the tesselation to \a *Point is mapped to spherical coordinates with the zero angle being given 3592 * by the mapped down \a *Reference. Hence, the biggest and the smallest angles are those of the two shanks of the 3593 * triangle we are looking for. 3594 * 3595 * @param *SetOfNeighbours all points for which the angle should be calculated 3596 * @param *Point of which get all connected points 3597 * @param *Reference Reference vector for zero angle or NULL for no preference 3598 * @return list of the all points linked to the provided one 3599 */ 3600 TesselPointList * Tesselation::GetCircleOfSetOfPoints(TesselPointSet *SetOfNeighbours, const TesselPoint* const Point, const Vector * const Reference) const 3601 { 3602 Info FunctionInfo(__func__); 3603 map<double, TesselPoint*> anglesOfPoints; 3604 TesselPointList *connectedCircle = new TesselPointList; 2877 3605 Vector center; 2878 3606 Vector PlaneNormal; … … 2881 3609 Vector helper; 2882 3610 2883 if ( connectedPoints == NULL) {2884 Log() << Verbose(2) << "Could not find any connected points!" << endl;3611 if (SetOfNeighbours == NULL) { 3612 eLog() << Verbose(2) << "Could not find any connected points!" << endl; 2885 3613 delete(connectedCircle); 2886 3614 return NULL; 2887 3615 } 2888 Log() << Verbose(2) << "Begin of GetCircleOfConnectedPoints" << endl; 2889 3616 3617 // check whether there's something to do 3618 if (SetOfNeighbours->size() < 3) { 3619 for (TesselPointSet::iterator TesselRunner = SetOfNeighbours->begin(); TesselRunner != SetOfNeighbours->end(); TesselRunner++) 3620 connectedCircle->push_back(*TesselRunner); 3621 return connectedCircle; 3622 } 3623 3624 Log() << Verbose(1) << "INFO: Point is " << *Point << " and Reference is " << *Reference << "." << endl; 2890 3625 // calculate central point 2891 for (set<TesselPoint*>::const_iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++) 2892 center.AddVector((*TesselRunner)->node); 3626 3627 TesselPointSet::const_iterator TesselA = SetOfNeighbours->begin(); 3628 TesselPointSet::const_iterator TesselB = SetOfNeighbours->begin(); 3629 TesselPointSet::const_iterator TesselC = SetOfNeighbours->begin(); 3630 TesselB++; 3631 TesselC++; 3632 TesselC++; 3633 int counter = 0; 3634 while (TesselC != SetOfNeighbours->end()) { 3635 helper.MakeNormalVector((*TesselA)->node, (*TesselB)->node, (*TesselC)->node); 3636 Log() << Verbose(0) << "Making normal vector out of " << *(*TesselA) << ", " << *(*TesselB) << " and " << *(*TesselC) << ":" << helper << endl; 3637 counter++; 3638 TesselA++; 3639 TesselB++; 3640 TesselC++; 3641 PlaneNormal.AddVector(&helper); 3642 } 2893 3643 //Log() << Verbose(0) << "Summed vectors " << center << "; number of points " << connectedPoints.size() 2894 // << "; scale factor " << 1.0/connectedPoints.size();2895 center.Scale(1.0/connectedPoints->size());2896 Log() << Verbose(4) << "INFO: Calculated center of all circle points is " << center << "." << endl;2897 2898 // projection plane of the circle is at the closes Point and normal is pointing away from center of all circle points2899 PlaneNormal.CopyVector(Point->node);2900 PlaneNormal.SubtractVector(¢er);2901 PlaneNormal.Normalize();2902 Log() << Verbose( 4) << "INFO: Calculated plane normal of circle is " << PlaneNormal << "." << endl;3644 // << "; scale factor " << counter; 3645 PlaneNormal.Scale(1.0/(double)counter); 3646 // Log() << Verbose(1) << "INFO: Calculated center of all circle points is " << center << "." << endl; 3647 // 3648 // // projection plane of the circle is at the closes Point and normal is pointing away from center of all circle points 3649 // PlaneNormal.CopyVector(Point->node); 3650 // PlaneNormal.SubtractVector(¢er); 3651 // PlaneNormal.Normalize(); 3652 Log() << Verbose(1) << "INFO: Calculated plane normal of circle is " << PlaneNormal << "." << endl; 2903 3653 2904 3654 // construct one orthogonal vector … … 2909 3659 } 2910 3660 if ((Reference == NULL) || (AngleZero.NormSquared() < MYEPSILON )) { 2911 Log() << Verbose( 4) << "Using alternatively " << *(*connectedPoints->begin())->node << " as angle 0 referencer." << endl;2912 AngleZero.CopyVector((* connectedPoints->begin())->node);3661 Log() << Verbose(1) << "Using alternatively " << *(*SetOfNeighbours->begin())->node << " as angle 0 referencer." << endl; 3662 AngleZero.CopyVector((*SetOfNeighbours->begin())->node); 2913 3663 AngleZero.SubtractVector(Point->node); 2914 3664 AngleZero.ProjectOntoPlane(&PlaneNormal); … … 2918 3668 } 2919 3669 } 2920 Log() << Verbose( 4) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl;3670 Log() << Verbose(1) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl; 2921 3671 if (AngleZero.NormSquared() > MYEPSILON) 2922 3672 OrthogonalVector.MakeNormalVector(&PlaneNormal, &AngleZero); 2923 3673 else 2924 3674 OrthogonalVector.MakeNormalVector(&PlaneNormal); 2925 Log() << Verbose( 4) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl;3675 Log() << Verbose(1) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl; 2926 3676 2927 3677 // go through all connected points and calculate angle 2928 for (set<TesselPoint*>::iterator listRunner = connectedPoints->begin(); listRunner != connectedPoints->end(); listRunner++) { 3678 pair <map<double, TesselPoint*>::iterator, bool > InserterTest; 3679 for (TesselPointSet::iterator listRunner = SetOfNeighbours->begin(); listRunner != SetOfNeighbours->end(); listRunner++) { 2929 3680 helper.CopyVector((*listRunner)->node); 2930 3681 helper.SubtractVector(Point->node); 2931 3682 helper.ProjectOntoPlane(&PlaneNormal); 2932 3683 double angle = GetAngle(helper, AngleZero, OrthogonalVector); 2933 Log() << Verbose(3) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl; 2934 anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner))); 3684 if (angle > M_PI) // the correction is of no use here (and not desired) 3685 angle = 2.*M_PI - angle; 3686 Log() << Verbose(0) << "INFO: Calculated angle between " << helper << " and " << AngleZero << " is " << angle << " for point " << **listRunner << "." << endl; 3687 InserterTest = anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner))); 3688 if (!InserterTest.second) { 3689 eLog() << Verbose(0) << "GetCircleOfSetOfPoints() got two atoms with same angle: " << *((InserterTest.first)->second) << " and " << (*listRunner) << endl; 3690 performCriticalExit(); 3691 } 2935 3692 } 2936 3693 … … 2938 3695 connectedCircle->push_back(AngleRunner->second); 2939 3696 } 2940 2941 delete(connectedPoints);2942 2943 Log() << Verbose(2) << "End of GetCircleOfConnectedPoints" << endl;2944 3697 2945 3698 return connectedCircle; … … 2952 3705 * @return list of the all points linked to the provided one 2953 3706 */ 2954 list<list<TesselPoint*> *> * Tesselation::GetPathsOfConnectedPoints(const TesselPoint* const Point) const 2955 { 3707 ListOfTesselPointList * Tesselation::GetPathsOfConnectedPoints(const TesselPoint* const Point) const 3708 { 3709 Info FunctionInfo(__func__); 2956 3710 map<double, TesselPoint*> anglesOfPoints; 2957 list< list<TesselPoint*> *> *ListOfPaths = new list<list<TesselPoint*>*>;2958 list<TesselPoint*>*connectedPath = NULL;3711 list< TesselPointList *> *ListOfPaths = new list< TesselPointList *>; 3712 TesselPointList *connectedPath = NULL; 2959 3713 Vector center; 2960 3714 Vector PlaneNormal; … … 2993 3747 } else if (!LineRunner->second) { 2994 3748 LineRunner->second = true; 2995 connectedPath = new list<TesselPoint*>;3749 connectedPath = new TesselPointList; 2996 3750 triangle = NULL; 2997 3751 CurrentLine = runner->second; 2998 3752 StartLine = CurrentLine; 2999 3753 CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint); 3000 Log() << Verbose( 3)<< "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << "." << endl;3754 Log() << Verbose(1)<< "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << "." << endl; 3001 3755 do { 3002 3756 // push current one 3003 Log() << Verbose( 3) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl;3757 Log() << Verbose(1) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl; 3004 3758 connectedPath->push_back(CurrentPoint->node); 3005 3759 3006 3760 // find next triangle 3007 3761 for (TriangleMap::iterator Runner = CurrentLine->triangles.begin(); Runner != CurrentLine->triangles.end(); Runner++) { 3008 Log() << Verbose( 3) << "INFO: Inspecting triangle " << *Runner->second << "." << endl;3762 Log() << Verbose(1) << "INFO: Inspecting triangle " << *Runner->second << "." << endl; 3009 3763 if ((Runner->second != triangle)) { // look for first triangle not equal to old one 3010 3764 triangle = Runner->second; … … 3013 3767 if (!TriangleRunner->second) { 3014 3768 TriangleRunner->second = true; 3015 Log() << Verbose( 3) << "INFO: Connecting triangle is " << *triangle << "." << endl;3769 Log() << Verbose(1) << "INFO: Connecting triangle is " << *triangle << "." << endl; 3016 3770 break; 3017 3771 } else { 3018 Log() << Verbose( 3) << "INFO: Skipping " << *triangle << ", as we have already visited it." << endl;3772 Log() << Verbose(1) << "INFO: Skipping " << *triangle << ", as we have already visited it." << endl; 3019 3773 triangle = NULL; 3020 3774 } … … 3031 3785 if ((triangle->lines[i] != CurrentLine) && (triangle->lines[i]->ContainsBoundaryPoint(ReferencePoint))) { // not the current line and still containing Point 3032 3786 CurrentLine = triangle->lines[i]; 3033 Log() << Verbose( 3) << "INFO: Connecting line is " << *CurrentLine << "." << endl;3787 Log() << Verbose(1) << "INFO: Connecting line is " << *CurrentLine << "." << endl; 3034 3788 break; 3035 3789 } … … 3045 3799 } while (CurrentLine != StartLine); 3046 3800 // last point is missing, as it's on start line 3047 Log() << Verbose( 3) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl;3801 Log() << Verbose(1) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl; 3048 3802 if (StartLine->GetOtherEndpoint(ReferencePoint)->node != connectedPath->back()) 3049 3803 connectedPath->push_back(StartLine->GetOtherEndpoint(ReferencePoint)->node); … … 3051 3805 ListOfPaths->push_back(connectedPath); 3052 3806 } else { 3053 Log() << Verbose( 3) << "INFO: Skipping " << *runner->second << ", as we have already visited it." << endl;3807 Log() << Verbose(1) << "INFO: Skipping " << *runner->second << ", as we have already visited it." << endl; 3054 3808 } 3055 3809 } … … 3067 3821 * @return list of the closed paths 3068 3822 */ 3069 list<list<TesselPoint*> *> * Tesselation::GetClosedPathsOfConnectedPoints(const TesselPoint* const Point) const 3070 { 3071 list<list<TesselPoint*> *> *ListofPaths = GetPathsOfConnectedPoints(Point); 3072 list<list<TesselPoint*> *> *ListofClosedPaths = new list<list<TesselPoint*> *>; 3073 list<TesselPoint*> *connectedPath = NULL; 3074 list<TesselPoint*> *newPath = NULL; 3823 ListOfTesselPointList * Tesselation::GetClosedPathsOfConnectedPoints(const TesselPoint* const Point) const 3824 { 3825 Info FunctionInfo(__func__); 3826 list<TesselPointList *> *ListofPaths = GetPathsOfConnectedPoints(Point); 3827 list<TesselPointList *> *ListofClosedPaths = new list<TesselPointList *>; 3828 TesselPointList *connectedPath = NULL; 3829 TesselPointList *newPath = NULL; 3075 3830 int count = 0; 3076 3831 3077 3832 3078 list<TesselPoint*>::iterator CircleRunner;3079 list<TesselPoint*>::iterator CircleStart;3080 3081 for(list< list<TesselPoint*>*>::iterator ListRunner = ListofPaths->begin(); ListRunner != ListofPaths->end(); ListRunner++) {3833 TesselPointList::iterator CircleRunner; 3834 TesselPointList::iterator CircleStart; 3835 3836 for(list<TesselPointList *>::iterator ListRunner = ListofPaths->begin(); ListRunner != ListofPaths->end(); ListRunner++) { 3082 3837 connectedPath = *ListRunner; 3083 3838 3084 Log() << Verbose( 2) << "INFO: Current path is " << connectedPath << "." << endl;3839 Log() << Verbose(1) << "INFO: Current path is " << connectedPath << "." << endl; 3085 3840 3086 3841 // go through list, look for reappearance of starting Point and count … … 3088 3843 3089 3844 // go through list, look for reappearance of starting Point and create list 3090 list<TesselPoint*>::iterator Marker = CircleStart;3845 TesselPointList::iterator Marker = CircleStart; 3091 3846 for (CircleRunner = CircleStart; CircleRunner != connectedPath->end(); CircleRunner++) { 3092 3847 if ((*CircleRunner == *CircleStart) && (CircleRunner != CircleStart)) { // is not the very first point 3093 3848 // we have a closed circle from Marker to new Marker 3094 Log() << Verbose( 3) << count+1 << ". closed path consists of: ";3095 newPath = new list<TesselPoint*>;3096 list<TesselPoint*>::iterator CircleSprinter = Marker;3849 Log() << Verbose(1) << count+1 << ". closed path consists of: "; 3850 newPath = new TesselPointList; 3851 TesselPointList::iterator CircleSprinter = Marker; 3097 3852 for (; CircleSprinter != CircleRunner; CircleSprinter++) { 3098 3853 newPath->push_back(*CircleSprinter); … … 3108 3863 } 3109 3864 } 3110 Log() << Verbose( 3) << "INFO: " << count << " closed additional path(s) have been created." << endl;3865 Log() << Verbose(1) << "INFO: " << count << " closed additional path(s) have been created." << endl; 3111 3866 3112 3867 // delete list of paths … … 3128 3883 * \return pointer to allocated list of triangles 3129 3884 */ 3130 set<BoundaryTriangleSet*> *Tesselation::GetAllTriangles(const BoundaryPointSet * const Point) const 3131 { 3132 set<BoundaryTriangleSet*> *connectedTriangles = new set<BoundaryTriangleSet*>; 3885 TriangleSet *Tesselation::GetAllTriangles(const BoundaryPointSet * const Point) const 3886 { 3887 Info FunctionInfo(__func__); 3888 TriangleSet *connectedTriangles = new TriangleSet; 3133 3889 3134 3890 if (Point == NULL) { … … 3168 3924 return 0.; 3169 3925 } else 3170 Log() << Verbose( 2) << "Removing point " << *point << " from tesselated boundary ..." << endl;3926 Log() << Verbose(0) << "Removing point " << *point << " from tesselated boundary ..." << endl; 3171 3927 3172 3928 // copy old location for the volume … … 3179 3935 } 3180 3936 3181 list< list<TesselPoint*>*> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(point->node);3182 list<TesselPoint*>*connectedPath = NULL;3937 list<TesselPointList *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(point->node); 3938 TesselPointList *connectedPath = NULL; 3183 3939 3184 3940 // gather all triangles 3185 3941 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) 3186 3942 count+=LineRunner->second->triangles.size(); 3187 map<class BoundaryTriangleSet *, int>Candidates;3943 TriangleMap Candidates; 3188 3944 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) { 3189 3945 line = LineRunner->second; 3190 3946 for (TriangleMap::iterator TriangleRunner = line->triangles.begin(); TriangleRunner != line->triangles.end(); TriangleRunner++) { 3191 3947 triangle = TriangleRunner->second; 3192 Candidates.insert( pair<class BoundaryTriangleSet *, int> (triangle, triangle->Nr) );3948 Candidates.insert( TrianglePair (triangle->Nr, triangle) ); 3193 3949 } 3194 3950 } … … 3197 3953 count=0; 3198 3954 NormalVector.Zero(); 3199 for ( map<class BoundaryTriangleSet *, int>::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) {3200 Log() << Verbose( 3) << "INFO: Removing triangle " << *(Runner->first) << "." << endl;3201 NormalVector.SubtractVector(&Runner-> first->NormalVector); // has to point inward3202 RemoveTesselationTriangle(Runner-> first);3955 for (TriangleMap::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) { 3956 Log() << Verbose(1) << "INFO: Removing triangle " << *(Runner->second) << "." << endl; 3957 NormalVector.SubtractVector(&Runner->second->NormalVector); // has to point inward 3958 RemoveTesselationTriangle(Runner->second); 3203 3959 count++; 3204 3960 } 3205 3961 Log() << Verbose(1) << count << " triangles were removed." << endl; 3206 3962 3207 list< list<TesselPoint*>*>::iterator ListAdvance = ListOfClosedPaths->begin();3208 list< list<TesselPoint*>*>::iterator ListRunner = ListAdvance;3209 map<class BoundaryTriangleSet *, int>::iterator NumberRunner = Candidates.begin();3210 list<TesselPoint*>::iterator StartNode, MiddleNode, EndNode;3963 list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin(); 3964 list<TesselPointList *>::iterator ListRunner = ListAdvance; 3965 TriangleMap::iterator NumberRunner = Candidates.begin(); 3966 TesselPointList::iterator StartNode, MiddleNode, EndNode; 3211 3967 double angle; 3212 3968 double smallestangle; … … 3222 3978 3223 3979 // re-create all triangles by going through connected points list 3224 list<class BoundaryLineSet *>NewLines;3980 LineList NewLines; 3225 3981 for (;!connectedPath->empty();) { 3226 3982 // search middle node with widest angle to next neighbours … … 3228 3984 smallestangle = 0.; 3229 3985 for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) { 3230 Log() << Verbose( 3) << "INFO: MiddleNode is " << **MiddleNode << "." << endl;3986 Log() << Verbose(1) << "INFO: MiddleNode is " << **MiddleNode << "." << endl; 3231 3987 // construct vectors to next and previous neighbour 3232 3988 StartNode = MiddleNode; … … 3256 4012 MiddleNode = EndNode; 3257 4013 if (MiddleNode == connectedPath->end()) { 3258 Log() << Verbose(1) << "CRITICAL: Could not find a smallest angle!" << endl;3259 exit(255);4014 eLog() << Verbose(0) << "CRITICAL: Could not find a smallest angle!" << endl; 4015 performCriticalExit(); 3260 4016 } 3261 4017 StartNode = MiddleNode; … … 3266 4022 if (EndNode == connectedPath->end()) 3267 4023 EndNode = connectedPath->begin(); 3268 Log() << Verbose( 4) << "INFO: StartNode is " << **StartNode << "." << endl;3269 Log() << Verbose( 4) << "INFO: MiddleNode is " << **MiddleNode << "." << endl;3270 Log() << Verbose( 4) << "INFO: EndNode is " << **EndNode << "." << endl;3271 Log() << Verbose( 3) << "INFO: Attempting to create triangle " << (*StartNode)->Name << ", " << (*MiddleNode)->Name << " and " << (*EndNode)->Name << "." << endl;4024 Log() << Verbose(2) << "INFO: StartNode is " << **StartNode << "." << endl; 4025 Log() << Verbose(2) << "INFO: MiddleNode is " << **MiddleNode << "." << endl; 4026 Log() << Verbose(2) << "INFO: EndNode is " << **EndNode << "." << endl; 4027 Log() << Verbose(1) << "INFO: Attempting to create triangle " << (*StartNode)->Name << ", " << (*MiddleNode)->Name << " and " << (*EndNode)->Name << "." << endl; 3272 4028 TriangleCandidates[0] = *StartNode; 3273 4029 TriangleCandidates[1] = *MiddleNode; … … 3275 4031 triangle = GetPresentTriangle(TriangleCandidates); 3276 4032 if (triangle != NULL) { 3277 eLog() << Verbose( 2) << "New triangle already present, skipping!" << endl;4033 eLog() << Verbose(0) << "New triangle already present, skipping!" << endl; 3278 4034 StartNode++; 3279 4035 MiddleNode++; … … 3287 4043 continue; 3288 4044 } 3289 Log() << Verbose( 5) << "Adding new triangle points."<< endl;4045 Log() << Verbose(3) << "Adding new triangle points."<< endl; 3290 4046 AddTesselationPoint(*StartNode, 0); 3291 4047 AddTesselationPoint(*MiddleNode, 1); 3292 4048 AddTesselationPoint(*EndNode, 2); 3293 Log() << Verbose( 5) << "Adding new triangle lines."<< endl;4049 Log() << Verbose(3) << "Adding new triangle lines."<< endl; 3294 4050 AddTesselationLine(TPS[0], TPS[1], 0); 3295 4051 AddTesselationLine(TPS[0], TPS[2], 1); … … 3306 4062 // prepare nodes for next triangle 3307 4063 StartNode = EndNode; 3308 Log() << Verbose( 4) << "Removing " << **MiddleNode << " from closed path, remaining points: " << connectedPath->size() << "." << endl;4064 Log() << Verbose(2) << "Removing " << **MiddleNode << " from closed path, remaining points: " << connectedPath->size() << "." << endl; 3309 4065 connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles) 3310 4066 if (connectedPath->size() == 2) { // we are done … … 3313 4069 break; 3314 4070 } else if (connectedPath->size() < 2) { // something's gone wrong! 3315 Log() << Verbose(1) << "CRITICAL: There are only two endpoints left!" << endl;3316 exit(255);4071 eLog() << Verbose(0) << "CRITICAL: There are only two endpoints left!" << endl; 4072 performCriticalExit(); 3317 4073 } else { 3318 4074 MiddleNode = StartNode; … … 3328 4084 // maximize the inner lines (we preferentially created lines with a huge angle, which is for the tesselation not wanted though useful for the closing) 3329 4085 if (NewLines.size() > 1) { 3330 list<class BoundaryLineSet *>::iterator Candidate;4086 LineList::iterator Candidate; 3331 4087 class BoundaryLineSet *OtherBase = NULL; 3332 4088 double tmp, maxgain; 3333 4089 do { 3334 4090 maxgain = 0; 3335 for( list<class BoundaryLineSet *>::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) {4091 for(LineList::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) { 3336 4092 tmp = PickFarthestofTwoBaselines(*Runner); 3337 4093 if (maxgain < tmp) { … … 3342 4098 if (maxgain != 0) { 3343 4099 volume += maxgain; 3344 Log() << Verbose( 3) << "Flipping baseline with highest volume" << **Candidate << "." << endl;4100 Log() << Verbose(1) << "Flipping baseline with highest volume" << **Candidate << "." << endl; 3345 4101 OtherBase = FlipBaseline(*Candidate); 3346 4102 NewLines.erase(Candidate); … … 3353 4109 delete(connectedPath); 3354 4110 } 3355 Log() << Verbose( 1) << count << " triangles were created." << endl;4111 Log() << Verbose(0) << count << " triangles were created." << endl; 3356 4112 } else { 3357 4113 while (!ListOfClosedPaths->empty()) { … … 3361 4117 delete(connectedPath); 3362 4118 } 3363 Log() << Verbose( 1) << "No need to create any triangles." << endl;4119 Log() << Verbose(0) << "No need to create any triangles." << endl; 3364 4120 } 3365 4121 delete(ListOfClosedPaths); 3366 4122 3367 Log() << Verbose( 1) << "Removed volume is " << volume << "." << endl;4123 Log() << Verbose(0) << "Removed volume is " << volume << "." << endl; 3368 4124 3369 4125 return volume; … … 3375 4131 * Finds triangles belonging to the three provided points. 3376 4132 * 3377 * @param *Points[3] list, is expected to contain three points 4133 * @param *Points[3] list, is expected to contain three points (NULL means wildcard) 3378 4134 * 3379 4135 * @return triangles which belong to the provided points, will be empty if there are none, 3380 4136 * will usually be one, in case of degeneration, there will be two 3381 4137 */ 3382 list<BoundaryTriangleSet*> *Tesselation::FindTriangles(const TesselPoint* const Points[3]) const 3383 { 3384 list<BoundaryTriangleSet*> *result = new list<BoundaryTriangleSet*>; 4138 TriangleList *Tesselation::FindTriangles(const TesselPoint* const Points[3]) const 4139 { 4140 Info FunctionInfo(__func__); 4141 TriangleList *result = new TriangleList; 3385 4142 LineMap::const_iterator FindLine; 3386 4143 TriangleMap::const_iterator FindTriangle; 3387 4144 class BoundaryPointSet *TrianglePoints[3]; 4145 size_t NoOfWildcards = 0; 3388 4146 3389 4147 for (int i = 0; i < 3; i++) { 3390 PointMap::const_iterator FindPoint = PointsOnBoundary.find(Points[i]->nr);3391 if (FindPoint != PointsOnBoundary.end()) {3392 TrianglePoints[i] = FindPoint->second;4148 if (Points[i] == NULL) { 4149 NoOfWildcards++; 4150 TrianglePoints[i] = NULL; 3393 4151 } else { 3394 TrianglePoints[i] = NULL; 3395 } 3396 } 3397 3398 // checks lines between the points in the Points for their adjacent triangles 3399 for (int i = 0; i < 3; i++) { 3400 if (TrianglePoints[i] != NULL) { 3401 for (int j = i+1; j < 3; j++) { 3402 if (TrianglePoints[j] != NULL) { 3403 for (FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->nr); // is a multimap! 3404 (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->nr); 3405 FindLine++) { 3406 for (FindTriangle = FindLine->second->triangles.begin(); 3407 FindTriangle != FindLine->second->triangles.end(); 3408 FindTriangle++) { 3409 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { 3410 result->push_back(FindTriangle->second); 4152 PointMap::const_iterator FindPoint = PointsOnBoundary.find(Points[i]->nr); 4153 if (FindPoint != PointsOnBoundary.end()) { 4154 TrianglePoints[i] = FindPoint->second; 4155 } else { 4156 TrianglePoints[i] = NULL; 4157 } 4158 } 4159 } 4160 4161 switch (NoOfWildcards) { 4162 case 0: // checks lines between the points in the Points for their adjacent triangles 4163 for (int i = 0; i < 3; i++) { 4164 if (TrianglePoints[i] != NULL) { 4165 for (int j = i+1; j < 3; j++) { 4166 if (TrianglePoints[j] != NULL) { 4167 for (FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->nr); // is a multimap! 4168 (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->nr); 4169 FindLine++) { 4170 for (FindTriangle = FindLine->second->triangles.begin(); 4171 FindTriangle != FindLine->second->triangles.end(); 4172 FindTriangle++) { 4173 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { 4174 result->push_back(FindTriangle->second); 4175 } 4176 } 3411 4177 } 4178 // Is it sufficient to consider one of the triangle lines for this. 4179 return result; 3412 4180 } 3413 4181 } 3414 // Is it sufficient to consider one of the triangle lines for this.3415 return result;3416 4182 } 3417 4183 } 3418 } 4184 break; 4185 case 1: // copy all triangles of the respective line 4186 { 4187 int i=0; 4188 for (; i < 3; i++) 4189 if (TrianglePoints[i] == NULL) 4190 break; 4191 for (FindLine = TrianglePoints[(i+1)%3]->lines.find(TrianglePoints[(i+2)%3]->node->nr); // is a multimap! 4192 (FindLine != TrianglePoints[(i+1)%3]->lines.end()) && (FindLine->first == TrianglePoints[(i+2)%3]->node->nr); 4193 FindLine++) { 4194 for (FindTriangle = FindLine->second->triangles.begin(); 4195 FindTriangle != FindLine->second->triangles.end(); 4196 FindTriangle++) { 4197 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { 4198 result->push_back(FindTriangle->second); 4199 } 4200 } 4201 } 4202 break; 4203 } 4204 case 2: // copy all triangles of the respective point 4205 { 4206 int i=0; 4207 for (; i < 3; i++) 4208 if (TrianglePoints[i] != NULL) 4209 break; 4210 for (LineMap::const_iterator line = TrianglePoints[i]->lines.begin(); line != TrianglePoints[i]->lines.end(); line++) 4211 for (TriangleMap::const_iterator triangle = line->second->triangles.begin(); triangle != line->second->triangles.end(); triangle++) 4212 result->push_back(triangle->second); 4213 result->sort(); 4214 result->unique(); 4215 break; 4216 } 4217 case 3: // copy all triangles 4218 { 4219 for (TriangleMap::const_iterator triangle = TrianglesOnBoundary.begin(); triangle != TrianglesOnBoundary.end(); triangle++) 4220 result->push_back(triangle->second); 4221 break; 4222 } 4223 default: 4224 eLog() << Verbose(0) << "Number of wildcards is greater than 3, cannot happen!" << endl; 4225 performCriticalExit(); 4226 break; 3419 4227 } 3420 4228 3421 4229 return result; 3422 4230 } 4231 4232 struct BoundaryLineSetCompare { 4233 bool operator() (const BoundaryLineSet * const a, const BoundaryLineSet * const b) { 4234 int lowerNra = -1; 4235 int lowerNrb = -1; 4236 4237 if (a->endpoints[0] < a->endpoints[1]) 4238 lowerNra = 0; 4239 else 4240 lowerNra = 1; 4241 4242 if (b->endpoints[0] < b->endpoints[1]) 4243 lowerNrb = 0; 4244 else 4245 lowerNrb = 1; 4246 4247 if (a->endpoints[lowerNra] < b->endpoints[lowerNrb]) 4248 return true; 4249 else if (a->endpoints[lowerNra] > b->endpoints[lowerNrb]) 4250 return false; 4251 else { // both lower-numbered endpoints are the same ... 4252 if (a->endpoints[(lowerNra+1)%2] < b->endpoints[(lowerNrb+1)%2]) 4253 return true; 4254 else if (a->endpoints[(lowerNra+1)%2] > b->endpoints[(lowerNrb+1)%2]) 4255 return false; 4256 } 4257 return false; 4258 }; 4259 }; 4260 4261 #define UniqueLines set < class BoundaryLineSet *, BoundaryLineSetCompare> 3423 4262 3424 4263 /** … … 3428 4267 * in the list, once as key and once as value 3429 4268 */ 3430 map<int, int> * Tesselation::FindAllDegeneratedLines() 3431 { 3432 map<int, class BoundaryLineSet *> AllLines; 3433 map<int, int> * DegeneratedLines = new map<int, int>; 4269 IndexToIndex * Tesselation::FindAllDegeneratedLines() 4270 { 4271 Info FunctionInfo(__func__); 4272 UniqueLines AllLines; 4273 IndexToIndex * DegeneratedLines = new IndexToIndex; 3434 4274 3435 4275 // sanity check 3436 4276 if (LinesOnBoundary.empty()) { 3437 Log() << Verbose(1) << "Warning:FindAllDegeneratedTriangles() was called without any tesselation structure.";4277 eLog() << Verbose(2) << "FindAllDegeneratedTriangles() was called without any tesselation structure."; 3438 4278 return DegeneratedLines; 3439 4279 } 3440 4280 3441 4281 LineMap::iterator LineRunner1; 3442 pair< LineMap::iterator, bool> tester;4282 pair< UniqueLines::iterator, bool> tester; 3443 4283 for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) { 3444 tester = AllLines.insert( pair<int,BoundaryLineSet *> (LineRunner1->second->endpoints[0]->Nr, LineRunner1->second));3445 if ( (!tester.second) && (tester.first->second->endpoints[1]->Nr == LineRunner1->second->endpoints[1]->Nr)) { // found degenerated line3446 DegeneratedLines->insert ( pair<int, int> (LineRunner1->second->Nr, tester.first->second->Nr) );3447 DegeneratedLines->insert ( pair<int, int> ( tester.first->second->Nr, LineRunner1->second->Nr) );4284 tester = AllLines.insert( LineRunner1->second ); 4285 if (!tester.second) { // found degenerated line 4286 DegeneratedLines->insert ( pair<int, int> (LineRunner1->second->Nr, (*tester.first)->Nr) ); 4287 DegeneratedLines->insert ( pair<int, int> ((*tester.first)->Nr, LineRunner1->second->Nr) ); 3448 4288 } 3449 4289 } … … 3451 4291 AllLines.clear(); 3452 4292 3453 Log() << Verbose(1) << "FindAllDegeneratedLines() found " << DegeneratedLines->size() << " lines." << endl; 3454 map<int,int>::iterator it; 3455 for (it = DegeneratedLines->begin(); it != DegeneratedLines->end(); it++) 3456 Log() << Verbose(2) << (*it).first << " => " << (*it).second << endl; 4293 Log() << Verbose(0) << "FindAllDegeneratedLines() found " << DegeneratedLines->size() << " lines." << endl; 4294 IndexToIndex::iterator it; 4295 for (it = DegeneratedLines->begin(); it != DegeneratedLines->end(); it++) { 4296 const LineMap::const_iterator Line1 = LinesOnBoundary.find((*it).first); 4297 const LineMap::const_iterator Line2 = LinesOnBoundary.find((*it).second); 4298 if (Line1 != LinesOnBoundary.end() && Line2 != LinesOnBoundary.end()) 4299 Log() << Verbose(0) << *Line1->second << " => " << *Line2->second << endl; 4300 else 4301 eLog() << Verbose(1) << "Either " << (*it).first << " or " << (*it).second << " are not in LinesOnBoundary!" << endl; 4302 } 3457 4303 3458 4304 return DegeneratedLines; … … 3465 4311 * in the list, once as key and once as value 3466 4312 */ 3467 map<int, int> * Tesselation::FindAllDegeneratedTriangles() 3468 { 3469 map<int, int> * DegeneratedLines = FindAllDegeneratedLines(); 3470 map<int, int> * DegeneratedTriangles = new map<int, int>; 4313 IndexToIndex * Tesselation::FindAllDegeneratedTriangles() 4314 { 4315 Info FunctionInfo(__func__); 4316 IndexToIndex * DegeneratedLines = FindAllDegeneratedLines(); 4317 IndexToIndex * DegeneratedTriangles = new IndexToIndex; 3471 4318 3472 4319 TriangleMap::iterator TriangleRunner1, TriangleRunner2; … … 3474 4321 class BoundaryLineSet *line1 = NULL, *line2 = NULL; 3475 4322 3476 for ( map<int, int>::iterator LineRunner = DegeneratedLines->begin(); LineRunner != DegeneratedLines->end(); ++LineRunner) {4323 for (IndexToIndex::iterator LineRunner = DegeneratedLines->begin(); LineRunner != DegeneratedLines->end(); ++LineRunner) { 3477 4324 // run over both lines' triangles 3478 4325 Liner = LinesOnBoundary.find(LineRunner->first); … … 3494 4341 delete(DegeneratedLines); 3495 4342 3496 Log() << Verbose( 1) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles->size() << " triangles:" << endl;3497 map<int,int>::iterator it;4343 Log() << Verbose(0) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles->size() << " triangles:" << endl; 4344 IndexToIndex::iterator it; 3498 4345 for (it = DegeneratedTriangles->begin(); it != DegeneratedTriangles->end(); it++) 3499 Log() << Verbose( 2) << (*it).first << " => " << (*it).second << endl;4346 Log() << Verbose(0) << (*it).first << " => " << (*it).second << endl; 3500 4347 3501 4348 return DegeneratedTriangles; … … 3508 4355 void Tesselation::RemoveDegeneratedTriangles() 3509 4356 { 3510 map<int, int> * DegeneratedTriangles = FindAllDegeneratedTriangles(); 4357 Info FunctionInfo(__func__); 4358 IndexToIndex * DegeneratedTriangles = FindAllDegeneratedTriangles(); 3511 4359 TriangleMap::iterator finder; 3512 4360 BoundaryTriangleSet *triangle = NULL, *partnerTriangle = NULL; 3513 4361 int count = 0; 3514 4362 3515 Log() << Verbose(1) << "Begin of RemoveDegeneratedTriangles" << endl; 3516 3517 for (map<int, int>::iterator TriangleKeyRunner = DegeneratedTriangles->begin(); 4363 for (IndexToIndex::iterator TriangleKeyRunner = DegeneratedTriangles->begin(); 3518 4364 TriangleKeyRunner != DegeneratedTriangles->end(); ++TriangleKeyRunner 3519 4365 ) { … … 3572 4418 // erase the pair 3573 4419 count += (int) DegeneratedTriangles->erase(triangle->Nr); 3574 Log() << Verbose( 1) << "RemoveDegeneratedTriangles() removes triangle " << *triangle << "." << endl;4420 Log() << Verbose(0) << "RemoveDegeneratedTriangles() removes triangle " << *triangle << "." << endl; 3575 4421 RemoveTesselationTriangle(triangle); 3576 4422 count += (int) DegeneratedTriangles->erase(partnerTriangle->Nr); 3577 Log() << Verbose( 1) << "RemoveDegeneratedTriangles() removes triangle " << *partnerTriangle << "." << endl;4423 Log() << Verbose(0) << "RemoveDegeneratedTriangles() removes triangle " << *partnerTriangle << "." << endl; 3578 4424 RemoveTesselationTriangle(partnerTriangle); 3579 4425 } else { 3580 Log() << Verbose( 1) << "RemoveDegeneratedTriangles() does not remove triangle " << *triangle4426 Log() << Verbose(0) << "RemoveDegeneratedTriangles() does not remove triangle " << *triangle 3581 4427 << " and its partner " << *partnerTriangle << " because it is essential for at" 3582 4428 << " least one of the endpoints to be kept in the tesselation structure." << endl; … … 3584 4430 } 3585 4431 delete(DegeneratedTriangles); 3586 3587 Log() << Verbose(1) << "RemoveDegeneratedTriangles() removed " << count << " triangles:" << endl; 3588 Log() << Verbose(1) << "End of RemoveDegeneratedTriangles" << endl; 4432 if (count > 0) 4433 LastTriangle = NULL; 4434 4435 Log() << Verbose(0) << "RemoveDegeneratedTriangles() removed " << count << " triangles:" << endl; 3589 4436 } 3590 4437 … … 3599 4446 void Tesselation::AddBoundaryPointByDegeneratedTriangle(class TesselPoint *point, LinkedCell *LC) 3600 4447 { 3601 Log() << Verbose(2) << "Begin of AddBoundaryPointByDegeneratedTriangle" << endl; 3602 4448 Info FunctionInfo(__func__); 3603 4449 // find nearest boundary point 3604 4450 class TesselPoint *BackupPoint = NULL; 3605 class TesselPoint *NearestPoint = FindClosest Point(point->node, BackupPoint, LC);4451 class TesselPoint *NearestPoint = FindClosestTesselPoint(point->node, BackupPoint, LC); 3606 4452 class BoundaryPointSet *NearestBoundaryPoint = NULL; 3607 4453 PointMap::iterator PointRunner; … … 3616 4462 return; 3617 4463 } 3618 Log() << Verbose( 2) << "Nearest point on boundary is " << NearestPoint->Name << "." << endl;4464 Log() << Verbose(0) << "Nearest point on boundary is " << NearestPoint->Name << "." << endl; 3619 4465 3620 4466 // go through its lines and find the best one to split … … 3649 4495 3650 4496 // create new triangle to connect point (connects automatically with the missing spot of the chosen line) 3651 Log() << Verbose( 5) << "Adding new triangle points."<< endl;4497 Log() << Verbose(2) << "Adding new triangle points."<< endl; 3652 4498 AddTesselationPoint((BestLine->endpoints[0]->node), 0); 3653 4499 AddTesselationPoint((BestLine->endpoints[1]->node), 1); 3654 4500 AddTesselationPoint(point, 2); 3655 Log() << Verbose( 5) << "Adding new triangle lines."<< endl;4501 Log() << Verbose(2) << "Adding new triangle lines."<< endl; 3656 4502 AddTesselationLine(TPS[0], TPS[1], 0); 3657 4503 AddTesselationLine(TPS[0], TPS[2], 1); … … 3660 4506 BTS->GetNormalVector(TempTriangle->NormalVector); 3661 4507 BTS->NormalVector.Scale(-1.); 3662 Log() << Verbose( 3) << "INFO: NormalVector of new triangle is " << BTS->NormalVector << "." << endl;4508 Log() << Verbose(1) << "INFO: NormalVector of new triangle is " << BTS->NormalVector << "." << endl; 3663 4509 AddTesselationTriangle(); 3664 4510 3665 4511 // create other side of this triangle and close both new sides of the first created triangle 3666 Log() << Verbose( 5) << "Adding new triangle points."<< endl;4512 Log() << Verbose(2) << "Adding new triangle points."<< endl; 3667 4513 AddTesselationPoint((BestLine->endpoints[0]->node), 0); 3668 4514 AddTesselationPoint((BestLine->endpoints[1]->node), 1); 3669 4515 AddTesselationPoint(point, 2); 3670 Log() << Verbose( 5) << "Adding new triangle lines."<< endl;4516 Log() << Verbose(2) << "Adding new triangle lines."<< endl; 3671 4517 AddTesselationLine(TPS[0], TPS[1], 0); 3672 4518 AddTesselationLine(TPS[0], TPS[2], 1); … … 3674 4520 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 3675 4521 BTS->GetNormalVector(TempTriangle->NormalVector); 3676 Log() << Verbose( 3) << "INFO: NormalVector of other new triangle is " << BTS->NormalVector << "." << endl;4522 Log() << Verbose(1) << "INFO: NormalVector of other new triangle is " << BTS->NormalVector << "." << endl; 3677 4523 AddTesselationTriangle(); 3678 4524 … … 3681 4527 if ((BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[0])) && (BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[1]))) { 3682 4528 if (BestLine == BTS->lines[i]){ 3683 Log() << Verbose(1) << "CRITICAL:BestLine is same as found line, something's wrong here!" << endl;3684 exit(255);4529 eLog() << Verbose(0) << "BestLine is same as found line, something's wrong here!" << endl; 4530 performCriticalExit(); 3685 4531 } 3686 4532 BTS->lines[i]->triangles.insert( pair<int, class BoundaryTriangleSet *> (TempTriangle->Nr, TempTriangle) ); … … 3689 4535 } 3690 4536 } 3691 3692 // exit3693 Log() << Verbose(2) << "End of AddBoundaryPointByDegeneratedTriangle" << endl;3694 4537 }; 3695 4538 … … 3701 4544 void Tesselation::Output(const char *filename, const PointCloud * const cloud) 3702 4545 { 4546 Info FunctionInfo(__func__); 3703 4547 ofstream *tempstream = NULL; 3704 4548 string NameofTempFile; … … 3713 4557 NameofTempFile.erase(npos, 1); 3714 4558 NameofTempFile.append(TecplotSuffix); 3715 Log() << Verbose( 1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";4559 Log() << Verbose(0) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 3716 4560 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 3717 4561 WriteTecplotFile(tempstream, this, cloud, TriangleFilesWritten); … … 3727 4571 NameofTempFile.erase(npos, 1); 3728 4572 NameofTempFile.append(Raster3DSuffix); 3729 Log() << Verbose( 1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";4573 Log() << Verbose(0) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 3730 4574 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 3731 4575 WriteRaster3dFile(tempstream, this, cloud); … … 3739 4583 TriangleFilesWritten++; 3740 4584 }; 4585 4586 struct BoundaryPolygonSetCompare { 4587 bool operator()(const BoundaryPolygonSet * s1, const BoundaryPolygonSet * s2) const { 4588 if (s1->endpoints.size() < s2->endpoints.size()) 4589 return true; 4590 else if (s1->endpoints.size() > s2->endpoints.size()) 4591 return false; 4592 else { // equality of number of endpoints 4593 PointSet::const_iterator Walker1 = s1->endpoints.begin(); 4594 PointSet::const_iterator Walker2 = s2->endpoints.begin(); 4595 while ((Walker1 != s1->endpoints.end()) || (Walker2 != s2->endpoints.end())) { 4596 if ((*Walker1)->Nr < (*Walker2)->Nr) 4597 return true; 4598 else if ((*Walker1)->Nr > (*Walker2)->Nr) 4599 return false; 4600 Walker1++; 4601 Walker2++; 4602 } 4603 return false; 4604 } 4605 } 4606 }; 4607 4608 #define UniquePolygonSet set < BoundaryPolygonSet *, BoundaryPolygonSetCompare> 4609 4610 /** Finds all degenerated polygons and calls ReTesselateDegeneratedPolygon()/ 4611 * \return number of polygons found 4612 */ 4613 int Tesselation::CorrectAllDegeneratedPolygons() 4614 { 4615 Info FunctionInfo(__func__); 4616 4617 /// 2. Go through all BoundaryPointSet's, check their triangles' NormalVector 4618 IndexToIndex *DegeneratedTriangles = FindAllDegeneratedTriangles(); 4619 set < BoundaryPointSet *> EndpointCandidateList; 4620 pair < set < BoundaryPointSet *>::iterator, bool > InsertionTester; 4621 pair < map < int, Vector *>::iterator, bool > TriangleInsertionTester; 4622 for (PointMap::const_iterator Runner = PointsOnBoundary.begin(); Runner != PointsOnBoundary.end(); Runner++) { 4623 Log() << Verbose(0) << "Current point is " << *Runner->second << "." << endl; 4624 map < int, Vector *> TriangleVectors; 4625 // gather all NormalVectors 4626 Log() << Verbose(1) << "Gathering triangles ..." << endl; 4627 for (LineMap::const_iterator LineRunner = (Runner->second)->lines.begin(); LineRunner != (Runner->second)->lines.end(); LineRunner++) 4628 for (TriangleMap::const_iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) { 4629 if (DegeneratedTriangles->find(TriangleRunner->second->Nr) == DegeneratedTriangles->end()) { 4630 TriangleInsertionTester = TriangleVectors.insert( pair< int, Vector *> ((TriangleRunner->second)->Nr, &((TriangleRunner->second)->NormalVector)) ); 4631 if (TriangleInsertionTester.second) 4632 Log() << Verbose(1) << " Adding triangle " << *(TriangleRunner->second) << " to triangles to check-list." << endl; 4633 } else { 4634 Log() << Verbose(1) << " NOT adding triangle " << *(TriangleRunner->second) << " as it's a simply degenerated one." << endl; 4635 } 4636 } 4637 // check whether there are two that are parallel 4638 Log() << Verbose(1) << "Finding two parallel triangles ..." << endl; 4639 for (map < int, Vector *>::iterator VectorWalker = TriangleVectors.begin(); VectorWalker != TriangleVectors.end(); VectorWalker++) 4640 for (map < int, Vector *>::iterator VectorRunner = VectorWalker; VectorRunner != TriangleVectors.end(); VectorRunner++) 4641 if (VectorWalker != VectorRunner) { // skip equals 4642 const double SCP = VectorWalker->second->ScalarProduct(VectorRunner->second); // ScalarProduct should result in -1. for degenerated triangles 4643 Log() << Verbose(1) << "Checking " << *VectorWalker->second<< " against " << *VectorRunner->second << ": " << SCP << endl; 4644 if (fabs(SCP + 1.) < ParallelEpsilon) { 4645 InsertionTester = EndpointCandidateList.insert((Runner->second)); 4646 if (InsertionTester.second) 4647 Log() << Verbose(0) << " Adding " << *Runner->second << " to endpoint candidate list." << endl; 4648 // and break out of both loops 4649 VectorWalker = TriangleVectors.end(); 4650 VectorRunner = TriangleVectors.end(); 4651 break; 4652 } 4653 } 4654 } 4655 4656 /// 3. Find connected endpoint candidates and put them into a polygon 4657 UniquePolygonSet ListofDegeneratedPolygons; 4658 BoundaryPointSet *Walker = NULL; 4659 BoundaryPointSet *OtherWalker = NULL; 4660 BoundaryPolygonSet *Current = NULL; 4661 stack <BoundaryPointSet*> ToCheckConnecteds; 4662 while (!EndpointCandidateList.empty()) { 4663 Walker = *(EndpointCandidateList.begin()); 4664 if (Current == NULL) { // create a new polygon with current candidate 4665 Log() << Verbose(0) << "Starting new polygon set at point " << *Walker << endl; 4666 Current = new BoundaryPolygonSet; 4667 Current->endpoints.insert(Walker); 4668 EndpointCandidateList.erase(Walker); 4669 ToCheckConnecteds.push(Walker); 4670 } 4671 4672 // go through to-check stack 4673 while (!ToCheckConnecteds.empty()) { 4674 Walker = ToCheckConnecteds.top(); // fetch ... 4675 ToCheckConnecteds.pop(); // ... and remove 4676 for (LineMap::const_iterator LineWalker = Walker->lines.begin(); LineWalker != Walker->lines.end(); LineWalker++) { 4677 OtherWalker = (LineWalker->second)->GetOtherEndpoint(Walker); 4678 Log() << Verbose(1) << "Checking " << *OtherWalker << endl; 4679 set < BoundaryPointSet *>::iterator Finder = EndpointCandidateList.find(OtherWalker); 4680 if (Finder != EndpointCandidateList.end()) { // found a connected partner 4681 Log() << Verbose(1) << " Adding to polygon." << endl; 4682 Current->endpoints.insert(OtherWalker); 4683 EndpointCandidateList.erase(Finder); // remove from candidates 4684 ToCheckConnecteds.push(OtherWalker); // but check its partners too 4685 } else { 4686 Log() << Verbose(1) << " is not connected to " << *Walker << endl; 4687 } 4688 } 4689 } 4690 4691 Log() << Verbose(0) << "Final polygon is " << *Current << endl; 4692 ListofDegeneratedPolygons.insert(Current); 4693 Current = NULL; 4694 } 4695 4696 const int counter = ListofDegeneratedPolygons.size(); 4697 4698 Log() << Verbose(0) << "The following " << counter << " degenerated polygons have been found: " << endl; 4699 for (UniquePolygonSet::iterator PolygonRunner = ListofDegeneratedPolygons.begin(); PolygonRunner != ListofDegeneratedPolygons.end(); PolygonRunner++) 4700 Log() << Verbose(0) << " " << **PolygonRunner << endl; 4701 4702 /// 4. Go through all these degenerated polygons 4703 for (UniquePolygonSet::iterator PolygonRunner = ListofDegeneratedPolygons.begin(); PolygonRunner != ListofDegeneratedPolygons.end(); PolygonRunner++) { 4704 stack <int> TriangleNrs; 4705 Vector NormalVector; 4706 /// 4a. Gather all triangles of this polygon 4707 TriangleSet *T = (*PolygonRunner)->GetAllContainedTrianglesFromEndpoints(); 4708 4709 // check whether number is bigger than 2, otherwise it's just a simply degenerated one and nothing to do. 4710 if (T->size() == 2) { 4711 Log() << Verbose(1) << " Skipping degenerated polygon, is just a (already simply degenerated) triangle." << endl; 4712 delete(T); 4713 continue; 4714 } 4715 4716 // check whether number is even 4717 // If this case occurs, we have to think about it! 4718 // The Problem is probably due to two degenerated polygons being connected by a bridging, non-degenerated polygon, as somehow one node has 4719 // connections to either polygon ... 4720 if (T->size() % 2 != 0) { 4721 eLog() << Verbose(0) << " degenerated polygon contains an odd number of triangles, probably contains bridging non-degenerated ones, too!" << endl; 4722 performCriticalExit(); 4723 } 4724 4725 TriangleSet::iterator TriangleWalker = T->begin(); // is the inner iterator 4726 /// 4a. Get NormalVector for one side (this is "front") 4727 NormalVector.CopyVector(&(*TriangleWalker)->NormalVector); 4728 Log() << Verbose(1) << "\"front\" defining triangle is " << **TriangleWalker << " and Normal vector of \"front\" side is " << NormalVector << endl; 4729 TriangleWalker++; 4730 TriangleSet::iterator TriangleSprinter = TriangleWalker; // is the inner advanced iterator 4731 /// 4b. Remove all triangles whose NormalVector is in opposite direction (i.e. "back") 4732 BoundaryTriangleSet *triangle = NULL; 4733 while (TriangleSprinter != T->end()) { 4734 TriangleWalker = TriangleSprinter; 4735 triangle = *TriangleWalker; 4736 TriangleSprinter++; 4737 Log() << Verbose(1) << "Current triangle to test for removal: " << *triangle << endl; 4738 if (triangle->NormalVector.ScalarProduct(&NormalVector) < 0) { // if from other side, then delete and remove from list 4739 Log() << Verbose(1) << " Removing ... " << endl; 4740 TriangleNrs.push(triangle->Nr); 4741 T->erase(TriangleWalker); 4742 RemoveTesselationTriangle(triangle); 4743 } else 4744 Log() << Verbose(1) << " Keeping ... " << endl; 4745 } 4746 /// 4c. Copy all "front" triangles but with inverse NormalVector 4747 TriangleWalker = T->begin(); 4748 while (TriangleWalker != T->end()) { // go through all front triangles 4749 Log() << Verbose(1) << " Re-creating triangle " << **TriangleWalker << " with NormalVector " << (*TriangleWalker)->NormalVector << endl; 4750 for (int i = 0; i < 3; i++) 4751 AddTesselationPoint((*TriangleWalker)->endpoints[i]->node, i); 4752 AddTesselationLine(TPS[0], TPS[1], 0); 4753 AddTesselationLine(TPS[0], TPS[2], 1); 4754 AddTesselationLine(TPS[1], TPS[2], 2); 4755 if (TriangleNrs.empty()) 4756 eLog() << Verbose(0) << "No more free triangle numbers!" << endl; 4757 BTS = new BoundaryTriangleSet(BLS, TriangleNrs.top()); // copy triangle ... 4758 AddTesselationTriangle(); // ... and add 4759 TriangleNrs.pop(); 4760 BTS->NormalVector.CopyVector(&(*TriangleWalker)->NormalVector); 4761 BTS->NormalVector.Scale(-1.); 4762 TriangleWalker++; 4763 } 4764 if (!TriangleNrs.empty()) { 4765 eLog() << Verbose(0) << "There have been less triangles created than removed!" << endl; 4766 } 4767 delete(T); // remove the triangleset 4768 } 4769 4770 IndexToIndex * SimplyDegeneratedTriangles = FindAllDegeneratedTriangles(); 4771 Log() << Verbose(0) << "Final list of simply degenerated triangles found, containing " << SimplyDegeneratedTriangles->size() << " triangles:" << endl; 4772 IndexToIndex::iterator it; 4773 for (it = SimplyDegeneratedTriangles->begin(); it != SimplyDegeneratedTriangles->end(); it++) 4774 Log() << Verbose(0) << (*it).first << " => " << (*it).second << endl; 4775 delete(SimplyDegeneratedTriangles); 4776 4777 /// 5. exit 4778 UniquePolygonSet::iterator PolygonRunner; 4779 while (!ListofDegeneratedPolygons.empty()) { 4780 PolygonRunner = ListofDegeneratedPolygons.begin(); 4781 delete(*PolygonRunner); 4782 ListofDegeneratedPolygons.erase(PolygonRunner); 4783 } 4784 4785 return counter; 4786 };
Note:
See TracChangeset
for help on using the changeset viewer.
