Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tesselation/tesselation.cpp

    r8592c9 re2396e  
    3535#include "CodePatterns/MemDebug.hpp"
    3636
     37#include <algorithm>
     38#include <boost/foreach.hpp>
    3739#include <fstream>
    3840#include <iomanip>
     41#include <iterator>
    3942#include <sstream>
    4043
     
    6669class molecule;
    6770
    68 const char *TecplotSuffix=".dat";
    69 const char *Raster3DSuffix=".r3d";
    70 const char *VRMLSUffix=".wrl";
    71 
    72 const double ParallelEpsilon=1e-3;
     71const char *TecplotSuffix = ".dat";
     72const char *Raster3DSuffix = ".r3d";
     73const char *VRMLSUffix = ".wrl";
     74
     75const double ParallelEpsilon = 1e-3;
    7376const double Tesselation::HULLEPSILON = 1e-9;
    7477
     
    7679 */
    7780Tesselation::Tesselation() :
    78   PointsOnBoundaryCount(0),
    79   LinesOnBoundaryCount(0),
    80   TrianglesOnBoundaryCount(0),
    81   LastTriangle(NULL),
    82   TriangleFilesWritten(0),
    83   InternalPointer(PointsOnBoundary.begin())
     81    PointsOnBoundaryCount(0), LinesOnBoundaryCount(0), TrianglesOnBoundaryCount(0), LastTriangle(NULL), TriangleFilesWritten(0), InternalPointer(PointsOnBoundary.begin())
    8482{
    8583  //Info FunctionInfo(__func__);
     
    113111{
    114112  // create linkedcell
    115         LinkedCell_deprecated *LinkedList = new LinkedCell_deprecated(cloud, 2.*SPHERERADIUS);
    116 
    117         // check for at least three points
    118         {
    119           bool ThreePointsFound = true;
    120           cloud.GoToFirst();
    121     for (size_t i=0;i<3;++i, cloud.GoToNext())
     113  LinkedCell_deprecated *LinkedList = new LinkedCell_deprecated(cloud, 2. * SPHERERADIUS);
     114
     115  // check for at least three points
     116  {
     117    bool ThreePointsFound = true;
     118    cloud.GoToFirst();
     119    for (size_t i = 0; i < 3; ++i, cloud.GoToNext())
    122120      ThreePointsFound &= (!cloud.IsEnd());
    123121    cloud.GoToFirst();
     
    126124      return;
    127125    }
    128         }
    129 
    130         // find a starting triangle
     126  }
     127
     128  // find a starting triangle
    131129  FindStartingTriangle(SPHERERADIUS, LinkedList);
    132130
     
    142140        //the line is there, so there is a triangle, but only one.
    143141        const bool TesselationFailFlag = FindNextSuitableTriangle(*baseline, *T, SPHERERADIUS, LinkedList);
    144         ASSERT( TesselationFailFlag,
    145             "Tesselation::operator() - no suitable candidate triangle found.");
     142        ASSERT(TesselationFailFlag, "Tesselation::operator() - no suitable candidate triangle found.");
    146143      }
    147144    }
    148145
    149146    // 2b. search for smallest ShortestAngle among all candidates
    150     double ShortestAngle = 4.*M_PI;
     147    double ShortestAngle = 4. * M_PI;
    151148    for (CandidateMap::iterator Runner = OpenLines.begin(); Runner != OpenLines.end(); Runner++) {
    152149      if (Runner->second->ShortestAngle < ShortestAngle) {
     
    155152      }
    156153    }
    157     if ((ShortestAngle == 4.*M_PI) || (baseline->pointlist.empty()))
     154    if ((ShortestAngle == 4. * M_PI) || (baseline->pointlist.empty()))
    158155      OneLoopWithoutSuccessFlag = false;
    159156    else {
     
    161158    }
    162159  }
     160
     161  delete LinkedList;
    163162}
    164163
     
    170169double Tesselation::getVolumeOfConvexEnvelope(const bool IsAngstroem) const
    171170{
     171  // calculate center of gravity
     172  Vector center;
     173  if (!PointsOnBoundary.empty()) {
     174    for (PointMap::const_iterator iter = PointsOnBoundary.begin();
     175        iter != PointsOnBoundary.end(); ++iter)
     176      center += iter->second->node->getPosition();
     177    center *= 1./(double)PointsOnBoundary.size();
     178  }
     179
     180  // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
    172181  double volume = 0.;
    173   Vector x;
    174   Vector y;
    175 
    176   // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
    177   for (TriangleMap::const_iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++)
    178     { // go through every triangle, calculate volume of its pyramid with CoG as peak
    179       x = runner->second->getEndpoint(0) - runner->second->getEndpoint(1);
    180       const double G = runner->second->getArea();
    181       x = runner->second->getPlane().getNormal();
    182       x.Scale(runner->second->getEndpoint(1).ScalarProduct(x));
    183       const double h = x.Norm(); // distance of CoG to triangle
    184       const double PyramidVolume = (1. / 3.) * G * h; // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)
    185       LOG(1, "INFO: Area of triangle is " << setprecision(10) << G << " "
    186           << (IsAngstroem ? "angstrom" : "atomiclength") << "^2, height is "
    187           << h << " and the volume is " << PyramidVolume << " "
    188           << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
    189       volume += PyramidVolume;
    190     }
    191   LOG(0, "RESULT: The summed volume is " << setprecision(6)
    192       << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
     182  for (TriangleMap::const_iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) { // go through every triangle, calculate volume of its pyramid with CoG as peak
     183    const double TetrahedronVolume = CalculateVolumeofGeneralTetraeder(
     184        runner->second->endpoints[0]->getPosition(),
     185        runner->second->endpoints[1]->getPosition(),
     186        runner->second->endpoints[2]->getPosition(),
     187        center);
     188    LOG(1, "INFO: volume of tetrahedron is " << setprecision(10) << TetrahedronVolume
     189        << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
     190    volume += TetrahedronVolume;
     191  }
     192  LOG(0, "RESULT: The summed volume is " << setprecision(6) << volume
     193      << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
    193194
    194195  return volume;
     
    207208
    208209  // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
    209   for (TriangleMap::const_iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++)
    210     { // go through every triangle, calculate volume of its pyramid with CoG as peak
    211                 const double area = runner->second->getArea();
    212                 LOG(1, "INFO: Area of triangle is " << setprecision(10) << area << " "
    213           << (IsAngstroem ? "angstrom" : "atomiclength") << "^2.");
    214       surfacearea += area;
    215     }
    216   LOG(0, "RESULT: The summed surface area is " << setprecision(6)
    217       << surfacearea << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
     210  for (TriangleMap::const_iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) { // go through every triangle, calculate volume of its pyramid with CoG as peak
     211    const double area = runner->second->getArea();
     212    LOG(1, "INFO: Area of triangle is " << setprecision(10) << area << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^2.");
     213    surfacearea += area;
     214  }
     215  LOG(0, "RESULT: The summed surface area is " << setprecision(6) << surfacearea << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
    218216
    219217  return surfacearea;
    220218}
    221 
    222219
    223220/** Gueses first starting triangle of the convex envelope.
     
    251248        tmp = B->second->node->DistanceSquared(C->second->node->getPosition());
    252249        distance += tmp * tmp;
    253         DistanceMMap.insert(DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator> (B, C)));
     250        DistanceMMap.insert(DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator>(B, C)));
    254251      }
    255252    }
     
    271268    // 2. next, we have to check whether all points reside on only one side of the triangle
    272269    // 3. construct plane vector
    273     PlaneVector = Plane(A->second->node->getPosition(),
    274                         baseline->second.first->second->node->getPosition(),
    275                         baseline->second.second->second->node->getPosition()).getNormal();
     270    PlaneVector = Plane(A->second->node->getPosition(), baseline->second.first->second->node->getPosition(), baseline->second.second->second->node->getPosition()).getNormal();
    276271    LOG(2, "Plane vector of candidate triangle is " << PlaneVector);
    277272    // 4. loop over all points
     
    388383        // prepare some auxiliary vectors
    389384        Vector BaseLineCenter, BaseLine;
    390         BaseLineCenter = 0.5 * ((baseline->second->endpoints[0]->node->getPosition()) +
    391                                 (baseline->second->endpoints[1]->node->getPosition()));
     385        BaseLineCenter = 0.5 * ((baseline->second->endpoints[0]->node->getPosition()) + (baseline->second->endpoints[1]->node->getPosition()));
    392386        BaseLine = (baseline->second->endpoints[0]->node->getPosition()) - (baseline->second->endpoints[1]->node->getPosition());
    393387
     
    407401        // vector in propagation direction (out of triangle)
    408402        // project center vector onto triangle plane (points from intersection plane-NormalVector to plane-CenterVector intersection)
    409         PropagationVector = Plane(BaseLine, NormalVector,0).getNormal();
     403        PropagationVector = Plane(BaseLine, NormalVector, 0).getNormal();
    410404        TempVector = CenterVector - (baseline->second->endpoints[0]->node->getPosition()); // TempVector is vector on triangle plane pointing from one baseline egde towards center!
    411405        //LOG(0, "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << ".");
     
    460454            // in case NOT both were found, create virtually this triangle, get its normal vector, calculate angle
    461455            flag = true;
    462             VirtualNormalVector = Plane((baseline->second->endpoints[0]->node->getPosition()),
    463                                         (baseline->second->endpoints[1]->node->getPosition()),
    464                                         (target->second->node->getPosition())).getNormal();
    465             TempVector = (1./3.) * ((baseline->second->endpoints[0]->node->getPosition()) +
    466                                     (baseline->second->endpoints[1]->node->getPosition()) +
    467                                     (target->second->node->getPosition()));
     456            VirtualNormalVector = Plane((baseline->second->endpoints[0]->node->getPosition()), (baseline->second->endpoints[1]->node->getPosition()), (target->second->node->getPosition())).getNormal();
     457            TempVector = (1. / 3.) * ((baseline->second->endpoints[0]->node->getPosition()) + (baseline->second->endpoints[1]->node->getPosition()) + (target->second->node->getPosition()));
    468458            TempVector -= (*Center);
    469459            // make it always point outward
     
    477467              winner = target;
    478468              LOG(5, "DEBUG: New winner " << *winner->second->node << " due to smaller angle between normal vectors.");
    479             } else if (fabs(SmallestAngle - TempAngle) < MYEPSILON) { // check the angle to propagation, both possible targets are in one plane! (their normals have same angle)
    480               // hence, check the angles to some normal direction from our base line but in this common plane of both targets...
    481               helper = (target->second->node->getPosition()) - BaseLineCenter;
    482               helper.ProjectOntoPlane(BaseLine);
    483               // ...the one with the smaller angle is the better candidate
    484               TempVector = (target->second->node->getPosition()) - BaseLineCenter;
    485               TempVector.ProjectOntoPlane(VirtualNormalVector);
    486               TempAngle = TempVector.Angle(helper);
    487               TempVector = (winner->second->node->getPosition()) - BaseLineCenter;
    488               TempVector.ProjectOntoPlane(VirtualNormalVector);
    489               if (TempAngle < TempVector.Angle(helper)) {
    490                 TempAngle = NormalVector.Angle(VirtualNormalVector);
    491                 SmallestAngle = TempAngle;
    492                 winner = target;
    493                 LOG(5, "DEBUG: New winner " << *winner->second->node << " due to smaller angle " << TempAngle << " to propagation direction.");
     469            } else
     470              if (fabs(SmallestAngle - TempAngle) < MYEPSILON) { // check the angle to propagation, both possible targets are in one plane! (their normals have same angle)
     471                // hence, check the angles to some normal direction from our base line but in this common plane of both targets...
     472                helper = (target->second->node->getPosition()) - BaseLineCenter;
     473                helper.ProjectOntoPlane(BaseLine);
     474                // ...the one with the smaller angle is the better candidate
     475                TempVector = (target->second->node->getPosition()) - BaseLineCenter;
     476                TempVector.ProjectOntoPlane(VirtualNormalVector);
     477                TempAngle = TempVector.Angle(helper);
     478                TempVector = (winner->second->node->getPosition()) - BaseLineCenter;
     479                TempVector.ProjectOntoPlane(VirtualNormalVector);
     480                if (TempAngle < TempVector.Angle(helper)) {
     481                  TempAngle = NormalVector.Angle(VirtualNormalVector);
     482                  SmallestAngle = TempAngle;
     483                  winner = target;
     484                  LOG(5, "DEBUG: New winner " << *winner->second->node << " due to smaller angle " << TempAngle << " to propagation direction.");
     485                } else
     486                  LOG(5, "DEBUG: Keeping old winner " << *winner->second->node << " due to smaller angle to propagation direction.");
    494487              } else
    495                 LOG(5, "DEBUG: Keeping old winner " << *winner->second->node << " due to smaller angle to propagation direction.");
    496             } else
    497               LOG(5, "DEBUG: Keeping old winner " << *winner->second->node << " due to smaller angle between normal vectors.");
     488                LOG(5, "DEBUG: Keeping old winner " << *winner->second->node << " due to smaller angle between normal vectors.");
    498489          }
    499490        } // end of loop over all boundary points
     
    562553
    563554  cloud.GoToFirst();
    564   PointCloudAdaptor< Tesselation, MapValueIterator<Tesselation::iterator> > newcloud(this, cloud.GetName());
     555  PointCloudAdaptor<Tesselation, MapValueIterator<Tesselation::iterator> > newcloud(this, cloud.GetName());
    565556  BoundaryPoints = new LinkedCell_deprecated(newcloud, 5.);
    566557  while (!cloud.IsEnd()) { // we only have to go once through all points, as boundary can become only bigger
     
    729720 * @param *b second endpoint
    730721 * @param n index of Tesselation::BLS giving the line with both endpoints
    731  */
    732 void Tesselation::AddTesselationLine(const Vector * const OptCenter, const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n)
     722 * @return true - inserted a new line, false - present line used
     723 */
     724bool Tesselation::AddTesselationLine(const Vector * const OptCenter, const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n)
    733725{
    734726  bool insertNewLine = true;
     
    746738      if (FindLine->second->triangles.size() == 1) {
    747739        CandidateMap::iterator Finder = OpenLines.find(FindLine->second);
    748         if (!Finder->second->pointlist.empty())
    749           LOG(4, "DEBUG: line " << *(FindLine->second) << " is open with candidate " << **(Finder->second->pointlist.begin()) << ".");
    750         else
    751           LOG(4, "DEBUG: line " << *(FindLine->second) << " is open with no candidate.");
    752         // get open line
    753         for (TesselPointList::const_iterator CandidateChecker = Finder->second->pointlist.begin(); CandidateChecker != Finder->second->pointlist.end(); ++CandidateChecker) {
    754           if ((*(CandidateChecker) == candidate->node) && (OptCenter == NULL || OptCenter->DistanceSquared(Finder->second->OptCenter) < MYEPSILON )) { // stop searching if candidate matches
    755             LOG(4, "ACCEPT: Candidate " << *(*CandidateChecker) << " has the right center " << Finder->second->OptCenter << ".");
     740        ASSERT(Finder != OpenLines.end(), "Tesselation::AddTesselationLine() - " + toString(*FindLine->second) + " is not a new line and not in OpenLines.");
     741        if (Finder->second != NULL) {
     742          if (!Finder->second->pointlist.empty())
     743            LOG(4, "DEBUG: line " << *(FindLine->second) << " is open with candidate " << **(Finder->second->pointlist.begin()) << ".");
     744          else {
     745            LOG(4, "ACCEPT: line " << *(FindLine->second) << " is open with no candidate.");
    756746            insertNewLine = false;
    757747            WinningLine = FindLine->second;
    758             break;
    759           } else {
    760             LOG(5, "REJECT: Candidate " << *(*CandidateChecker) << "'s center " << Finder->second->OptCenter << " does not match desired on " << *OptCenter << ".");
    761748          }
     749          // get open line
     750          for (TesselPointList::const_iterator CandidateChecker = Finder->second->pointlist.begin(); CandidateChecker != Finder->second->pointlist.end(); ++CandidateChecker) {
     751            if ((*(CandidateChecker) == candidate->node) && (OptCenter == NULL || OptCenter->DistanceSquared(Finder->second->OptCenter) < MYEPSILON)) { // stop searching if candidate matches
     752              LOG(4, "ACCEPT: Candidate " << *(*CandidateChecker) << " has the right center " << Finder->second->OptCenter << ".");
     753              insertNewLine = false;
     754              WinningLine = FindLine->second;
     755              break;
     756            } else {
     757              LOG(5, "REJECT: Candidate " << *(*CandidateChecker) << "'s center " << Finder->second->OptCenter << " does not match desired on " << *OptCenter << ".");
     758            }
     759          }
     760        } else {
     761          LOG(4, "ACCEPT: There are no candidates for present open line, use what we have.");
     762          insertNewLine = false;
     763          WinningLine = FindLine->second;
    762764        }
    763765      }
     
    770772    AddExistingTesselationTriangleLine(WinningLine, n);
    771773  }
     774
     775  return insertNewLine;
    772776}
    773777;
     
    794798  // also add to open lines
    795799  CandidateForTesselation *CFT = new CandidateForTesselation(BLS[n]);
    796   OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *> (BLS[n], CFT));
     800  OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *>(BLS[n], CFT));
    797801}
    798802;
     
    883887      } else {
    884888        output << "still attached to another triangle: ";
    885         OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *> (triangle->lines[i], NULL));
    886889        for (TriangleMap::iterator TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); TriangleRunner++)
    887890          output << "\t[" << (TriangleRunner->second)->Nr << "|" << *((TriangleRunner->second)->endpoints[0]) << ", " << *((TriangleRunner->second)->endpoints[1]) << ", " << *((TriangleRunner->second)->endpoints[2]) << "] \t";
     891        OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *>(triangle->lines[i], NULL));
    888892      }
    889893      LOG(3, "DEBUG: " << output.str());
     
    919923  else
    920924    Numbers[1] = -1;
     925
     926  // erase from OpenLines if present
     927  {
     928    CandidateMap::iterator openlineiter = OpenLines.find(line);
     929    if (openlineiter != OpenLines.end())
     930      OpenLines.erase(openlineiter);
     931  }
    921932
    922933  for (int i = 0; i < 2; i++) {
     
    937948        LOG(4, "DEBUG: " << *line->endpoints[i] << " has no more lines it's attached to, erasing.");
    938949        RemoveTesselationPoint(line->endpoints[i]);
    939       } else if (DoLog(0)) {
    940         std::stringstream output;
    941         output << "DEBUG: " << *line->endpoints[i] << " has still lines it's attached to: ";
    942         for (LineMap::iterator LineRunner = line->endpoints[i]->lines.begin(); LineRunner != line->endpoints[i]->lines.end(); LineRunner++)
    943           output << "[" << *(LineRunner->second) << "] \t";
    944         LOG(4, output.str());
    945       }
     950      } else
     951        if (DoLog(0)) {
     952          std::stringstream output;
     953          output << "DEBUG: " << *line->endpoints[i] << " has still lines it's attached to: ";
     954          for (LineMap::iterator LineRunner = line->endpoints[i]->lines.begin(); LineRunner != line->endpoints[i]->lines.end(); LineRunner++)
     955            output << "[" << *(LineRunner->second) << "] \t";
     956          LOG(4, output.str());
     957        }
    946958      line->endpoints[i] = NULL; // free'd or not: disconnect
    947959    } else
     
    985997  //Info FunctionInfo(__func__);
    986998
    987   LOG(3, "DEBUG: Checking whether sphere contains no others points ...");
     999  LOG(3, "DEBUG: Checking degeneracy by whether sphere contains no others points ...");
    9881000  bool flag = true;
    9891001
     
    9921004  TesselPointList *ListofPoints = LC->GetPointsInsideSphere(RADIUS, &CandidateLine.OtherOptCenter);
    9931005
    994   LOG(3, "DEBUG: The following atoms are inside sphere at " << CandidateLine.OtherOptCenter << ":");
     1006  LOG(3, "DEBUG: CheckDegeneracy: There are " << ListofPoints->size() << " points inside the sphere.");
     1007  LOG(4, "DEBUG: The following atoms are inside sphere at " << CandidateLine.OtherOptCenter << ":");
    9951008  for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner)
    996     LOG(3, "DEBUG:   " << *(*Runner) << " with distance " << (*Runner)->distance(CandidateLine.OtherOptCenter) << ".");
     1009    LOG(4, "DEBUG:   " << *(*Runner) << " with distance " << (*Runner)->distance(CandidateLine.OtherOptCenter) << ".");
    9971010
    9981011  // remove triangles's endpoints
     
    10081021    LOG(3, "DEBUG: CheckDegeneracy: There are still " << ListofPoints->size() << " points inside the sphere.");
    10091022    flag = false;
    1010     LOG(3, "DEBUG: External atoms inside of sphere at " << CandidateLine.OtherOptCenter << ":");
     1023    LOG(4, "DEBUG: External atoms inside of sphere at " << CandidateLine.OtherOptCenter << ":");
    10111024    for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner)
    1012       LOG(3, "DEBUG:   " << *(*Runner) << " with distance " << (*Runner)->distance(CandidateLine.OtherOptCenter) << ".");
    1013   }
    1014   delete (ListofPoints);
     1025      LOG(4, "DEBUG:   " << *(*Runner) << " with distance " << (*Runner)->distance(CandidateLine.OtherOptCenter) << ".");
     1026  }
     1027  delete ListofPoints;
    10151028
    10161029  return flag;
     
    11551168
    11561169  // 1. searching topmost point with respect to each axis
     1170  LOG(2, "INFO: Searching for topmost pointer from each axis.");
    11571171  for (int i = 0; i < NDIM; i++) { // each axis
    11581172    LC->n[i] = LC->N[i] - 1; // current axis is topmost cell
     
    11761190  }
    11771191
    1178   if (DoLog(1)) {
     1192  if (DoLog(3)) {
    11791193    std::stringstream output;
    11801194    output << "Found maximum coordinates: ";
     
    11901204    BaseLine = new BoundaryLineSet();
    11911205    BaseLine->endpoints[0] = new BoundaryPointSet(MaxPoint[k]);
    1192     LOG(2, "DEBUG: Coordinates of start node at " << *BaseLine->endpoints[0]->node << ".");
     1206    LOG(2, "INFO: Coordinates of start node at " << *BaseLine->endpoints[0]->node << ".");
    11931207
    11941208    double ShortestAngle;
     
    12031217    }
    12041218    BaseLine->endpoints[1] = new BoundaryPointSet(Temporary);
    1205     LOG(1, "INFO: Second node is at " << *Temporary << ".");
     1219    LOG(2, "INFO: Second node is at " << *Temporary << ".");
    12061220
    12071221    // construct center of circle
    12081222    CircleCenter = 0.5 * ((BaseLine->endpoints[0]->node->getPosition()) + (BaseLine->endpoints[1]->node->getPosition()));
    1209     LOG(1, "INFO: CircleCenter is at " << CircleCenter << ".");
     1223    LOG(4, "DEBUG: CircleCenter is at " << CircleCenter << ".");
    12101224
    12111225    // construct normal vector of circle
    12121226    CirclePlaneNormal = (BaseLine->endpoints[0]->node->getPosition()) - (BaseLine->endpoints[1]->node->getPosition());
    1213     LOG(1, "INFO: CirclePlaneNormal is at " << CirclePlaneNormal << ".");
     1227    LOG(4, "DEBUG: CirclePlaneNormal is at " << CirclePlaneNormal << ".");
    12141228
    12151229    double radius = CirclePlaneNormal.NormSquared();
     
    12181232    NormalVector.ProjectOntoPlane(CirclePlaneNormal);
    12191233    NormalVector.Normalize();
    1220     LOG(1, "INFO: NormalVector is at " << NormalVector << ".");
     1234    LOG(4, "DEBUG: NormalVector is at " << NormalVector << ".");
    12211235    ShortestAngle = 2. * M_PI; // This will indicate the quadrant.
    12221236
    1223     SphereCenter = (CircleRadius * NormalVector) +  CircleCenter;
     1237    SphereCenter = (CircleRadius * NormalVector) + CircleCenter;
    12241238    // Now, NormalVector and SphereCenter are two orthonormalized vectors in the plane defined by CirclePlaneNormal (not normalized)
    12251239
    12261240    // look in one direction of baseline for initial candidate
    12271241    try {
    1228       SearchDirection = Plane(CirclePlaneNormal, NormalVector,0).getNormal();  // whether we look "left" first or "right" first is not important ...
    1229     } catch(LinearAlgebraException) {
    1230       ELOG(1, "Vectors are linear dependent: "
    1231           << CirclePlaneNormal << ", " << NormalVector << ".");
     1242      SearchDirection = Plane(CirclePlaneNormal, NormalVector, 0).getNormal(); // whether we look "left" first or "right" first is not important ...
     1243    } catch (LinearAlgebraException &e) {
     1244      ELOG(1, "Vectors are linear dependent: " << CirclePlaneNormal << ", " << NormalVector << ".");
    12321245      delete BaseLine;
    12331246      continue;
     
    12351248
    12361249    // adding point 1 and point 2 and add the line between them
    1237     LOG(2, "DEBUG: Found second point is at " << *BaseLine->endpoints[1]->node << ".");
     1250    LOG(3, "DEBUG: Found second point is at " << *BaseLine->endpoints[1]->node << ".");
    12381251
    12391252    //LOG(1, "INFO: OldSphereCenter is at " << helper << ".");
     
    12441257      for (TesselPointList::iterator it = OptCandidates.pointlist.begin(); it != OptCandidates.pointlist.end(); it++)
    12451258        output << *(*it);
    1246       LOG(2, "DEBUG: List of third Points is: " << output.str());
     1259      LOG(3, "DEBUG: List of third Points is: " << output.str());
    12471260    }
    12481261    if (!OptCandidates.pointlist.empty()) {
     
    14061419//  return result;
    14071420//};
    1408 
    14091421/** This function finds a triangle to a line, adjacent to an existing one.
    14101422 * @param out output stream for debugging
     
    14381450
    14391451  // construct center of circle
    1440   CircleCenter = 0.5 * ((CandidateLine.BaseLine->endpoints[0]->node->getPosition()) +
    1441                         (CandidateLine.BaseLine->endpoints[1]->node->getPosition()));
     1452  CircleCenter = 0.5 * ((CandidateLine.BaseLine->endpoints[0]->node->getPosition()) + (CandidateLine.BaseLine->endpoints[1]->node->getPosition()));
    14421453
    14431454  // construct normal vector of circle
    1444   CirclePlaneNormal = (CandidateLine.BaseLine->endpoints[0]->node->getPosition()) -
    1445                       (CandidateLine.BaseLine->endpoints[1]->node->getPosition());
     1455  CirclePlaneNormal = (CandidateLine.BaseLine->endpoints[0]->node->getPosition()) - (CandidateLine.BaseLine->endpoints[1]->node->getPosition());
    14461456
    14471457  // calculate squared radius of circle
     
    14531463    CircleRadius = RADIUS * RADIUS - radius / 4.;
    14541464    CirclePlaneNormal.Normalize();
    1455     LOG(3, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
    1456 
    1457     LOG(3, "DEBUG: OldSphereCenter is at " << T.SphereCenter << ".");
     1465    LOG(4, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
     1466
     1467    LOG(4, "DEBUG: OldSphereCenter is at " << T.SphereCenter << ".");
    14581468
    14591469    // construct SearchDirection and an "outward pointer"
    1460     SearchDirection = Plane(RelativeSphereCenter, CirclePlaneNormal,0).getNormal();
     1470    SearchDirection = Plane(RelativeSphereCenter, CirclePlaneNormal, 0).getNormal();
    14611471    helper = CircleCenter - (ThirdPoint->node->getPosition());
    1462     if (helper.ScalarProduct(SearchDirection) < -HULLEPSILON)// ohoh, SearchDirection points inwards!
     1472    if (helper.ScalarProduct(SearchDirection) < -HULLEPSILON) // ohoh, SearchDirection points inwards!
    14631473      SearchDirection.Scale(-1.);
    1464     LOG(3, "DEBUG: SearchDirection is " << SearchDirection << ".");
     1474    LOG(4, "DEBUG: SearchDirection is " << SearchDirection << ".");
    14651475    if (fabs(RelativeSphereCenter.ScalarProduct(SearchDirection)) > HULLEPSILON) {
    14661476      // rotated the wrong way!
     
    14721482
    14731483  } else {
    1474     LOG(3, "DEBUG: Circumcircle for base line " << *CandidateLine.BaseLine << " and base triangle " << T << " is too big!");
     1484    LOG(4, "DEBUG: Circumcircle for base line " << *CandidateLine.BaseLine << " and base triangle " << T << " is too big!");
    14751485  }
    14761486
     
    15051515    baseline = Runner->second;
    15061516    if (baseline->pointlist.empty()) {
    1507       ASSERT((baseline->BaseLine->triangles.size() == 1),"Open line without exactly one attached triangle");
     1517      ASSERT((baseline->BaseLine->triangles.size() == 1), "Open line without exactly one attached triangle");
    15081518      T = (((baseline->BaseLine->triangles.begin()))->second);
    15091519      LOG(4, "DEBUG: Finding best candidate for open line " << *baseline->BaseLine << " of triangle " << *T);
     
    15381548  TesselPointList *connectedClosestPoints = GetCircleOfSetOfPoints(&SetOfNeighbours, TurningPoint, CandidateLine.BaseLine->endpoints[1]->node->getPosition());
    15391549
    1540   {
     1550  if (DoLog(3)) {
    15411551    std::stringstream output;
    15421552    for (TesselPointList::iterator TesselRunner = connectedClosestPoints->begin(); TesselRunner != connectedClosestPoints->end(); ++TesselRunner)
    15431553      output << **TesselRunner;
    1544     LOG(3, "DEBUG: List of Candidates for Turning Point " << *TurningPoint << ":");
     1554    LOG(3, "DEBUG: List of Candidates for Turning Point " << *TurningPoint << ":" << output.str());
    15451555  }
    15461556
     
    15831593  }
    15841594  delete (connectedClosestPoints);
    1585 };
     1595}
     1596;
    15861597
    15871598/** for polygons (multiple candidates for a baseline) sets internal edges to the correct next candidate.
     
    16031614      else {
    16041615        LOG(4, "DEBUG: line " << *(FindLine->second) << " is open with no candidate, setting to next Sprinter" << (*Sprinter));
    1605         Finder->second->T = BTS;  // is last triangle
     1616        Finder->second->T = BTS; // is last triangle
    16061617        Finder->second->pointlist.push_back(Sprinter);
    16071618        Finder->second->ShortestAngle = 0.;
     
    16101621    }
    16111622  }
    1612 };
     1623}
     1624;
    16131625
    16141626/** If a given \a *triangle is degenerated, this adds both sides.
     
    16461658  // give some verbose output about the whole procedure
    16471659  if (CandidateLine.T != NULL)
    1648     LOG(2, "DEBUG: --> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << ".");
     1660    LOG(2, "INFO: --> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << ".");
    16491661  else
    1650     LOG(2, "DEBUG: --> New starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle.");
     1662    LOG(2, "INFO: --> New starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle.");
    16511663  triangle = BTS;
    16521664
     
    17321744;
    17331745
     1746bool Tesselation::isConvex() const
     1747{
     1748  bool status = true;
     1749  // go through all lines on boundary
     1750  for (LineMap::const_iterator lineiter = LinesOnBoundary.begin();
     1751      lineiter != LinesOnBoundary.end(); ++lineiter) {
     1752    if (!lineiter->second->CheckConvexityCriterion()) {
     1753      LOG(2, "DEBUG: Line " << *lineiter->second << " is not convex.");
     1754      status = false;
     1755    }
     1756  }
     1757  return status;
     1758}
     1759
    17341760/** Checks whether the quadragon of the two triangles connect to \a *Base is convex.
    17351761 * We look whether the closest point on \a *Base with respect to the other baseline is outside
     
    18681894    }
    18691895    for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {
    1870     LOG(4, "DEBUG: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << ".");
     1896      LOG(4, "DEBUG: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << ".");
    18711897      BaseLineNormal += (runner->second->NormalVector);
    18721898    }
     
    18971923  class BoundaryLineSet *OldLines[4], *NewLine;
    18981924  class BoundaryPointSet *OldPoints[2];
    1899   Vector BaseLineNormal;
     1925  Vector BaseLineNormal[2];
     1926  Vector OtherEndpoint[2]; // fourth point to either triangle
    19001927  int OldTriangleNrs[2], OldBaseLineNr;
    19011928  int i, m;
    19021929
    19031930  // calculate NormalVector for later use
    1904   BaseLineNormal.Zero();
    19051931  if (Base->triangles.size() < 2) {
    19061932    ELOG(1, "Less than two triangles are attached to this baseline!");
    19071933    return NULL;
    19081934  }
    1909   for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {
    1910     LOG(1, "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << ".");
    1911     BaseLineNormal += (runner->second->NormalVector);
    1912   }
    1913   BaseLineNormal.Scale(-1. / 2.); // has to point inside for BoundaryTriangleSet::GetNormalVector()
     1935  {
     1936    int i=0;
     1937    for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {
     1938      LOG(5, "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << ".");
     1939      OtherEndpoint[(i+1)%2] = runner->second->GetThirdEndpoint(Base)->node->getPosition();
     1940      BaseLineNormal[i++] = (runner->second->NormalVector);
     1941      ASSERT( i <= 2,
     1942          "Tesselation::FlipBaseline() - not exactly two triangles found.");
     1943    }
     1944  }
    19141945
    19151946  // get the two triangles
     
    19411972
    19421973  // index OldLines and OldPoints
     1974  // note that oldlines[0,1] belong to first triangle and hence first normal
     1975  // vector and oldlines[2,3] belong to second triangle and its normal vector
    19431976  for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++)
    19441977    for (int j = 0; j < 3; j++) // all of their endpoints and baselines
     
    19501983        OldPoints[m++] = runner->second->endpoints[j];
    19511984
     1985  Vector BasePoints[2]; // endpoints of Base
     1986  if (OldLines[0]->ContainsBoundaryPoint(Base->endpoints[0])) {
     1987    BasePoints[0] = Base->endpoints[0]->node->getPosition();
     1988    BasePoints[1] = Base->endpoints[1]->node->getPosition();
     1989  } else {
     1990    BasePoints[0] = Base->endpoints[1]->node->getPosition();
     1991    BasePoints[1] = Base->endpoints[0]->node->getPosition();
     1992  }
    19521993  // check whether everything is in place to create new lines and triangles
    19531994  if (i < 4) {
     
    19652006      return NULL;
    19662007    }
     2008
     2009  // construct plane of first triangle for calculating normal vectors later
     2010  const Plane triangleplane = Base->triangles.begin()->second->getPlane();
     2011  // get fourth point projected down onto this plane
     2012  const Vector Intersection = triangleplane.getClosestPoint(OtherEndpoint[0]);
    19672013
    19682014  // remove triangles and baseline removes itself
     
    19712017  m = 0;
    19722018  // first obtain all triangle to delete ... (otherwise we pull the carpet (Base) from under the for-loop's feet)
    1973   list <BoundaryTriangleSet *> TrianglesOfBase;
     2019  list<BoundaryTriangleSet *> TrianglesOfBase;
    19742020  for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); ++runner)
    19752021    TrianglesOfBase.push_back(runner->second);
    19762022  // .. then delete each triangle (which deletes the line as well)
    1977   for (list <BoundaryTriangleSet *>::iterator runner = TrianglesOfBase.begin(); !TrianglesOfBase.empty(); runner = TrianglesOfBase.begin()) {
     2023  for (list<BoundaryTriangleSet *>::iterator runner = TrianglesOfBase.begin(); !TrianglesOfBase.empty(); runner = TrianglesOfBase.begin()) {
    19782024    LOG(3, "DEBUG: Deleting triangle " << *(*runner) << ".");
    19792025    OldTriangleNrs[m++] = (*runner)->Nr;
     
    19882034  LinesOnBoundary.insert(LinePair(OldBaseLineNr, NewLine)); // no need for check for unique insertion as NewLine is definitely a new one
    19892035  LOG(3, "DEBUG: Created new baseline " << *NewLine << ".");
     2036
     2037  // Explanation for normal vector choice:
     2038  // Decisive for the normal vector of the new triangle is whether the fourth
     2039  // endpoint is with respect to the joining boundary line on one side or on
     2040  // the other with respect to the endpoint of the plane triangle that is not
     2041  // contained in the joining boundary line.
    19902042
    19912043  // construct new triangles with flipped baseline
     
    20002052    BLS[2] = NewLine;
    20012053    BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[0]);
    2002     BTS->GetNormalVector(BaseLineNormal);
     2054    {
     2055      Line joiningline = makeLineThrough(
     2056          OldLines[0]->endpoints[0]->node->getPosition(),
     2057          OldLines[0]->endpoints[1]->node->getPosition());
     2058      // BasePoints[1] is not contained in OldLines[0], hence is third endpoint
     2059      // of plane triangle. BasePoints[0] is in the joining OldLines[0] and
     2060      // we check whether Intersection is on same side as BasePoints[1] or not.
     2061      const Vector pointinginside =
     2062          joiningline.getClosestPoint(BasePoints[1]) - BasePoints[1];
     2063      const Vector pointingtointersection =
     2064          joiningline.getClosestPoint(Intersection) - Intersection;
     2065      const double sign_of_intersection =
     2066          pointingtointersection.ScalarProduct(pointinginside);
     2067      LOG(4, "DEBUG: Sign of SKP between both lines w.r.t " << *OldLines[0]
     2068          << " is " << sign_of_intersection << ".");
     2069      const double sign_of_normal = (sign_of_intersection >= 0) ? -1. : +1.;
     2070      LOG(4, "DEBUG: Opposite normal direction is "
     2071          << sign_of_normal * BaseLineNormal[0] << ".");
     2072      BTS->GetNormalVector(sign_of_normal * BaseLineNormal[0]);
     2073    }
    20032074    AddTesselationTriangle(OldTriangleNrs[0]);
    20042075    LOG(3, "DEBUG: Created new triangle " << *BTS << ".");
     
    20082079    BLS[2] = NewLine;
    20092080    BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[1]);
    2010     BTS->GetNormalVector(BaseLineNormal);
     2081    {
     2082      Line joiningline = makeLineThrough(
     2083          OldLines[1]->endpoints[0]->node->getPosition(),
     2084          OldLines[1]->endpoints[1]->node->getPosition());
     2085      // BasePoints[0] is not contained in OldLines[1], hence is third endpoint
     2086      // of plane triangle. BasePoints[1] is in th1e joining OldLines[1] and
     2087      // we check whether Intersection is on same side as BasePoints[0] or not.
     2088      const Vector pointinginside =
     2089          joiningline.getClosestPoint(BasePoints[0]) - BasePoints[0];
     2090      const Vector pointingtointersection =
     2091          joiningline.getClosestPoint(Intersection) - Intersection;
     2092      const double sign_of_intersection =
     2093          pointingtointersection.ScalarProduct(pointinginside);
     2094      LOG(4, "DEBUG: Sign of SKP between both lines w.r.t " << *OldLines[1]
     2095          << " is " << sign_of_intersection << ".");
     2096      const double sign_of_normal = (sign_of_intersection >= 0) ? -1. : +1.;
     2097      LOG(4, "DEBUG: Opposite normal direction is "
     2098          << sign_of_normal * BaseLineNormal[0] << ".");
     2099      BTS->GetNormalVector(sign_of_normal * BaseLineNormal[0]);
     2100    }
    20112101    AddTesselationTriangle(OldTriangleNrs[1]);
    20122102    LOG(3, "DEBUG: Created new triangle " << *BTS << ".");
     
    21552245  TesselPoint *Candidate = NULL;
    21562246
    2157   LOG(3, "DEBUG: NormalVector of BaseTriangle is " << NormalVector << ".");
     2247  LOG(4, "DEBUG: NormalVector of BaseTriangle is " << NormalVector << ".");
    21582248
    21592249  // copy old center
     
    21632253
    21642254  // construct center of circle
    2165   CircleCenter = 0.5 * ((CandidateLine.BaseLine->endpoints[0]->node->getPosition()) +
    2166                         (CandidateLine.BaseLine->endpoints[1]->node->getPosition()));
     2255  CircleCenter = 0.5 * ((CandidateLine.BaseLine->endpoints[0]->node->getPosition()) + (CandidateLine.BaseLine->endpoints[1]->node->getPosition()));
    21672256
    21682257  // construct normal vector of circle
    2169   CirclePlaneNormal = (CandidateLine.BaseLine->endpoints[0]->node->getPosition()) -
    2170                       (CandidateLine.BaseLine->endpoints[1]->node->getPosition());
     2258  CirclePlaneNormal = (CandidateLine.BaseLine->endpoints[0]->node->getPosition()) - (CandidateLine.BaseLine->endpoints[1]->node->getPosition());
    21712259
    21722260  RelativeOldSphereCenter = OldSphereCenter - CircleCenter;
     
    21772265    CircleRadius = RADIUS * RADIUS - radius;
    21782266    CirclePlaneNormal.Normalize();
    2179     LOG(3, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
     2267    LOG(4, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
    21802268
    21812269    // test whether old center is on the band's plane
     
    21862274    radius = RelativeOldSphereCenter.NormSquared();
    21872275    if (fabs(radius - CircleRadius) < HULLEPSILON) {
    2188       LOG(3, "DEBUG: RelativeOldSphereCenter is at " << RelativeOldSphereCenter << ".");
     2276      LOG(4, "DEBUG: RelativeOldSphereCenter is at " << RelativeOldSphereCenter << ".");
    21892277
    21902278      // check SearchDirection
    2191       LOG(3, "DEBUG: SearchDirection is " << SearchDirection << ".");
     2279      LOG(4, "DEBUG: SearchDirection is " << SearchDirection << ".");
    21922280      if (fabs(RelativeOldSphereCenter.ScalarProduct(SearchDirection)) > HULLEPSILON) { // rotated the wrong way!
    21932281        ELOG(1, "SearchDirection and RelativeOldSphereCenter are not orthogonal!");
     
    22302318                  // find center on the plane
    22312319                  GetCenterofCircumcircle(NewPlaneCenter, CandidateLine.BaseLine->endpoints[0]->node->getPosition(), CandidateLine.BaseLine->endpoints[1]->node->getPosition(), Candidate->getPosition());
    2232                   LOG(3, "DEBUG: NewPlaneCenter is " << NewPlaneCenter << ".");
     2320                  LOG(5, "DEBUG: NewPlaneCenter is " << NewPlaneCenter << ".");
    22332321
    22342322                  try {
    2235                     NewNormalVector = Plane((CandidateLine.BaseLine->endpoints[0]->node->getPosition()),
    2236                                             (CandidateLine.BaseLine->endpoints[1]->node->getPosition()),
    2237                                             (Candidate->getPosition())).getNormal();
    2238                     LOG(3, "DEBUG: NewNormalVector is " << NewNormalVector << ".");
     2323                    NewNormalVector = Plane((CandidateLine.BaseLine->endpoints[0]->node->getPosition()), (CandidateLine.BaseLine->endpoints[1]->node->getPosition()), (Candidate->getPosition())).getNormal();
     2324                    LOG(5, "DEBUG: NewNormalVector is " << NewNormalVector << ".");
    22392325                    radius = CandidateLine.BaseLine->endpoints[0]->node->DistanceSquared(NewPlaneCenter);
    2240                     LOG(3, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
    2241                     LOG(3, "DEBUG: SearchDirection is " << SearchDirection << ".");
    2242                     LOG(3, "DEBUG: Radius of CircumCenterCircle is " << radius << ".");
     2326                    LOG(5, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
     2327                    LOG(5, "DEBUG: SearchDirection is " << SearchDirection << ".");
     2328                    LOG(5, "DEBUG: Radius of CircumCenterCircle is " << radius << ".");
    22432329                    if (radius < RADIUS * RADIUS) {
    22442330                      otherradius = CandidateLine.BaseLine->endpoints[1]->node->DistanceSquared(NewPlaneCenter);
     
    22462332                        // construct both new centers
    22472333                        NewSphereCenter = NewPlaneCenter;
    2248                         OtherNewSphereCenter= NewPlaneCenter;
     2334                        OtherNewSphereCenter = NewPlaneCenter;
    22492335                        helper = NewNormalVector;
    22502336                        helper.Scale(sqrt(RADIUS * RADIUS - radius));
    2251                         LOG(4, "DEBUG: Distance of NewPlaneCenter " << NewPlaneCenter << " to either NewSphereCenter is " << helper.Norm() << " of vector " << helper << " with sphere radius " << RADIUS << ".");
     2337                        LOG(5, "DEBUG: Distance of NewPlaneCenter " << NewPlaneCenter << " to either NewSphereCenter is " << helper.Norm() << " of vector " << helper << " with sphere radius " << RADIUS << ".");
    22522338                        NewSphereCenter += helper;
    2253                         LOG(4, "DEBUG: NewSphereCenter is at " << NewSphereCenter << ".");
     2339                        LOG(5, "DEBUG: NewSphereCenter is at " << NewSphereCenter << ".");
    22542340                        // OtherNewSphereCenter is created by the same vector just in the other direction
    22552341                        helper.Scale(-1.);
    22562342                        OtherNewSphereCenter += helper;
    2257                         LOG(4, "DEBUG: OtherNewSphereCenter is at " << OtherNewSphereCenter << ".");
     2343                        LOG(5, "DEBUG: OtherNewSphereCenter is at " << OtherNewSphereCenter << ".");
    22582344                        alpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, NewSphereCenter, OldSphereCenter, NormalVector, SearchDirection, HULLEPSILON);
    22592345                        Otheralpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, OtherNewSphereCenter, OldSphereCenter, NormalVector, SearchDirection, HULLEPSILON);
     
    22762362                          if ((CandidateLine.ShortestAngle - HULLEPSILON) < alpha) {
    22772363                            CandidateLine.pointlist.push_back(Candidate);
    2278                             LOG(2, "ACCEPT: We have found an equally good candidate: " << *(Candidate) << " with " << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << ".");
     2364                            LOG(3, "ACCEPT: We have found an equally good candidate: " << *(Candidate) << " with " << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << ".");
    22792365                          } else {
    22802366                            // remove all candidates from the list and then the list itself
    22812367                            CandidateLine.pointlist.clear();
    22822368                            CandidateLine.pointlist.push_back(Candidate);
    2283                             LOG(2, "ACCEPT: We have found a better candidate: " << *(Candidate) << " with " << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << ".");
     2369                            LOG(3, "ACCEPT: We have found a better candidate: " << *(Candidate) << " with " << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << ".");
    22842370                          }
    22852371                          CandidateLine.ShortestAngle = alpha;
    2286                           LOG(2, "DEBUG: There are " << CandidateLine.pointlist.size() << " candidates in the list now.");
     2372                          LOG(4, "DEBUG: There are " << CandidateLine.pointlist.size() << " candidates in the list now.");
    22872373                        } else {
    22882374                          if ((Candidate != NULL) && (CandidateLine.pointlist.begin() != CandidateLine.pointlist.end())) {
    2289                             LOG(3, "REJECT: Old candidate " << *(*CandidateLine.pointlist.begin()) << " with " << CandidateLine.ShortestAngle << " is better than new one " << *Candidate << " with " << alpha << " .");
     2375                            LOG(4, "REJECT: Old candidate " << *(*CandidateLine.pointlist.begin()) << " with " << CandidateLine.ShortestAngle << " is better than new one " << *Candidate << " with " << alpha << " .");
    22902376                          } else {
    2291                             LOG(3, "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected.");
     2377                            LOG(4, "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected.");
    22922378                          }
    22932379                        }
    22942380                      } else {
    2295                         ELOG(0, "REJECT: Distance to center of circumcircle is not the same from each corner of the triangle: " << fabs(radius - otherradius));
     2381                        ASSERT(0, std::string("FindThirdPointForTesselation() - ") + std::string("REJECT: Distance to center of circumcircle is not the same from each corner of the triangle: ") + toString(fabs(radius - otherradius)));
    22962382                      }
    22972383                    } else {
    2298                       LOG(3, "REJECT: NewSphereCenter " << NewSphereCenter << " for " << *Candidate << " is too far away: " << radius << ".");
     2384                      LOG(4, "REJECT: NewSphereCenter " << NewSphereCenter << " for " << *Candidate << " is too far away: " << radius << ".");
    22992385                    }
    2300                   }
    2301                   catch (LinearDependenceException &excp){
    2302                     LOG(3, boost::diagnostic_information(excp));
    2303                     LOG(3, "REJECT: Three points from " << *CandidateLine.BaseLine << " and Candidate " << *Candidate << " are linear-dependent.");
     2386                  } catch (LinearDependenceException &excp) {
     2387                    LOG(4, boost::diagnostic_information(excp));
     2388                    LOG(4, "REJECT: Three points from " << *CandidateLine.BaseLine << " and Candidate " << *Candidate << " are linear-dependent.");
    23042389                  }
    23052390                } else {
    23062391                  if (ThirdPoint != NULL) {
    2307                     LOG(3, "REJECT: Base triangle " << *CandidateLine.BaseLine << " and " << *ThirdPoint << " contains Candidate " << *Candidate << ".");
     2392                    LOG(4, "REJECT: Base triangle " << *CandidateLine.BaseLine << " and " << *ThirdPoint << " contains Candidate " << *Candidate << ".");
    23082393                  } else {
    2309                     LOG(3, "REJECT: Base triangle " << *CandidateLine.BaseLine << " contains Candidate " << *Candidate << ".");
     2394                    LOG(4, "REJECT: Base triangle " << *CandidateLine.BaseLine << " contains Candidate " << *Candidate << ".");
    23102395                  }
    23112396                }
     
    23182403  } else {
    23192404    if (ThirdPoint != NULL)
    2320       LOG(3, "Circumcircle for base line " << *CandidateLine.BaseLine << " and third node " << *ThirdPoint << " is too big!");
     2405      LOG(4, "DEBUG: Circumcircle for base line " << *CandidateLine.BaseLine << " and third node " << *ThirdPoint << " is too big!");
    23212406    else
    2322       LOG(3, "Circumcircle for base line " << *CandidateLine.BaseLine << " is too big!");
    2323   }
    2324 
    2325   LOG(2, "DEBUG: Sorting candidate list ...");
     2407      LOG(4, "DEBUG: Circumcircle for base line " << *CandidateLine.BaseLine << " is too big!");
     2408  }
     2409
     2410  LOG(5, "DEBUG: Sorting candidate list ...");
    23262411  if (CandidateLine.pointlist.size() > 1) {
    23272412    CandidateLine.pointlist.unique();
     
    23292414  }
    23302415
    2331   if ((!CandidateLine.pointlist.empty()) && (!CandidateLine.CheckValidity(RADIUS, LC))) {
    2332     ELOG(0, "There were other points contained in the rolling sphere as well!");
    2333     performCriticalExit();
    2334   }
     2416  ASSERT(CandidateLine.pointlist.empty() || (CandidateLine.CheckValidity(RADIUS, LC)), std::string("Tesselation::FindThirdPointForTesselation()") + std::string("There were other points contained in the rolling sphere as well!"));
    23352417}
    23362418;
     
    23442426{
    23452427  //Info FunctionInfo(__func__);
    2346   const BoundaryLineSet * lines[2] = { line1, line2 };
     2428  const BoundaryLineSet * lines[2] = {line1, line2};
    23472429  class BoundaryPointSet *node = NULL;
    23482430  PointMap OrderMap;
     
    23512433    // for both lines
    23522434    for (int j = 0; j < 2; j++) { // for both endpoints
    2353       OrderTest = OrderMap.insert(pair<int, class BoundaryPointSet *> (lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j]));
     2435      OrderTest = OrderMap.insert(pair<int, class BoundaryPointSet *>(lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j]));
    23542436      if (!OrderTest.second) { // if insertion fails, we have common endpoint
    23552437        node = OrderTest.first->second;
     
    24002482              // we should make sure that both triangles end up in the same entry
    24012483              // in the distance multimap. Hence, we round to 6 digit precision.
    2402               const double distance =
    2403                   1e-6*floor(FindPoint->second->node->DistanceSquared(x)*1e+6);
     2484              const double distance = 1e-6 * floor(FindPoint->second->node->DistanceSquared(x) * 1e+6);
    24042485              points->insert(DistanceToPointPair(distance, FindPoint->second));
    24052486              LOG(3, "DEBUG: Putting " << *FindPoint->second << " into the list.");
     
    24462527    for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) {
    24472528      // calculate closest point on line to desired point
    2448       helper = 0.5 * (((LineRunner->second)->endpoints[0]->node->getPosition()) +
    2449                       ((LineRunner->second)->endpoints[1]->node->getPosition()));
     2529      helper = 0.5 * (((LineRunner->second)->endpoints[0]->node->getPosition()) + ((LineRunner->second)->endpoints[1]->node->getPosition()));
    24502530      Center = (x) - helper;
    2451       BaseLine = ((LineRunner->second)->endpoints[0]->node->getPosition()) -
    2452                  ((LineRunner->second)->endpoints[1]->node->getPosition());
     2531      BaseLine = ((LineRunner->second)->endpoints[0]->node->getPosition()) - ((LineRunner->second)->endpoints[1]->node->getPosition());
    24532532      Center.ProjectOntoPlane(BaseLine);
    24542533      const double distance = Center.NormSquared();
     
    25072586    for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) {
    25082587
    2509       BaseLine = ((LineRunner->second)->endpoints[0]->node->getPosition()) -
    2510                  ((LineRunner->second)->endpoints[1]->node->getPosition());
     2588      BaseLine = ((LineRunner->second)->endpoints[0]->node->getPosition()) - ((LineRunner->second)->endpoints[1]->node->getPosition());
    25112589      const double lengthBase = BaseLine.NormSquared();
    25122590
     
    25242602          MinDistance = lengthEnd;
    25252603          LOG(1, "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[0]->node << " is closer with " << lengthEnd << ".");
    2526         } else if (fabs(lengthEnd - MinDistance) < MYEPSILON) { // additional best candidate
    2527           ClosestLines.insert(LineRunner->second);
    2528           LOG(1, "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[1]->node << " is equally good with " << lengthEnd << ".");
    2529         } else { // line is worse
    2530           LOG(1, "REJECT: Line " << *LineRunner->second << " to either endpoints is further away than present closest line candidate: " << lengthEndA << ", " << lengthEndB << ", and distance is longer than baseline:" << lengthBase << ".");
    2531         }
     2604        } else
     2605          if (fabs(lengthEnd - MinDistance) < MYEPSILON) { // additional best candidate
     2606            ClosestLines.insert(LineRunner->second);
     2607            LOG(1, "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[1]->node << " is equally good with " << lengthEnd << ".");
     2608          } else { // line is worse
     2609            LOG(1, "REJECT: Line " << *LineRunner->second << " to either endpoints is further away than present closest line candidate: " << lengthEndA << ", " << lengthEndB << ", and distance is longer than baseline:" << lengthBase << ".");
     2610          }
    25322611      } else { // intersection is closer, calculate
    25332612        // calculate closest point on line to desired point
     
    26552734  double distance = 0.;
    26562735
    2657   if (triangle == NULL) {// is boundary point or only point in point cloud?
     2736  if (triangle == NULL) { // is boundary point or only point in point cloud?
    26582737    LOG(1, "No triangle given!");
    26592738    return -1.;
     
    27642843      takePoint = true;
    27652844      current = findLines->second->endpoints[1]->node;
    2766     } else if (findLines->second->endpoints[1]->Nr == Point->getNr()) {
    2767       takePoint = true;
    2768       current = findLines->second->endpoints[0]->node;
    2769     }
     2845    } else
     2846      if (findLines->second->endpoints[1]->Nr == Point->getNr()) {
     2847        takePoint = true;
     2848        current = findLines->second->endpoints[0]->node;
     2849      }
    27702850
    27712851    if (takePoint) {
     
    28072887  Vector OrthogonalVector;
    28082888  Vector helper;
    2809   const TesselPoint * const TrianglePoints[3] = { Point, NULL, NULL };
     2889  const TesselPoint * const TrianglePoints[3] = {Point, NULL, NULL};
    28102890  TriangleList *triangles = NULL;
    28112891
     
    28182898  // calculate central point
    28192899  triangles = FindTriangles(TrianglePoints);
    2820   if ((triangles != NULL) && (!triangles->empty())) {
    2821     for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++)
    2822       PlaneNormal += (*Runner)->NormalVector;
    2823   } else {
    2824     ELOG(0, "Could not find any triangles for point " << *Point << ".");
    2825     performCriticalExit();
    2826   }
     2900  ASSERT((triangles == NULL) || (triangles->empty()), std::string("Tesselation::GetCircleOfConnectedTriangles()") + std::string("Could not find any triangles for point " + toString(*Point) + "."));
     2901  for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++)
     2902    PlaneNormal += (*Runner)->NormalVector;
    28272903  PlaneNormal.Scale(1.0 / triangles->size());
    28282904  LOG(4, "DEBUG: Calculated PlaneNormal of all circle points is " << PlaneNormal << ".");
     
    28362912    AngleZero = ((*SetOfNeighbours->begin())->getPosition()) - (Point->getPosition());
    28372913    AngleZero.ProjectOntoPlane(PlaneNormal);
    2838     if (AngleZero.NormSquared() < MYEPSILON) {
    2839       ELOG(0, "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!");
    2840       performCriticalExit();
    2841     }
     2914    ASSERT(AngleZero.NormSquared() > MYEPSILON, std::string("Tesselation::GetCircleOfConnectedTriangles() - ") + std::string("AngleZero is 0 even with alternative reference.") + std::string("The algorithm has to be changed here!"));
    28422915  }
    28432916  LOG(4, "DEBUG: Reference vector on this plane representing angle 0 is " << AngleZero << ".");
    28442917  if (AngleZero.NormSquared() > MYEPSILON)
    2845     OrthogonalVector = Plane(PlaneNormal, AngleZero,0).getNormal();
     2918    OrthogonalVector = Plane(PlaneNormal, AngleZero, 0).getNormal();
    28462919  else
    28472920    OrthogonalVector.MakeNormalTo(PlaneNormal);
     
    28542927    double angle = GetAngle(helper, AngleZero, OrthogonalVector);
    28552928    LOG(4, "DEBUG" << angle << " for point " << **listRunner << ".");
    2856     anglesOfPoints.insert(pair<double, TesselPoint*> (angle, (*listRunner)));
     2929    anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner)));
    28572930  }
    28582931
     
    29092982  int counter = 0;
    29102983  while (TesselC != SetOfNeighbours->end()) {
    2911     helper = Plane(((*TesselA)->getPosition()),
    2912                    ((*TesselB)->getPosition()),
    2913                    ((*TesselC)->getPosition())).getNormal();
     2984    helper = Plane(((*TesselA)->getPosition()), ((*TesselB)->getPosition()), ((*TesselC)->getPosition())).getNormal();
    29142985    LOG(5, "DEBUG: Making normal vector out of " << *(*TesselA) << ", " << *(*TesselB) << " and " << *(*TesselC) << ":" << helper);
    29152986    counter++;
     
    29202991  }
    29212992  //LOG(0, "Summed vectors " << center << "; number of points " << connectedPoints.size() << "; scale factor " << counter);
    2922   PlaneNormal.Scale(1.0 / (double) counter);
     2993  PlaneNormal.Scale(1.0 / (double)counter);
    29232994  //  LOG(1, "INFO: Calculated center of all circle points is " << center << ".");
    29242995  //
     
    29343005    AngleZero.ProjectOntoPlane(PlaneNormal);
    29353006  }
    2936   if ((Reference.IsZero()) || (AngleZero.NormSquared() < MYEPSILON )) {
     3007  if ((Reference.IsZero()) || (AngleZero.NormSquared() < MYEPSILON)) {
    29373008    LOG(4, "DEBUG: Using alternatively " << (*SetOfNeighbours->begin())->getPosition() << " as angle 0 referencer.");
    29383009    AngleZero = ((*SetOfNeighbours->begin())->getPosition()) - (Point->getPosition());
    29393010    AngleZero.ProjectOntoPlane(PlaneNormal);
    2940     if (AngleZero.NormSquared() < MYEPSILON) {
    2941       ELOG(0, "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!");
    2942       performCriticalExit();
    2943     }
     3011    ASSERT(AngleZero.NormSquared() > MYEPSILON, std::string("Tesselation::GetCircleOfSetOfPoints() - ") + std::string("AngleZero is 0 even with alternative reference.") + std::string("The algorithm has to be changed here!"));
    29443012  }
    29453013  LOG(4, "DEBUG: Reference vector on this plane representing angle 0 is " << AngleZero << ".");
    29463014  if (AngleZero.NormSquared() > MYEPSILON)
    2947     OrthogonalVector = Plane(PlaneNormal, AngleZero,0).getNormal();
     3015    OrthogonalVector = Plane(PlaneNormal, AngleZero, 0).getNormal();
    29483016  else
    29493017    OrthogonalVector.MakeNormalTo(PlaneNormal);
     
    29593027      angle = 2. * M_PI - angle;
    29603028    LOG(4, "DEBUG: Calculated angle between " << helper << " and " << AngleZero << " is " << angle << " for point " << **listRunner << ".");
    2961     InserterTest = anglesOfPoints.insert(pair<double, TesselPoint*> (angle, (*listRunner)));
    2962     if (!InserterTest.second) {
    2963       ELOG(0, "GetCircleOfSetOfPoints() got two atoms with same angle: " << *((InserterTest.first)->second) << " and " << (*listRunner));
    2964       performCriticalExit();
    2965     }
     3029    InserterTest = anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner)));
     3030    ASSERT(InserterTest.second, std::string("Tesselation::GetCircleOfSetOfPoints() - ") + std::string("got two atoms with same angle " + toString(*((InserterTest.first)->second))) + std::string(" and " + toString((*listRunner))));
    29663031  }
    29673032
     
    29833048  //Info FunctionInfo(__func__);
    29843049  map<double, TesselPoint*> anglesOfPoints;
    2985   list<TesselPointList *> *ListOfPaths = new list<TesselPointList *> ;
     3050  list<TesselPointList *> *ListOfPaths = new list<TesselPointList *>;
    29863051  TesselPointList *connectedPath = NULL;
    29873052  Vector center;
     
    30093074  map<class BoundaryTriangleSet *, bool>::iterator TriangleRunner;
    30103075  for (LineMap::iterator Runner = ReferencePoint->lines.begin(); Runner != ReferencePoint->lines.end(); Runner++) {
    3011     TouchedLine.insert(pair<class BoundaryLineSet *, bool> (Runner->second, false));
    3012     for (TriangleMap::iterator Sprinter = Runner->second->triangles.begin(); Sprinter != Runner->second->triangles.end(); Sprinter++)
    3013       TouchedTriangle.insert(pair<class BoundaryTriangleSet *, bool> (Sprinter->second, false));
     3076    LOG(4, "DEBUG: Adding " << *Runner->second << " to TouchedLine map.");
     3077    TouchedLine.insert(pair<class BoundaryLineSet *, bool>(Runner->second, false));
     3078    for (TriangleMap::iterator Sprinter = Runner->second->triangles.begin(); Sprinter != Runner->second->triangles.end(); Sprinter++) {
     3079      LOG(4, "DEBUG: Adding " << *Sprinter->second << " to TouchedTriangle map.");
     3080      TouchedTriangle.insert(pair<class BoundaryTriangleSet *, bool>(Sprinter->second, false));
     3081    }
    30143082  }
    30153083  if (!ReferencePoint->lines.empty()) {
     
    30183086      if (LineRunner == TouchedLine.end()) {
    30193087        ELOG(1, "I could not find " << *runner->second << " in the touched list.");
    3020       } else if (!LineRunner->second) {
    3021         LineRunner->second = true;
    3022         connectedPath = new TesselPointList;
    3023         triangle = NULL;
    3024         CurrentLine = runner->second;
    3025         StartLine = CurrentLine;
    3026         CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
    3027         LOG(1, "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << ".");
    3028         do {
    3029           // push current one
    3030           LOG(1, "INFO: Putting " << *CurrentPoint << " at end of path.");
    3031           connectedPath->push_back(CurrentPoint->node);
    3032 
    3033           // find next triangle
    3034           for (TriangleMap::iterator Runner = CurrentLine->triangles.begin(); Runner != CurrentLine->triangles.end(); Runner++) {
    3035             LOG(1, "INFO: Inspecting triangle " << *Runner->second << ".");
    3036             if ((Runner->second != triangle)) { // look for first triangle not equal to old one
    3037               triangle = Runner->second;
    3038               TriangleRunner = TouchedTriangle.find(triangle);
    3039               if (TriangleRunner != TouchedTriangle.end()) {
    3040                 if (!TriangleRunner->second) {
    3041                   TriangleRunner->second = true;
    3042                   LOG(1, "INFO: Connecting triangle is " << *triangle << ".");
    3043                   break;
     3088      } else
     3089        if (!LineRunner->second) {
     3090          LineRunner->second = true;
     3091          connectedPath = new TesselPointList;
     3092          triangle = NULL;
     3093          CurrentLine = runner->second;
     3094          StartLine = CurrentLine;
     3095          CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
     3096          LOG(3, "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << ".");
     3097          do {
     3098            // push current one
     3099            LOG(3, "INFO: Putting " << *CurrentPoint << " at end of path.");
     3100            connectedPath->push_back(CurrentPoint->node);
     3101
     3102            // find next triangle
     3103            for (TriangleMap::iterator Runner = CurrentLine->triangles.begin(); Runner != CurrentLine->triangles.end(); Runner++) {
     3104              LOG(4, "DEBUG: Inspecting triangle " << *Runner->second << ".");
     3105              if ((Runner->second != triangle)) { // look for first triangle not equal to old one
     3106                triangle = Runner->second;
     3107                TriangleRunner = TouchedTriangle.find(triangle);
     3108                if (TriangleRunner != TouchedTriangle.end()) {
     3109                  if (!TriangleRunner->second) {
     3110                    TriangleRunner->second = true;
     3111                    LOG(4, "DEBUG: Connecting triangle is " << *triangle << ".");
     3112                    break;
     3113                  } else {
     3114                    LOG(4, "DEBUG: Skipping " << *triangle << ", as we have already visited it.");
     3115                    triangle = NULL;
     3116                  }
    30443117                } else {
    3045                   LOG(1, "INFO: Skipping " << *triangle << ", as we have already visited it.");
     3118                  ELOG(1, "I could not find " << *triangle << " in the touched list.");
    30463119                  triangle = NULL;
    30473120                }
    30483121              } else {
    3049                 ELOG(1, "I could not find " << *triangle << " in the touched list.");
     3122                // as we have stumbled upon the same triangle, we don't need the check anymore
    30503123                triangle = NULL;
    30513124              }
    30523125            }
     3126            if (triangle == NULL)
     3127              break;
     3128            // find next line
     3129            for (int i = 0; i < 3; i++) {
     3130              if ((triangle->lines[i] != CurrentLine) && (triangle->lines[i]->ContainsBoundaryPoint(ReferencePoint))) { // not the current line and still containing Point
     3131                CurrentLine = triangle->lines[i];
     3132                LOG(3, "INFO: Connecting line is " << *CurrentLine << ".");
     3133                break;
     3134              }
     3135            }
     3136            LineRunner = TouchedLine.find(CurrentLine);
     3137            if (LineRunner == TouchedLine.end())
     3138              ELOG(1, "I could not find " << *CurrentLine << " in the touched list.");
     3139            else
     3140              LineRunner->second = true;
     3141            // find next point
     3142            CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
     3143
     3144          } while (CurrentLine != StartLine);
     3145          // last point is missing, as it's on start line
     3146          if (StartLine->GetOtherEndpoint(ReferencePoint)->node != connectedPath->back()) {
     3147            LOG(3, "INFO: Putting " << *CurrentPoint << " at end of path to close it.");
     3148            connectedPath->push_back(StartLine->GetOtherEndpoint(ReferencePoint)->node);
    30533149          }
    3054           if (triangle == NULL)
    3055             break;
    3056           // find next line
    3057           for (int i = 0; i < 3; i++) {
    3058             if ((triangle->lines[i] != CurrentLine) && (triangle->lines[i]->ContainsBoundaryPoint(ReferencePoint))) { // not the current line and still containing Point
    3059               CurrentLine = triangle->lines[i];
    3060               LOG(1, "INFO: Connecting line is " << *CurrentLine << ".");
    3061               break;
    3062             }
    3063           }
    3064           LineRunner = TouchedLine.find(CurrentLine);
    3065           if (LineRunner == TouchedLine.end())
    3066             ELOG(1, "I could not find " << *CurrentLine << " in the touched list.");
    3067           else
    3068             LineRunner->second = true;
    3069           // find next point
    3070           CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
    3071 
    3072         } while (CurrentLine != StartLine);
    3073         // last point is missing, as it's on start line
    3074         LOG(1, "INFO: Putting " << *CurrentPoint << " at end of path.");
    3075         if (StartLine->GetOtherEndpoint(ReferencePoint)->node != connectedPath->back())
    3076           connectedPath->push_back(StartLine->GetOtherEndpoint(ReferencePoint)->node);
    3077 
    3078         ListOfPaths->push_back(connectedPath);
    3079       } else {
    3080         LOG(1, "INFO: Skipping " << *runner->second << ", as we have already visited it.");
    3081       }
     3150
     3151          ListOfPaths->push_back(connectedPath);
     3152        } else {
     3153          LOG(3, "DEBUG: Skipping " << *runner->second << ", as we have already visited it.");
     3154        }
    30823155    }
    30833156  } else {
     
    30983171  //Info FunctionInfo(__func__);
    30993172  list<TesselPointList *> *ListofPaths = GetPathsOfConnectedPoints(Point);
    3100   list<TesselPointList *> *ListofClosedPaths = new list<TesselPointList *> ;
     3173  list<TesselPointList *> *ListofClosedPaths = new list<TesselPointList *>;
    31013174  TesselPointList *connectedPath = NULL;
    31023175  TesselPointList *newPath = NULL;
     
    31083181    connectedPath = *ListRunner;
    31093182
    3110     LOG(1, "INFO: Current path is " << connectedPath << ".");
     3183    if (DoLog(2)) {
     3184      std::stringstream output;
     3185      output << "INFO: Current path is ";
     3186      BOOST_FOREACH(const TesselPoint * const item, *connectedPath) {
     3187        output << *item << " ";
     3188      }
     3189      LOG(1, output.str());
     3190    }
    31113191
    31123192    // go through list, look for reappearance of starting Point and count
     
    31173197      if ((*CircleRunner == *CircleStart) && (CircleRunner != CircleStart)) { // is not the very first point
    31183198        // we have a closed circle from Marker to new Marker
    3119         if (DoLog(1)) {
     3199        if (DoLog(3)) {
    31203200          std::stringstream output;
    3121           output << count + 1 << ". closed path consists of: ";
    3122           for (TesselPointList::iterator CircleSprinter = Marker;
    3123               CircleSprinter != CircleRunner;
    3124               CircleSprinter++)
     3201          output << "DEBUG: " << count + 1 << ". closed path consists of: ";
     3202          for (TesselPointList::iterator CircleSprinter = Marker; CircleSprinter != CircleRunner; CircleSprinter++)
    31253203            output << (**CircleSprinter) << " <-> ";
    31263204          LOG(1, output.str());
     
    31383216    }
    31393217  }
    3140   LOG(1, "INFO: " << count << " closed additional path(s) have been created.");
     3218  LOG(2, "DEBUG: " << count << " closed additional path(s) have been created.");
    31413219
    31423220  // delete list of paths
     
    31763254}
    31773255;
     3256
     3257struct CloserToPiHalf
     3258{
     3259  bool operator()(double angle, double smallestangle)
     3260  {
     3261    return (fabs(angle - M_PI / 2.) < fabs(smallestangle - M_PI / 2.));
     3262  }
     3263};
     3264
     3265bool Tesselation::IsPointBelowSurroundingPolygon(const BoundaryPointSet *_point) const
     3266{
     3267  // check for NULL
     3268  if (_point == NULL) {
     3269    return false;
     3270  }
     3271
     3272  // get list of connected points
     3273  if (_point->lines.empty()) {
     3274    LOG(1, "INFO: point " << *_point << " is not connected to any lines.");
     3275    return false;
     3276  }
     3277  bool PointIsBelow = true;
     3278
     3279  // create Orthogonal vector as reference for angle (pointing into [pi,2pi) interval)
     3280  Vector OrthogonalVector;
     3281  for (LineMap::const_iterator lineiter = _point->lines.begin();
     3282      lineiter != _point->lines.end(); ++lineiter)
     3283    for (TriangleMap::const_iterator triangleiter = lineiter->second->triangles.begin();
     3284        triangleiter != lineiter->second->triangles.end();
     3285        ++triangleiter)
     3286        OrthogonalVector += triangleiter->second->NormalVector;
     3287  OrthogonalVector.Normalize();
     3288
     3289  // go through all closed paths for this point
     3290  typedef list<TesselPointList *> TPL_list_t;
     3291  const TPL_list_t *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(_point->node);
     3292  for (TPL_list_t::const_iterator closedpathsiter = ListOfClosedPaths->begin();
     3293      (closedpathsiter != ListOfClosedPaths->end()) && PointIsBelow;
     3294      ++closedpathsiter) {
     3295    const TesselPointList *connectedPath = *closedpathsiter;
     3296
     3297    TesselPointList::const_iterator ListAdvance = connectedPath->begin(); // gives angle direction
     3298    TesselPointList::const_iterator ListRunner = ListAdvance++;
     3299    for (; (ListAdvance != connectedPath->end()) && PointIsBelow;
     3300        ListRunner = ListAdvance++) { // go through all closed paths
     3301      LOG(2, "DEBUG: Current reference node is " << **ListRunner
     3302          << ", advanced node is " << **ListAdvance);
     3303
     3304      // reference vector to point to check for this point of connected path
     3305      const Vector Reference =
     3306          ((*ListAdvance)->getPosition()) - ((*ListRunner)->getPosition());
     3307
     3308      // go through all other points in this connected path
     3309      for (TesselPointList::const_iterator OtherRunner = ListAdvance;
     3310          (OtherRunner != ListRunner) && PointIsBelow;
     3311          ++OtherRunner == connectedPath->end() ?
     3312              OtherRunner = connectedPath->begin() :
     3313              OtherRunner) {
     3314        if (OtherRunner == ListAdvance)
     3315          continue;
     3316        LOG(3, "DEBUG: Current other node is " << **OtherRunner);
     3317
     3318        // build the plane with normal vector
     3319        const Vector onebeam =
     3320            ((*OtherRunner)->getPosition()) - ((*ListAdvance)->getPosition());
     3321        Vector NormalVector = Reference;
     3322        NormalVector.VectorProduct(onebeam);
     3323        // needs to point in same general direction as average NormalVector of all triangles
     3324        if (NormalVector.ScalarProduct(OrthogonalVector) < 0)
     3325          NormalVector *= -1.;
     3326        try {
     3327          Plane plane(NormalVector, ((*ListRunner)->getPosition()));
     3328
     3329          // check whether point is below
     3330          if (plane.SignedDistance(_point->node->getPosition()) > 0) {
     3331            LOG(2, "DEBUG: For plane " << plane << " point " << *_point
     3332                << " would remain above.");
     3333            PointIsBelow = false;
     3334          }
     3335        } catch (ZeroVectorException &e) {
     3336          ELOG(3, "Vectors are linear dependent, skipping.");
     3337        }
     3338      }
     3339    }
     3340  }
     3341  delete ListOfClosedPaths;
     3342
     3343  return PointIsBelow;
     3344}
     3345
     3346double Tesselation::RemovePointSurroundedByPolygon(
     3347    TesselPointList *connectedPath,
     3348    BoundaryPointSet *point)
     3349{
     3350  double volume = 0.;
     3351  const Vector OldPoint = point->node->getPosition();
     3352
     3353  TesselPoint *oldNode = point->node;
     3354  // remove present triangles for this connectedPath
     3355  unsigned int count = 0;
     3356  for (TesselPointList::const_iterator iter = connectedPath->begin();
     3357      iter != connectedPath->end(); ++iter)
     3358    LOG(4, "DEBUG: Node in connectedPath is " << **iter);
     3359
     3360  {
     3361    TesselPointList::iterator FirstNode, SecondNode;
     3362    SecondNode = connectedPath->begin();
     3363    FirstNode = SecondNode++;
     3364    for (;FirstNode != connectedPath->end(); ++SecondNode, ++FirstNode) {
     3365      LOG(3, "DEBUG: MiddleNode is " << **FirstNode << ".");
     3366      if (SecondNode == connectedPath->end())
     3367        SecondNode = connectedPath->begin();
     3368      TesselPoint *TriangleCandidates[3];
     3369      TriangleCandidates[0] = *FirstNode;
     3370      TriangleCandidates[1] = *SecondNode;
     3371      TriangleCandidates[2] = oldNode;
     3372      BoundaryTriangleSet *triangle = GetPresentTriangle(TriangleCandidates);
     3373      ASSERT( triangle != NULL,
     3374          "Tesselation::RemovePointSurroundedByPolygon() - triangle to points "
     3375          +toString((**SecondNode))+", "+toString((**FirstNode))+" and "
     3376          +toString(*oldNode)+" does not exist.");
     3377      LOG(3, "DEBUG: Removing triangle " << *triangle << ".");
     3378      RemoveTesselationTriangle(triangle);
     3379      ++count;
     3380    }
     3381    LOG(2, "INFO: " << count << " triangles were removed.");
     3382  }
     3383
     3384  // re-create all triangles by going through connected points list
     3385  LineList NewLines;
     3386  typedef std::vector<double> angles_t;
     3387  angles_t angles;
     3388  count = 0;
     3389  for (; !connectedPath->empty();) {
     3390    // search middle node with widest angle to next neighbours
     3391    TesselPointList::iterator StartNode, MiddleNode, EndNode;
     3392    for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) {
     3393      LOG(3, "INFO: MiddleNode is " << **MiddleNode << ".");
     3394      // construct vectors to next and previous neighbour
     3395      StartNode = MiddleNode;
     3396      if (StartNode == connectedPath->begin())
     3397        StartNode = connectedPath->end();
     3398      StartNode--;
     3399      //LOG(3, "INFO: StartNode is " << **StartNode << ".");
     3400      const Vector Point = ((*StartNode)->getPosition()) - ((*MiddleNode)->getPosition());
     3401      EndNode = MiddleNode;
     3402      EndNode++;
     3403      if (EndNode == connectedPath->end())
     3404        EndNode = connectedPath->begin();
     3405      //LOG(3, "INFO: EndNode is " << **StartNode << ".");
     3406      const Vector Reference = ((*EndNode)->getPosition()) - ((*MiddleNode)->getPosition());
     3407      Vector OrthogonalVector = ((*MiddleNode)->getPosition()) - OldPoint;
     3408      OrthogonalVector.MakeNormalTo(Reference);
     3409      angles.push_back(GetAngle(Point, Reference, OrthogonalVector));
     3410    }
     3411    ASSERT( !angles.empty(),
     3412        "Tesselation::RemovePointSurroundedByPolygon() - angles empty");
     3413    const angles_t::const_iterator maxiter = std::max_element(angles.begin(), angles.end());
     3414    angles_t::const_iterator miniter = angles.begin();
     3415    // distinguish between convex and nonconvex polygon
     3416    if (*maxiter > M_PI) {
     3417      // connectedPath is not convex: The idea is to fill any kinks pointing
     3418      // inside into the connectedPath close to this concave spot first, making
     3419      // it eventually become convex.
     3420      // Hence, use adjacent (and convex) fill-in point
     3421      miniter = (maxiter == angles.begin()) ? angles.end()-1 : maxiter-1;
     3422      if (*miniter > M_PI) {
     3423        miniter = (maxiter+1 == angles.end()) ? angles.begin() : maxiter+1;
     3424        if (*miniter > M_PI) {
     3425          miniter = std::min_element(angles.begin(), angles.end());
     3426        }
     3427      }
     3428    } else {
     3429      // is convex
     3430      miniter = std::min_element(angles.begin(), angles.end(), CloserToPiHalf());
     3431    }
     3432    MiddleNode = connectedPath->begin();
     3433    std::advance(MiddleNode, std::distance(const_cast<const angles_t &>(angles).begin(), miniter));
     3434
     3435    ASSERT(MiddleNode != connectedPath->end(),
     3436        "Tesselation::RemovePointSurroundedByPolygon() - Could not find a smallest angle!");
     3437    angles.clear();
     3438    StartNode = MiddleNode;
     3439    EndNode = MiddleNode;
     3440    if (StartNode == connectedPath->begin())
     3441      StartNode = connectedPath->end();
     3442    StartNode--;
     3443    EndNode++;
     3444    if (EndNode == connectedPath->end())
     3445      EndNode = connectedPath->begin();
     3446    LOG(2, "INFO: StartNode is " << **StartNode << ".");
     3447    LOG(2, "INFO: MiddleNode is " << **MiddleNode << ".");
     3448    LOG(2, "INFO: EndNode is " << **EndNode << ".");
     3449    LOG(1, "INFO: Attempting to create triangle " << (*StartNode)->getName() << ", " << (*MiddleNode)->getName() << " and " << (*EndNode)->getName() << ".");
     3450    TesselPoint *TriangleCandidates[3];
     3451    TriangleCandidates[0] = *StartNode;
     3452    TriangleCandidates[1] = *MiddleNode;
     3453    TriangleCandidates[2] = *EndNode;
     3454    BoundaryTriangleSet *triangle = GetPresentTriangle(TriangleCandidates);
     3455    if (triangle != NULL) {
     3456      const Vector center = 1./3. * ((*StartNode)->getPosition()
     3457              + (*MiddleNode)->getPosition()
     3458              + (*EndNode)->getPosition());
     3459      const Vector NormalVector = OldPoint - center;
     3460      // check orientation of normal vector (that points inside)
     3461      ASSERT( triangle->NormalVector.ScalarProduct(NormalVector) > std::numeric_limits<double>::epsilon()*1e2,
     3462          "Tesselation::RemovePointSurroundedByPolygon() - New triangle with same orientation already present as "
     3463          +toString(*triangle)+"!");
     3464    }
     3465
     3466    LOG(3, "DEBUG: Adding new triangle points.");
     3467    AddTesselationPoint(*StartNode, 0);
     3468    AddTesselationPoint(*MiddleNode, 1);
     3469    AddTesselationPoint(*EndNode, 2);
     3470    LOG(3, "DEBUG: Adding new triangle lines.");
     3471    AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0);
     3472    // line between start and end must be new (except for very last triangle)
     3473    if (AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1))
     3474      NewLines.push_back(BLS[1]);
     3475    AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2);
     3476    BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     3477    const Vector center = 1./3. * ((*StartNode)->getPosition()
     3478            + (*MiddleNode)->getPosition()
     3479            + (*EndNode)->getPosition());
     3480    const Vector NormalVector = OldPoint - center;
     3481    BTS->GetNormalVector(NormalVector);
     3482    AddTesselationTriangle();
     3483    // calculate volume summand as a general tetraeder
     3484    volume += CalculateVolumeofGeneralTetraeder(
     3485        TPS[0]->node->getPosition(),
     3486        TPS[1]->node->getPosition(),
     3487        TPS[2]->node->getPosition(),
     3488        OldPoint);
     3489    // advance number
     3490    ++count;
     3491
     3492    // prepare nodes for next triangle
     3493    LOG(3, "DEBUG: Removing " << **MiddleNode << " from closed path.");
     3494    connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles)
     3495    LOG(3, "DEBUG: Remaining points: " << connectedPath->size() << ".");
     3496    ASSERT(connectedPath->size() >= 2,
     3497        "Tesselation::RemovePointSurroundedByPolygon() - There are only two endpoints left!");
     3498    if (connectedPath->size() == 2) { // we are done
     3499      connectedPath->remove(*StartNode); // remove the start node
     3500      connectedPath->remove(*EndNode); // remove the end node
     3501    }
     3502  }
     3503  LOG(1, "INFO: " << count << " triangles were created.");
     3504
     3505  return volume;
     3506}
    31783507
    31793508/** Removes a boundary point from the envelope while keeping it closed.
     
    31903519double Tesselation::RemovePointFromTesselatedSurface(class BoundaryPointSet *point)
    31913520{
    3192   class BoundaryLineSet *line = NULL;
    3193   class BoundaryTriangleSet *triangle = NULL;
    3194   Vector OldPoint, NormalVector;
    31953521  double volume = 0;
    3196   int count = 0;
    31973522
    31983523  if (point == NULL) {
     
    32023527    LOG(4, "DEBUG: Removing point " << *point << " from tesselated boundary ...");
    32033528
    3204   // copy old location for the volume
    3205   OldPoint = (point->node->getPosition());
    3206 
    32073529  // get list of connected points
    32083530  if (point->lines.empty()) {
     
    32123534
    32133535  list<TesselPointList *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(point->node);
    3214   TesselPointList *connectedPath = NULL;
    3215 
    3216   // gather all triangles
    3217   for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++)
    3218     count += LineRunner->second->triangles.size();
    3219   TriangleMap Candidates;
    3220   for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) {
    3221     line = LineRunner->second;
    3222     for (TriangleMap::iterator TriangleRunner = line->triangles.begin(); TriangleRunner != line->triangles.end(); TriangleRunner++) {
    3223       triangle = TriangleRunner->second;
    3224       Candidates.insert(TrianglePair(triangle->Nr, triangle));
    3225     }
    3226   }
    3227 
    3228   // remove all triangles
    3229   count = 0;
    3230   NormalVector.Zero();
    3231   for (TriangleMap::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) {
    3232     LOG(1, "INFO: Removing triangle " << *(Runner->second) << ".");
    3233     NormalVector -= Runner->second->NormalVector; // has to point inward
    3234     RemoveTesselationTriangle(Runner->second);
    3235     count++;
    3236   }
    3237   LOG(1, count << " triangles were removed.");
    3238 
     3536  list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin();
     3537  list<TesselPointList *>::iterator ListRunner = ListAdvance;
     3538//  TriangleMap::iterator NumberRunner = Candidates.begin();
     3539  Vector Point, Reference, OrthogonalVector;
     3540  for (; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths
     3541    if (ListAdvance != ListOfClosedPaths->end())
     3542      ListAdvance++;
     3543
     3544    TesselPointList *connectedPath = *ListRunner;
     3545
     3546    volume += RemovePointSurroundedByPolygon(connectedPath, point);
     3547
     3548    ListOfClosedPaths->remove(connectedPath);
     3549    delete (connectedPath);
     3550  }
     3551  delete (ListOfClosedPaths);
     3552
     3553  LOG(1, "INFO: Removed volume is " << volume << ".");
     3554
     3555  return volume;
     3556}
     3557;
     3558
     3559bool Tesselation::CheckAllConcaveInPolygon(
     3560    const TesselPointList *connectedPath,
     3561    const BoundaryPointSet *point
     3562    )
     3563{
     3564  // check whether lines in this path to point to remove are all concave
     3565  bool all_lines_concave = true;
     3566  if (connectedPath->size() >= 2) {
     3567    TesselPointList::const_iterator StartNode, MiddleNode, EndNode;
     3568    // have nearest neighbors to a middle node to know adjacent triangles
     3569    for (MiddleNode = connectedPath->begin();
     3570        all_lines_concave && (MiddleNode != connectedPath->end());
     3571        MiddleNode++) {
     3572      LOG(3, "INFO: MiddleNode is " << **MiddleNode << ".");
     3573      EndNode = MiddleNode;
     3574      if (EndNode == connectedPath->begin())
     3575        EndNode = connectedPath->end();
     3576      --EndNode;
     3577      StartNode = MiddleNode;
     3578      ++StartNode;
     3579      if (StartNode == connectedPath->end())
     3580        StartNode = connectedPath->begin();
     3581
     3582      AddTesselationPoint(point->node, 0);
     3583      AddTesselationPoint(*MiddleNode, 1);
     3584
     3585      ASSERT( point->lines.find((*MiddleNode)->getNr()) != point->lines.end(),
     3586          "Tesselation::CheckAllConcaveInPolygon() - MiddleNode "
     3587          +toString(**MiddleNode)+" not present in "
     3588          +toString(*point)+"'s lines.");
     3589
     3590      // get line between Node and point and check
     3591      std::pair<LineMap::const_iterator, LineMap::const_iterator> FindPair =
     3592          point->lines.equal_range((*MiddleNode)->getNr());
     3593      LineMap::const_iterator FindLine = FindPair.first;
     3594      for (; FindLine != FindPair.second; ++FindLine) {
     3595        // line  has got two triangles, check whether they resemble those
     3596        // with start and endnode
     3597        const BoundaryLineSet *currentline = FindLine->second;
     3598        unsigned int matching_triangles = 0;
     3599        for (TriangleMap::const_iterator triangleiter = currentline->triangles.begin();
     3600            triangleiter != currentline->triangles.end(); ++triangleiter) {
     3601          const BoundaryTriangleSet *triangle = triangleiter->second;
     3602          AddTesselationPoint(*StartNode, 2);
     3603          if (triangle->IsPresentTupel(TPS))
     3604            ++matching_triangles;
     3605          AddTesselationPoint(*EndNode, 2);
     3606          if (triangle->IsPresentTupel(TPS))
     3607            ++matching_triangles;
     3608        }
     3609        if (matching_triangles == 2)
     3610          break;
     3611      }
     3612      if (FindLine != FindPair.second) {
     3613        LOG(3, "INFO: Current line of point " << *point << " is " << *FindLine->second << ".");
     3614        all_lines_concave &= !FindLine->second->CheckConvexityCriterion();
     3615      }
     3616    }
     3617  } else {
     3618    // check the single line
     3619    if (connectedPath->empty())
     3620      return false;
     3621    LineMap::const_iterator FindLine = point->lines.find((*connectedPath->begin())->getNr());
     3622    ASSERT( FindLine != point->lines.end(),
     3623        "Tesselation::CheckAllConcaveInPolygon() - point "
     3624        +toString((*connectedPath->begin())->getNr())+" not present in "
     3625        +toString(*point)+"'s lines.");
     3626    return !FindLine->second->CheckConvexityCriterion();
     3627  }
     3628
     3629  return all_lines_concave;
     3630}
     3631
     3632/** Removes a boundary point from the envelope while keeping it closed.
     3633 * We remove the old triangles connected to the point and re-create new triangles to close the surface following this ansatz:
     3634 *  -# a closed path(s) of boundary points surrounding the point to be removed is constructed
     3635 *  -# on each closed path, we pick three adjacent points, create a triangle with them and subtract the middle point from the path
     3636 *  -# we advance two points (i.e. the next triangle will start at the ending point of the last triangle) and continue as before
     3637 *  -# the surface is closed, when the path is empty
     3638 * Thereby, we (hopefully) make sure that the removed points remains beneath the surface (this is checked via IsInnerPoint eventually).
     3639 * \param *out output stream for debugging
     3640 * \param *point point to be removed
     3641 * \return volume added to the volume inside the tesselated surface by the removal
     3642 */
     3643double Tesselation::RemoveFullConcavePointFromTesselatedSurface(class BoundaryPointSet *point)
     3644{
     3645  double volume = 0;
     3646
     3647  if (point == NULL) {
     3648    ELOG(1, "Cannot remove the point " << point << ", it's NULL!");
     3649    return 0.;
     3650  } else
     3651    LOG(4, "DEBUG: Removing point " << *point << " from tesselated boundary ...");
     3652
     3653  // get list of connected points
     3654  if (point->lines.empty()) {
     3655    ELOG(1, "Cannot remove the point " << *point << ", it's connected to no lines!");
     3656    return 0.;
     3657  }
     3658
     3659  list<TesselPointList *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(point->node);
    32393660  list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin();
    32403661  list<TesselPointList *>::iterator ListRunner = ListAdvance;
    32413662//  TriangleMap::iterator NumberRunner = Candidates.begin();
    32423663  TesselPointList::iterator StartNode, MiddleNode, EndNode;
    3243   double angle;
    3244   double smallestangle;
    32453664  Vector Point, Reference, OrthogonalVector;
    3246   if (count > 2) { // less than three triangles, then nothing will be created
    3247     class TesselPoint *TriangleCandidates[3];
    3248     count = 0;
    3249     for (; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths
    3250       if (ListAdvance != ListOfClosedPaths->end())
    3251         ListAdvance++;
    3252 
    3253       connectedPath = *ListRunner;
    3254       // re-create all triangles by going through connected points list
    3255       LineList NewLines;
    3256       for (; !connectedPath->empty();) {
    3257         // search middle node with widest angle to next neighbours
    3258         EndNode = connectedPath->end();
    3259         smallestangle = 0.;
    3260         for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) {
    3261           LOG(1, "INFO: MiddleNode is " << **MiddleNode << ".");
    3262           // construct vectors to next and previous neighbour
    3263           StartNode = MiddleNode;
    3264           if (StartNode == connectedPath->begin())
    3265             StartNode = connectedPath->end();
    3266           StartNode--;
    3267           //LOG(3, "INFO: StartNode is " << **StartNode << ".");
    3268           Point = ((*StartNode)->getPosition()) - ((*MiddleNode)->getPosition());
    3269           StartNode = MiddleNode;
    3270           StartNode++;
    3271           if (StartNode == connectedPath->end())
    3272             StartNode = connectedPath->begin();
    3273           //LOG(3, "INFO: EndNode is " << **StartNode << ".");
    3274           Reference = ((*StartNode)->getPosition()) - ((*MiddleNode)->getPosition());
    3275           OrthogonalVector = ((*MiddleNode)->getPosition()) - OldPoint;
    3276           OrthogonalVector.MakeNormalTo(Reference);
    3277           angle = GetAngle(Point, Reference, OrthogonalVector);
    3278           //if (angle < M_PI)  // no wrong-sided triangles, please?
    3279           if (fabs(angle - M_PI) < fabs(smallestangle - M_PI)) { // get straightest angle (i.e. construct those triangles with smallest area first)
    3280             smallestangle = angle;
    3281             EndNode = MiddleNode;
    3282           }
    3283         }
    3284         MiddleNode = EndNode;
    3285         if (MiddleNode == connectedPath->end()) {
    3286           ELOG(0, "CRITICAL: Could not find a smallest angle!");
    3287           performCriticalExit();
    3288         }
    3289         StartNode = MiddleNode;
    3290         if (StartNode == connectedPath->begin())
    3291           StartNode = connectedPath->end();
    3292         StartNode--;
    3293         EndNode++;
    3294         if (EndNode == connectedPath->end())
    3295           EndNode = connectedPath->begin();
    3296         LOG(2, "INFO: StartNode is " << **StartNode << ".");
    3297         LOG(2, "INFO: MiddleNode is " << **MiddleNode << ".");
    3298         LOG(2, "INFO: EndNode is " << **EndNode << ".");
    3299         LOG(1, "INFO: Attempting to create triangle " << (*StartNode)->getName() << ", " << (*MiddleNode)->getName() << " and " << (*EndNode)->getName() << ".");
    3300         TriangleCandidates[0] = *StartNode;
    3301         TriangleCandidates[1] = *MiddleNode;
    3302         TriangleCandidates[2] = *EndNode;
    3303         triangle = GetPresentTriangle(TriangleCandidates);
    3304         if (triangle != NULL) {
    3305           ELOG(0, "New triangle already present, skipping!");
    3306           StartNode++;
    3307           MiddleNode++;
    3308           EndNode++;
    3309           if (StartNode == connectedPath->end())
    3310             StartNode = connectedPath->begin();
    3311           if (MiddleNode == connectedPath->end())
    3312             MiddleNode = connectedPath->begin();
    3313           if (EndNode == connectedPath->end())
    3314             EndNode = connectedPath->begin();
    3315           continue;
    3316         }
    3317         LOG(3, "Adding new triangle points.");
    3318         AddTesselationPoint(*StartNode, 0);
    3319         AddTesselationPoint(*MiddleNode, 1);
    3320         AddTesselationPoint(*EndNode, 2);
    3321         LOG(3, "Adding new triangle lines.");
    3322         AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0);
    3323         AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1);
    3324         NewLines.push_back(BLS[1]);
    3325         AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2);
    3326         BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    3327         BTS->GetNormalVector(NormalVector);
    3328         AddTesselationTriangle();
    3329         // calculate volume summand as a general tetraeder
    3330         volume += CalculateVolumeofGeneralTetraeder(TPS[0]->node->getPosition(), TPS[1]->node->getPosition(), TPS[2]->node->getPosition(), OldPoint);
    3331         // advance number
    3332         count++;
    3333 
    3334         // prepare nodes for next triangle
    3335         StartNode = EndNode;
    3336         LOG(2, "Removing " << **MiddleNode << " from closed path, remaining points: " << connectedPath->size() << ".");
    3337         connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles)
    3338         if (connectedPath->size() == 2) { // we are done
    3339           connectedPath->remove(*StartNode); // remove the start node
    3340           connectedPath->remove(*EndNode); // remove the end node
    3341           break;
    3342         } else if (connectedPath->size() < 2) { // something's gone wrong!
    3343           ELOG(0, "CRITICAL: There are only two endpoints left!");
    3344           performCriticalExit();
    3345         } else {
    3346           MiddleNode = StartNode;
    3347           MiddleNode++;
    3348           if (MiddleNode == connectedPath->end())
    3349             MiddleNode = connectedPath->begin();
    3350           EndNode = MiddleNode;
    3351           EndNode++;
    3352           if (EndNode == connectedPath->end())
    3353             EndNode = connectedPath->begin();
    3354         }
    3355       }
    3356       // maximize the inner lines (we preferentially created lines with a huge angle, which is for the tesselation not wanted though useful for the closing)
    3357       if (NewLines.size() > 1) {
    3358         LineList::iterator Candidate;
    3359         class BoundaryLineSet *OtherBase = NULL;
    3360         double tmp, maxgain;
    3361         do {
    3362           maxgain = 0;
    3363           for (LineList::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) {
    3364             tmp = PickFarthestofTwoBaselines(*Runner);
    3365             if (maxgain < tmp) {
    3366               maxgain = tmp;
    3367               Candidate = Runner;
    3368             }
    3369           }
    3370           if (maxgain != 0) {
    3371             volume += maxgain;
    3372             LOG(1, "Flipping baseline with highest volume" << **Candidate << ".");
    3373             OtherBase = FlipBaseline(*Candidate);
    3374             NewLines.erase(Candidate);
    3375             NewLines.push_back(OtherBase);
    3376           }
    3377         } while (maxgain != 0.);
    3378       }
    3379 
    3380       ListOfClosedPaths->remove(connectedPath);
    3381       delete (connectedPath);
    3382     }
    3383     LOG(1, "INFO: " << count << " triangles were created.");
    3384   } else {
    3385     while (!ListOfClosedPaths->empty()) {
    3386       ListRunner = ListOfClosedPaths->begin();
    3387       connectedPath = *ListRunner;
    3388       ListOfClosedPaths->remove(connectedPath);
    3389       delete (connectedPath);
    3390     }
    3391     LOG(3, "DEBUG: No need to create any triangles.");
     3665  for (; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths
     3666    if (ListAdvance != ListOfClosedPaths->end())
     3667      ListAdvance++;
     3668
     3669    TesselPointList *connectedPath = *ListRunner;
     3670
     3671    if (CheckAllConcaveInPolygon(connectedPath, point)) {
     3672      LOG(1, "INFO: ... point " << *point << " cannot be on convex envelope, all lines concave.");
     3673      volume += RemovePointSurroundedByPolygon(connectedPath, point);
     3674    }
     3675
     3676    ListOfClosedPaths->remove(connectedPath);
     3677    delete (connectedPath);
    33923678  }
    33933679  delete (ListOfClosedPaths);
    33943680
    3395   LOG(1, "INFO: Removed volume is " << volume << ".");
     3681  if (volume > 0.)
     3682    LOG(1, "INFO: Removed volume is " << volume << ".");
    33963683
    33973684  return volume;
     
    34373724            if (TrianglePoints[j] != NULL) {
    34383725              for (FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->getNr()); // is a multimap!
    3439               (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->getNr()); FindLine++) {
     3726                  (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->getNr()); FindLine++) {
    34403727                for (FindTriangle = FindLine->second->triangles.begin(); FindTriangle != FindLine->second->triangles.end(); FindTriangle++) {
    34413728                  if (FindTriangle->second->IsPresentTupel(TrianglePoints)) {
     
    34583745          break;
    34593746      for (FindLine = TrianglePoints[(i + 1) % 3]->lines.find(TrianglePoints[(i + 2) % 3]->node->getNr()); // is a multimap!
    3460       (FindLine != TrianglePoints[(i + 1) % 3]->lines.end()) && (FindLine->first == TrianglePoints[(i + 2) % 3]->node->getNr()); FindLine++) {
     3747          (FindLine != TrianglePoints[(i + 1) % 3]->lines.end()) && (FindLine->first == TrianglePoints[(i + 2) % 3]->node->getNr()); FindLine++) {
    34613748        for (FindTriangle = FindLine->second->triangles.begin(); FindTriangle != FindLine->second->triangles.end(); FindTriangle++) {
    34623749          if (FindTriangle->second->IsPresentTupel(TrianglePoints)) {
     
    34873774    }
    34883775    default:
    3489       ELOG(0, "Number of wildcards is greater than 3, cannot happen!");
    3490       performCriticalExit();
     3776      ASSERT(0, "Tesselation::FindTriangles() - Number of wildcards is greater than 3, cannot happen!");
    34913777      break;
    34923778  }
     
    35143800    if (a->endpoints[lowerNra] < b->endpoints[lowerNrb])
    35153801      return true;
    3516     else if (a->endpoints[lowerNra] > b->endpoints[lowerNrb])
    3517       return false;
    3518     else { // both lower-numbered endpoints are the same ...
    3519       if (a->endpoints[(lowerNra + 1) % 2] < b->endpoints[(lowerNrb + 1) % 2])
    3520         return true;
    3521       else if (a->endpoints[(lowerNra + 1) % 2] > b->endpoints[(lowerNrb + 1) % 2])
     3802    else
     3803      if (a->endpoints[lowerNra] > b->endpoints[lowerNrb])
    35223804        return false;
    3523     }
     3805      else { // both lower-numbered endpoints are the same ...
     3806        if (a->endpoints[(lowerNra + 1) % 2] < b->endpoints[(lowerNrb + 1) % 2])
     3807          return true;
     3808        else
     3809          if (a->endpoints[(lowerNra + 1) % 2] > b->endpoints[(lowerNrb + 1) % 2])
     3810            return false;
     3811      }
    35243812    return false;
    35253813  }
     
    35423830
    35433831  // sanity check
    3544   if (LinesOnBoundary.empty()) {
    3545     ELOG(2, "FindAllDegeneratedTriangles() was called without any tesselation structure.");
    3546     return DegeneratedLines;
    3547   }
    3548   LineMap::iterator LineRunner1;
    3549   pair<UniqueLines::iterator, bool> tester;
     3832      if (LinesOnBoundary.empty()) {
     3833        ELOG(2, "FindAllDegeneratedTriangles() was called without any tesselation structure.");
     3834        return DegeneratedLines;
     3835      }
     3836      LineMap::iterator LineRunner1;
     3837      pair<UniqueLines::iterator, bool> tester;
    35503838  for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) {
    35513839    tester = AllLines.insert(LineRunner1->second);
     
    35643852    const LineMap::const_iterator Line2 = LinesOnBoundary.find((*it).second);
    35653853    if (Line1 != LinesOnBoundary.end() && Line2 != LinesOnBoundary.end())
    3566       LOG(3, "DEBUG: " << *Line1->second << " => " << *Line2->second);
     3854    LOG(3, "DEBUG: " << *Line1->second << " => " << *Line2->second);
    35673855    else
    3568       ELOG(1, "Either " << (*it).first << " or " << (*it).second << " are not in LinesOnBoundary!");
     3856    ELOG(1, "Either " << (*it).first << " or " << (*it).second << " are not in LinesOnBoundary!");
    35693857  }
    35703858
     
    35983886      for (TriangleRunner2 = line2->triangles.begin(); TriangleRunner2 != line2->triangles.end(); ++TriangleRunner2) {
    35993887        if ((TriangleRunner1->second != TriangleRunner2->second) && (TriangleRunner1->second->IsPresentTupel(TriangleRunner2->second))) {
    3600           DegeneratedTriangles->insert(pair<int, int> (TriangleRunner1->second->Nr, TriangleRunner2->second->Nr));
    3601           DegeneratedTriangles->insert(pair<int, int> (TriangleRunner2->second->Nr, TriangleRunner1->second->Nr));
     3888          DegeneratedTriangles->insert(pair<int, int>(TriangleRunner1->second->Nr, TriangleRunner2->second->Nr));
     3889          DegeneratedTriangles->insert(pair<int, int>(TriangleRunner2->second->Nr, TriangleRunner1->second->Nr));
    36023890        }
    36033891      }
     
    36263914
    36273915  // iterate over all degenerated triangles
    3628   for (IndexToIndex::iterator TriangleKeyRunner = DegeneratedTriangles->begin(); !DegeneratedTriangles->empty(); TriangleKeyRunner = DegeneratedTriangles->begin()) {
     3916  for (IndexToIndex::iterator TriangleKeyRunner = DegeneratedTriangles->begin();
     3917      !DegeneratedTriangles->empty();
     3918      TriangleKeyRunner = DegeneratedTriangles->begin()) {
    36293919    LOG(3, "DEBUG: Checking presence of triangles " << TriangleKeyRunner->first << " and " << TriangleKeyRunner->second << ".");
    36303920    // both ways are stored in the map, only use one
     
    36673957//                OtherpartnerTriangle = TriangleRunner->second;
    36683958//              }
    3669             /// interchanges their lines so that triangle->lines[i] == partnerTriangle->lines[j]
    3670             // the line of triangle receives the degenerated ones
    3671             triangle->lines[i]->triangles.erase(Othertriangle->Nr);
     3959              /// interchanges their lines so that triangle->lines[i] == partnerTriangle->lines[j]
     3960              // the line of triangle receives the degenerated ones
     3961              triangle->lines[i]->triangles.erase(Othertriangle->Nr);
    36723962            triangle->lines[i]->triangles.insert(TrianglePair(partnerTriangle->Nr, partnerTriangle));
    36733963            for (int k = 0; k < 3; k++)
     
    36833973
    36843974      // erase the pair
    3685       count += (int) DegeneratedTriangles->erase(triangle->Nr);
     3975      count += (int)DegeneratedTriangles->erase(triangle->Nr);
    36863976      LOG(4, "DEBUG: RemoveDegeneratedTriangles() removes triangle " << *triangle << ".");
    36873977      RemoveTesselationTriangle(triangle);
    3688       count += (int) DegeneratedTriangles->erase(partnerTriangle->Nr);
     3978      count += (int)DegeneratedTriangles->erase(partnerTriangle->Nr);
    36893979      LOG(4, "DEBUG: RemoveDegeneratedTriangles() removes triangle " << *partnerTriangle << ".");
    36903980      RemoveTesselationTriangle(partnerTriangle);
    36913981    } else {
    36923982      LOG(4, "DEBUG: RemoveDegeneratedTriangles() does not remove triangle " << *triangle << " and its partner " << *partnerTriangle << " because it is essential for at" << " least one of the endpoints to be kept in the tesselation structure.");
     3983      // we need to remove them from the list nonetheless
     3984      DegeneratedTriangles->erase(triangle->Nr);
     3985      DegeneratedTriangles->erase(partnerTriangle->Nr);
    36933986    }
    36943987  }
     
    37344027  class BoundaryLineSet *BestLine = NULL;
    37354028  for (LineMap::iterator Runner = NearestBoundaryPoint->lines.begin(); Runner != NearestBoundaryPoint->lines.end(); Runner++) {
    3736     BaseLine = (Runner->second->endpoints[0]->node->getPosition()) -
    3737                (Runner->second->endpoints[1]->node->getPosition());
    3738     CenterToPoint = 0.5 * ((Runner->second->endpoints[0]->node->getPosition()) +
    3739                            (Runner->second->endpoints[1]->node->getPosition()));
     4029    BaseLine = (Runner->second->endpoints[0]->node->getPosition()) - (Runner->second->endpoints[1]->node->getPosition());
     4030    CenterToPoint = 0.5 * ((Runner->second->endpoints[0]->node->getPosition()) + (Runner->second->endpoints[1]->node->getPosition()));
    37404031    CenterToPoint -= (point->getPosition());
    37414032    angle = CenterToPoint.Angle(BaseLine);
    3742     if (fabs(angle - M_PI/2.) < fabs(BestAngle - M_PI/2.)) {
     4033    if (fabs(angle - M_PI / 2.) < fabs(BestAngle - M_PI / 2.)) {
    37434034      BestAngle = angle;
    37444035      BestLine = Runner->second;
     
    37894080  for (int i = 0; i < 3; i++) { // look for the same line as BestLine (only it's its degenerated companion)
    37904081    if ((BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[0])) && (BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[1]))) {
    3791       if (BestLine == BTS->lines[i]) {
    3792         ELOG(0, "BestLine is same as found line, something's wrong here!");
    3793         performCriticalExit();
    3794       }
    3795       BTS->lines[i]->triangles.insert(pair<int, class BoundaryTriangleSet *> (TempTriangle->Nr, TempTriangle));
     4082      ASSERT(BestLine != BTS->lines[i], std::string("Tesselation::AddBoundaryPointByDegeneratedTriangle() - ") + std::string("BestLine is same as found line, something's wrong here!"));
     4083      BTS->lines[i]->triangles.insert(pair<int, class BoundaryTriangleSet *>(TempTriangle->Nr, TempTriangle));
    37964084      TempTriangle->lines[nr] = BTS->lines[i];
    37974085      break;
     
    38154103  if (LastTriangle != NULL) {
    38164104    stringstream sstr;
    3817     sstr << "-"<< TrianglesOnBoundary.size() << "-" << LastTriangle->getEndpointName(0) << "_" << LastTriangle->getEndpointName(1) << "_" << LastTriangle->getEndpointName(2);
     4105    sstr << "-" << TrianglesOnBoundary.size() << "-" << LastTriangle->getEndpointName(0) << "_" << LastTriangle->getEndpointName(1) << "_" << LastTriangle->getEndpointName(2);
    38184106    NumberName = sstr.str();
    38194107    if (DoTecplotOutput) {
     
    38574145    if (s1->endpoints.size() < s2->endpoints.size())
    38584146      return true;
    3859     else if (s1->endpoints.size() > s2->endpoints.size())
    3860       return false;
    3861     else { // equality of number of endpoints
    3862       PointSet::const_iterator Walker1 = s1->endpoints.begin();
    3863       PointSet::const_iterator Walker2 = s2->endpoints.begin();
    3864       while ((Walker1 != s1->endpoints.end()) || (Walker2 != s2->endpoints.end())) {
    3865         if ((*Walker1)->Nr < (*Walker2)->Nr)
    3866           return true;
    3867         else if ((*Walker1)->Nr > (*Walker2)->Nr)
    3868           return false;
    3869         Walker1++;
    3870         Walker2++;
     4147    else
     4148      if (s1->endpoints.size() > s2->endpoints.size())
     4149        return false;
     4150      else { // equality of number of endpoints
     4151        PointSet::const_iterator Walker1 = s1->endpoints.begin();
     4152        PointSet::const_iterator Walker2 = s2->endpoints.begin();
     4153        while ((Walker1 != s1->endpoints.end()) || (Walker2 != s2->endpoints.end())) {
     4154          if ((*Walker1)->Nr < (*Walker2)->Nr)
     4155            return true;
     4156          else
     4157            if ((*Walker1)->Nr > (*Walker2)->Nr)
     4158              return false;
     4159          Walker1++;
     4160          Walker2++;
     4161        }
     4162        return false;
    38714163      }
    3872       return false;
    3873     }
    38744164  }
    38754165};
     
    38964186      for (TriangleMap::const_iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) {
    38974187        if (DegeneratedTriangles->find(TriangleRunner->second->Nr) == DegeneratedTriangles->end()) {
    3898           TriangleInsertionTester = TriangleVectors.insert(pair<int, Vector *> ((TriangleRunner->second)->Nr, &((TriangleRunner->second)->NormalVector)));
     4188          TriangleInsertionTester = TriangleVectors.insert(pair<int, Vector *>((TriangleRunner->second)->Nr, &((TriangleRunner->second)->NormalVector)));
    38994189          if (TriangleInsertionTester.second)
    39004190            LOG(5, "DEBUG:  Adding triangle " << *(TriangleRunner->second) << " to triangles to check-list.");
     
    39094199        if (VectorWalker != VectorRunner) { // skip equals
    39104200          const double SCP = VectorWalker->second->ScalarProduct(*VectorRunner->second); // ScalarProduct should result in -1. for degenerated triangles
    3911           LOG(4, "DEBUG: Checking " << *VectorWalker->second << " against " << *VectorRunner->second << ": " << SCP);
     4201          LOG(4, "DEBUG: Checking " << *(VectorWalker->second) << " against " << *(VectorRunner->second) << ": " << SCP);
    39124202          if (fabs(SCP + 1.) < ParallelEpsilon) {
    39134203            InsertionTester = EndpointCandidateList.insert((Runner->second));
     
    39914281    // The Problem is probably due to two degenerated polygons being connected by a bridging, non-degenerated polygon, as somehow one node has
    39924282    // connections to either polygon ...
    3993     if (T->size() % 2 != 0) {
    3994       ELOG(0, " degenerated polygon contains an odd number of triangles, probably contains bridging non-degenerated ones, too!");
    3995       performCriticalExit();
    3996     }
     4283    ASSERT(T->size() % 2 == 0, std::string("Tesselation::CorrectAllDegeneratedPolygons() - ") + std::string(" degenerated polygon contains an odd number of triangles,") + std::string(" probably contains bridging non-degenerated ones, too!"));
    39974284    TriangleSet::iterator TriangleWalker = T->begin(); // is the inner iterator
    39984285    /// 4a. Get NormalVector for one side (this is "front")
Note: See TracChangeset for help on using the changeset viewer.