Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/tesselation.cpp

    r29812d r7dea7c  
    66 */
    77
     8#include "helpers.hpp"
     9#include "linkedcell.hpp"
    810#include "tesselation.hpp"
    9 #include "memoryallocator.hpp"
     11#include "tesselationhelpers.hpp"
     12#include "vector.hpp"
     13
     14class molecule;
    1015
    1116// ======================================== Points on Boundary =================================
     
    3742BoundaryPointSet::~BoundaryPointSet()
    3843{
    39   cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl;
     44  //cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl;
    4045  if (!lines.empty())
    4146    cerr << "WARNING: Memory Leak! I " << *this << " am still connected to some lines." << endl;
     
    6772ostream & operator <<(ostream &ost, BoundaryPointSet &a)
    6873{
    69   ost << "[" << a.Nr << "|" << a.node->Name << "]";
     74  ost << "[" << a.Nr << "|" << a.node->Name << " at " << *a.node->node << "]";
    7075  return ost;
    7176}
     
    125130        for (LineMap::iterator Runner = erasor.first; Runner != erasor.second; Runner++)
    126131          if ((*Runner).second == this) {
    127             cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
     132            //cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
    128133            endpoints[i]->lines.erase(Runner);
    129134            break;
    130135          }
    131136      } else { // there's just a single line left
    132         if (endpoints[i]->lines.erase(Nr))
    133           cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
     137        if (endpoints[i]->lines.erase(Nr)) {
     138          //cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
     139        }
    134140      }
    135141      if (endpoints[i]->lines.empty()) {
    136         cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;
     142        //cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;
    137143        if (endpoints[i] != NULL) {
    138144          delete(endpoints[i]);
     
    168174
    169175/** Checks whether the adjacent triangles of a baseline are convex or not.
    170  * We sum the two angles of each normal vector with a ficticious normnal vector from this baselinbe pointing outwards.
     176 * We sum the two angles of each height vector with respect to the center of the baseline.
    171177 * If greater/equal M_PI than we are convex.
    172178 * \param *out output stream for debugging
     
    178184  // get the two triangles
    179185  if (triangles.size() != 2) {
    180     *out << Verbose(1) << "ERROR: Baseline " << *this << " is connect to less than two triangles, Tesselation incomplete!" << endl;
     186    *out << Verbose(1) << "ERROR: Baseline " << *this << " is connected to less than two triangles, Tesselation incomplete!" << endl;
    181187    return true;
    182188  }
     
    201207    NormalCheck.Scale(sign);
    202208    sign = -sign;
    203     BaseLineNormal.SubtractVector(&runner->second->NormalVector);   // we subtract as BaseLineNormal has to point inward in direction of [pi,2pi]
     209    if (runner->second->NormalVector.NormSquared() > MYEPSILON)
     210      BaseLineNormal.CopyVector(&runner->second->NormalVector);   // yes, copy second on top of first
     211    else {
     212      *out << Verbose(1) << "CRITICAL: Triangle " << *runner->second << " has zero normal vector!" << endl;
     213      exit(255);
     214    }
    204215    node = runner->second->GetThirdEndpoint(this);
    205216    if (node != NULL) {
     
    211222      i++;
    212223    } else {
    213       //*out << Verbose(2) << "WARNING: I cannot find third node in triangle, something's wrong." << endl;
     224      //*out << Verbose(2) << "ERROR: I cannot find third node in triangle, something's wrong." << endl;
    214225      return true;
    215226    }
     
    217228  //*out << Verbose(3) << "INFO: BaselineNormal is " << BaseLineNormal << "." << endl;
    218229  if (NormalCheck.NormSquared() < MYEPSILON) {
    219     *out << Verbose(2) << "ACCEPT: Normalvectors of both triangles are the same: convex." << endl;
     230    *out << Verbose(3) << "ACCEPT: Normalvectors of both triangles are the same: convex." << endl;
    220231    return true;
    221232  }
     233  BaseLineNormal.Scale(-1.);
    222234  double angle = GetAngle(helper[0], helper[1], BaseLineNormal);
    223235  if ((angle - M_PI) > -MYEPSILON) {
    224     *out << Verbose(2) << "ACCEPT: Angle is greater than pi: convex." << endl;
     236    *out << Verbose(3) << "ACCEPT: Angle is greater than pi: convex." << endl;
    225237    return true;
    226238  } else {
    227     *out << Verbose(2) << "REJECT: Angle is less than pi: concave." << endl;
     239    *out << Verbose(3) << "REJECT: Angle is less than pi: concave." << endl;
    228240    return false;
    229241  }
     
    262274ostream & operator <<(ostream &ost, BoundaryLineSet &a)
    263275{
    264   ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," << a.endpoints[1]->node->Name << "]";
     276  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << "," << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "]";
    265277  return ost;
    266278};
     
    332344  for (int i = 0; i < 3; i++) {
    333345    if (lines[i] != NULL) {
    334       if (lines[i]->triangles.erase(Nr))
    335         cout << Verbose(5) << "Triangle Nr." << Nr << " erased in line " << *lines[i] << "." << endl;
     346      if (lines[i]->triangles.erase(Nr)) {
     347        //cout << Verbose(5) << "Triangle Nr." << Nr << " erased in line " << *lines[i] << "." << endl;
     348      }
    336349      if (lines[i]->triangles.empty()) {
    337           cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;
     350          //cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;
    338351          delete (lines[i]);
    339352          lines[i] = NULL;
     
    341354    }
    342355  }
    343   cout << Verbose(5) << "Erasing triangle Nr." << Nr << " itself." << endl;
     356  //cout << Verbose(5) << "Erasing triangle Nr." << Nr << " itself." << endl;
    344357};
    345358
     
    361374 * We call Vector::GetIntersectionWithPlane() to receive the intersection point with the plane
    362375 * This we test if it's really on the plane and whether it's inside the triangle on the plane or not.
    363  * The latter is done as follows: if it's really outside, then for any endpoint of the triangle and it's opposite
    364  * base line, the intersection between the line from endpoint to intersection and the base line will have a Vector::NormSquared()
    365  * smaller than the first line.
     376 * The latter is done as follows: We calculate the cross point of one of the triangle's baseline with the line
     377 * given by the intersection and the third basepoint. Then, we check whether it's on the baseline (i.e. between
     378 * the first two basepoints) or not.
    366379 * \param *out output stream for debugging
    367380 * \param *MolCenter offset vector of line
     
    395408    exit(255);
    396409  }
    397   CrossPoint.SubtractVector(endpoints[i%3]->node->node);
     410  CrossPoint.SubtractVector(endpoints[i%3]->node->node);  // cross point was returned as absolute vector
    398411
    399412  // check whether intersection is inside or not by comparing length of intersection and length of cross point
    400   if ((CrossPoint.NormSquared() - helper.NormSquared()) > -MYEPSILON) { // inside
     413  if ((CrossPoint.NormSquared() - helper.NormSquared()) < MYEPSILON) { // inside
    401414    return true;
    402415  } else { // outside!
     
    426439  for(int i=0;i<3;i++)
    427440    if (point == endpoints[i])
     441      return true;
     442  return false;
     443};
     444
     445/** Checks whether point is any of the three endpoints this triangle contains.
     446 * \param *point TesselPoint to test
     447 * \return true - point is of the triangle, false - is not
     448 */
     449bool BoundaryTriangleSet::ContainsBoundaryPoint(class TesselPoint *point)
     450{
     451  for(int i=0;i<3;i++)
     452    if (point == endpoints[i]->node)
    428453      return true;
    429454  return false;
     
    451476};
    452477
     478/** Checks whether three given \a *Points coincide with triangle's endpoints.
     479 * \param *Points[3] pointer to BoundaryPointSet
     480 * \return true - is the very triangle, false - is not
     481 */
     482bool BoundaryTriangleSet::IsPresentTupel(class BoundaryTriangleSet *T)
     483{
     484  return (((endpoints[0] == T->endpoints[0])
     485            || (endpoints[0] == T->endpoints[1])
     486            || (endpoints[0] == T->endpoints[2])
     487          ) && (
     488            (endpoints[1] == T->endpoints[0])
     489            || (endpoints[1] == T->endpoints[1])
     490            || (endpoints[1] == T->endpoints[2])
     491          ) && (
     492            (endpoints[2] == T->endpoints[0])
     493            || (endpoints[2] == T->endpoints[1])
     494            || (endpoints[2] == T->endpoints[2])
     495
     496          ));
     497};
     498
    453499/** Returns the endpoint which is not contained in the given \a *line.
    454500 * \param *line baseline defining two endpoints
     
    485531ostream &operator <<(ostream &ost, BoundaryTriangleSet &a)
    486532{
    487   ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << ","
    488       << a.endpoints[1]->node->Name << "," << a.endpoints[2]->node->Name << "]";
     533  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << ","
     534      << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "," << a.endpoints[2]->node->Name << " at " << *a.endpoints[2]->node->node << "]";
    489535  return ost;
    490536};
     
    505551TesselPoint::~TesselPoint()
    506552{
    507   Free(&Name);
    508553};
    509554
     
    512557ostream & operator << (ostream &ost, const TesselPoint &a)
    513558{
    514   ost << "[" << (a.Name) << "|" << &a << "]";
     559  ost << "[" << (a.Name) << "|" << a.Name << " at " << *a.node << "]";
    515560  return ost;
    516561};
     
    569614  TrianglesOnBoundaryCount = 0;
    570615  InternalPointer = PointsOnBoundary.begin();
     616  LastTriangle = NULL;
     617  TriangleFilesWritten = 0;
    571618}
    572619;
     
    585632      cerr << "ERROR: The triangle " << runner->first << " has already been free'd." << endl;
    586633  }
     634  cout << "This envelope was written to file " << TriangleFilesWritten << " times(s)." << endl;
    587635}
    588636;
     
    10521100  Vector *Center = cloud->GetCenter(out);
    10531101  list<BoundaryTriangleSet*> *triangles = NULL;
     1102  bool AddFlag = false;
     1103  LinkedCell *BoundaryPoints = NULL;
    10541104
    10551105  *out << Verbose(1) << "Begin of InsertStraddlingPoints" << endl;
    10561106
    10571107  cloud->GoToFirst();
     1108  BoundaryPoints = new LinkedCell(this, 5.);
    10581109  while (!cloud->IsEnd()) {  // we only have to go once through all points, as boundary can become only bigger
    1059     LinkedCell BoundaryPoints(this, 5.);
     1110    if (AddFlag) {
     1111      delete(BoundaryPoints);
     1112      BoundaryPoints = new LinkedCell(this, 5.);
     1113      AddFlag = false;
     1114    }
    10601115    Walker = cloud->GetPoint();
    10611116    *out << Verbose(2) << "Current point is " << *Walker << "." << endl;
    10621117    // get the next triangle
    1063     triangles = FindClosestTrianglesToPoint(out, Walker->node, &BoundaryPoints);
    1064     if (triangles == NULL) {
    1065       *out << Verbose(1) << "No triangles found, probably a tesselation point itself." << endl;
     1118    triangles = FindClosestTrianglesToPoint(out, Walker->node, BoundaryPoints);
     1119    BTS = triangles->front();
     1120    if ((triangles == NULL) || (BTS->ContainsBoundaryPoint(Walker))) {
     1121      *out << Verbose(2) << "No triangles found, probably a tesselation point itself." << endl;
    10661122      cloud->GoToNext();
    10671123      continue;
    10681124    } else {
    1069       BTS = triangles->front();
    10701125    }
    10711126    *out << Verbose(2) << "Closest triangle is " << *BTS << "." << endl;
     
    10901145        // add Walker to boundary points
    10911146        *out << Verbose(2) << "Adding " << *Walker << " to BoundaryPoints." << endl;
     1147        AddFlag = true;
    10921148        if (AddBoundaryPoint(Walker,0))
    10931149          NewPoint = BPS[0];
     
    11801236  } else {
    11811237    delete TPS[n];
    1182     cout << Verbose(3) << "Node " << *((InsertUnique.first)->second->node) << " is already present in PointsOnBoundary." << endl;
     1238    cout << Verbose(4) << "Node " << *((InsertUnique.first)->second->node) << " is already present in PointsOnBoundary." << endl;
    11831239    TPS[n] = (InsertUnique.first)->second;
    11841240  }
     
    11971253
    11981254  if (a->lines.find(b->node->nr) != a->lines.end()) {
    1199     LineMap::iterator FindLine;
     1255    LineMap::iterator FindLine = a->lines.find(b->node->nr);
    12001256    pair<LineMap::iterator,LineMap::iterator> FindPair;
    12011257    FindPair = a->lines.equal_range(b->node->nr);
    1202 
    1203     for (FindLine = FindPair.first; FindLine != FindPair.second; ++FindLine) {
     1258    cout << Verbose(5) << "INFO: There is at least one line between " << *a << " and " << *b << ": " << *(FindLine->second) << "." << endl;
     1259
     1260    for (FindLine = FindPair.first; FindLine != FindPair.second; FindLine++) {
    12041261      // If there is a line with less than two attached triangles, we don't need a new line.
    12051262      if (FindLine->second->triangles.size() < 2) {
    12061263        insertNewLine = false;
    1207         cout << Verbose(3) << "Using existing line " << *FindLine->second << endl;
     1264        cout << Verbose(4) << "Using existing line " << *FindLine->second << endl;
    12081265
    12091266        BPS[0] = FindLine->second->endpoints[0];
     
    12321289void Tesselation::AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n)
    12331290{
    1234   cout << Verbose(3) << "Adding line between " << *(a->node) << " and " << *(b->node) << "." << endl;
     1291  cout << Verbose(4) << "Adding line [" << LinesOnBoundaryCount << "|" << *(a->node) << " and " << *(b->node) << "." << endl;
    12351292  BPS[0] = a;
    12361293  BPS[1] = b;
     
    12421299};
    12431300
    1244 /** Function tries to add Triangle just created to Triangle and remarks if already existent (Failure of algorithm).
    1245  * Furthermore it adds the triangle to all of its lines, in order to recognize those which are saturated later.
     1301/** Function adds triangle to global list.
     1302 * Furthermore, the triangle receives the next free id and id counter \a TrianglesOnBoundaryCount is increased.
    12461303 */
    12471304void Tesselation::AddTesselationTriangle()
     
    12521309  TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS));
    12531310  TrianglesOnBoundaryCount++;
     1311
     1312  // set as last new triangle
     1313  LastTriangle = BTS;
     1314
     1315  // NOTE: add triangle to local maps is done in constructor of BoundaryTriangleSet
     1316};
     1317
     1318/** Function adds triangle to global list.
     1319 * Furthermore, the triangle number is set to \a nr.
     1320 * \param nr triangle number
     1321 */
     1322void Tesselation::AddTesselationTriangle(int nr)
     1323{
     1324  cout << Verbose(1) << "Adding triangle to global TrianglesOnBoundary map." << endl;
     1325
     1326  // add triangle to global map
     1327  TrianglesOnBoundary.insert(TrianglePair(nr, BTS));
     1328
     1329  // set as last new triangle
     1330  LastTriangle = BTS;
    12541331
    12551332  // NOTE: add triangle to local maps is done in constructor of BoundaryTriangleSet
     
    12721349          cout << Verbose(5) << *triangle->lines[i] << " is no more attached to any triangle, erasing." << endl;
    12731350          RemoveTesselationLine(triangle->lines[i]);
    1274           triangle->lines[i] = NULL;
    1275       } else
    1276         cout << Verbose(5) << *triangle->lines[i] << " is still attached to another triangle." << endl;
     1351      } else {
     1352        cout << Verbose(5) << *triangle->lines[i] << " is still attached to another triangle: ";
     1353        for(TriangleMap::iterator TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); TriangleRunner++)
     1354          cout << "[" << (TriangleRunner->second)->Nr << "|" << *((TriangleRunner->second)->endpoints[0]) << ", " << *((TriangleRunner->second)->endpoints[1]) << ", " << *((TriangleRunner->second)->endpoints[2]) << "] \t";
     1355        cout << endl;
     1356//        for (int j=0;j<2;j++) {
     1357//          cout << Verbose(5) << "Lines of endpoint " << *(triangle->lines[i]->endpoints[j]) << ": ";
     1358//          for(LineMap::iterator LineRunner = triangle->lines[i]->endpoints[j]->lines.begin(); LineRunner != triangle->lines[i]->endpoints[j]->lines.end(); LineRunner++)
     1359//            cout << "[" << *(LineRunner->second) << "] \t";
     1360//          cout << endl;
     1361//        }
     1362      }
     1363      triangle->lines[i] = NULL;  // free'd or not: disconnect
    12771364    } else
    12781365      cerr << "ERROR: This line " << i << " has already been free'd." << endl;
     
    12941381  if (line == NULL)
    12951382    return;
    1296   // get other endpoint number of finding copies of same line
     1383  // get other endpoint number for finding copies of same line
    12971384  if (line->endpoints[1] != NULL)
    12981385    Numbers[0] = line->endpoints[1]->Nr;
     
    13211408        cout << Verbose(5) << *line->endpoints[i] << " has no more lines it's attached to, erasing." << endl;
    13221409        RemoveTesselationPoint(line->endpoints[i]);
    1323         line->endpoints[i] = NULL;
    1324       } else
    1325         cout << Verbose(5) << *line->endpoints[i] << " has still lines it's attached to." << endl;
     1410      } else {
     1411        cout << Verbose(5) << *line->endpoints[i] << " has still lines it's attached to: ";
     1412        for(LineMap::iterator LineRunner = line->endpoints[i]->lines.begin(); LineRunner != line->endpoints[i]->lines.end(); LineRunner++)
     1413          cout << "[" << *(LineRunner->second) << "] \t";
     1414        cout << endl;
     1415      }
     1416      line->endpoints[i] = NULL;  // free'd or not: disconnect
    13261417    } else
    13271418      cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl;
     
    13901481          }
    13911482          // Only one of the triangle lines must be considered for the triangle count.
    1392           *out << Verbose(2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl;
    1393           return adjacentTriangleCount;
     1483          //*out << Verbose(2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl;
     1484          //return adjacentTriangleCount;
    13941485        }
    13951486      }
     
    14001491  *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
    14011492  return adjacentTriangleCount;
     1493};
     1494
     1495/** Checks whether the triangle consisting of the three points is already present.
     1496 * Searches for the points in Tesselation::PointsOnBoundary and checks their
     1497 * lines. If any of the three edges already has two triangles attached, false is
     1498 * returned.
     1499 * \param *out output stream for debugging
     1500 * \param *Candidates endpoints of the triangle candidate
     1501 * \return NULL - none found or pointer to triangle
     1502 */
     1503class BoundaryTriangleSet * Tesselation::GetPresentTriangle(ofstream *out, TesselPoint *Candidates[3])
     1504{
     1505  class BoundaryTriangleSet *triangle = NULL;
     1506  class BoundaryPointSet *Points[3];
     1507
     1508  // builds a triangle point set (Points) of the end points
     1509  for (int i = 0; i < 3; i++) {
     1510    PointMap::iterator FindPoint = PointsOnBoundary.find(Candidates[i]->nr);
     1511    if (FindPoint != PointsOnBoundary.end()) {
     1512      Points[i] = FindPoint->second;
     1513    } else {
     1514      Points[i] = NULL;
     1515    }
     1516  }
     1517
     1518  // checks lines between the points in the Points for their adjacent triangles
     1519  for (int i = 0; i < 3; i++) {
     1520    if (Points[i] != NULL) {
     1521      for (int j = i; j < 3; j++) {
     1522        if (Points[j] != NULL) {
     1523          LineMap::iterator FindLine = Points[i]->lines.find(Points[j]->node->nr);
     1524          for (; (FindLine != Points[i]->lines.end()) && (FindLine->first == Points[j]->node->nr); FindLine++) {
     1525            TriangleMap *triangles = &FindLine->second->triangles;
     1526            for (TriangleMap::iterator FindTriangle = triangles->begin(); FindTriangle != triangles->end(); FindTriangle++) {
     1527              if (FindTriangle->second->IsPresentTupel(Points)) {
     1528                if ((triangle == NULL) || (triangle->Nr > FindTriangle->second->Nr))
     1529                  triangle = FindTriangle->second;
     1530              }
     1531            }
     1532          }
     1533          // Only one of the triangle lines must be considered for the triangle count.
     1534          //*out << Verbose(2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl;
     1535          //return adjacentTriangleCount;
     1536        }
     1537      }
     1538    }
     1539  }
     1540
     1541  return triangle;
    14021542};
    14031543
     
    14611601  CandidateList *OptCandidates = new CandidateList();
    14621602  for (int k=0;k<NDIM;k++) {
     1603    Oben.Zero();
    14631604    Oben.x[k] = 1.;
    14641605    FirstPoint = MaxPoint[k];
     
    14691610    ShortestAngle = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.
    14701611
    1471     FindSecondPointForTesselation(FirstPoint, NULL, Oben, OptCandidate, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_...
     1612    FindSecondPointForTesselation(FirstPoint, Oben, OptCandidate, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_...
    14721613    SecondPoint = OptCandidate;
    14731614    if (SecondPoint == NULL)  // have we found a second point?
    14741615      continue;
    1475     else
    1476       cout << Verbose(1) << "Found second point is at " << *SecondPoint->node << ".\n";
    14771616
    14781617    helper.CopyVector(FirstPoint->node);
     
    14961635
    14971636    // adding point 1 and point 2 and add the line between them
     1637    cout << Verbose(1) << "Coordinates of start node at " << *FirstPoint->node << "." << endl;
    14981638    AddTesselationPoint(FirstPoint, 0);
     1639    cout << Verbose(1) << "Found second point is at " << *SecondPoint->node << ".\n";
    14991640    AddTesselationPoint(SecondPoint, 1);
    15001641    AddTesselationLine(TPS[0], TPS[1], 0);
     
    15691710 * @param *LC LinkedCell structure with neighbouring points
    15701711 */
    1571 bool Tesselation::FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, int N, LinkedCell *LC)
     1712bool Tesselation::FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, LinkedCell *LC)
    15721713{
    15731714  cout << Verbose(0) << "Begin of FindNextSuitableTriangle\n";
     
    16041745    CircleRadius = RADIUS*RADIUS - radius/4.;
    16051746    CirclePlaneNormal.Normalize();
    1606     cout << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;
     1747    //cout << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;
    16071748
    16081749    // construct old center
     
    16911832        result = false;
    16921833      }
    1693     } else if (existentTrianglesCount == 1) { // If there is a planar region within the structure, we need this triangle a second time.
     1834    } else if ((existentTrianglesCount >= 1) && (existentTrianglesCount <= 3)) { // If there is a planar region within the structure, we need this triangle a second time.
    16941835        AddTesselationPoint((*it)->point, 0);
    16951836        AddTesselationPoint(BaseRay->endpoints[0]->node, 1);
     
    17321873    // set baseline to new ray from ref point (here endpoints[0]->node) to current candidate (here (*it)->point))
    17331874    BaseRay = BLS[0];
     1875    if ((BTS != NULL) && (BTS->NormalVector.NormSquared() < MYEPSILON)) {
     1876      *out << Verbose(1) << "CRITICAL: Triangle " << *BTS << " has zero normal vector!" << endl;
     1877      exit(255);
     1878    }
     1879
    17341880  }
    17351881
     
    17501896 * \param *out output stream for debugging
    17511897 * \param *Base line to be flipped
    1752  * \return NULL - concave, otherwise endpoint that makes it concave
     1898 * \return NULL - convex, otherwise endpoint that makes it concave
    17531899 */
    17541900class BoundaryPointSet *Tesselation::IsConvexRectangle(ofstream *out, class BoundaryLineSet *Base)
     
    18271973 * \param *out output stream for debugging
    18281974 * \param *Base line to be flipped
    1829  * \return true - line was changed, false - same line as before
    1830  */
    1831 bool Tesselation::PickFarthestofTwoBaselines(ofstream *out, class BoundaryLineSet *Base)
     1975 * \return volume change due to flipping (0 - then no flipped occured)
     1976 */
     1977double Tesselation::PickFarthestofTwoBaselines(ofstream *out, class BoundaryLineSet *Base)
    18321978{
    18331979  class BoundaryLineSet *OtherBase;
    18341980  Vector *ClosestPoint[2];
     1981  double volume;
    18351982
    18361983  int m=0;
     
    18521999  Distance.CopyVector(ClosestPoint[1]);
    18532000  Distance.SubtractVector(ClosestPoint[0]);
     2001
     2002  // calculate volume
     2003  volume = CalculateVolumeofGeneralTetraeder(Base->endpoints[1]->node->node, OtherBase->endpoints[0]->node->node, OtherBase->endpoints[1]->node->node, Base->endpoints[0]->node->node);
    18542004
    18552005  // delete the temporary other base line and the closest points
     
    18662016    if (Base->triangles.size() < 2) {
    18672017      *out << Verbose(2) << "ERROR: Less than two triangles are attached to this baseline!" << endl;
    1868       return false;
     2018      return 0.;
    18692019    }
    18702020    for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {
     
    18762026    if (Distance.ScalarProduct(&BaseLineNormal) > MYEPSILON) { // Distance points outwards, hence OtherBase higher than Base -> flip
    18772027      *out << Verbose(2) << "ACCEPT: Other base line would be higher: Flipping baseline." << endl;
    1878       FlipBaseline(out, Base);
    1879       return true;
     2028      // calculate volume summand as a general tetraeder
     2029      return volume;
    18802030    } else {  // Base higher than OtherBase -> do nothing
    18812031      *out << Verbose(2) << "REJECT: Base line is higher: Nothing to do." << endl;
    1882       return false;
    1883     }
    1884   }
    1885 };
    1886 
    1887 /** Returns the closest point on \a *Base with respect to \a *OtherBase.
    1888  * \param *out output stream for debugging
    1889  * \param *Base reference line
    1890  * \param *OtherBase other base line
    1891  * \return Vector on reference line that has closest distance
    1892  */
    1893 Vector * GetClosestPointBetweenLine(ofstream *out, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase)
    1894 {
    1895   // construct the plane of the two baselines (i.e. take both their directional vectors)
    1896   Vector Normal;
    1897   Vector Baseline, OtherBaseline;
    1898   Baseline.CopyVector(Base->endpoints[1]->node->node);
    1899   Baseline.SubtractVector(Base->endpoints[0]->node->node);
    1900   OtherBaseline.CopyVector(OtherBase->endpoints[1]->node->node);
    1901   OtherBaseline.SubtractVector(OtherBase->endpoints[0]->node->node);
    1902   Normal.CopyVector(&Baseline);
    1903   Normal.VectorProduct(&OtherBaseline);
    1904   Normal.Normalize();
    1905   *out << Verbose(4) << "First direction is " << Baseline << ", second direction is " << OtherBaseline << ", normal of intersection plane is " << Normal << "." << endl;
    1906 
    1907   // project one offset point of OtherBase onto this plane (and add plane offset vector)
    1908   Vector NewOffset;
    1909   NewOffset.CopyVector(OtherBase->endpoints[0]->node->node);
    1910   NewOffset.SubtractVector(Base->endpoints[0]->node->node);
    1911   NewOffset.ProjectOntoPlane(&Normal);
    1912   NewOffset.AddVector(Base->endpoints[0]->node->node);
    1913   Vector NewDirection;
    1914   NewDirection.CopyVector(&NewOffset);
    1915   NewDirection.AddVector(&OtherBaseline);
    1916 
    1917   // calculate the intersection between this projected baseline and Base
    1918   Vector *Intersection = new Vector;
    1919   Intersection->GetIntersectionOfTwoLinesOnPlane(out, Base->endpoints[0]->node->node, Base->endpoints[1]->node->node, &NewOffset, &NewDirection, &Normal);
    1920   Normal.CopyVector(Intersection);
    1921   Normal.SubtractVector(Base->endpoints[0]->node->node);
    1922   *out << Verbose(3) << "Found closest point on " << *Base << " at " << *Intersection << ", factor in line is " << fabs(Normal.ScalarProduct(&Baseline)/Baseline.NormSquared()) << "." << endl;
    1923 
    1924   return Intersection;
     2032      return 0.;
     2033    }
     2034  }
    19252035};
    19262036
     
    19302040 * \param *out output stream for debugging
    19312041 * \param *Base line to be flipped
    1932  * \return true - flipping successful, false - something went awry
    1933  */
    1934 bool Tesselation::FlipBaseline(ofstream *out, class BoundaryLineSet *Base)
     2042 * \return pointer to allocated new baseline - flipping successful, NULL - something went awry
     2043 */
     2044class BoundaryLineSet * Tesselation::FlipBaseline(ofstream *out, class BoundaryLineSet *Base)
    19352045{
    19362046  class BoundaryLineSet *OldLines[4], *NewLine;
     
    19462056  if (Base->triangles.size() < 2) {
    19472057    *out << Verbose(2) << "ERROR: Less than two triangles are attached to this baseline!" << endl;
    1948     return false;
     2058    return NULL;
    19492059  }
    19502060  for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {
     
    19822092  if (i<4) {
    19832093    *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl;
    1984     return false;
     2094    return NULL;
    19852095  }
    19862096  for (int j=0;j<4;j++)
    19872097    if (OldLines[j] == NULL) {
    19882098      *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl;
    1989       return false;
     2099      return NULL;
    19902100    }
    19912101  for (int j=0;j<2;j++)
    19922102    if (OldPoints[j] == NULL) {
    19932103      *out << Verbose(1) << "ERROR: We have not gathered enough endpoints!" << endl;
    1994       return false;
     2104      return NULL;
    19952105    }
    19962106
     
    20242134    BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[0]);
    20252135    BTS->GetNormalVector(BaseLineNormal);
    2026     TrianglesOnBoundary.insert(TrianglePair(OldTriangleNrs[0], BTS));
     2136    AddTesselationTriangle(OldTriangleNrs[0]);
    20272137    *out << Verbose(3) << "INFO: Created new triangle " << *BTS << "." << endl;
    20282138
     
    20322142    BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[1]);
    20332143    BTS->GetNormalVector(BaseLineNormal);
    2034     TrianglesOnBoundary.insert(TrianglePair(OldTriangleNrs[1], BTS));
     2144    AddTesselationTriangle(OldTriangleNrs[1]);
    20352145    *out << Verbose(3) << "INFO: Created new triangle " << *BTS << "." << endl;
    20362146  } else {
    20372147    *out << Verbose(1) << "The four old lines do not connect, something's utterly wrong here!" << endl;
    2038     return false;
     2148    return NULL;
    20392149  }
    20402150
    20412151  *out << Verbose(1) << "End of FlipBaseline" << endl;
    2042   return true;
     2152  return NewLine;
    20432153};
    20442154
     
    20462156/** Finds the second point of starting triangle.
    20472157 * \param *a first node
    2048  * \param *Candidate pointer to candidate node on return
    20492158 * \param Oben vector indicating the outside
    20502159 * \param OptCandidate reference to recommended candidate on return
     
    20532162 * \param *LC LinkedCell structure with neighbouring points
    20542163 */
    2055 void Tesselation::FindSecondPointForTesselation(TesselPoint* a, TesselPoint* Candidate, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, LinkedCell *LC)
     2164void Tesselation::FindSecondPointForTesselation(TesselPoint* a, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, LinkedCell *LC)
    20562165{
    20572166  cout << Verbose(2) << "Begin of FindSecondPointForTesselation" << endl;
    20582167  Vector AngleCheck;
     2168  class TesselPoint* Candidate = NULL;
    20592169  double norm = -1., angle;
    20602170  LinkedNodes *List = NULL;
     
    21912301  cout << Verbose(1) << "Begin of FindThirdPointForTesselation" << endl;
    21922302
    2193   //cout << Verbose(2) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl;
     2303  cout << Verbose(2) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl;
    21942304
    21952305  // construct center of circle
     
    22162326    radius = OldSphereCenter.ScalarProduct(&OldSphereCenter);
    22172327    if (fabs(radius - CircleRadius) < HULLEPSILON) {
     2328      //cout << Verbose(2) << "INFO: OldSphereCenter is at " << OldSphereCenter << "." << endl;
    22182329
    22192330      // check SearchDirection
     
    23922503  TesselPoint *trianglePoints[3];
    23932504  TesselPoint *SecondPoint = NULL;
     2505  list<BoundaryTriangleSet*> *triangles = NULL;
    23942506
    23952507  if (LinesOnBoundary.empty()) {
     
    24022514  // check whether closest point is "too close" :), then it's inside
    24032515  if (trianglePoints[0] == NULL) {
    2404     *out << Verbose(1) << "Is the only point, no one else is closeby." << endl;
     2516    *out << Verbose(2) << "Is the only point, no one else is closeby." << endl;
    24052517    return NULL;
    24062518  }
    24072519  if (trianglePoints[0]->node->DistanceSquared(x) < MYEPSILON) {
    2408     *out << Verbose(1) << "Point is right on a tesselation point, no nearest triangle." << endl;
    2409     return NULL;
    2410   }
    2411   list<TesselPoint*> *connectedPoints = GetCircleOfConnectedPoints(out, trianglePoints[0]);
    2412   list<TesselPoint*> *connectedClosestPoints = GetNeighboursOnCircleOfConnectedPoints(out, connectedPoints, trianglePoints[0], x);
    2413   delete(connectedPoints);
    2414   trianglePoints[1] = connectedClosestPoints->front();
    2415   trianglePoints[2] = connectedClosestPoints->back();
    2416   for (int i=0;i<3;i++) {
    2417     if (trianglePoints[i] == NULL) {
    2418       *out << Verbose(1) << "IsInnerPoint encounters serious error, point " << i << " not found." << endl;
    2419     }
    2420     //*out << Verbose(1) << "List of possible points:" << endl;
    2421     //*out << Verbose(2) << *trianglePoints[i] << endl;
    2422   }
    2423 
    2424   list<BoundaryTriangleSet*> *triangles = FindTriangles(trianglePoints);
    2425 
    2426   delete(connectedClosestPoints);
     2520    *out << Verbose(3) << "Point is right on a tesselation point, no nearest triangle." << endl;
     2521    PointMap::iterator PointRunner = PointsOnBoundary.find(trianglePoints[0]->nr);
     2522    triangles = new list<BoundaryTriangleSet*>;
     2523    if (PointRunner != PointsOnBoundary.end()) {
     2524      for(LineMap::iterator LineRunner = PointRunner->second->lines.begin(); LineRunner != PointRunner->second->lines.end(); LineRunner++)
     2525        for(TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++)
     2526          triangles->push_back(TriangleRunner->second);
     2527      triangles->sort();
     2528      triangles->unique();
     2529    } else {
     2530      PointRunner = PointsOnBoundary.find(SecondPoint->nr);
     2531      trianglePoints[0] = SecondPoint;
     2532      if (PointRunner != PointsOnBoundary.end()) {
     2533        for(LineMap::iterator LineRunner = PointRunner->second->lines.begin(); LineRunner != PointRunner->second->lines.end(); LineRunner++)
     2534          for(TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++)
     2535            triangles->push_back(TriangleRunner->second);
     2536        triangles->sort();
     2537        triangles->unique();
     2538      } else {
     2539        *out << Verbose(1) << "ERROR: I cannot find a boundary point to the tessel point " << *trianglePoints[0] << "." << endl;
     2540        return NULL;
     2541      }
     2542    }
     2543  } else {
     2544    list<TesselPoint*> *connectedClosestPoints = GetCircleOfConnectedPoints(out, trianglePoints[0], x);
     2545    trianglePoints[1] = connectedClosestPoints->front();
     2546    trianglePoints[2] = connectedClosestPoints->back();
     2547    for (int i=0;i<3;i++) {
     2548      if (trianglePoints[i] == NULL) {
     2549        *out << Verbose(1) << "ERROR: IsInnerPoint encounters serious error, point " << i << " not found." << endl;
     2550      }
     2551      //*out << Verbose(2) << "List of triangle points:" << endl;
     2552      //*out << Verbose(3) << *trianglePoints[i] << endl;
     2553    }
     2554
     2555    triangles = FindTriangles(trianglePoints);
     2556    *out << Verbose(2) << "List of possible triangles:" << endl;
     2557    for(list<BoundaryTriangleSet*>::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++)
     2558      *out << Verbose(3) << **Runner << endl;
     2559
     2560    delete(connectedClosestPoints);
     2561  }
    24272562 
    24282563  if (triangles->empty()) {
    2429     *out << Verbose(0) << "Error: There is no nearest triangle. Please check the tesselation structure.";
     2564    *out << Verbose(0) << "ERROR: There is no nearest triangle. Please check the tesselation structure.";
     2565    delete(triangles);
    24302566    return NULL;
    24312567  } else
     
    24432579  class BoundaryTriangleSet *result = NULL;
    24442580  list<BoundaryTriangleSet*> *triangles = FindClosestTrianglesToPoint(out, x, LC);
     2581  Vector Center;
    24452582
    24462583  if (triangles == NULL)
    24472584    return NULL;
    24482585
    2449   if (x->ScalarProduct(&triangles->front()->NormalVector) < 0)
    2450     result = triangles->back();
    2451   else
     2586  if (triangles->size() == 1) { // there is no degenerate case
    24522587    result = triangles->front();
    2453 
     2588    *out << Verbose(2) << "Normal Vector of this triangle is " << result->NormalVector << "." << endl;
     2589  } else {
     2590    result = triangles->front();
     2591    result->GetCenter(&Center);
     2592    Center.SubtractVector(x);
     2593    *out << Verbose(2) << "Normal Vector of this front side is " << result->NormalVector << "." << endl;
     2594    if (Center.ScalarProduct(&result->NormalVector) < 0) {
     2595      result = triangles->back();
     2596      *out << Verbose(2) << "Normal Vector of this back side is " << result->NormalVector << "." << endl;
     2597      if (Center.ScalarProduct(&result->NormalVector) < 0) {
     2598        *out << Verbose(1) << "ERROR: Front and back side yield NormalVector in wrong direction!" << endl;
     2599      }
     2600    }
     2601  }
    24542602  delete(triangles);
    24552603  return result;
     
    24662614{
    24672615  class BoundaryTriangleSet *result = FindClosestTriangleToPoint(out, &Point, LC);
    2468   if (result == NULL)
     2616  Vector Center;
     2617
     2618  if (result == NULL) {// is boundary point or only point in point cloud?
     2619    *out << Verbose(1) << Point << " is the only point in vicinity." << endl;
     2620    return false;
     2621  }
     2622
     2623  result->GetCenter(&Center);
     2624  *out << Verbose(3) << "INFO: Central point of the triangle is " << Center << "." << endl;
     2625  Center.SubtractVector(&Point);
     2626  *out << Verbose(3) << "INFO: Vector from center to point to test is " << Center << "." << endl;
     2627  if (Center.ScalarProduct(&result->NormalVector) > -MYEPSILON) {
     2628    *out << Verbose(1) << Point << " is an inner point." << endl;
    24692629    return true;
    2470   if (Point.ScalarProduct(&result->NormalVector) < 0)
    2471     return true;
    2472   else
     2630  } else {
     2631    *out << Verbose(1) << Point << " is NOT an inner point." << endl;
    24732632    return false;
     2633  }
    24742634}
    24752635
     
    24832643bool Tesselation::IsInnerPoint(ofstream *out, TesselPoint *Point, LinkedCell* LC)
    24842644{
    2485   class BoundaryTriangleSet *result = FindClosestTriangleToPoint(out, Point->node, LC);
    2486   if (result == NULL)
    2487     return true;
    2488   if (Point->node->ScalarProduct(&result->NormalVector) < 0)
    2489     return true;
    2490   else
    2491     return false;
     2645  return IsInnerPoint(out, *(Point->node), LC);
    24922646}
    24932647
     
    24962650 * @param *Point of which get all connected points
    24972651 *
    2498  * @return list of the all points linked to the provided one
    2499  */
    2500 list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point)
    2501 {
    2502   list<TesselPoint*> *connectedPoints = new list<TesselPoint*>;
     2652 * @return set of the all points linked to the provided one
     2653 */
     2654set<TesselPoint*> * Tesselation::GetAllConnectedPoints(ofstream *out, TesselPoint* Point)
     2655{
     2656  set<TesselPoint*> *connectedPoints = new set<TesselPoint*>;
    25032657  class BoundaryPointSet *ReferencePoint = NULL;
    25042658  TesselPoint* current;
     
    25102664    ReferencePoint = PointRunner->second;
    25112665  } else {
    2512     *out << Verbose(2) << "getCircleOfConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl;
     2666    *out << Verbose(2) << "GetAllConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl;
    25132667    ReferencePoint = NULL;
    25142668  }
    25152669
    2516   // little trick so that we look just through lines connect to the BoundaryPoint 
     2670  // little trick so that we look just through lines connect to the BoundaryPoint
    25172671  // OR fall-back to look through all lines if there is no such BoundaryPoint
    25182672  LineMap *Lines = &LinesOnBoundary;
     
    25212675  LineMap::iterator findLines = Lines->begin();
    25222676  while (findLines != Lines->end()) {
    2523     takePoint = false;
    2524 
    2525     if (findLines->second->endpoints[0]->Nr == Point->nr) {
    2526       takePoint = true;
    2527       current = findLines->second->endpoints[1]->node;
    2528     } else if (findLines->second->endpoints[1]->Nr == Point->nr) {
    2529       takePoint = true;
    2530       current = findLines->second->endpoints[0]->node;
    2531     }
    2532    
    2533     if (takePoint) {
    2534       *out << Verbose(3) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is taken into the circle." << endl;
    2535       connectedPoints->push_back(current);
    2536     }
    2537 
    2538     findLines++;
     2677   takePoint = false;
     2678
     2679   if (findLines->second->endpoints[0]->Nr == Point->nr) {
     2680     takePoint = true;
     2681     current = findLines->second->endpoints[1]->node;
     2682   } else if (findLines->second->endpoints[1]->Nr == Point->nr) {
     2683     takePoint = true;
     2684     current = findLines->second->endpoints[0]->node;
     2685   }
     2686
     2687   if (takePoint) {
     2688     *out << Verbose(5) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is enlisted." << endl;
     2689     connectedPoints->insert(current);
     2690   }
     2691
     2692   findLines++;
    25392693  }
    25402694
     
    25432697    return NULL;
    25442698  }
     2699
    25452700  return connectedPoints;
    2546 }
    2547 
    2548 /** Gets the two neighbouring points with respect to a reference line to the provided point.
     2701};
     2702
     2703
     2704/** Gets all points connected to the provided point by triangulation lines, ordered such that we have the circle round the point.
    25492705 * Maps them down onto the plane designated by the axis \a *Point and \a *Reference. The center of all points
    25502706 * connected in the tesselation to \a *Point is mapped to spherical coordinates with the zero angle being given
     
    25532709 *
    25542710 * @param *out output stream for debugging
    2555  * @param *connectedPoints list of connected points to the central \a *Point
    25562711 * @param *Point of which get all connected points
    2557  * @param *Reference Vector to be checked whether it is an inner point
    2558  *
    2559  * @return list of the two points linked to the provided one and closest to the point to be checked,
    2560  */
    2561 list<TesselPoint*> * Tesselation::GetNeighboursOnCircleOfConnectedPoints(ofstream *out, list<TesselPoint*> *connectedPoints, TesselPoint* Point, Vector* Reference)
     2712 * @param *Reference Reference vector for zero angle or NULL for no preference
     2713 * @return list of the all points linked to the provided one
     2714 */
     2715list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point, Vector *Reference)
    25622716{
    25632717  map<double, TesselPoint*> anglesOfPoints;
    2564   map<double, TesselPoint*>::iterator runner;
    2565   ;
    2566   Vector center, PlaneNormal, OrthogonalVector, helper, AngleZero;
    2567 
    2568   if (connectedPoints->size() == 0) { // if have not found any points
    2569     *out << Verbose(1) << "ERROR: We have not found any connected points to " << *Point<< "." << endl;
    2570     return NULL;
    2571   }
     2718  set<TesselPoint*> *connectedPoints = GetAllConnectedPoints(out, Point);
     2719  list<TesselPoint*> *connectedCircle = new list<TesselPoint*>;
     2720  Vector center;
     2721  Vector PlaneNormal;
     2722  Vector AngleZero;
     2723  Vector OrthogonalVector;
     2724  Vector helper;
    25722725
    25732726  // calculate central point
    2574   for (list<TesselPoint*>::iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++)
     2727  for (set<TesselPoint*>::iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++)
    25752728    center.AddVector((*TesselRunner)->node);
    25762729  //*out << "Summed vectors " << center << "; number of points " << connectedPoints.size()
     
    25862739
    25872740  // construct one orthogonal vector
    2588   AngleZero.CopyVector(Reference);
     2741  if (Reference != NULL)
     2742    AngleZero.CopyVector(Reference);
     2743  else
     2744    AngleZero.CopyVector((*connectedPoints->begin())->node);
    25892745  AngleZero.SubtractVector(Point->node);
    25902746  AngleZero.ProjectOntoPlane(&PlaneNormal);
     
    25942750
    25952751  // go through all connected points and calculate angle
    2596   for (list<TesselPoint*>::iterator listRunner = connectedPoints->begin(); listRunner != connectedPoints->end(); listRunner++) {
     2752  for (set<TesselPoint*>::iterator listRunner = connectedPoints->begin(); listRunner != connectedPoints->end(); listRunner++) {
    25972753    helper.CopyVector((*listRunner)->node);
    25982754    helper.SubtractVector(Point->node);
    25992755    helper.ProjectOntoPlane(&PlaneNormal);
    26002756    double angle = GetAngle(helper, AngleZero, OrthogonalVector);
    2601     *out << Verbose(2) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl;
     2757    *out << Verbose(3) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl;
    26022758    anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner)));
    26032759  }
    26042760
    2605   list<TesselPoint*> *result = new list<TesselPoint*>;
    2606   runner = anglesOfPoints.begin();
    2607   result->push_back(runner->second);
    2608   runner = anglesOfPoints.end();
    2609   runner--;
    2610   result->push_back(runner->second);
    2611 
    2612   *out << Verbose(2) << "List of closest points has " << result->size() << " elements, which are "
    2613     << *(result->front()) << " and " << *(result->back()) << endl;
    2614 
    2615   return result;
     2761  for(map<double, TesselPoint*>::iterator AngleRunner = anglesOfPoints.begin(); AngleRunner != anglesOfPoints.end(); AngleRunner++) {
     2762    connectedCircle->push_back(AngleRunner->second);
     2763  }
     2764
     2765  delete(connectedPoints);
     2766  return connectedCircle;
    26162767}
    26172768
     2769/** Gets all points connected to the provided point by triangulation lines, ordered such that we walk along a closed path.
     2770 *
     2771 * @param *out output stream for debugging
     2772 * @param *Point of which get all connected points
     2773 * @return list of the all points linked to the provided one
     2774 */
     2775list<list<TesselPoint*> *> * Tesselation::GetPathsOfConnectedPoints(ofstream *out, TesselPoint* Point)
     2776{
     2777  map<double, TesselPoint*> anglesOfPoints;
     2778  list<list<TesselPoint*> *> *ListOfPaths = new list<list<TesselPoint*> *>;
     2779  list<TesselPoint*> *connectedPath = NULL;
     2780  Vector center;
     2781  Vector PlaneNormal;
     2782  Vector AngleZero;
     2783  Vector OrthogonalVector;
     2784  Vector helper;
     2785  class BoundaryPointSet *ReferencePoint = NULL;
     2786  class BoundaryPointSet *CurrentPoint = NULL;
     2787  class BoundaryTriangleSet *triangle = NULL;
     2788  class BoundaryLineSet *CurrentLine = NULL;
     2789  class BoundaryLineSet *StartLine = NULL;
     2790
     2791  // find the respective boundary point
     2792  PointMap::iterator PointRunner = PointsOnBoundary.find(Point->nr);
     2793  if (PointRunner != PointsOnBoundary.end()) {
     2794    ReferencePoint = PointRunner->second;
     2795  } else {
     2796    *out << Verbose(2) << "ERROR: GetPathOfConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl;
     2797    return NULL;
     2798  }
     2799
     2800  map <class BoundaryLineSet *, bool> TouchedLine;
     2801  map <class BoundaryTriangleSet *, bool> TouchedTriangle;
     2802  map <class BoundaryLineSet *, bool>::iterator LineRunner;
     2803  map <class BoundaryTriangleSet *, bool>::iterator TriangleRunner;
     2804  for (LineMap::iterator Runner = ReferencePoint->lines.begin(); Runner != ReferencePoint->lines.end(); Runner++) {
     2805    TouchedLine.insert( pair <class BoundaryLineSet *, bool>(Runner->second, false) );
     2806    for (TriangleMap::iterator Sprinter = Runner->second->triangles.begin(); Sprinter != Runner->second->triangles.end(); Sprinter++)
     2807      TouchedTriangle.insert( pair <class BoundaryTriangleSet *, bool>(Sprinter->second, false) );
     2808  }
     2809  if (!ReferencePoint->lines.empty()) {
     2810    for (LineMap::iterator runner = ReferencePoint->lines.begin(); runner != ReferencePoint->lines.end(); runner++) {
     2811      LineRunner = TouchedLine.find(runner->second);
     2812      if (LineRunner == TouchedLine.end()) {
     2813        *out << Verbose(2) << "ERROR: I could not find " << *runner->second << " in the touched list." << endl;
     2814      } else if (!LineRunner->second) {
     2815        LineRunner->second = true;
     2816        connectedPath = new list<TesselPoint*>;
     2817        triangle = NULL;
     2818        CurrentLine = runner->second;
     2819        StartLine = CurrentLine;
     2820        CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
     2821        *out << Verbose(3)<< "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << "." << endl;
     2822        do {
     2823          // push current one
     2824          *out << Verbose(3) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl;
     2825          connectedPath->push_back(CurrentPoint->node);
     2826
     2827          // find next triangle
     2828          for (TriangleMap::iterator Runner = CurrentLine->triangles.begin(); Runner != CurrentLine->triangles.end(); Runner++) {
     2829            *out << Verbose(3) << "INFO: Inspecting triangle " << *Runner->second << "." << endl;
     2830            if ((Runner->second != triangle)) { // look for first triangle not equal to old one
     2831              triangle = Runner->second;
     2832              TriangleRunner = TouchedTriangle.find(triangle);
     2833              if (TriangleRunner != TouchedTriangle.end()) {
     2834                if (!TriangleRunner->second) {
     2835                  TriangleRunner->second = true;
     2836                  *out << Verbose(3) << "INFO: Connecting triangle is " << *triangle << "." << endl;
     2837                  break;
     2838                } else {
     2839                  *out << Verbose(3) << "INFO: Skipping " << *triangle << ", as we have already visited it." << endl;
     2840                  triangle = NULL;
     2841                }
     2842              } else {
     2843                *out << Verbose(2) << "ERROR: I could not find " << *triangle << " in the touched list." << endl;
     2844                triangle = NULL;
     2845              }
     2846            }
     2847          }
     2848          if (triangle == NULL)
     2849            break;
     2850          // find next line
     2851          for (int i=0;i<3;i++) {
     2852            if ((triangle->lines[i] != CurrentLine) && (triangle->lines[i]->ContainsBoundaryPoint(ReferencePoint))) { // not the current line and still containing Point
     2853              CurrentLine = triangle->lines[i];
     2854              *out << Verbose(3) << "INFO: Connecting line is " << *CurrentLine << "." << endl;
     2855              break;
     2856            }
     2857          }
     2858          LineRunner = TouchedLine.find(CurrentLine);
     2859          if (LineRunner == TouchedLine.end())
     2860            *out << Verbose(2) << "ERROR: I could not find " << *CurrentLine << " in the touched list." << endl;
     2861          else
     2862            LineRunner->second = true;
     2863          // find next point
     2864          CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
     2865
     2866        } while (CurrentLine != StartLine);
     2867        // last point is missing, as it's on start line
     2868        *out << Verbose(3) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl;
     2869        if (StartLine->GetOtherEndpoint(ReferencePoint)->node != connectedPath->back())
     2870          connectedPath->push_back(StartLine->GetOtherEndpoint(ReferencePoint)->node);
     2871
     2872        ListOfPaths->push_back(connectedPath);
     2873      } else {
     2874        *out << Verbose(3) << "INFO: Skipping " << *runner->second << ", as we have already visited it." << endl;
     2875      }
     2876    }
     2877  } else {
     2878    *out << Verbose(1) << "ERROR: There are no lines attached to " << *ReferencePoint << "." << endl;
     2879  }
     2880
     2881  return ListOfPaths;
     2882}
     2883
     2884/** Gets all closed paths on the circle of points connected to the provided point by triangulation lines, if this very point is removed.
     2885 * From GetPathsOfConnectedPoints() extracts all single loops of intracrossing paths in the list of closed paths.
     2886 * @param *out output stream for debugging
     2887 * @param *Point of which get all connected points
     2888 * @return list of the closed paths
     2889 */
     2890list<list<TesselPoint*> *> * Tesselation::GetClosedPathsOfConnectedPoints(ofstream *out, TesselPoint* Point)
     2891{
     2892  list<list<TesselPoint*> *> *ListofPaths = GetPathsOfConnectedPoints(out, Point);
     2893  list<list<TesselPoint*> *> *ListofClosedPaths = new list<list<TesselPoint*> *>;
     2894  list<TesselPoint*> *connectedPath = NULL;
     2895  list<TesselPoint*> *newPath = NULL;
     2896  int count = 0;
     2897
     2898
     2899  list<TesselPoint*>::iterator CircleRunner;
     2900  list<TesselPoint*>::iterator CircleStart;
     2901
     2902  for(list<list<TesselPoint*> *>::iterator ListRunner = ListofPaths->begin(); ListRunner != ListofPaths->end(); ListRunner++) {
     2903    connectedPath = *ListRunner;
     2904
     2905    *out << Verbose(2) << "INFO: Current path is " << connectedPath << "." << endl;
     2906
     2907    // go through list, look for reappearance of starting Point and count
     2908    CircleStart = connectedPath->begin();
     2909
     2910    // go through list, look for reappearance of starting Point and create list
     2911    list<TesselPoint*>::iterator Marker = CircleStart;
     2912    for (CircleRunner = CircleStart; CircleRunner != connectedPath->end(); CircleRunner++) {
     2913      if ((*CircleRunner == *CircleStart) && (CircleRunner != CircleStart)) { // is not the very first point
     2914        // we have a closed circle from Marker to new Marker
     2915        *out << Verbose(3) << count+1 << ". closed path consists of: ";
     2916        newPath = new list<TesselPoint*>;
     2917        list<TesselPoint*>::iterator CircleSprinter = Marker;
     2918        for (; CircleSprinter != CircleRunner; CircleSprinter++) {
     2919          newPath->push_back(*CircleSprinter);
     2920          *out << (**CircleSprinter) << " <-> ";
     2921        }
     2922        *out << ".." << endl;
     2923        count++;
     2924        Marker = CircleRunner;
     2925
     2926        // add to list
     2927        ListofClosedPaths->push_back(newPath);
     2928      }
     2929    }
     2930  }
     2931  *out << Verbose(3) << "INFO: " << count << " closed additional path(s) have been created." << endl;
     2932
     2933  // delete list of paths
     2934  while (!ListofPaths->empty()) {
     2935    connectedPath = *(ListofPaths->begin());
     2936    ListofPaths->remove(connectedPath);
     2937    delete(connectedPath);
     2938  }
     2939  delete(ListofPaths);
     2940
     2941  // exit
     2942  return ListofClosedPaths;
     2943};
     2944
     2945
     2946/** Gets all belonging triangles for a given BoundaryPointSet.
     2947 * \param *out output stream for debugging
     2948 * \param *Point BoundaryPoint
     2949 * \return pointer to allocated list of triangles
     2950 */
     2951set<BoundaryTriangleSet*> *Tesselation::GetAllTriangles(ofstream *out, class BoundaryPointSet *Point)
     2952{
     2953  set<BoundaryTriangleSet*> *connectedTriangles = new set<BoundaryTriangleSet*>;
     2954
     2955  if (Point == NULL) {
     2956    *out << Verbose(1) << "ERROR: Point given is NULL." << endl;
     2957  } else {
     2958    // go through its lines and insert all triangles
     2959    for (LineMap::iterator LineRunner = Point->lines.begin(); LineRunner != Point->lines.end(); LineRunner++)
     2960      for (TriangleMap::iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) {
     2961      connectedTriangles->insert(TriangleRunner->second);
     2962    }
     2963  }
     2964
     2965  return connectedTriangles;
     2966};
     2967
     2968
    26182969/** Removes a boundary point from the envelope while keeping it closed.
    2619  * We create new triangles and remove the old ones connected to the point.
     2970 * We remove the old triangles connected to the point and re-create new triangles to close the surface following this ansatz:
     2971 *  -# a closed path(s) of boundary points surrounding the point to be removed is constructed
     2972 *  -# on each closed path, we pick three adjacent points, create a triangle with them and subtract the middle point from the path
     2973 *  -# we advance two points (i.e. the next triangle will start at the ending point of the last triangle) and continue as before
     2974 *  -# the surface is closed, when the path is empty
     2975 * Thereby, we (hopefully) make sure that the removed points remains beneath the surface (this is checked via IsInnerPoint eventually).
    26202976 * \param *out output stream for debugging
    26212977 * \param *point point to be removed
     
    26252981  class BoundaryLineSet *line = NULL;
    26262982  class BoundaryTriangleSet *triangle = NULL;
    2627   Vector OldPoint, TetraederVector[3];
     2983  Vector OldPoint, NormalVector;
    26282984  double volume = 0;
    2629   int *numbers = NULL;
    26302985  int count = 0;
    2631   int i;
    26322986
    26332987  if (point == NULL) {
     
    26452999    return 0.;
    26463000  }
    2647   list<TesselPoint*> *CircleofPoints = GetCircleOfConnectedPoints(out, point->node);
    2648 
    2649   // remove all triangles
     3001
     3002  list<list<TesselPoint*> *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(out, point->node);
     3003  list<TesselPoint*> *connectedPath = NULL;
     3004
     3005  // gather all triangles
    26503006  for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++)
    26513007    count+=LineRunner->second->triangles.size();
    2652   numbers = new int[count];
    2653   class BoundaryTriangleSet **Candidates = new BoundaryTriangleSet*[count];
    2654   i=0;
    2655   for (LineMap::iterator LineRunner = point->lines.begin(); (point != NULL) && (LineRunner != point->lines.end()); LineRunner++) {
     3008  map<class BoundaryTriangleSet *, int> Candidates;
     3009  for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) {
    26563010    line = LineRunner->second;
    26573011    for (TriangleMap::iterator TriangleRunner = line->triangles.begin(); TriangleRunner != line->triangles.end(); TriangleRunner++) {
    26583012      triangle = TriangleRunner->second;
    2659       Candidates[i] = triangle;
    2660       numbers[i++] = triangle->Nr;
    2661     }
    2662   }
    2663   for (int j=0;j<i;j++) {
    2664     RemoveTesselationTriangle(Candidates[j]);
    2665   }
    2666   delete[](Candidates);
    2667   *out << Verbose(1) << i << " triangles were removed." << endl;
    2668 
    2669   // re-create all triangles by going through connected points list
    2670   list<TesselPoint*>::iterator CircleRunner = CircleofPoints->begin();
    2671   list<TesselPoint*>::iterator OtherCircleRunner = CircleofPoints->begin();
    2672   class TesselPoint *CentralNode = *CircleRunner;
    2673   // advance two with CircleRunner and one with OtherCircleRunner
    2674   CircleRunner++;
    2675   CircleRunner++;
    2676   OtherCircleRunner++;
    2677   i=0;
    2678   cout << Verbose(2) << "INFO: CentralNode is " << *CentralNode << "." << endl;
    2679   for (; (OtherCircleRunner != CircleofPoints->end()) && (CircleRunner != CircleofPoints->end()); (CircleRunner++), (OtherCircleRunner++)) {
    2680     cout << Verbose(3) << "INFO: CircleRunner's node is " << **CircleRunner << "." << endl;
    2681     cout << Verbose(3) << "INFO: OtherCircleRunner's node is " << **OtherCircleRunner << "." << endl;
    2682     *out << Verbose(4) << "Adding new triangle points."<< endl;
    2683     AddTesselationPoint(CentralNode, 0);
    2684     AddTesselationPoint(*OtherCircleRunner, 1);
    2685     AddTesselationPoint(*CircleRunner, 2);
    2686     *out << Verbose(4) << "Adding new triangle lines."<< endl;
    2687     AddTesselationLine(TPS[0], TPS[1], 0);
    2688     AddTesselationLine(TPS[0], TPS[2], 1);
    2689     AddTesselationLine(TPS[1], TPS[2], 2);
    2690     BTS = new class BoundaryTriangleSet(BLS, numbers[i]);
    2691     TrianglesOnBoundary.insert(TrianglePair(numbers[i], BTS));
    2692     *out << Verbose(4) << "Created triangle " << *BTS << "." << endl;
    2693     // calculate volume summand as a general tetraeder
    2694     for (int j=0;j<3;j++) {
    2695       TetraederVector[j].CopyVector(TPS[j]->node->node);
    2696       TetraederVector[j].SubtractVector(&OldPoint);
    2697     }
    2698     OldPoint.CopyVector(&TetraederVector[0]);
    2699     OldPoint.VectorProduct(&TetraederVector[1]);
    2700     volume += 1./6. * fabs(OldPoint.ScalarProduct(&TetraederVector[2]));
    2701     // advance number
    2702     i++;
    2703     if (i >= count)
    2704       *out << Verbose(2) << "WARNING: Maximum of numbers reached!" << endl;
    2705   }
    2706   *out << Verbose(1) << i << " triangles were created." << endl;
    2707 
    2708   delete[](numbers);
    2709 
    2710   return volume;
    2711 };
    2712 
    2713 /** Checks for a new special triangle whether one of its edges is already present with one one triangle connected.
    2714  * This enforces that special triangles (i.e. degenerated ones) should at last close the open-edge frontier and not
    2715  * make it bigger (i.e. closing one (the baseline) and opening two new ones).
    2716  * \param TPS[3] nodes of the triangle
    2717  * \return true - there is such a line (i.e. creation of degenerated triangle is valid), false - no such line (don't create)
    2718  */
    2719 bool CheckLineCriteriaForDegeneratedTriangle(class BoundaryPointSet *nodes[3])
    2720 {
    2721   bool result = false;
    2722   int counter = 0;
    2723 
    2724   // check all three points
    2725   for (int i=0;i<3;i++)
    2726     for (int j=i+1; j<3; j++) {
    2727       if (nodes[i]->lines.find(nodes[j]->node->nr) != nodes[i]->lines.end()) {  // there already is a line
    2728         LineMap::iterator FindLine;
    2729         pair<LineMap::iterator,LineMap::iterator> FindPair;
    2730         FindPair = nodes[i]->lines.equal_range(nodes[j]->node->nr);
    2731         for (FindLine = FindPair.first; FindLine != FindPair.second; ++FindLine) {
    2732           // If there is a line with less than two attached triangles, we don't need a new line.
    2733           if (FindLine->second->triangles.size() < 2) {
    2734             counter++;
    2735             break;  // increase counter only once per edge
    2736           }
     3013      Candidates.insert( pair<class BoundaryTriangleSet *, int> (triangle, triangle->Nr) );
     3014    }
     3015  }
     3016
     3017  // remove all triangles
     3018  count=0;
     3019  NormalVector.Zero();
     3020  for (map<class BoundaryTriangleSet *, int>::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) {
     3021    *out << Verbose(3) << "INFO: Removing triangle " << *(Runner->first) << "." << endl;
     3022    NormalVector.SubtractVector(&Runner->first->NormalVector); // has to point inward
     3023    RemoveTesselationTriangle(Runner->first);
     3024    count++;
     3025  }
     3026  *out << Verbose(1) << count << " triangles were removed." << endl;
     3027
     3028  list<list<TesselPoint*> *>::iterator ListAdvance = ListOfClosedPaths->begin();
     3029  list<list<TesselPoint*> *>::iterator ListRunner = ListAdvance;
     3030  map<class BoundaryTriangleSet *, int>::iterator NumberRunner = Candidates.begin();
     3031  list<TesselPoint*>::iterator StartNode, MiddleNode, EndNode;
     3032  double angle;
     3033  double smallestangle;
     3034  Vector Point, Reference, OrthogonalVector;
     3035  if (count > 2) {  // less than three triangles, then nothing will be created
     3036    class TesselPoint *TriangleCandidates[3];
     3037    count = 0;
     3038    for ( ; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) {  // go through all closed paths
     3039      if (ListAdvance != ListOfClosedPaths->end())
     3040        ListAdvance++;
     3041
     3042      connectedPath = *ListRunner;
     3043
     3044      // re-create all triangles by going through connected points list
     3045      list<class BoundaryLineSet *> NewLines;
     3046      for (;!connectedPath->empty();) {
     3047        // search middle node with widest angle to next neighbours
     3048        EndNode = connectedPath->end();
     3049        smallestangle = 0.;
     3050        for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) {
     3051          cout << Verbose(3) << "INFO: MiddleNode is " << **MiddleNode << "." << endl;
     3052          // construct vectors to next and previous neighbour
     3053          StartNode = MiddleNode;
     3054          if (StartNode == connectedPath->begin())
     3055            StartNode = connectedPath->end();
     3056          StartNode--;
     3057          //cout << Verbose(3) << "INFO: StartNode is " << **StartNode << "." << endl;
     3058          Point.CopyVector((*StartNode)->node);
     3059          Point.SubtractVector((*MiddleNode)->node);
     3060          StartNode = MiddleNode;
     3061          StartNode++;
     3062          if (StartNode == connectedPath->end())
     3063            StartNode = connectedPath->begin();
     3064          //cout << Verbose(3) << "INFO: EndNode is " << **StartNode << "." << endl;
     3065          Reference.CopyVector((*StartNode)->node);
     3066          Reference.SubtractVector((*MiddleNode)->node);
     3067          OrthogonalVector.CopyVector((*MiddleNode)->node);
     3068          OrthogonalVector.SubtractVector(&OldPoint);
     3069          OrthogonalVector.MakeNormalVector(&Reference);
     3070          angle = GetAngle(Point, Reference, OrthogonalVector);
     3071          //if (angle < M_PI)  // no wrong-sided triangles, please?
     3072            if(fabs(angle - M_PI) < fabs(smallestangle - M_PI)) {  // get straightest angle (i.e. construct those triangles with smallest area first)
     3073              smallestangle = angle;
     3074              EndNode = MiddleNode;
     3075            }
    27373076        }
    2738       } else { // no line
    2739         cout << Verbose(1) << "The line between " << nodes[i] << " and " << nodes[j] << " is not yet present, hence no need for a degenerate triangle." << endl;
    2740         result = true;
     3077        MiddleNode = EndNode;
     3078        if (MiddleNode == connectedPath->end()) {
     3079          cout << Verbose(1) << "CRITICAL: Could not find a smallest angle!" << endl;
     3080          exit(255);
     3081        }
     3082        StartNode = MiddleNode;
     3083        if (StartNode == connectedPath->begin())
     3084          StartNode = connectedPath->end();
     3085        StartNode--;
     3086        EndNode++;
     3087        if (EndNode == connectedPath->end())
     3088          EndNode = connectedPath->begin();
     3089        cout << Verbose(4) << "INFO: StartNode is " << **StartNode << "." << endl;
     3090        cout << Verbose(4) << "INFO: MiddleNode is " << **MiddleNode << "." << endl;
     3091        cout << Verbose(4) << "INFO: EndNode is " << **EndNode << "." << endl;
     3092        *out << Verbose(3) << "INFO: Attempting to create triangle " << (*StartNode)->Name << ", " << (*MiddleNode)->Name << " and " << (*EndNode)->Name << "." << endl;
     3093        TriangleCandidates[0] = *StartNode;
     3094        TriangleCandidates[1] = *MiddleNode;
     3095        TriangleCandidates[2] = *EndNode;
     3096        triangle = GetPresentTriangle(out, TriangleCandidates);
     3097        if (triangle != NULL) {
     3098          cout << Verbose(1) << "WARNING: New triangle already present, skipping!" << endl;
     3099          StartNode++;
     3100          MiddleNode++;
     3101          EndNode++;
     3102          if (StartNode == connectedPath->end())
     3103            StartNode = connectedPath->begin();
     3104          if (MiddleNode == connectedPath->end())
     3105            MiddleNode = connectedPath->begin();
     3106          if (EndNode == connectedPath->end())
     3107            EndNode = connectedPath->begin();
     3108          continue;
     3109        }
     3110        *out << Verbose(5) << "Adding new triangle points."<< endl;
     3111        AddTesselationPoint(*StartNode, 0);
     3112        AddTesselationPoint(*MiddleNode, 1);
     3113        AddTesselationPoint(*EndNode, 2);
     3114        *out << Verbose(5) << "Adding new triangle lines."<< endl;
     3115        AddTesselationLine(TPS[0], TPS[1], 0);
     3116        AddTesselationLine(TPS[0], TPS[2], 1);
     3117        NewLines.push_back(BLS[1]);
     3118        AddTesselationLine(TPS[1], TPS[2], 2);
     3119        BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     3120        BTS->GetNormalVector(NormalVector);
     3121        AddTesselationTriangle();
     3122        // calculate volume summand as a general tetraeder
     3123        volume += CalculateVolumeofGeneralTetraeder(TPS[0]->node->node, TPS[1]->node->node, TPS[2]->node->node, &OldPoint);
     3124        // advance number
     3125        count++;
     3126
     3127        // prepare nodes for next triangle
     3128        StartNode = EndNode;
     3129        cout << Verbose(4) << "Removing " << **MiddleNode << " from closed path, remaining points: " << connectedPath->size() << "." << endl;
     3130        connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles)
     3131        if (connectedPath->size() == 2) { // we are done
     3132          connectedPath->remove(*StartNode); // remove the start node
     3133          connectedPath->remove(*EndNode); // remove the end node
     3134          break;
     3135        } else if (connectedPath->size() < 2) { // something's gone wrong!
     3136          cout << Verbose(1) << "CRITICAL: There are only two endpoints left!" << endl;
     3137          exit(255);
     3138        } else {
     3139          MiddleNode = StartNode;
     3140          MiddleNode++;
     3141          if (MiddleNode == connectedPath->end())
     3142            MiddleNode = connectedPath->begin();
     3143          EndNode = MiddleNode;
     3144          EndNode++;
     3145          if (EndNode == connectedPath->end())
     3146            EndNode = connectedPath->begin();
     3147        }
    27413148      }
    2742     }
    2743   if (counter > 1) {
    2744     cout << Verbose(2) << "INFO: Degenerate triangle is ok, at least two, here " << counter << ", existing lines are used." << endl;
    2745     result = true;
    2746   }
    2747   return result;
    2748 };
    2749 
    2750 
    2751 /** Sort function for the candidate list.
    2752  */
    2753 bool SortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2)
    2754 {
    2755   Vector BaseLineVector, OrthogonalVector, helper;
    2756   if (candidate1->BaseLine != candidate2->BaseLine) {  // sanity check
    2757     cout << Verbose(0) << "ERROR: sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl;
    2758     //return false;
    2759     exit(1);
    2760   }
    2761   // create baseline vector
    2762   BaseLineVector.CopyVector(candidate1->BaseLine->endpoints[1]->node->node);
    2763   BaseLineVector.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node);
    2764   BaseLineVector.Normalize();
    2765 
    2766   // create normal in-plane vector to cope with acos() non-uniqueness on [0,2pi] (note that is pointing in the "right" direction already, hence ">0" test!)
    2767   helper.CopyVector(candidate1->BaseLine->endpoints[0]->node->node);
    2768   helper.SubtractVector(candidate1->point->node);
    2769   OrthogonalVector.CopyVector(&helper);
    2770   helper.VectorProduct(&BaseLineVector);
    2771   OrthogonalVector.SubtractVector(&helper);
    2772   OrthogonalVector.Normalize();
    2773 
    2774   // calculate both angles and correct with in-plane vector
    2775   helper.CopyVector(candidate1->point->node);
    2776   helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node);
    2777   double phi = BaseLineVector.Angle(&helper);
    2778   if (OrthogonalVector.ScalarProduct(&helper) > 0) {
    2779     phi = 2.*M_PI - phi;
    2780   }
    2781   helper.CopyVector(candidate2->point->node);
    2782   helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node);
    2783   double psi = BaseLineVector.Angle(&helper);
    2784   if (OrthogonalVector.ScalarProduct(&helper) > 0) {
    2785     psi = 2.*M_PI - psi;
    2786   }
    2787 
    2788   cout << Verbose(2) << *candidate1->point << " has angle " << phi << endl;
    2789   cout << Verbose(2) << *candidate2->point << " has angle " << psi << endl;
    2790 
    2791   // return comparison
    2792   return phi < psi;
    2793 };
    2794 
    2795 /**
    2796  * Finds the point which is second closest to the provided one.
    2797  *
    2798  * @param Point to which to find the second closest other point
    2799  * @param linked cell structure
    2800  *
    2801  * @return point which is second closest to the provided one
    2802  */
    2803 TesselPoint* FindSecondClosestPoint(const Vector* Point, LinkedCell* LC)
    2804 {
    2805   LinkedNodes *List = NULL;
    2806   TesselPoint* closestPoint = NULL;
    2807   TesselPoint* secondClosestPoint = NULL;
    2808   double distance = 1e16;
    2809   double secondDistance = 1e16;
    2810   Vector helper;
    2811   int N[NDIM], Nlower[NDIM], Nupper[NDIM];
    2812 
    2813   LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly
    2814   for(int i=0;i<NDIM;i++) // store indices of this cell
    2815     N[i] = LC->n[i];
    2816   cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;
    2817 
    2818   LC->GetNeighbourBounds(Nlower, Nupper);
    2819   //cout << endl;
    2820   for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
    2821     for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
    2822       for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
    2823         List = LC->GetCurrentCell();
    2824         cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;
    2825         if (List != NULL) {
    2826           for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
    2827             helper.CopyVector(Point);
    2828             helper.SubtractVector((*Runner)->node);
    2829             double currentNorm = helper. Norm();
    2830             if (currentNorm < distance) {
    2831               // remember second point
    2832               secondDistance = distance;
    2833               secondClosestPoint = closestPoint;
    2834               // mark down new closest point
    2835               distance = currentNorm;
    2836               closestPoint = (*Runner);
    2837               cout << Verbose(2) << "INFO: New Nearest Neighbour is " << *closestPoint << "." << endl;
     3149      // maximize the inner lines (we preferentially created lines with a huge angle, which is for the tesselation not wanted though useful for the closing)
     3150      if (NewLines.size() > 1) {
     3151        list<class BoundaryLineSet *>::iterator Candidate;
     3152        class BoundaryLineSet *OtherBase = NULL;
     3153        double tmp, maxgain;
     3154        do {
     3155          maxgain = 0;
     3156          for(list<class BoundaryLineSet *>::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) {
     3157            tmp = PickFarthestofTwoBaselines(out, *Runner);
     3158            if (maxgain < tmp) {
     3159              maxgain = tmp;
     3160              Candidate = Runner;
    28383161            }
    28393162          }
    2840         } else {
    2841           cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << ","
    2842             << LC->n[2] << " is invalid!" << endl;
    2843         }
     3163          if (maxgain != 0) {
     3164            volume += maxgain;
     3165            cout << Verbose(3) << "Flipping baseline with highest volume" << **Candidate << "." << endl;
     3166            OtherBase = FlipBaseline(out, *Candidate);
     3167            NewLines.erase(Candidate);
     3168            NewLines.push_back(OtherBase);
     3169          }
     3170        } while (maxgain != 0.);
    28443171      }
    28453172
    2846   return secondClosestPoint;
    2847 };
    2848 
    2849 /**
    2850  * Finds the point which is closest to the provided one.
    2851  *
    2852  * @param Point to which to find the closest other point
    2853  * @param SecondPoint the second closest other point on return, NULL if none found
    2854  * @param linked cell structure
    2855  *
    2856  * @return point which is closest to the provided one, NULL if none found
    2857  */
    2858 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, LinkedCell* LC)
    2859 {
    2860   LinkedNodes *List = NULL;
    2861   TesselPoint* closestPoint = NULL;
    2862   SecondPoint = NULL;
    2863   double distance = 1e16;
    2864   double secondDistance = 1e16;
    2865   Vector helper;
    2866   int N[NDIM], Nlower[NDIM], Nupper[NDIM];
    2867 
    2868   LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly
    2869   for(int i=0;i<NDIM;i++) // store indices of this cell
    2870     N[i] = LC->n[i];
    2871   cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;
    2872 
    2873   LC->GetNeighbourBounds(Nlower, Nupper);
    2874   //cout << endl;
    2875   for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
    2876     for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
    2877       for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
    2878         List = LC->GetCurrentCell();
    2879         cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;
    2880         if (List != NULL) {
    2881           for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
    2882             helper.CopyVector(Point);
    2883             helper.SubtractVector((*Runner)->node);
    2884             double currentNorm = helper. Norm();
    2885             if (currentNorm < distance) {
    2886               secondDistance = distance;
    2887               SecondPoint = closestPoint;
    2888               distance = currentNorm;
    2889               closestPoint = (*Runner);
    2890               cout << Verbose(2) << "INFO: New Nearest Neighbour is " << *closestPoint << "." << endl;
    2891             } else if (currentNorm < secondDistance) {
    2892               secondDistance = currentNorm;
    2893               SecondPoint = (*Runner);
    2894               cout << Verbose(2) << "INFO: New Second Nearest Neighbour is " << *SecondPoint << "." << endl;
    2895             }
    2896           }
    2897         } else {
    2898           cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << ","
    2899             << LC->n[2] << " is invalid!" << endl;
    2900         }
    2901       }
    2902 
    2903   return closestPoint;
    2904 };
     3173      ListOfClosedPaths->remove(connectedPath);
     3174      delete(connectedPath);
     3175    }
     3176    *out << Verbose(1) << count << " triangles were created." << endl;
     3177  } else {
     3178    while (!ListOfClosedPaths->empty()) {
     3179      ListRunner = ListOfClosedPaths->begin();
     3180      connectedPath = *ListRunner;
     3181      ListOfClosedPaths->remove(connectedPath);
     3182      delete(connectedPath);
     3183    }
     3184    *out << Verbose(1) << "No need to create any triangles." << endl;
     3185  }
     3186  delete(ListOfClosedPaths);
     3187
     3188  *out << Verbose(1) << "Removed volume is " << volume << "." << endl;
     3189
     3190  return volume;
     3191};
     3192
     3193
    29053194
    29063195/**
     
    29393228              FindTriangle = FindLine->second->triangles.begin();
    29403229              for (; FindTriangle != FindLine->second->triangles.end(); FindTriangle++) {
    2941                 if ((
    2942                   (FindTriangle->second->endpoints[0] == TrianglePoints[0])
    2943                     || (FindTriangle->second->endpoints[0] == TrianglePoints[1])
    2944                     || (FindTriangle->second->endpoints[0] == TrianglePoints[2])
    2945                   ) && (
    2946                     (FindTriangle->second->endpoints[1] == TrianglePoints[0])
    2947                     || (FindTriangle->second->endpoints[1] == TrianglePoints[1])
    2948                     || (FindTriangle->second->endpoints[1] == TrianglePoints[2])
    2949                   ) && (
    2950                     (FindTriangle->second->endpoints[2] == TrianglePoints[0])
    2951                     || (FindTriangle->second->endpoints[2] == TrianglePoints[1])
    2952                     || (FindTriangle->second->endpoints[2] == TrianglePoints[2])
    2953                   )
    2954                 ) {
     3230                if (FindTriangle->second->IsPresentTupel(TrianglePoints)) {
    29553231                  result->push_back(FindTriangle->second);
    29563232                }
     
    29703246
    29713247/**
     3248 * Finds all degenerated lines within the tesselation structure.
     3249 *
     3250 * @return map of keys of degenerated line pairs, each line occurs twice
     3251 *         in the list, once as key and once as value
     3252 */
     3253map<int, int> * Tesselation::FindAllDegeneratedLines()
     3254{
     3255  map<int, class BoundaryLineSet *> AllLines;
     3256  map<int, int> * DegeneratedLines = new map<int, int>;
     3257
     3258  // sanity check
     3259  if (LinesOnBoundary.empty()) {
     3260    cout << Verbose(1) << "Warning: FindAllDegeneratedTriangles() was called without any tesselation structure.";
     3261    return DegeneratedLines;
     3262  }
     3263
     3264  LineMap::iterator LineRunner1;
     3265  pair<LineMap::iterator, bool> tester;
     3266  for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) {
     3267    tester = AllLines.insert( pair<int,BoundaryLineSet *> (LineRunner1->second->endpoints[0]->Nr, LineRunner1->second) );
     3268    if ((!tester.second) && (tester.first->second->endpoints[1]->Nr == LineRunner1->second->endpoints[1]->Nr)) { // found degenerated line
     3269      DegeneratedLines->insert ( pair<int, int> (LineRunner1->second->Nr, tester.first->second->Nr) );
     3270      DegeneratedLines->insert ( pair<int, int> (tester.first->second->Nr, LineRunner1->second->Nr) );
     3271    }
     3272  }
     3273
     3274  AllLines.clear();
     3275
     3276  cout << Verbose(1) << "FindAllDegeneratedLines() found " << DegeneratedLines->size() << " lines." << endl;
     3277  map<int,int>::iterator it;
     3278  for (it = DegeneratedLines->begin(); it != DegeneratedLines->end(); it++)
     3279      cout << Verbose(2) << (*it).first << " => " << (*it).second << endl;
     3280
     3281  return DegeneratedLines;
     3282}
     3283
     3284/**
    29723285 * Finds all degenerated triangles within the tesselation structure.
    29733286 *
     
    29753288 *         in the list, once as key and once as value
    29763289 */
    2977 map<int, int> Tesselation::FindAllDegeneratedTriangles()
    2978 {
    2979   map<int, int> DegeneratedTriangles;
    2980 
    2981   // sanity check
    2982   if (LinesOnBoundary.empty()) {
    2983     cout << Verbose(1) << "Warning: FindAllDegeneratedTriangles() was called without any tesselation structure.";
    2984     return DegeneratedTriangles;
    2985   }
    2986 
    2987   LineMap::iterator LineRunner1, LineRunner2;
    2988 
    2989   for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) {
    2990     for (LineRunner2 = LinesOnBoundary.begin(); LineRunner2 != LinesOnBoundary.end(); ++LineRunner2) {
    2991       if ((LineRunner1->second != LineRunner2->second)
    2992         && (LineRunner1->second->endpoints[0] == LineRunner2->second->endpoints[0])
    2993         && (LineRunner1->second->endpoints[1] == LineRunner2->second->endpoints[1])
    2994       ) {
    2995         TriangleMap::iterator TriangleRunner1 = LineRunner1->second->triangles.begin(),
    2996           TriangleRunner2 = LineRunner2->second->triangles.begin();
    2997 
    2998         for (; TriangleRunner1 != LineRunner1->second->triangles.end(); ++TriangleRunner1) {
    2999           for (; TriangleRunner2 != LineRunner2->second->triangles.end(); ++TriangleRunner2) {
    3000             if ((TriangleRunner1->second != TriangleRunner2->second)
    3001               && (TriangleRunner1->second->endpoints[0] == TriangleRunner2->second->endpoints[0])
    3002               && (TriangleRunner1->second->endpoints[1] == TriangleRunner2->second->endpoints[1])
    3003               && (TriangleRunner1->second->endpoints[2] == TriangleRunner2->second->endpoints[2])
    3004             ) {
    3005               DegeneratedTriangles[TriangleRunner1->second->Nr] = TriangleRunner2->second->Nr;
    3006               DegeneratedTriangles[TriangleRunner2->second->Nr] = TriangleRunner1->second->Nr;
    3007             }
    3008           }
     3290map<int, int> * Tesselation::FindAllDegeneratedTriangles()
     3291{
     3292  map<int, int> * DegeneratedLines = FindAllDegeneratedLines();
     3293  map<int, int> * DegeneratedTriangles = new map<int, int>;
     3294
     3295  TriangleMap::iterator TriangleRunner1, TriangleRunner2;
     3296  LineMap::iterator Liner;
     3297  class BoundaryLineSet *line1 = NULL, *line2 = NULL;
     3298
     3299  for (map<int, int>::iterator LineRunner = DegeneratedLines->begin(); LineRunner != DegeneratedLines->end(); ++LineRunner) {
     3300    // run over both lines' triangles
     3301    Liner = LinesOnBoundary.find(LineRunner->first);
     3302    if (Liner != LinesOnBoundary.end())
     3303      line1 = Liner->second;
     3304    Liner = LinesOnBoundary.find(LineRunner->second);
     3305    if (Liner != LinesOnBoundary.end())
     3306      line2 = Liner->second;
     3307    for (TriangleRunner1 = line1->triangles.begin(); TriangleRunner1 != line1->triangles.end(); ++TriangleRunner1) {
     3308      for (TriangleRunner2 = line2->triangles.begin(); TriangleRunner2 != line2->triangles.end(); ++TriangleRunner2) {
     3309        if ((TriangleRunner1->second != TriangleRunner2->second)
     3310          && (TriangleRunner1->second->IsPresentTupel(TriangleRunner2->second))) {
     3311          DegeneratedTriangles->insert( pair<int, int> (TriangleRunner1->second->Nr, TriangleRunner2->second->Nr) );
     3312          DegeneratedTriangles->insert( pair<int, int> (TriangleRunner2->second->Nr, TriangleRunner1->second->Nr) );
    30093313        }
    30103314      }
    30113315    }
    30123316  }
    3013 
    3014   cout << Verbose(1) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles.size() << " triangles." << endl;
     3317  delete(DegeneratedLines);
     3318
     3319  cout << Verbose(1) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles->size() << " triangles:" << endl;
    30153320  map<int,int>::iterator it;
    3016   for (it = DegeneratedTriangles.begin(); it != DegeneratedTriangles.end(); it++)
     3321  for (it = DegeneratedTriangles->begin(); it != DegeneratedTriangles->end(); it++)
    30173322      cout << Verbose(2) << (*it).first << " => " << (*it).second << endl;
    30183323
     
    30263331void Tesselation::RemoveDegeneratedTriangles()
    30273332{
    3028   map<int, int> DegeneratedTriangles = FindAllDegeneratedTriangles();
    3029 
    3030   for (map<int, int>::iterator TriangleKeyRunner = DegeneratedTriangles.begin();
    3031     TriangleKeyRunner != DegeneratedTriangles.end(); ++TriangleKeyRunner
     3333  map<int, int> * DegeneratedTriangles = FindAllDegeneratedTriangles();
     3334  TriangleMap::iterator finder;
     3335  BoundaryTriangleSet *triangle = NULL, *partnerTriangle = NULL;
     3336  int count  = 0;
     3337
     3338  cout << Verbose(1) << "Begin of RemoveDegeneratedTriangles" << endl;
     3339
     3340  for (map<int, int>::iterator TriangleKeyRunner = DegeneratedTriangles->begin();
     3341    TriangleKeyRunner != DegeneratedTriangles->end(); ++TriangleKeyRunner
    30323342  ) {
    3033     BoundaryTriangleSet *triangle = TrianglesOnBoundary.find(TriangleKeyRunner->first)->second,
    3034       *partnerTriangle = TrianglesOnBoundary.find(TriangleKeyRunner->second)->second;
     3343    finder = TrianglesOnBoundary.find(TriangleKeyRunner->first);
     3344    if (finder != TrianglesOnBoundary.end())
     3345      triangle = finder->second;
     3346    else
     3347      break;
     3348    finder = TrianglesOnBoundary.find(TriangleKeyRunner->second);
     3349    if (finder != TrianglesOnBoundary.end())
     3350      partnerTriangle = finder->second;
     3351    else
     3352      break;
    30353353
    30363354    bool trianglesShareLine = false;
     
    30443362      && (triangle->endpoints[0]->LinesCount > 2)
    30453363    ) {
     3364      // check whether we have to fix lines
     3365      BoundaryTriangleSet *Othertriangle = NULL;
     3366      BoundaryTriangleSet *OtherpartnerTriangle = NULL;
     3367      TriangleMap::iterator TriangleRunner;
     3368      for (int i = 0; i < 3; ++i)
     3369        for (int j = 0; j < 3; ++j)
     3370          if (triangle->lines[i] != partnerTriangle->lines[j]) {
     3371            // get the other two triangles
     3372            for (TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); ++TriangleRunner)
     3373              if (TriangleRunner->second != triangle) {
     3374                Othertriangle = TriangleRunner->second;
     3375              }
     3376            for (TriangleRunner = partnerTriangle->lines[i]->triangles.begin(); TriangleRunner != partnerTriangle->lines[i]->triangles.end(); ++TriangleRunner)
     3377              if (TriangleRunner->second != partnerTriangle) {
     3378                OtherpartnerTriangle = TriangleRunner->second;
     3379              }
     3380            /// interchanges their lines so that triangle->lines[i] == partnerTriangle->lines[j]
     3381            // the line of triangle receives the degenerated ones
     3382            triangle->lines[i]->triangles.erase(Othertriangle->Nr);
     3383            triangle->lines[i]->triangles.insert( TrianglePair( partnerTriangle->Nr, partnerTriangle) );
     3384            for (int k=0;k<3;k++)
     3385              if (triangle->lines[i] == Othertriangle->lines[k]) {
     3386                Othertriangle->lines[k] = partnerTriangle->lines[j];
     3387                break;
     3388              }
     3389            // the line of partnerTriangle receives the non-degenerated ones
     3390            partnerTriangle->lines[j]->triangles.erase( partnerTriangle->Nr);
     3391            partnerTriangle->lines[j]->triangles.insert( TrianglePair( Othertriangle->Nr, Othertriangle) );
     3392            partnerTriangle->lines[j] = triangle->lines[i];
     3393          }
     3394
     3395      // erase the pair
     3396      count += (int) DegeneratedTriangles->erase(triangle->Nr);
    30463397      cout << Verbose(1) << "RemoveDegeneratedTriangles() removes triangle " << *triangle << "." << endl;
    30473398      RemoveTesselationTriangle(triangle);
     3399      count += (int) DegeneratedTriangles->erase(partnerTriangle->Nr);
    30483400      cout << Verbose(1) << "RemoveDegeneratedTriangles() removes triangle " << *partnerTriangle << "." << endl;
    30493401      RemoveTesselationTriangle(partnerTriangle);
    3050       DegeneratedTriangles.erase(DegeneratedTriangles.find(partnerTriangle->Nr));
    30513402    } else {
    30523403      cout << Verbose(1) << "RemoveDegeneratedTriangles() does not remove triangle " << *triangle
     
    30553406    }
    30563407  }
     3408  delete(DegeneratedTriangles);
     3409
     3410  cout << Verbose(1) << "RemoveDegeneratedTriangles() removed " << count << " triangles:" << endl;
     3411  cout << Verbose(1) << "End of RemoveDegeneratedTriangles" << endl;
    30573412}
    30583413
    3059 /** Gets the angle between a point and a reference relative to the provided center.
    3060  * We have two shanks point and reference between which the angle is calculated
    3061  * and by scalar product with OrthogonalVector we decide the interval.
    3062  * @param point to calculate the angle for
    3063  * @param reference to which to calculate the angle
    3064  * @param OrthogonalVector points in direction of [pi,2pi] interval
    3065  *
    3066  * @return angle between point and reference
    3067  */
    3068 double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector)
    3069 {
    3070   if (reference.IsZero())
    3071     return M_PI;
    3072 
    3073   // calculate both angles and correct with in-plane vector
    3074   if (point.IsZero())
    3075     return M_PI;
    3076   double phi = point.Angle(&reference);
    3077   if (OrthogonalVector.ScalarProduct(&point) > 0) {
    3078     phi = 2.*M_PI - phi;
    3079   }
    3080 
    3081   cout << Verbose(3) << "INFO: " << point << " has angle " << phi << " with respect to reference " << reference << "." << endl;
    3082 
    3083   return phi;
    3084 }
    3085 
     3414/** Adds an outside Tesselpoint to the envelope via (two) degenerated triangles.
     3415 * We look for the closest point on the boundary, we look through its connected boundary lines and
     3416 * seek the one with the minimum angle between its center point and the new point and this base line.
     3417 * We open up the line by adding a degenerated triangle, whose other side closes the base line again.
     3418 * \param *out output stream for debugging
     3419 * \param *point point to add
     3420 * \param *LC Linked Cell structure to find nearest point
     3421 */
     3422void Tesselation::AddBoundaryPointByDegeneratedTriangle(ofstream *out, class TesselPoint *point, LinkedCell *LC)
     3423{
     3424  *out << Verbose(2) << "Begin of AddBoundaryPointByDegeneratedTriangle" << endl;
     3425
     3426  // find nearest boundary point
     3427  class TesselPoint *BackupPoint = NULL;
     3428  class TesselPoint *NearestPoint = FindClosestPoint(point->node, BackupPoint, LC);
     3429  class BoundaryPointSet *NearestBoundaryPoint = NULL;
     3430  PointMap::iterator PointRunner;
     3431
     3432  if (NearestPoint == point)
     3433    NearestPoint = BackupPoint;
     3434  PointRunner = PointsOnBoundary.find(NearestPoint->nr);
     3435  if (PointRunner != PointsOnBoundary.end()) {
     3436    NearestBoundaryPoint = PointRunner->second;
     3437  } else {
     3438    *out << Verbose(1) << "ERROR: I cannot find the boundary point." << endl;
     3439    return;
     3440  }
     3441  *out << Verbose(2) << "Nearest point on boundary is " << NearestPoint->Name << "." << endl;
     3442
     3443  // go through its lines and find the best one to split
     3444  Vector CenterToPoint;
     3445  Vector BaseLine;
     3446  double angle, BestAngle = 0.;
     3447  class BoundaryLineSet *BestLine = NULL;
     3448  for (LineMap::iterator Runner = NearestBoundaryPoint->lines.begin(); Runner != NearestBoundaryPoint->lines.end(); Runner++) {
     3449    BaseLine.CopyVector(Runner->second->endpoints[0]->node->node);
     3450    BaseLine.SubtractVector(Runner->second->endpoints[1]->node->node);
     3451    CenterToPoint.CopyVector(Runner->second->endpoints[0]->node->node);
     3452    CenterToPoint.AddVector(Runner->second->endpoints[1]->node->node);
     3453    CenterToPoint.Scale(0.5);
     3454    CenterToPoint.SubtractVector(point->node);
     3455    angle = CenterToPoint.Angle(&BaseLine);
     3456    if (fabs(angle - M_PI/2.) < fabs(BestAngle - M_PI/2.)) {
     3457      BestAngle = angle;
     3458      BestLine = Runner->second;
     3459    }
     3460  }
     3461
     3462  // remove one triangle from the chosen line
     3463  class BoundaryTriangleSet *TempTriangle = (BestLine->triangles.begin())->second;
     3464  BestLine->triangles.erase(TempTriangle->Nr);
     3465  int nr = -1;
     3466  for (int i=0;i<3; i++) {
     3467    if (TempTriangle->lines[i] == BestLine) {
     3468      nr = i;
     3469      break;
     3470    }
     3471  }
     3472
     3473  // create new triangle to connect point (connects automatically with the missing spot of the chosen line)
     3474  *out << Verbose(5) << "Adding new triangle points."<< endl;
     3475  AddTesselationPoint((BestLine->endpoints[0]->node), 0);
     3476  AddTesselationPoint((BestLine->endpoints[1]->node), 1);
     3477  AddTesselationPoint(point, 2);
     3478  *out << Verbose(5) << "Adding new triangle lines."<< endl;
     3479  AddTesselationLine(TPS[0], TPS[1], 0);
     3480  AddTesselationLine(TPS[0], TPS[2], 1);
     3481  AddTesselationLine(TPS[1], TPS[2], 2);
     3482  BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     3483  BTS->GetNormalVector(TempTriangle->NormalVector);
     3484  BTS->NormalVector.Scale(-1.);
     3485  *out << Verbose(3) << "INFO: NormalVector of new triangle is " << BTS->NormalVector << "." << endl;
     3486  AddTesselationTriangle();
     3487
     3488  // create other side of this triangle and close both new sides of the first created triangle
     3489  *out << Verbose(5) << "Adding new triangle points."<< endl;
     3490  AddTesselationPoint((BestLine->endpoints[0]->node), 0);
     3491  AddTesselationPoint((BestLine->endpoints[1]->node), 1);
     3492  AddTesselationPoint(point, 2);
     3493  *out << Verbose(5) << "Adding new triangle lines."<< endl;
     3494  AddTesselationLine(TPS[0], TPS[1], 0);
     3495  AddTesselationLine(TPS[0], TPS[2], 1);
     3496  AddTesselationLine(TPS[1], TPS[2], 2);
     3497  BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     3498  BTS->GetNormalVector(TempTriangle->NormalVector);
     3499  *out << Verbose(3) << "INFO: NormalVector of other new triangle is " << BTS->NormalVector << "." << endl;
     3500  AddTesselationTriangle();
     3501
     3502  // add removed triangle to the last open line of the second triangle
     3503  for (int i=0;i<3;i++) { // look for the same line as BestLine (only it's its degenerated companion)
     3504    if ((BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[0])) && (BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[1]))) {
     3505      if (BestLine == BTS->lines[i]){
     3506        *out << Verbose(1) << "CRITICAL: BestLine is same as found line, something's wrong here!" << endl;
     3507        exit(255);
     3508      }
     3509      BTS->lines[i]->triangles.insert( pair<int, class BoundaryTriangleSet *> (TempTriangle->Nr, TempTriangle) );
     3510      TempTriangle->lines[nr] = BTS->lines[i];
     3511      break;
     3512    }
     3513  }
     3514
     3515  // exit
     3516  *out << Verbose(2) << "End of AddBoundaryPointByDegeneratedTriangle" << endl;
     3517};
     3518
     3519/** Writes the envelope to file.
     3520 * \param *out otuput stream for debugging
     3521 * \param *filename basename of output file
     3522 * \param *cloud PointCloud structure with all nodes
     3523 */
     3524void Tesselation::Output(ofstream *out, const char *filename, PointCloud *cloud)
     3525{
     3526  ofstream *tempstream = NULL;
     3527  string NameofTempFile;
     3528  char NumberName[255];
     3529
     3530  if (LastTriangle != NULL) {
     3531    sprintf(NumberName, "-%04d-%s_%s_%s", (int)TrianglesOnBoundary.size(), LastTriangle->endpoints[0]->node->Name, LastTriangle->endpoints[1]->node->Name, LastTriangle->endpoints[2]->node->Name);
     3532    if (DoTecplotOutput) {
     3533      string NameofTempFile(filename);
     3534      NameofTempFile.append(NumberName);
     3535      for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos))
     3536      NameofTempFile.erase(npos, 1);
     3537      NameofTempFile.append(TecplotSuffix);
     3538      *out << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
     3539      tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
     3540      WriteTecplotFile(out, tempstream, this, cloud, TriangleFilesWritten);
     3541      tempstream->close();
     3542      tempstream->flush();
     3543      delete(tempstream);
     3544    }
     3545
     3546    if (DoRaster3DOutput) {
     3547      string NameofTempFile(filename);
     3548      NameofTempFile.append(NumberName);
     3549      for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos))
     3550      NameofTempFile.erase(npos, 1);
     3551      NameofTempFile.append(Raster3DSuffix);
     3552      *out << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
     3553      tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
     3554      WriteRaster3dFile(out, tempstream, this, cloud);
     3555      IncludeSphereinRaster3D(out, tempstream, this, cloud);
     3556      tempstream->close();
     3557      tempstream->flush();
     3558      delete(tempstream);
     3559    }
     3560  }
     3561  if (DoTecplotOutput || DoRaster3DOutput)
     3562    TriangleFilesWritten++;
     3563};
Note: See TracChangeset for help on using the changeset viewer.