Changeset 30ce7d for src


Ignore:
Timestamp:
Oct 19, 2014, 5:13:11 PM (10 years ago)
Author:
Frederik Heber <heber@…>
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)
Message:

Extracted RemovePointSurroundedByPolygon() out of Tesselation::RemovePointFromTesselatedSurface()

Location:
src/Tesselation
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Tesselation/tesselation.cpp

    r77eec5 r30ce7d  
    33303330}
    33313331
     3332double 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
    33323494/** Removes a boundary point from the envelope while keeping it closed.
    33333495 * We remove the old triangles connected to the point and re-create new triangles to close the surface following this ansatz:
     
    33433505double Tesselation::RemovePointFromTesselatedSurface(class BoundaryPointSet *point)
    33443506{
    3345   class BoundaryLineSet *line = NULL;
    3346   class BoundaryTriangleSet *triangle = NULL;
    3347   Vector OldPoint; //, NormalVector;
    33483507  double volume = 0;
    3349   int count = 0;
    33503508
    33513509  if (point == NULL) {
     
    33553513    LOG(4, "DEBUG: Removing point " << *point << " from tesselated boundary ...");
    33563514
    3357   // copy old location for the volume
    3358   OldPoint = (point->node->getPosition());
    3359 
    33603515  // get list of connected points
    33613516  if (point->lines.empty()) {
     
    33653520
    33663521  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
     3545bool 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 */
     3629double 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);
    33923646  list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin();
    33933647  list<TesselPointList *>::iterator ListRunner = ListAdvance;
     
    33953649  TesselPointList::iterator StartNode, MiddleNode, EndNode;
    33963650  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);
    35483664  }
    35493665  delete (ListOfClosedPaths);
    35503666
    3551   LOG(1, "INFO: Removed volume is " << volume << ".");
     3667  if (volume > 0.)
     3668    LOG(1, "INFO: Removed volume is " << volume << ".");
    35523669
    35533670  return volume;
  • src/Tesselation/tesselation.hpp

    r77eec5 r30ce7d  
    103103    void GuessStartingTriangle();
    104104    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);
    105113    double RemovePointFromTesselatedSurface(class BoundaryPointSet *point);
    106114    class BoundaryLineSet * FlipBaseline(class BoundaryLineSet *Base);
Note: See TracChangeset for help on using the changeset viewer.