- Timestamp:
- Oct 19, 2014, 5:13:11 PM (10 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:
- 6da9e9
- Parents:
- 77eec5
- git-author:
- Frederik Heber <heber@…> (10/09/14 07:37:06)
- git-committer:
- Frederik Heber <heber@…> (10/19/14 17:13:11)
- Location:
- src/Tesselation
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tesselation/tesselation.cpp
r77eec5 r30ce7d 3330 3330 } 3331 3331 3332 double Tesselation::RemovePointSurroundedByPolygon( 3333 TesselPointList *connectedPath, 3334 BoundaryPointSet *point) 3335 { 3336 double volume = 0.; 3337 const Vector OldPoint = point->node->getPosition(); 3338 3339 TesselPoint *oldNode = point->node; 3340 // remove present triangles for this connectedPath 3341 unsigned int count = 0; 3342 for (TesselPointList::const_iterator iter = connectedPath->begin(); 3343 iter != connectedPath->end(); ++iter) 3344 LOG(4, "DEBUG: Node in connectedPath is " << **iter); 3345 3346 { 3347 TesselPointList::iterator FirstNode, SecondNode; 3348 SecondNode = connectedPath->begin(); 3349 FirstNode = SecondNode++; 3350 for (;FirstNode != connectedPath->end(); ++SecondNode, ++FirstNode) { 3351 LOG(3, "DEBUG: MiddleNode is " << **FirstNode << "."); 3352 if (SecondNode == connectedPath->end()) 3353 SecondNode = connectedPath->begin(); 3354 TesselPoint *TriangleCandidates[3]; 3355 TriangleCandidates[0] = *FirstNode; 3356 TriangleCandidates[1] = *SecondNode; 3357 TriangleCandidates[2] = oldNode; 3358 BoundaryTriangleSet *triangle = GetPresentTriangle(TriangleCandidates); 3359 ASSERT( triangle != NULL, 3360 "Tesselation::RemovePointSurroundedByPolygon() - triangle to points " 3361 +toString((**SecondNode))+", "+toString((**FirstNode))+" and " 3362 +toString(*oldNode)+" does not exist."); 3363 LOG(3, "DEBUG: Removing triangle " << *triangle << "."); 3364 RemoveTesselationTriangle(triangle); 3365 ++count; 3366 } 3367 LOG(2, "INFO: " << count << " triangles were removed."); 3368 } 3369 3370 // re-create all triangles by going through connected points list 3371 LineList NewLines; 3372 typedef std::vector<double> angles_t; 3373 angles_t angles; 3374 count = 0; 3375 for (; !connectedPath->empty();) { 3376 // search middle node with widest angle to next neighbours 3377 TesselPointList::iterator StartNode, MiddleNode, EndNode; 3378 for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) { 3379 LOG(3, "INFO: MiddleNode is " << **MiddleNode << "."); 3380 // construct vectors to next and previous neighbour 3381 StartNode = MiddleNode; 3382 if (StartNode == connectedPath->begin()) 3383 StartNode = connectedPath->end(); 3384 StartNode--; 3385 //LOG(3, "INFO: StartNode is " << **StartNode << "."); 3386 const Vector Point = ((*StartNode)->getPosition()) - ((*MiddleNode)->getPosition()); 3387 EndNode = MiddleNode; 3388 EndNode++; 3389 if (EndNode == connectedPath->end()) 3390 EndNode = connectedPath->begin(); 3391 //LOG(3, "INFO: EndNode is " << **StartNode << "."); 3392 const Vector Reference = ((*EndNode)->getPosition()) - ((*MiddleNode)->getPosition()); 3393 Vector OrthogonalVector = ((*MiddleNode)->getPosition()) - OldPoint; 3394 OrthogonalVector.MakeNormalTo(Reference); 3395 angles.push_back(GetAngle(Point, Reference, OrthogonalVector)); 3396 } 3397 ASSERT( !angles.empty(), 3398 "Tesselation::RemovePointSurroundedByPolygon() - angles empty"); 3399 const angles_t::const_iterator maxiter = std::max_element(angles.begin(), angles.end()); 3400 angles_t::const_iterator miniter = angles.begin(); 3401 // distinguish between convex and nonconvex polygon 3402 if (*maxiter > M_PI) { 3403 // connectedPath is not convex: The idea is to fill any kinks pointing 3404 // inside into the connectedPath close to this concave spot first, making 3405 // it eventually become convex. 3406 // Hence, use adjacent (and convex) fill-in point 3407 miniter = (maxiter == angles.begin()) ? angles.end()-1 : maxiter-1; 3408 if (*miniter > M_PI) { 3409 miniter = (maxiter+1 == angles.end()) ? angles.begin() : maxiter+1; 3410 if (*miniter > M_PI) { 3411 miniter = std::min_element(angles.begin(), angles.end()); 3412 } 3413 } 3414 } else { 3415 // is convex 3416 miniter = std::min_element(angles.begin(), angles.end(), CloserToPiHalf()); 3417 } 3418 MiddleNode = connectedPath->begin(); 3419 std::advance(MiddleNode, std::distance(const_cast<const angles_t &>(angles).begin(), miniter)); 3420 3421 ASSERT(MiddleNode != connectedPath->end(), 3422 "Tesselation::RemovePointSurroundedByPolygon() - Could not find a smallest angle!"); 3423 angles.clear(); 3424 StartNode = MiddleNode; 3425 EndNode = MiddleNode; 3426 if (StartNode == connectedPath->begin()) 3427 StartNode = connectedPath->end(); 3428 StartNode--; 3429 EndNode++; 3430 if (EndNode == connectedPath->end()) 3431 EndNode = connectedPath->begin(); 3432 LOG(2, "INFO: StartNode is " << **StartNode << "."); 3433 LOG(2, "INFO: MiddleNode is " << **MiddleNode << "."); 3434 LOG(2, "INFO: EndNode is " << **EndNode << "."); 3435 LOG(1, "INFO: Attempting to create triangle " << (*StartNode)->getName() << ", " << (*MiddleNode)->getName() << " and " << (*EndNode)->getName() << "."); 3436 TesselPoint *TriangleCandidates[3]; 3437 TriangleCandidates[0] = *StartNode; 3438 TriangleCandidates[1] = *MiddleNode; 3439 TriangleCandidates[2] = *EndNode; 3440 BoundaryTriangleSet *triangle = GetPresentTriangle(TriangleCandidates); 3441 if (triangle != NULL) { 3442 const Vector center = 1./3. * ((*StartNode)->getPosition() 3443 + (*MiddleNode)->getPosition() 3444 + (*EndNode)->getPosition()); 3445 const Vector NormalVector = OldPoint - center; 3446 // check orientation of normal vector (that points inside) 3447 ASSERT( triangle->NormalVector.ScalarProduct(NormalVector) > std::numeric_limits<double>::epsilon()*1e2, 3448 "Tesselation::RemovePointSurroundedByPolygon() - New triangle with same orientation already present as " 3449 +toString(*triangle)+"!"); 3450 } 3451 3452 LOG(3, "DEBUG: Adding new triangle points."); 3453 AddTesselationPoint(*StartNode, 0); 3454 AddTesselationPoint(*MiddleNode, 1); 3455 AddTesselationPoint(*EndNode, 2); 3456 LOG(3, "DEBUG: Adding new triangle lines."); 3457 AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0); 3458 // line between start and end must be new (except for very last triangle) 3459 if (AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1)) 3460 NewLines.push_back(BLS[1]); 3461 AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2); 3462 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 3463 const Vector center = 1./3. * ((*StartNode)->getPosition() 3464 + (*MiddleNode)->getPosition() 3465 + (*EndNode)->getPosition()); 3466 const Vector NormalVector = OldPoint - center; 3467 BTS->GetNormalVector(NormalVector); 3468 AddTesselationTriangle(); 3469 // calculate volume summand as a general tetraeder 3470 volume += CalculateVolumeofGeneralTetraeder( 3471 TPS[0]->node->getPosition(), 3472 TPS[1]->node->getPosition(), 3473 TPS[2]->node->getPosition(), 3474 OldPoint); 3475 // advance number 3476 ++count; 3477 3478 // prepare nodes for next triangle 3479 LOG(3, "DEBUG: Removing " << **MiddleNode << " from closed path."); 3480 connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles) 3481 LOG(3, "DEBUG: Remaining points: " << connectedPath->size() << "."); 3482 ASSERT(connectedPath->size() >= 2, 3483 "Tesselation::RemovePointSurroundedByPolygon() - There are only two endpoints left!"); 3484 if (connectedPath->size() == 2) { // we are done 3485 connectedPath->remove(*StartNode); // remove the start node 3486 connectedPath->remove(*EndNode); // remove the end node 3487 } 3488 } 3489 LOG(1, "INFO: " << count << " triangles were created."); 3490 3491 return volume; 3492 } 3493 3332 3494 /** Removes a boundary point from the envelope while keeping it closed. 3333 3495 * We remove the old triangles connected to the point and re-create new triangles to close the surface following this ansatz: … … 3343 3505 double Tesselation::RemovePointFromTesselatedSurface(class BoundaryPointSet *point) 3344 3506 { 3345 class BoundaryLineSet *line = NULL;3346 class BoundaryTriangleSet *triangle = NULL;3347 Vector OldPoint; //, NormalVector;3348 3507 double volume = 0; 3349 int count = 0;3350 3508 3351 3509 if (point == NULL) { … … 3355 3513 LOG(4, "DEBUG: Removing point " << *point << " from tesselated boundary ..."); 3356 3514 3357 // copy old location for the volume3358 OldPoint = (point->node->getPosition());3359 3360 3515 // get list of connected points 3361 3516 if (point->lines.empty()) { … … 3365 3520 3366 3521 list<TesselPointList *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(point->node); 3367 TesselPointList *connectedPath = NULL; 3368 3369 // gather all triangles 3370 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) 3371 count += LineRunner->second->triangles.size(); 3372 TriangleMap Candidates; 3373 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) { 3374 line = LineRunner->second; 3375 for (TriangleMap::iterator TriangleRunner = line->triangles.begin(); TriangleRunner != line->triangles.end(); TriangleRunner++) { 3376 triangle = TriangleRunner->second; 3377 Candidates.insert(TrianglePair(triangle->Nr, triangle)); 3378 } 3379 } 3380 3381 // remove all triangles 3382 count = 0; 3383 // NormalVector.Zero(); 3384 for (TriangleMap::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) { 3385 LOG(3, "DEBUG: Removing triangle " << *(Runner->second) << "."); 3386 // NormalVector -= Runner->second->NormalVector; // has to point inward 3387 RemoveTesselationTriangle(Runner->second); 3388 count++; 3389 } 3390 LOG(2, "INFO: " << count << " triangles were removed."); 3391 3522 list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin(); 3523 list<TesselPointList *>::iterator ListRunner = ListAdvance; 3524 // TriangleMap::iterator NumberRunner = Candidates.begin(); 3525 Vector Point, Reference, OrthogonalVector; 3526 for (; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths 3527 if (ListAdvance != ListOfClosedPaths->end()) 3528 ListAdvance++; 3529 3530 TesselPointList *connectedPath = *ListRunner; 3531 3532 volume += RemovePointSurroundedByPolygon(connectedPath, point); 3533 3534 ListOfClosedPaths->remove(connectedPath); 3535 delete (connectedPath); 3536 } 3537 delete (ListOfClosedPaths); 3538 3539 LOG(1, "INFO: Removed volume is " << volume << "."); 3540 3541 return volume; 3542 } 3543 ; 3544 3545 bool Tesselation::CheckAllConcaveInPolygon( 3546 const TesselPointList *connectedPath, 3547 const BoundaryPointSet *point 3548 ) 3549 { 3550 // check whether lines in this path to point to remove are all concave 3551 bool all_lines_concave = true; 3552 if (connectedPath->size() >= 2) { 3553 TesselPointList::const_iterator StartNode, MiddleNode, EndNode; 3554 // have nearest neighbors to a middle node to know adjacent triangles 3555 for (MiddleNode = connectedPath->begin(); 3556 all_lines_concave && (MiddleNode != connectedPath->end()); 3557 MiddleNode++) { 3558 LOG(3, "INFO: MiddleNode is " << **MiddleNode << "."); 3559 EndNode = MiddleNode; 3560 if (EndNode == connectedPath->begin()) 3561 EndNode = connectedPath->end(); 3562 --EndNode; 3563 StartNode = MiddleNode; 3564 ++StartNode; 3565 if (StartNode == connectedPath->end()) 3566 StartNode = connectedPath->begin(); 3567 3568 AddTesselationPoint(point->node, 0); 3569 AddTesselationPoint(*MiddleNode, 1); 3570 3571 ASSERT( point->lines.find((*MiddleNode)->getNr()) != point->lines.end(), 3572 "Tesselation::CheckAllConcaveInPolygon() - MiddleNode " 3573 +toString(**MiddleNode)+" not present in " 3574 +toString(*point)+"'s lines."); 3575 3576 // get line between Node and point and check 3577 std::pair<LineMap::const_iterator, LineMap::const_iterator> FindPair = 3578 point->lines.equal_range((*MiddleNode)->getNr()); 3579 LineMap::const_iterator FindLine = FindPair.first; 3580 for (; FindLine != FindPair.second; ++FindLine) { 3581 // line has got two triangles, check whether they resemble those 3582 // with start and endnode 3583 const BoundaryLineSet *currentline = FindLine->second; 3584 unsigned int matching_triangles = 0; 3585 for (TriangleMap::const_iterator triangleiter = currentline->triangles.begin(); 3586 triangleiter != currentline->triangles.end(); ++triangleiter) { 3587 const BoundaryTriangleSet *triangle = triangleiter->second; 3588 AddTesselationPoint(*StartNode, 2); 3589 if (triangle->IsPresentTupel(TPS)) 3590 ++matching_triangles; 3591 AddTesselationPoint(*EndNode, 2); 3592 if (triangle->IsPresentTupel(TPS)) 3593 ++matching_triangles; 3594 } 3595 if (matching_triangles == 2) 3596 break; 3597 } 3598 if (FindLine != FindPair.second) { 3599 LOG(3, "INFO: Current line of point " << *point << " is " << *FindLine->second << "."); 3600 all_lines_concave &= !FindLine->second->CheckConvexityCriterion(); 3601 } 3602 } 3603 } else { 3604 // check the single line 3605 if (connectedPath->empty()) 3606 return false; 3607 LineMap::const_iterator FindLine = point->lines.find((*connectedPath->begin())->getNr()); 3608 ASSERT( FindLine != point->lines.end(), 3609 "Tesselation::CheckAllConcaveInPolygon() - point " 3610 +toString((*connectedPath->begin())->getNr())+" not present in " 3611 +toString(*point)+"'s lines."); 3612 return !FindLine->second->CheckConvexityCriterion(); 3613 } 3614 3615 return all_lines_concave; 3616 } 3617 3618 /** Removes a boundary point from the envelope while keeping it closed. 3619 * We remove the old triangles connected to the point and re-create new triangles to close the surface following this ansatz: 3620 * -# a closed path(s) of boundary points surrounding the point to be removed is constructed 3621 * -# on each closed path, we pick three adjacent points, create a triangle with them and subtract the middle point from the path 3622 * -# we advance two points (i.e. the next triangle will start at the ending point of the last triangle) and continue as before 3623 * -# the surface is closed, when the path is empty 3624 * Thereby, we (hopefully) make sure that the removed points remains beneath the surface (this is checked via IsInnerPoint eventually). 3625 * \param *out output stream for debugging 3626 * \param *point point to be removed 3627 * \return volume added to the volume inside the tesselated surface by the removal 3628 */ 3629 double Tesselation::RemoveFullConcavePointFromTesselatedSurface(class BoundaryPointSet *point) 3630 { 3631 double volume = 0; 3632 3633 if (point == NULL) { 3634 ELOG(1, "Cannot remove the point " << point << ", it's NULL!"); 3635 return 0.; 3636 } else 3637 LOG(4, "DEBUG: Removing point " << *point << " from tesselated boundary ..."); 3638 3639 // get list of connected points 3640 if (point->lines.empty()) { 3641 ELOG(1, "Cannot remove the point " << *point << ", it's connected to no lines!"); 3642 return 0.; 3643 } 3644 3645 list<TesselPointList *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(point->node); 3392 3646 list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin(); 3393 3647 list<TesselPointList *>::iterator ListRunner = ListAdvance; … … 3395 3649 TesselPointList::iterator StartNode, MiddleNode, EndNode; 3396 3650 Vector Point, Reference, OrthogonalVector; 3397 if (count > 2) { // less than three triangles, then nothing will be created 3398 class TesselPoint *TriangleCandidates[3]; 3399 count = 0; 3400 for (; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths 3401 if (ListAdvance != ListOfClosedPaths->end()) 3402 ListAdvance++; 3403 3404 connectedPath = *ListRunner; 3405 // re-create all triangles by going through connected points list 3406 LineList NewLines; 3407 typedef std::vector<double> angles_t; 3408 angles_t angles; 3409 for (; !connectedPath->empty();) { 3410 // search middle node with widest angle to next neighbours 3411 EndNode = connectedPath->end(); 3412 for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) { 3413 LOG(3, "INFO: MiddleNode is " << **MiddleNode << "."); 3414 // construct vectors to next and previous neighbour 3415 StartNode = MiddleNode; 3416 if (StartNode == connectedPath->begin()) 3417 StartNode = connectedPath->end(); 3418 StartNode--; 3419 //LOG(3, "INFO: StartNode is " << **StartNode << "."); 3420 Point = ((*StartNode)->getPosition()) - ((*MiddleNode)->getPosition()); 3421 StartNode = MiddleNode; 3422 StartNode++; 3423 if (StartNode == connectedPath->end()) 3424 StartNode = connectedPath->begin(); 3425 //LOG(3, "INFO: EndNode is " << **StartNode << "."); 3426 Reference = ((*StartNode)->getPosition()) - ((*MiddleNode)->getPosition()); 3427 OrthogonalVector = ((*MiddleNode)->getPosition()) - OldPoint; 3428 OrthogonalVector.MakeNormalTo(Reference); 3429 angles.push_back(GetAngle(Point, Reference, OrthogonalVector)); 3430 } 3431 const angles_t::const_iterator maxiter = std::max_element(angles.begin(), angles.end()); 3432 angles_t::const_iterator miniter = angles.begin(); 3433 // distinguish between convex and nonconvex polygon 3434 if (*maxiter > M_PI) { 3435 // connectedPath is not convex 3436 // use adjacent (and convx) fill-in point 3437 miniter = (maxiter == angles.begin()) ? angles.end()-1 : maxiter-1; 3438 if (*miniter > M_PI) { 3439 miniter = (maxiter+1 == angles.end()) ? angles.begin() : maxiter+1; 3440 if (*(++miniter) > M_PI) { 3441 miniter = std::min_element(angles.begin(), angles.end()); 3442 } 3443 } 3444 } else { 3445 // is convex 3446 miniter = std::min_element(angles.begin(), angles.end(), CloserToPiHalf()); 3447 } 3448 MiddleNode = connectedPath->begin(); 3449 std::advance(MiddleNode, std::distance(const_cast<const angles_t &>(angles).begin(), miniter)); 3450 angles.clear(); 3451 3452 ASSERT(MiddleNode != connectedPath->end(), 3453 "Tesselation::RemovePointFromTesselatedSurface() - Could not find a smallest angle!"); 3454 StartNode = MiddleNode; 3455 EndNode = MiddleNode; 3456 if (StartNode == connectedPath->begin()) 3457 StartNode = connectedPath->end(); 3458 StartNode--; 3459 EndNode++; 3460 if (EndNode == connectedPath->end()) 3461 EndNode = connectedPath->begin(); 3462 LOG(2, "INFO: StartNode is " << **StartNode << "."); 3463 LOG(2, "INFO: MiddleNode is " << **MiddleNode << "."); 3464 LOG(2, "INFO: EndNode is " << **EndNode << "."); 3465 LOG(1, "INFO: Attempting to create triangle " << (*StartNode)->getName() << ", " << (*MiddleNode)->getName() << " and " << (*EndNode)->getName() << "."); 3466 TriangleCandidates[0] = *StartNode; 3467 TriangleCandidates[1] = *MiddleNode; 3468 TriangleCandidates[2] = *EndNode; 3469 triangle = GetPresentTriangle(TriangleCandidates); 3470 if (triangle != NULL) { 3471 const Vector center = 1./3. * ((*StartNode)->getPosition() 3472 + (*MiddleNode)->getPosition() 3473 + (*EndNode)->getPosition()); 3474 const Vector NormalVector = OldPoint - center; 3475 // check orientation of normal vector (that points inside) 3476 ASSERT( triangle->NormalVector.ScalarProduct(NormalVector) > std::numeric_limits<double>::epsilon()*1e2, 3477 "Tesselation::RemovePointFromTesselatedSurface() - New triangle with same orientation already present as " 3478 +toString(*triangle)+"!"); 3479 } 3480 if (0) { 3481 StartNode++; 3482 MiddleNode++; 3483 EndNode++; 3484 if (StartNode == connectedPath->end()) 3485 StartNode = connectedPath->begin(); 3486 if (MiddleNode == connectedPath->end()) 3487 MiddleNode = connectedPath->begin(); 3488 if (EndNode == connectedPath->end()) 3489 EndNode = connectedPath->begin(); 3490 continue; 3491 } 3492 LOG(3, "DEBUG: Adding new triangle points."); 3493 AddTesselationPoint(*StartNode, 0); 3494 AddTesselationPoint(*MiddleNode, 1); 3495 AddTesselationPoint(*EndNode, 2); 3496 LOG(3, "DEBUG: Adding new triangle lines."); 3497 AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0); 3498 // line between start and end must be new (except for very last triangle) 3499 if (AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1)) 3500 NewLines.push_back(BLS[1]); 3501 AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2); 3502 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 3503 const Vector center = 1./3. * ((*StartNode)->getPosition() 3504 + (*MiddleNode)->getPosition() 3505 + (*EndNode)->getPosition()); 3506 const Vector NormalVector = OldPoint - center; 3507 BTS->GetNormalVector(NormalVector); 3508 AddTesselationTriangle(); 3509 // calculate volume summand as a general tetraeder 3510 volume += CalculateVolumeofGeneralTetraeder(TPS[0]->node->getPosition(), TPS[1]->node->getPosition(), TPS[2]->node->getPosition(), OldPoint); 3511 // advance number 3512 count++; 3513 3514 // prepare nodes for next triangle 3515 LOG(3, "DEBUG: Removing " << **MiddleNode << " from closed path."); 3516 connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles) 3517 LOG(3, "DEBUG: Remaining points: " << connectedPath->size() << "."); 3518 ASSERT(connectedPath->size() >= 2, "Tesselation::RemovePointFromTesselatedSurface() - There are only two endpoints left!"); 3519 if (connectedPath->size() == 2) { // we are done 3520 connectedPath->remove(*StartNode); // remove the start node 3521 connectedPath->remove(*EndNode); // remove the end node 3522 break; 3523 } else { 3524 StartNode = EndNode; 3525 MiddleNode = StartNode; 3526 MiddleNode++; 3527 if (MiddleNode == connectedPath->end()) 3528 MiddleNode = connectedPath->begin(); 3529 EndNode = MiddleNode; 3530 EndNode++; 3531 if (EndNode == connectedPath->end()) 3532 EndNode = connectedPath->begin(); 3533 } 3534 } 3535 3536 ListOfClosedPaths->remove(connectedPath); 3537 delete (connectedPath); 3538 } 3539 LOG(1, "INFO: " << count << " triangles were created."); 3540 } else { 3541 while (!ListOfClosedPaths->empty()) { 3542 ListRunner = ListOfClosedPaths->begin(); 3543 connectedPath = *ListRunner; 3544 ListOfClosedPaths->remove(connectedPath); 3545 delete (connectedPath); 3546 } 3547 LOG(3, "DEBUG: No need to create any triangles."); 3651 for (; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths 3652 if (ListAdvance != ListOfClosedPaths->end()) 3653 ListAdvance++; 3654 3655 TesselPointList *connectedPath = *ListRunner; 3656 3657 if (CheckAllConcaveInPolygon(connectedPath, point)) { 3658 LOG(1, "INFO: ... point " << *point << " cannot be on convex envelope, all lines concave."); 3659 volume += RemovePointSurroundedByPolygon(connectedPath, point); 3660 } 3661 3662 ListOfClosedPaths->remove(connectedPath); 3663 delete (connectedPath); 3548 3664 } 3549 3665 delete (ListOfClosedPaths); 3550 3666 3551 LOG(1, "INFO: Removed volume is " << volume << "."); 3667 if (volume > 0.) 3668 LOG(1, "INFO: Removed volume is " << volume << "."); 3552 3669 3553 3670 return volume; -
src/Tesselation/tesselation.hpp
r77eec5 r30ce7d 103 103 void GuessStartingTriangle(); 104 104 bool InsertStraddlingPoints(IPointCloud & cloud, const LinkedCell_deprecated *LC); 105 double RemovePointSurroundedByPolygon( 106 TesselPointList *connectedPath, 107 BoundaryPointSet *point); 108 bool CheckAllConcaveInPolygon( 109 const TesselPointList *connectedPath, 110 const BoundaryPointSet *point 111 ); 112 double RemoveFullConcavePointFromTesselatedSurface(class BoundaryPointSet *point); 105 113 double RemovePointFromTesselatedSurface(class BoundaryPointSet *point); 106 114 class BoundaryLineSet * FlipBaseline(class BoundaryLineSet *Base);
Note:
See TracChangeset
for help on using the changeset viewer.