- Timestamp:
- Aug 17, 2009, 10:30:53 AM (15 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, 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:
- 093645
- Parents:
- 86381b
- Location:
- src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/tesselation.cpp
r86381b r16d866 10 10 // ======================================== Points on Boundary ================================= 11 11 12 /** Constructor of BoundaryPointSet. 13 */ 12 14 BoundaryPointSet::BoundaryPointSet() 13 15 { 14 16 LinesCount = 0; 15 17 Nr = -1; 16 } 17 ; 18 18 }; 19 20 /** Constructor of BoundaryPointSet with Tesselpoint. 21 * \param *Walker TesselPoint this boundary point represents 22 */ 19 23 BoundaryPointSet::BoundaryPointSet(TesselPoint *Walker) 20 24 { … … 22 26 LinesCount = 0; 23 27 Nr = Walker->nr; 24 } 25 ; 26 28 }; 29 30 /** Destructor of BoundaryPointSet. 31 * Sets node to NULL to avoid removing the original, represented TesselPoint. 32 * \note When removing point from a class Tesselation, use RemoveTesselationPoint() 33 */ 27 34 BoundaryPointSet::~BoundaryPointSet() 28 35 { … … 31 38 cerr << "WARNING: Memory Leak! I " << *this << " am still connected to some lines." << endl; 32 39 node = NULL; 33 } 34 ; 35 40 }; 41 42 /** Add a line to the LineMap of this point. 43 * \param *line line to add 44 */ 36 45 void BoundaryPointSet::AddLine(class BoundaryLineSet *line) 37 46 { … … 47 56 } 48 57 LinesCount++; 49 } 50 ; 51 52 ostream & 53 operator <<(ostream &ost, BoundaryPointSet &a) 58 }; 59 60 /** output operator for BoundaryPointSet. 61 * \param &ost output stream 62 * \param &a boundary point 63 */ 64 ostream & operator <<(ostream &ost, BoundaryPointSet &a) 54 65 { 55 66 ost << "[" << a.Nr << "|" << a.node->Name << "]"; … … 60 71 // ======================================== Lines on Boundary ================================= 61 72 73 /** Constructor of BoundaryLineSet. 74 */ 62 75 BoundaryLineSet::BoundaryLineSet() 63 76 { … … 65 78 endpoints[i] = NULL; 66 79 Nr = -1; 67 } 68 ; 69 80 }; 81 82 /** Constructor of BoundaryLineSet with two endpoints. 83 * Adds line automatically to each endpoints' LineMap 84 * \param *Point[2] array of two boundary points 85 * \param number number of the list 86 */ 70 87 BoundaryLineSet::BoundaryLineSet(class BoundaryPointSet *Point[2], int number) 71 88 { … … 79 96 // clear triangles list 80 97 cout << Verbose(5) << "New Line with endpoints " << *this << "." << endl; 81 } 82 ; 83 98 }; 99 100 /** Destructor for BoundaryLineSet. 101 * Removes itself from each endpoints' LineMap, calling RemoveTrianglePoint() when point not connected anymore. 102 * \note When removing lines from a class Tesselation, use RemoveTesselationLine() 103 */ 84 104 BoundaryLineSet::~BoundaryLineSet() 85 105 { 86 106 int Numbers[2]; 87 Numbers[0] = endpoints[1]->Nr; 88 Numbers[1] = endpoints[0]->Nr; 107 108 // get other endpoint number of finding copies of same line 109 if (endpoints[1] != NULL) 110 Numbers[0] = endpoints[1]->Nr; 111 else 112 Numbers[0] = -1; 113 if (endpoints[0] != NULL) 114 Numbers[1] = endpoints[0]->Nr; 115 else 116 Numbers[1] = -1; 117 89 118 for (int i = 0; i < 2; i++) { 90 cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 91 // as there may be multiple lines with same endpoints, we have to go through each and find in the endpoint's line list this line set 92 pair<LineMap::iterator, LineMap::iterator> erasor = endpoints[i]->lines.equal_range(Numbers[i]); 93 for (LineMap::iterator Runner = erasor.first; Runner != erasor.second; Runner++) 94 if ((*Runner).second == this) { 95 endpoints[i]->lines.erase(Runner); 96 break; 119 if (endpoints[i] != NULL) { 120 if (Numbers[i] != -1) { // as there may be multiple lines with same endpoints, we have to go through each and find in the endpoint's line list this line set 121 pair<LineMap::iterator, LineMap::iterator> erasor = endpoints[i]->lines.equal_range(Numbers[i]); 122 for (LineMap::iterator Runner = erasor.first; Runner != erasor.second; Runner++) 123 if ((*Runner).second == this) { 124 cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 125 endpoints[i]->lines.erase(Runner); 126 break; 127 } 128 } else { // there's just a single line left 129 if (endpoints[i]->lines.erase(Nr)) 130 cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 97 131 } 98 if (endpoints[i]->lines.empty()) { 99 cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl; 100 if (endpoints[i] != NULL) { 101 delete(endpoints[i]); 102 endpoints[i] = NULL; 103 } else 104 cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl; 105 } else 106 cout << Verbose(5) << *endpoints[i] << " has still lines it's attached to." << endl; 132 if (endpoints[i]->lines.empty()) { 133 cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl; 134 if (endpoints[i] != NULL) { 135 delete(endpoints[i]); 136 endpoints[i] = NULL; 137 } 138 } 139 } 107 140 } 108 141 if (!triangles.empty()) 109 142 cerr << "WARNING: Memory Leak! I " << *this << " am still connected to some triangles." << endl; 110 } 111 ; 112 113 void 114 BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle) 143 }; 144 145 /** Add triangle to TriangleMap of this boundary line. 146 * \param *triangle to add 147 */ 148 void BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle) 115 149 { 116 150 cout << Verbose(6) << "Add " << triangle->Nr << " to line " << *this << "." 117 151 << endl; 118 152 triangles.insert(TrianglePair(triangle->Nr, triangle)); 119 } 120 ; 153 }; 121 154 122 155 /** Checks whether we have a common endpoint with given \a *line. … … 218 251 }; 219 252 220 221 ostream & 222 operator <<(ostream &ost, BoundaryLineSet &a) 253 /** output operator for BoundaryLineSet. 254 * \param &ost output stream 255 * \param &a boundary line 256 */ 257 ostream & operator <<(ostream &ost, BoundaryLineSet &a) 223 258 { 224 259 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," << a.endpoints[1]->node->Name << "]"; 225 260 return ost; 226 } 227 ; 261 }; 228 262 229 263 // ======================================== Triangles on Boundary ================================= 230 264 231 265 /** Constructor for BoundaryTriangleSet. 266 */ 232 267 BoundaryTriangleSet::BoundaryTriangleSet() 233 268 { … … 238 273 } 239 274 Nr = -1; 240 } 241 ; 242 275 }; 276 277 /** Constructor for BoundaryTriangleSet with three lines. 278 * \param *line[3] lines that make up the triangle 279 * \param number number of triangle 280 */ 243 281 BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet *line[3], int number) 244 282 { … … 279 317 } 280 318 cout << "." << endl; 281 } 282 ; 283 319 }; 320 321 /** Destructor of BoundaryTriangleSet. 322 * Removes itself from each of its lines' LineMap and removes them if necessary. 323 * \note When removing triangles from a class Tesselation, use RemoveTesselationTriangle() 324 */ 284 325 BoundaryTriangleSet::~BoundaryTriangleSet() 285 326 { 286 327 for (int i = 0; i < 3; i++) { 287 cout << Verbose(5) << "Erasing triangle Nr." << Nr << endl; 288 lines[i]->triangles.erase(Nr); 289 if (lines[i]->triangles.empty()) { 290 if (lines[i] != NULL) { 291 cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl; 292 delete (lines[i]); 293 lines[i] = NULL; 294 } else 295 cerr << "ERROR: This line " << i << " has already been free'd." << endl; 296 } else 297 cout << Verbose(5) << *lines[i] << " is still attached to another triangle." << endl; 298 } 299 } 300 ; 328 if (lines[i] != NULL) { 329 if (lines[i]->triangles.erase(Nr)) 330 cout << Verbose(5) << "Triangle Nr." << Nr << " erased in line " << *lines[i] << "." << endl; 331 if (lines[i]->triangles.empty()) { 332 cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl; 333 delete (lines[i]); 334 lines[i] = NULL; 335 } 336 } 337 } 338 cout << Verbose(5) << "Erasing triangle Nr." << Nr << " itself." << endl; 339 }; 301 340 302 341 /** Calculates the normal vector for this triangle. … … 435 474 } 436 475 437 ostream & 438 operator <<(ostream &ost, BoundaryTriangleSet &a) 476 /** output operator for BoundaryTriangleSet. 477 * \param &ost output stream 478 * \param &a boundary triangle 479 */ 480 ostream &operator <<(ostream &ost, BoundaryTriangleSet &a) 439 481 { 440 482 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," 441 483 << a.endpoints[1]->node->Name << "," << a.endpoints[2]->node->Name << "]"; 442 484 return ost; 443 } 444 ; 485 }; 445 486 446 487 // =========================================================== class TESSELPOINT =========================================== … … 1044 1085 // add Walker to boundary points 1045 1086 *out << Verbose(2) << "Adding " << *Walker << " to BoundaryPoints." << endl; 1046 if (Add Point(Walker,0))1087 if (AddBoundaryPoint(Walker,0)) 1047 1088 NewPoint = BPS[0]; 1048 1089 else … … 1097 1138 }; 1098 1139 1099 /** Adds a npoint to the tesselation::PointsOnBoundary list.1140 /** Adds a point to the tesselation::PointsOnBoundary list. 1100 1141 * \param *Walker point to add 1101 1142 * \param n TesselStruct::BPS index to put pointer into … … 1103 1144 */ 1104 1145 bool 1105 Tesselation::Add Point(TesselPoint *Walker, int n)1146 Tesselation::AddBoundaryPoint(TesselPoint *Walker, int n) 1106 1147 { 1107 1148 PointTestPair InsertUnique; … … 1125 1166 */ 1126 1167 void 1127 Tesselation::AddT rianglePoint(TesselPoint* Candidate, int n)1168 Tesselation::AddTesselationPoint(TesselPoint* Candidate, int n) 1128 1169 { 1129 1170 PointTestPair InsertUnique; … … 1147 1188 * @param n index of Tesselation::BLS giving the line with both endpoints 1148 1189 */ 1149 void Tesselation::AddT riangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n) {1190 void Tesselation::AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n) { 1150 1191 bool insertNewLine = true; 1151 1192 … … 1171 1212 1172 1213 if (insertNewLine) { 1173 AlwaysAddT riangleLine(a, b, n);1214 AlwaysAddTesselationTriangleLine(a, b, n); 1174 1215 } 1175 1216 } … … 1184 1225 * @param n index of Tesselation::BLS giving the line with both endpoints 1185 1226 */ 1186 void Tesselation::AlwaysAddT riangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n)1227 void Tesselation::AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n) 1187 1228 { 1188 1229 cout << Verbose(3) << "Adding line between " << *(a->node) << " and " << *(b->node) << "." << endl; … … 1199 1240 * Furthermore it adds the triangle to all of its lines, in order to recognize those which are saturated later. 1200 1241 */ 1201 void 1202 Tesselation::AddTriangle() 1242 void Tesselation::AddTesselationTriangle() 1203 1243 { 1204 1244 cout << Verbose(1) << "Adding triangle to global TrianglesOnBoundary map." << endl; … … 1209 1249 1210 1250 // NOTE: add triangle to local maps is done in constructor of BoundaryTriangleSet 1211 } 1212 ; 1251 }; 1252 1253 /** Removes a triangle from the tesselation. 1254 * Removes itself from the TriangleMap's of its lines, calls for them RemoveTriangleLine() if they are no more connected. 1255 * Removes itself from memory. 1256 * \param *triangle to remove 1257 */ 1258 void Tesselation::RemoveTesselationTriangle(class BoundaryTriangleSet *triangle) 1259 { 1260 if (triangle == NULL) 1261 return; 1262 for (int i = 0; i < 3; i++) { 1263 if (triangle->lines[i] != NULL) { 1264 cout << Verbose(5) << "Removing triangle Nr." << triangle->Nr << " in line " << *triangle->lines[i] << "." << endl; 1265 triangle->lines[i]->triangles.erase(triangle->Nr); 1266 if (triangle->lines[i]->triangles.empty()) { 1267 cout << Verbose(5) << *triangle->lines[i] << " is no more attached to any triangle, erasing." << endl; 1268 RemoveTesselationLine(triangle->lines[i]); 1269 triangle->lines[i] = NULL; 1270 } else 1271 cout << Verbose(5) << *triangle->lines[i] << " is still attached to another triangle." << endl; 1272 } else 1273 cerr << "ERROR: This line " << i << " has already been free'd." << endl; 1274 } 1275 1276 if (TrianglesOnBoundary.erase(triangle->Nr)) 1277 cout << Verbose(5) << "Removing triangle Nr. " << triangle->Nr << "." << endl; 1278 delete(triangle); 1279 }; 1280 1281 /** Removes a line from the tesselation. 1282 * Removes itself from each endpoints' LineMap, then removes itself from global LinesOnBoundary list and free's the line. 1283 * \param *line line to remove 1284 */ 1285 void Tesselation::RemoveTesselationLine(class BoundaryLineSet *line) 1286 { 1287 int Numbers[2]; 1288 1289 if (line == NULL) 1290 return; 1291 // get other endpoint number of finding copies of same line 1292 if (line->endpoints[1] != NULL) 1293 Numbers[0] = line->endpoints[1]->Nr; 1294 else 1295 Numbers[0] = -1; 1296 if (line->endpoints[0] != NULL) 1297 Numbers[1] = line->endpoints[0]->Nr; 1298 else 1299 Numbers[1] = -1; 1300 1301 for (int i = 0; i < 2; i++) { 1302 if (line->endpoints[i] != NULL) { 1303 if (Numbers[i] != -1) { // as there may be multiple lines with same endpoints, we have to go through each and find in the endpoint's line list this line set 1304 pair<LineMap::iterator, LineMap::iterator> erasor = line->endpoints[i]->lines.equal_range(Numbers[i]); 1305 for (LineMap::iterator Runner = erasor.first; Runner != erasor.second; Runner++) 1306 if ((*Runner).second == line) { 1307 cout << Verbose(5) << "Removing Line Nr. " << line->Nr << " in boundary point " << *line->endpoints[i] << "." << endl; 1308 line->endpoints[i]->lines.erase(Runner); 1309 break; 1310 } 1311 } else { // there's just a single line left 1312 if (line->endpoints[i]->lines.erase(line->Nr)) 1313 cout << Verbose(5) << "Removing Line Nr. " << line->Nr << " in boundary point " << *line->endpoints[i] << "." << endl; 1314 } 1315 if (line->endpoints[i]->lines.empty()) { 1316 cout << Verbose(5) << *line->endpoints[i] << " has no more lines it's attached to, erasing." << endl; 1317 RemoveTesselationPoint(line->endpoints[i]); 1318 line->endpoints[i] = NULL; 1319 } else 1320 cout << Verbose(5) << *line->endpoints[i] << " has still lines it's attached to." << endl; 1321 } else 1322 cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl; 1323 } 1324 if (!line->triangles.empty()) 1325 cerr << "WARNING: Memory Leak! I " << *line << " am still connected to some triangles." << endl; 1326 1327 if (LinesOnBoundary.erase(line->Nr)) 1328 cout << Verbose(5) << "Removing line Nr. " << line->Nr << "." << endl; 1329 delete(line); 1330 }; 1331 1332 /** Removes a point from the tesselation. 1333 * Checks whether there are still lines connected, removes from global PointsOnBoundary list, then free's the point. 1334 * \note If a point should be removed, while keep the tesselated surface intact (i.e. closed), use RemovePointFromTesselatedSurface() 1335 * \param *point point to remove 1336 */ 1337 void Tesselation::RemoveTesselationPoint(class BoundaryPointSet *point) 1338 { 1339 if (point == NULL) 1340 return; 1341 if (PointsOnBoundary.erase(point->Nr)) 1342 cout << Verbose(5) << "Removing point Nr. " << point->Nr << "." << endl; 1343 delete(point); 1344 }; 1213 1345 1214 1346 /** Checks whether the triangle consisting of the three points is already present. … … 1359 1491 1360 1492 // adding point 1 and point 2 and add the line between them 1361 AddT rianglePoint(FirstPoint, 0);1362 AddT rianglePoint(SecondPoint, 1);1363 AddT riangleLine(TPS[0], TPS[1], 0);1493 AddTesselationPoint(FirstPoint, 0); 1494 AddTesselationPoint(SecondPoint, 1); 1495 AddTesselationLine(TPS[0], TPS[1], 0); 1364 1496 1365 1497 //cout << Verbose(2) << "INFO: OldSphereCenter is at " << helper << ".\n"; … … 1375 1507 for (CandidateList::iterator it = Opt_Candidates->begin(); it != Opt_Candidates->end(); ++it) { 1376 1508 // add third triangle point 1377 AddT rianglePoint((*it)->point, 2);1509 AddTesselationPoint((*it)->point, 2); 1378 1510 // add the second and third line 1379 AddT riangleLine(TPS[1], TPS[2], 1);1380 AddT riangleLine(TPS[0], TPS[2], 2);1511 AddTesselationLine(TPS[1], TPS[2], 1); 1512 AddTesselationLine(TPS[0], TPS[2], 2); 1381 1513 // ... and triangles to the Maps of the Tesselation class 1382 1514 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 1383 AddT riangle();1515 AddTesselationTriangle(); 1384 1516 // ... and calculate its normal vector (with correct orientation) 1385 1517 (*it)->OptCenter.Scale(-1.); … … 1394 1526 SecondPoint = (*it)->point; 1395 1527 // adding point 1 and point 2 and the line between them 1396 AddT rianglePoint(FirstPoint, 0);1397 AddT rianglePoint(SecondPoint, 1);1398 AddT riangleLine(TPS[0], TPS[1], 0);1528 AddTesselationPoint(FirstPoint, 0); 1529 AddTesselationPoint(SecondPoint, 1); 1530 AddTesselationLine(TPS[0], TPS[1], 0); 1399 1531 } 1400 1532 cout << Verbose(2) << "Projection is " << BTS->NormalVector.Projection(&Oben) << "." << endl; … … 1528 1660 // If there is no triangle, add it regularly. 1529 1661 if (existentTrianglesCount == 0) { 1530 AddT rianglePoint((*it)->point, 0);1531 AddT rianglePoint(BaseRay->endpoints[0]->node, 1);1532 AddT rianglePoint(BaseRay->endpoints[1]->node, 2);1662 AddTesselationPoint((*it)->point, 0); 1663 AddTesselationPoint(BaseRay->endpoints[0]->node, 1); 1664 AddTesselationPoint(BaseRay->endpoints[1]->node, 2); 1533 1665 1534 1666 if (CheckLineCriteriaforDegeneratedTriangle(TPS)) { 1535 AddT riangleLine(TPS[0], TPS[1], 0);1536 AddT riangleLine(TPS[0], TPS[2], 1);1537 AddT riangleLine(TPS[1], TPS[2], 2);1667 AddTesselationLine(TPS[0], TPS[1], 0); 1668 AddTesselationLine(TPS[0], TPS[2], 1); 1669 AddTesselationLine(TPS[1], TPS[2], 2); 1538 1670 1539 1671 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 1540 AddT riangle();1672 AddTesselationTriangle(); 1541 1673 (*it)->OptCenter.Scale(-1.); 1542 1674 BTS->GetNormalVector((*it)->OptCenter); … … 1555 1687 } 1556 1688 } else if (existentTrianglesCount == 1) { // If there is a planar region within the structure, we need this triangle a second time. 1557 AddT rianglePoint((*it)->point, 0);1558 AddT rianglePoint(BaseRay->endpoints[0]->node, 1);1559 AddT rianglePoint(BaseRay->endpoints[1]->node, 2);1689 AddTesselationPoint((*it)->point, 0); 1690 AddTesselationPoint(BaseRay->endpoints[0]->node, 1); 1691 AddTesselationPoint(BaseRay->endpoints[1]->node, 2); 1560 1692 1561 1693 // 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) 1562 1694 // i.e. at least one of the three lines must be present with TriangleCount <= 1 1563 1695 if (CheckLineCriteriaforDegeneratedTriangle(TPS)) { 1564 AddT riangleLine(TPS[0], TPS[1], 0);1565 AddT riangleLine(TPS[0], TPS[2], 1);1566 AddT riangleLine(TPS[1], TPS[2], 2);1696 AddTesselationLine(TPS[0], TPS[1], 0); 1697 AddTesselationLine(TPS[0], TPS[2], 1); 1698 AddTesselationLine(TPS[1], TPS[2], 2); 1567 1699 1568 1700 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 1569 AddT riangle(); // add to global map1701 AddTesselationTriangle(); // add to global map 1570 1702 1571 1703 (*it)->OtherOptCenter.Scale(-1.); … … 1608 1740 }; 1609 1741 1610 1611 /** Goes over all baselines and checks whether adjacent triangles and convex to each other. 1742 /** Checks whether the quadragon of the two triangles connect to \a *Base is convex. 1743 * We look whether the closest point on \a *Base with respect to the other baseline is outside 1744 * of the segment formed by both endpoints (concave) or not (convex). 1612 1745 * \param *out output stream for debugging 1613 * \return true - all baselines were corrected, false - there are still concave pieces 1614 */ 1615 bool Tesselation::CorrectConcaveBaselines(ofstream *out) 1616 { 1617 class BoundaryLineSet *OldLines[4], *NewLine; 1618 class BoundaryPointSet *OldPoints[2]; 1619 Vector BaseLineNormal; 1620 class BoundaryLineSet *Base = NULL; 1621 int OldTriangles[2], OldBaseLine; 1622 int i,m; 1623 1624 *out << Verbose(1) << "Begin of CorrectConcaveBaselines" << endl; 1625 1626 // go through every baseline 1627 LineMap::iterator Advancer = LinesOnBoundary.begin(); 1628 for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline != LinesOnBoundary.end(); baseline = Advancer) { 1629 Advancer++; // as the base line might be removed, we rather have the next one already present 1630 Base = baseline->second; 1631 *out << Verbose(2) << "Current baseline is " << *Base << " ... " << endl; 1632 // calculate NormalVector for later use 1746 * \param *Base line to be flipped 1747 * \return NULL - concave, otherwise endpoint that makes it concave 1748 */ 1749 class BoundaryPointSet *Tesselation::IsConvexRectangle(ofstream *out, class BoundaryLineSet *Base) 1750 { 1751 class BoundaryPointSet *Spot = NULL; 1752 class BoundaryLineSet *OtherBase; 1753 Vector *ClosestPoint[2]; 1754 1755 int m=0; 1756 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 1757 for (int j=0;j<3;j++) // all of their endpoints and baselines 1758 if (!Base->ContainsBoundaryPoint(runner->second->endpoints[j])) // and neither of its endpoints 1759 BPS[m++] = runner->second->endpoints[j]; 1760 OtherBase = new class BoundaryLineSet(BPS,-1); 1761 1762 *out << Verbose(3) << "INFO: Current base line is " << *Base << "." << endl; 1763 *out << Verbose(3) << "INFO: Other base line is " << *OtherBase << "." << endl; 1764 1765 // get the closest point on each line to the other line 1766 ClosestPoint[0] = GetClosestPointBetweenLine(out, Base, OtherBase); 1767 ClosestPoint[1] = GetClosestPointBetweenLine(out, OtherBase, Base); 1768 1769 // delete the temporary other base line 1770 delete(OtherBase); 1771 1772 // get the distance vector from Base line to OtherBase line 1773 Vector DistanceToIntersection, BaseLine; 1774 BaseLine.CopyVector(Base->endpoints[1]->node->node); 1775 BaseLine.SubtractVector(Base->endpoints[0]->node->node); 1776 DistanceToIntersection.CopyVector(ClosestPoint[0]); 1777 DistanceToIntersection.SubtractVector(Base->endpoints[0]->node->node); 1778 Spot = Base->endpoints[1]; 1779 if (BaseLine.ScalarProduct(&DistanceToIntersection) < -MYEPSILON) { 1780 DistanceToIntersection.CopyVector(ClosestPoint[0]); 1781 DistanceToIntersection.SubtractVector(Base->endpoints[1]->node->node); 1782 Spot = Base->endpoints[0]; 1783 if (BaseLine.ScalarProduct(&DistanceToIntersection) < -MYEPSILON) { 1784 *out << Verbose(3) << "ERROR: Something's very wrong here, both SKPs return negative?!" << endl; 1785 return NULL; 1786 } 1787 } 1788 if ((BaseLine.NormSquared() - DistanceToIntersection.NormSquared()) < -MYEPSILON) { // distance is smaller: concave 1789 *out << Verbose(3) << "INFO: Rectangle of triangles of base line " << *Base << " is concave: Base line squared length " << BaseLine.NormSquared() << " against Distance to intersection squared " << DistanceToIntersection.NormSquared() << "." << endl; 1790 return Spot; 1791 } else { // base line is longer: convex 1792 *out << Verbose(3) << "INFO: Rectangle of triangles of base line " << *Base << " is concave." << endl; 1793 return NULL; 1794 } 1795 1796 }; 1797 1798 1799 /** For a given boundary line \a *Base and its two triangles, picks the central baseline that is "higher". 1800 * \param *out output stream for debugging 1801 * \param *Base line to be flipped 1802 * \return true - line was changed, false - same line as before 1803 */ 1804 bool Tesselation::PickFarthestofTwoBaselines(ofstream *out, class BoundaryLineSet *Base) 1805 { 1806 class BoundaryLineSet *OtherBase; 1807 Vector *ClosestPoint[2]; 1808 1809 int m=0; 1810 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 1811 for (int j=0;j<3;j++) // all of their endpoints and baselines 1812 if (!Base->ContainsBoundaryPoint(runner->second->endpoints[j])) // and neither of its endpoints 1813 BPS[m++] = runner->second->endpoints[j]; 1814 OtherBase = new class BoundaryLineSet(BPS,-1); 1815 1816 *out << Verbose(3) << "INFO: Current base line is " << *Base << "." << endl; 1817 *out << Verbose(3) << "INFO: Other base line is " << *OtherBase << "." << endl; 1818 1819 // get the closest point on each line to the other line 1820 ClosestPoint[0] = GetClosestPointBetweenLine(out, Base, OtherBase); 1821 ClosestPoint[1] = GetClosestPointBetweenLine(out, OtherBase, Base); 1822 1823 // get the distance vector from Base line to OtherBase line 1824 Vector Distance; 1825 Distance.CopyVector(ClosestPoint[1]); 1826 Distance.SubtractVector(ClosestPoint[0]); 1827 1828 // delete the temporary other base line 1829 delete(OtherBase); 1830 1831 if (Distance.NormSquared() < MYEPSILON) { // check for intersection 1832 *out << Verbose(3) << "REJECT: Both lines have an intersection: Nothing to do." << endl; 1833 return false; 1834 } else { // check for sign against BaseLineNormal 1835 Vector BaseLineNormal; 1633 1836 BaseLineNormal.Zero(); 1634 1837 if (Base->triangles.size() < 2) { … … 1641 1844 } 1642 1845 BaseLineNormal.Scale(-1./2.); // has to point inside for BoundaryTriangleSet::GetNormalVector() 1643 // check convexity 1644 if (Base->CheckConvexityCriterion(out)) { // triangles are convex 1645 *out << Verbose(2) << "... has two convex triangles." << endl; 1646 } else { // not convex! 1647 *out << Verbose(2) << "... has two concave triangles!" << endl; 1648 // get the two triangles 1649 // gather four endpoints and four lines 1650 for (int j=0;j<4;j++) 1651 OldLines[j] = NULL; 1652 for (int j=0;j<2;j++) 1653 OldPoints[j] = NULL; 1654 i=0; 1655 m=0; 1656 *out << Verbose(3) << "The four old lines are: "; 1657 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 1658 for (int j=0;j<3;j++) // all of their endpoints and baselines 1659 if (runner->second->lines[j] != Base) { // pick not the central baseline 1660 OldLines[i++] = runner->second->lines[j]; 1661 *out << *runner->second->lines[j] << "\t"; 1662 } 1663 *out << endl; 1664 *out << Verbose(3) << "The two old points are: "; 1665 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 1666 for (int j=0;j<3;j++) // all of their endpoints and baselines 1667 if (!Base->ContainsBoundaryPoint(runner->second->endpoints[j])) { // and neither of its endpoints 1668 OldPoints[m++] = runner->second->endpoints[j]; 1669 *out << *runner->second->endpoints[j] << "\t"; 1670 } 1671 *out << endl; 1672 if (i<4) { 1673 *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl; 1674 return false; 1846 1847 if (Distance.ScalarProduct(&BaseLineNormal) > MYEPSILON) { // Distance points outwards, hence OtherBase higher than Base -> flip 1848 *out << Verbose(2) << "ACCEPT: Other base line would be higher: Flipping baseline." << endl; 1849 FlipBaseline(out, Base); 1850 return true; 1851 } else { // Base higher than OtherBase -> do nothing 1852 *out << Verbose(2) << "REJECT: Base line is higher: Nothing to do." << endl; 1853 return false; 1854 } 1855 } 1856 }; 1857 1858 /** Returns the closest point on \a *Base with respect to \a *OtherBase. 1859 * \param *out output stream for debugging 1860 * \param *Base reference line 1861 * \param *OtherBase other base line 1862 * \return Vector on reference line that has closest distance 1863 */ 1864 Vector * GetClosestPointBetweenLine(ofstream *out, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase) 1865 { 1866 // construct the plane of the two baselines (i.e. take both their directional vectors) 1867 Vector Normal; 1868 Vector OtherBaseline; 1869 Normal.CopyVector(Base->endpoints[1]->node->node); 1870 Normal.SubtractVector(Base->endpoints[0]->node->node); 1871 OtherBaseline.CopyVector(OtherBase->endpoints[1]->node->node); 1872 OtherBaseline.SubtractVector(OtherBase->endpoints[0]->node->node); 1873 Normal.VectorProduct(&OtherBaseline); 1874 Normal.Normalize(); 1875 1876 // project one offset point of OtherBase onto this plane 1877 Vector NewOffset; 1878 NewOffset.CopyVector(OtherBase->endpoints[0]->node->node); 1879 NewOffset.ProjectOntoPlane(&Normal); 1880 Vector NewDirection; 1881 NewDirection.CopyVector(OtherBase->endpoints[1]->node->node); 1882 NewDirection.ProjectOntoPlane(&Normal); 1883 1884 // calculate the intersection between this projected baseline and Base 1885 Vector *Intersection = new Vector; 1886 Intersection->GetIntersectionOfTwoLinesOnPlane(out, Base->endpoints[0]->node->node, Base->endpoints[1]->node->node, &NewOffset, &NewDirection, &Normal); 1887 1888 return Intersection; 1889 }; 1890 1891 /** For a given baseline and its two connected triangles, flips the baseline. 1892 * I.e. we create the new baseline between the other two endpoints of these four 1893 * endpoints and reconstruct the two triangles accordingly. 1894 * \param *out output stream for debugging 1895 * \param *Base line to be flipped 1896 * \return true - flipping successful, false - something went awry 1897 */ 1898 bool Tesselation::FlipBaseline(ofstream *out, class BoundaryLineSet *Base) 1899 { 1900 class BoundaryLineSet *OldLines[4], *NewLine; 1901 class BoundaryPointSet *OldPoints[2]; 1902 Vector BaseLineNormal; 1903 int OldTriangleNrs[2], OldBaseLineNr; 1904 int i,m; 1905 1906 *out << Verbose(1) << "Begin of FlipBaseline" << endl; 1907 1908 // calculate NormalVector for later use 1909 BaseLineNormal.Zero(); 1910 if (Base->triangles.size() < 2) { 1911 *out << Verbose(2) << "ERROR: Less than two triangles are attached to this baseline!" << endl; 1912 return false; 1913 } 1914 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { 1915 *out << Verbose(4) << "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << "." << endl; 1916 BaseLineNormal.AddVector(&(runner->second->NormalVector)); 1917 } 1918 BaseLineNormal.Scale(-1./2.); // has to point inside for BoundaryTriangleSet::GetNormalVector() 1919 1920 // get the two triangles 1921 // gather four endpoints and four lines 1922 for (int j=0;j<4;j++) 1923 OldLines[j] = NULL; 1924 for (int j=0;j<2;j++) 1925 OldPoints[j] = NULL; 1926 i=0; 1927 m=0; 1928 *out << Verbose(3) << "The four old lines are: "; 1929 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 1930 for (int j=0;j<3;j++) // all of their endpoints and baselines 1931 if (runner->second->lines[j] != Base) { // pick not the central baseline 1932 OldLines[i++] = runner->second->lines[j]; 1933 *out << *runner->second->lines[j] << "\t"; 1675 1934 } 1676 for (int j=0;j<4;j++) 1677 if (OldLines[j] == NULL) { 1678 *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl; 1679 return false; 1680 } 1681 for (int j=0;j<2;j++) 1682 if (OldPoints[j] == NULL) { 1683 *out << Verbose(1) << "ERROR: We have not gathered enough endpoints!" << endl; 1684 return false; 1685 } 1686 1687 // remove triangles and baseline removes itself 1688 *out << Verbose(3) << "INFO: Deleting baseline " << *Base << "." << endl; 1689 OldBaseLine = Base->Nr; 1690 LinesOnBoundary.erase(OldBaseLine); 1691 m=0; 1692 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { 1693 *out << Verbose(3) << "INFO: Deleting triangle " << *(runner->second) << "." << endl; 1694 TrianglesOnBoundary.erase(OldTriangles[m++] = runner->second->Nr); 1695 delete(runner->second); 1935 *out << endl; 1936 *out << Verbose(3) << "The two old points are: "; 1937 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 1938 for (int j=0;j<3;j++) // all of their endpoints and baselines 1939 if (!Base->ContainsBoundaryPoint(runner->second->endpoints[j])) { // and neither of its endpoints 1940 OldPoints[m++] = runner->second->endpoints[j]; 1941 *out << *runner->second->endpoints[j] << "\t"; 1696 1942 } 1697 1698 // construct new baseline (with same number as old one) 1699 BPS[0] = OldPoints[0]; 1700 BPS[1] = OldPoints[1]; 1701 NewLine = new class BoundaryLineSet(BPS, OldBaseLine); 1702 LinesOnBoundary.insert(LinePair(OldBaseLine, NewLine)); // no need for check for unique insertion as NewLine is definitely a new one 1703 *out << Verbose(3) << "INFO: Created new baseline " << *NewLine << "." << endl; 1704 1705 // construct new triangles with flipped baseline 1706 i=-1; 1707 if (OldLines[0]->IsConnectedTo(OldLines[2])) 1708 i=2; 1709 if (OldLines[0]->IsConnectedTo(OldLines[3])) 1710 i=3; 1711 if (i!=-1) { 1712 BLS[0] = OldLines[0]; 1713 BLS[1] = OldLines[i]; 1714 BLS[2] = NewLine; 1715 BTS = new class BoundaryTriangleSet(BLS, OldTriangles[0]); 1716 BTS->GetNormalVector(BaseLineNormal); 1717 TrianglesOnBoundary.insert(TrianglePair(OldTriangles[0], BTS)); 1718 *out << Verbose(3) << "INFO: Created new triangle " << *BTS << "." << endl; 1719 1720 BLS[0] = (i==2 ? OldLines[3] : OldLines[2]); 1721 BLS[1] = OldLines[1]; 1722 BLS[2] = NewLine; 1723 BTS = new class BoundaryTriangleSet(BLS, OldTriangles[1]); 1724 BTS->GetNormalVector(BaseLineNormal); 1725 TrianglesOnBoundary.insert(TrianglePair(OldTriangles[1], BTS)); 1726 *out << Verbose(3) << "INFO: Created new triangle " << *BTS << "." << endl; 1727 } else { 1728 *out << Verbose(1) << "The four old lines do not connect, something's utterly wrong here!" << endl; 1729 return false; 1730 } 1731 } 1732 } 1733 *out << Verbose(1) << "End of CorrectConcaveBaselines" << endl; 1943 *out << endl; 1944 1945 // check whether everything is in place to create new lines and triangles 1946 if (i<4) { 1947 *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl; 1948 return false; 1949 } 1950 for (int j=0;j<4;j++) 1951 if (OldLines[j] == NULL) { 1952 *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl; 1953 return false; 1954 } 1955 for (int j=0;j<2;j++) 1956 if (OldPoints[j] == NULL) { 1957 *out << Verbose(1) << "ERROR: We have not gathered enough endpoints!" << endl; 1958 return false; 1959 } 1960 1961 // remove triangles and baseline removes itself 1962 *out << Verbose(3) << "INFO: Deleting baseline " << *Base << " from global list." << endl; 1963 OldBaseLineNr = Base->Nr; 1964 m=0; 1965 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { 1966 *out << Verbose(3) << "INFO: Deleting triangle " << *(runner->second) << "." << endl; 1967 OldTriangleNrs[m++] = runner->second->Nr; 1968 RemoveTesselationTriangle(runner->second); 1969 } 1970 1971 // construct new baseline (with same number as old one) 1972 BPS[0] = OldPoints[0]; 1973 BPS[1] = OldPoints[1]; 1974 NewLine = new class BoundaryLineSet(BPS, OldBaseLineNr); 1975 LinesOnBoundary.insert(LinePair(OldBaseLineNr, NewLine)); // no need for check for unique insertion as NewLine is definitely a new one 1976 *out << Verbose(3) << "INFO: Created new baseline " << *NewLine << "." << endl; 1977 1978 // construct new triangles with flipped baseline 1979 i=-1; 1980 if (OldLines[0]->IsConnectedTo(OldLines[2])) 1981 i=2; 1982 if (OldLines[0]->IsConnectedTo(OldLines[3])) 1983 i=3; 1984 if (i!=-1) { 1985 BLS[0] = OldLines[0]; 1986 BLS[1] = OldLines[i]; 1987 BLS[2] = NewLine; 1988 BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[0]); 1989 BTS->GetNormalVector(BaseLineNormal); 1990 TrianglesOnBoundary.insert(TrianglePair(OldTriangleNrs[0], BTS)); 1991 *out << Verbose(3) << "INFO: Created new triangle " << *BTS << "." << endl; 1992 1993 BLS[0] = (i==2 ? OldLines[3] : OldLines[2]); 1994 BLS[1] = OldLines[1]; 1995 BLS[2] = NewLine; 1996 BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[1]); 1997 BTS->GetNormalVector(BaseLineNormal); 1998 TrianglesOnBoundary.insert(TrianglePair(OldTriangleNrs[1], BTS)); 1999 *out << Verbose(3) << "INFO: Created new triangle " << *BTS << "." << endl; 2000 } else { 2001 *out << Verbose(1) << "The four old lines do not connect, something's utterly wrong here!" << endl; 2002 return false; 2003 } 2004 2005 *out << Verbose(1) << "End of FlipBaseline" << endl; 1734 2006 return true; 1735 2007 }; 2008 1736 2009 1737 2010 /** Finds the second point of starting triangle. … … 2100 2373 return NULL; 2101 2374 } 2102 list<TesselPoint*> *connectedClosestPoints = getCircleOfConnectedPoints(out, trianglePoints[0], x); 2375 list<TesselPoint*> *connectedPoints = getCircleOfConnectedPoints(out, trianglePoints[0]); 2376 list<TesselPoint*> *connectedClosestPoints = getNeighboursonCircleofConnectedPoints(out, connectedPoints, trianglePoints[0], x); 2377 delete(connectedPoints); 2103 2378 trianglePoints[1] = connectedClosestPoints->front(); 2104 2379 trianglePoints[2] = connectedClosestPoints->back(); … … 2182 2457 2183 2458 /** Gets all points connected to the provided point by triangulation lines. 2184 * Maps them down onto the plane designated by the axis \a *Point and \a *Reference. The center of all points2185 * connected in the tesselation to \a *Point is mapped to spherical coordinates with the zero angle being given2186 * by the mapped down \a *Reference. Hence, the biggest and the smallest angles are those of the two shanks of the2187 * triangle we are looking for.2188 2459 * 2189 2460 * @param *Point of which get all connected points 2190 * @param *Reference Vector to be checked whether it is an inner point2191 2461 * 2192 * @return list of the two points linked to the provided one and closest to the point to be checked, 2193 */ 2194 list<TesselPoint*> * Tesselation::getCircleOfConnectedPoints(ofstream *out, TesselPoint* Point, Vector* Reference) 2195 { 2196 list<TesselPoint*> connectedPoints; 2197 map<double, TesselPoint*> anglesOfPoints; 2198 map<double, TesselPoint*>::iterator runner; 2199 list<TesselPoint*>::iterator listRunner; 2462 * @return list of the all points linked to the provided one 2463 */ 2464 list<TesselPoint*> * Tesselation::getCircleOfConnectedPoints(ofstream *out, TesselPoint* Point) 2465 { 2466 list<TesselPoint*> *connectedPoints = new list<TesselPoint*>; 2200 2467 class BoundaryPointSet *ReferencePoint = NULL; 2201 Vector center, PlaneNormal, currentPoint, OrthogonalVector, helper, AngleZero;2202 2468 TesselPoint* current; 2203 2469 bool takePoint = false; … … 2231 2497 if (takePoint) { 2232 2498 *out << Verbose(3) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is taken into the circle." << endl; 2233 connectedPoints.push_back(current); 2234 currentPoint.CopyVector(current->node); 2235 currentPoint.ProjectOntoPlane(&PlaneNormal); 2236 center.AddVector(¤tPoint); 2499 connectedPoints->push_back(current); 2237 2500 } 2238 2501 … … 2240 2503 } 2241 2504 2505 if (connectedPoints->size() == 0) { // if have not found any points 2506 *out << Verbose(1) << "ERROR: We have not found any connected points to " << *Point<< "." << endl; 2507 return NULL; 2508 } 2509 return connectedPoints; 2510 } 2511 2512 /** Gets the two neighbouring points with respect to a reference line to the provided point. 2513 * Maps them down onto the plane designated by the axis \a *Point and \a *Reference. The center of all points 2514 * connected in the tesselation to \a *Point is mapped to spherical coordinates with the zero angle being given 2515 * by the mapped down \a *Reference. Hence, the biggest and the smallest angles are those of the two shanks of the 2516 * triangle we are looking for. 2517 * 2518 * @param *out output stream for debugging 2519 * @param *connectedPoints list of connected points to the central \a *Point 2520 * @param *Point of which get all connected points 2521 * @param *Reference Vector to be checked whether it is an inner point 2522 * 2523 * @return list of the two points linked to the provided one and closest to the point to be checked, 2524 */ 2525 list<TesselPoint*> * Tesselation::getNeighboursonCircleofConnectedPoints(ofstream *out, list<TesselPoint*> *connectedPoints, TesselPoint* Point, Vector* Reference) 2526 { 2527 map<double, TesselPoint*> anglesOfPoints; 2528 map<double, TesselPoint*>::iterator runner; 2529 ; 2530 Vector center, PlaneNormal, OrthogonalVector, helper, AngleZero; 2531 2532 if (connectedPoints->size() == 0) { // if have not found any points 2533 *out << Verbose(1) << "ERROR: We have not found any connected points to " << *Point<< "." << endl; 2534 return NULL; 2535 } 2536 2537 // calculate central point 2538 for (list<TesselPoint*>::iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++) 2539 center.AddVector((*TesselRunner)->node); 2242 2540 //*out << "Summed vectors " << center << "; number of points " << connectedPoints.size() 2243 2541 // << "; scale factor " << 1.0/connectedPoints.size(); 2244 2245 if (connectedPoints.size() == 0) { // if have not found any points 2246 *out << Verbose(1) << "ERROR: We have not found any connected points to " << *Point<< "." << endl; 2247 return NULL; 2248 } 2249 center.Scale(1.0/connectedPoints.size()); 2250 2542 center.Scale(1.0/connectedPoints->size()); 2251 2543 *out << Verbose(4) << "INFO: Calculated center of all circle points is " << center << "." << endl; 2252 2544 … … 2264 2556 OrthogonalVector.MakeNormalVector(&PlaneNormal, &AngleZero); 2265 2557 *out << Verbose(4) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl; 2266 2558 2267 2559 // go through all connected points and calculate angle 2268 listRunner = connectedPoints.begin(); 2269 while (listRunner != connectedPoints.end()) { 2560 for (list<TesselPoint*>::iterator listRunner = connectedPoints->begin(); listRunner != connectedPoints->end(); listRunner++) { 2270 2561 helper.CopyVector((*listRunner)->node); 2271 2562 helper.SubtractVector(Point->node); … … 2274 2565 *out << Verbose(2) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl; 2275 2566 anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner))); 2276 listRunner++;2277 2567 } 2278 2568 … … 2289 2579 return result; 2290 2580 } 2581 2582 /** Removes a boundary point from the envelope while keeping it closed. 2583 * We create new triangles and remove the old ones connected to the point. 2584 * \param *out output stream for debugging 2585 * \param *point point to be removed 2586 * \return volume added to the volume inside the tesselated surface by the removal 2587 */ 2588 double Tesselation::RemovePointFromTesselatedSurface(ofstream *out, class BoundaryPointSet *point) { 2589 class BoundaryLineSet *line = NULL; 2590 class BoundaryTriangleSet *triangle = NULL; 2591 Vector OldPoint, TetraederVector[3]; 2592 double volume = 0; 2593 int *numbers = NULL; 2594 int count = 0; 2595 int i; 2596 2597 // copy old location for the volume 2598 OldPoint.CopyVector(point->node->node); 2599 2600 // get list of connected points 2601 if (point->lines.empty()) { 2602 *out << Verbose(1) << "ERROR: Cannot remove the point " << *point << ", it's connected to no lines!" << endl; 2603 return 0.; 2604 } 2605 list<TesselPoint*> *CircleofPoints = getCircleOfConnectedPoints(out, point->node); 2606 2607 // remove all triangles 2608 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) 2609 count+=LineRunner->second->triangles.size(); 2610 numbers = new int[count]; 2611 i=0; 2612 for (LineMap::iterator LineRunner = point->lines.begin(); (point != NULL) && (LineRunner != point->lines.end()); LineRunner++) { 2613 line = LineRunner->second; 2614 for (TriangleMap::iterator TriangleRunner = line->triangles.begin(); TriangleRunner != line->triangles.end(); TriangleRunner++) { 2615 triangle = TriangleRunner->second; 2616 *out << Verbose(2) << "Erasing triangle " << *triangle << "." << endl; 2617 numbers[i++] = triangle->Nr; 2618 RemoveTesselationTriangle(triangle); 2619 triangle = NULL; 2620 } 2621 } 2622 *out << Verbose(1) << i << " triangles were removed." << endl; 2623 2624 // re-create all triangles by going through connected points list 2625 list<TesselPoint*>::iterator CircleRunner = CircleofPoints->begin(); 2626 list<TesselPoint*>::iterator OtherCircleRunner = CircleofPoints->begin(); 2627 class TesselPoint *CentralNode = *CircleRunner; 2628 // advance two with CircleRunner and one with OtherCircleRunner 2629 CircleRunner++; 2630 CircleRunner++; 2631 OtherCircleRunner++; 2632 i=0; 2633 cout << Verbose(2) << "INFO: CentralNode is " << *CentralNode << "." << endl; 2634 for (; (OtherCircleRunner != CircleofPoints->end()) && (CircleRunner != CircleofPoints->end()); (CircleRunner++), (OtherCircleRunner++)) { 2635 cout << Verbose(3) << "INFO: CircleRunner's node is " << **CircleRunner << "." << endl; 2636 cout << Verbose(3) << "INFO: OtherCircleRunner's node is " << **OtherCircleRunner << "." << endl; 2637 *out << Verbose(4) << "Adding new triangle points."<< endl; 2638 AddTesselationPoint(CentralNode, 0); 2639 AddTesselationPoint(*OtherCircleRunner, 1); 2640 AddTesselationPoint(*CircleRunner, 2); 2641 *out << Verbose(4) << "Adding new triangle lines."<< endl; 2642 AddTesselationLine(TPS[0], TPS[1], 0); 2643 AddTesselationLine(TPS[0], TPS[2], 1); 2644 AddTesselationLine(TPS[1], TPS[2], 2); 2645 BTS = new class BoundaryTriangleSet(BLS, numbers[i]); 2646 TrianglesOnBoundary.insert(TrianglePair(numbers[i], BTS)); 2647 *out << Verbose(4) << "Created triangle " << *BTS << "." << endl; 2648 // calculate volume summand as a general tetraeder 2649 for (int j=0;j<3;j++) { 2650 TetraederVector[j].CopyVector(TPS[j]->node->node); 2651 TetraederVector[j].SubtractVector(&OldPoint); 2652 } 2653 OldPoint.CopyVector(&TetraederVector[0]); 2654 OldPoint.VectorProduct(&TetraederVector[1]); 2655 volume += 1./6. * fabs(OldPoint.ScalarProduct(&TetraederVector[2])); 2656 // advance number 2657 i++; 2658 if (i >= count) 2659 *out << Verbose(2) << "WARNING: Maximum of numbers reached!" << endl; 2660 } 2661 *out << Verbose(1) << i << " triangles were created." << endl; 2662 2663 delete[](numbers); 2664 2665 return volume; 2666 }; 2291 2667 2292 2668 /** Checks for a new special triangle whether one of its edges is already present with one one triangle connected. -
src/tesselation.hpp
r86381b r16d866 78 78 int LinesCount; 79 79 TesselPoint *node; 80 double value; 80 81 int Nr; 81 82 }; … … 190 191 virtual ~Tesselation(); 191 192 192 bool AddPoint(TesselPoint *Walker, int n); 193 void AddTrianglePoint(TesselPoint* Candidate, int n); 194 void AddTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n); 195 void AlwaysAddTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n); 196 void AddTriangle(); 193 void AddTesselationPoint(TesselPoint* Candidate, int n); 194 void AddTesselationLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n); 195 void AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n); 196 void AddTesselationTriangle(); 197 void RemoveTesselationTriangle(class BoundaryTriangleSet *triangle); 198 void RemoveTesselationLine(class BoundaryLineSet *line); 199 void RemoveTesselationPoint(class BoundaryPointSet *point); 200 197 201 bool IsInside(Vector *pointer); 198 202 class BoundaryPointSet *GetCommonEndpoint(class BoundaryLineSet * line1, class BoundaryLineSet * line2); … … 209 213 void GuessStartingTriangle(ofstream *out); 210 214 bool InsertStraddlingPoints(ofstream *out, PointCloud *cloud, LinkedCell *LC); 211 bool CorrectConcaveBaselines(ofstream *out); 212 213 list<TesselPoint*> * getCircleOfConnectedPoints(ofstream *out, TesselPoint* Point, Vector* Reference); 215 double RemovePointFromTesselatedSurface(ofstream *out, class BoundaryPointSet *point); 216 bool FlipBaseline(ofstream *out, class BoundaryLineSet *Base); 217 bool PickFarthestofTwoBaselines(ofstream *out, class BoundaryLineSet *Base); 218 class BoundaryPointSet *IsConvexRectangle(ofstream *out, class BoundaryLineSet *Base); 219 220 221 list<TesselPoint*> * getCircleOfConnectedPoints(ofstream *out, TesselPoint* Point); 222 list<TesselPoint*> * getNeighboursonCircleofConnectedPoints(ofstream *out, list<TesselPoint*> *connectedPoints, TesselPoint* Point, Vector* Reference); 214 223 list<BoundaryTriangleSet*> *FindTriangles(TesselPoint* Points[3]); 215 224 list<BoundaryTriangleSet*> * FindClosestTrianglesToPoint(ofstream *out, Vector *x, LinkedCell* LC); … … 217 226 bool IsInnerPoint(ofstream *out, Vector Point, LinkedCell* LC); 218 227 bool IsInnerPoint(ofstream *out, TesselPoint *Point, LinkedCell* LC); 228 bool AddBoundaryPoint(TesselPoint *Walker, int n); 219 229 220 230 PointMap PointsOnBoundary; … … 251 261 TesselPoint* findSecondClosestPoint(const Vector*, LinkedCell*); 252 262 double getAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector); 263 Vector * GetClosestPointBetweenLine(ofstream *out, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase); 253 264 254 265 #endif /* TESSELATION_HPP_ */
Note:
See TracChangeset
for help on using the changeset viewer.