Changes in / [3b1798:0516fd]


Ignore:
Files:
172 added
138 deleted
32 edited

Legend:

Unmodified
Added
Removed
  • LinearAlgebra/src/LinearAlgebra/Line.cpp

    r3b1798 r0516fd  
    120120 */
    121121Vector Line::getIntersection(const Line& otherLine) const{
    122   Info FunctionInfo(__func__);
    123 
    124122  pointset line1Points = getPointsOnLine();
    125123
     
    151149  //}
    152150  if (fabs(M->Determinant()) > LINALG_MYEPSILON()) {
    153     Log() << Verbose(1) << "Determinant of coefficient matrix is NOT zero." << endl;
     151    eLog() << Verbose(2) << "Determinant of coefficient matrix is NOT zero." << endl;
    154152    throw SkewException() << LinearAlgebraDeterminant(M->Determinant()) << LinearAlgebraMatrixContent(&(*M));
    155153  }
    156154
    157   Log() << Verbose(1) << "INFO: Line1a = " << Line1a << ", Line1b = " << Line1b << ", Line2a = " << Line2a << ", Line2b = " << Line2b << "." << endl;
     155  Log() << Verbose(6) << "INFO: Line1a = " << Line1a << ", Line1b = " << Line1b << ", Line2a = " << Line2a << ", Line2b = " << Line2b << "." << endl;
    158156
    159157
     
    163161  Vector c = Line2a - Line1a;
    164162  Vector d = Line2b - Line1b;
    165   Log() << Verbose(1) << "INFO: a = " << a << ", b = " << b << ", c = " << c << "." << endl;
     163  Log() << Verbose(7) << "INFO: a = " << a << ", b = " << b << ", c = " << c << "." << endl;
    166164  if ((a.NormSquared() <= LINALG_MYEPSILON()) || (b.NormSquared() <= LINALG_MYEPSILON())) {
    167165   res.Zero();
    168    Log() << Verbose(1) << "At least one of the lines is ill-defined, i.e. offset equals second vector." << endl;
     166   eLog() << Verbose(2) << "At least one of the lines is ill-defined, i.e. offset equals second vector." << endl;
    169167   throw LinearDependenceException() << LinearAlgebraVectorPair( make_pair(&a, &b) );
    170168  }
     
    178176    if ((factor > -LINALG_MYEPSILON()) && (factor - 1. <= LINALG_MYEPSILON())) {
    179177      res = Line2a;
    180       Log() << Verbose(1) << "Lines conincide." << endl;
     178      Log() << Verbose(5) << "Lines conincide." << endl;
    181179      return res;
    182180    } else {
     
    185183      if ((factor > -LINALG_MYEPSILON()) && (factor - 1. <= LINALG_MYEPSILON())) {
    186184        res = Line2b;
    187         Log() << Verbose(1) << "Lines conincide." << endl;
     185        Log() << Verbose(5) << "Lines conincide." << endl;
    188186        return res;
    189187      }
    190188    }
    191     Log() << Verbose(1) << "Lines are parallel." << endl;
     189    eLog() << Verbose(2) << "Lines are parallel." << endl;
    192190    res.Zero();
    193191    throw LinearDependenceException() << LinearAlgebraVectorPair( make_pair(&a, &b) );
     
    201199  temp2 = a;
    202200  temp2.VectorProduct(b);
    203   Log() << Verbose(1) << "INFO: temp1 = " << temp1 << ", temp2 = " << temp2 << "." << endl;
     201  Log() << Verbose(7) << "INFO: temp1 = " << temp1 << ", temp2 = " << temp2 << "." << endl;
    204202  if (fabs(temp2.NormSquared()) > LINALG_MYEPSILON())
    205203    s = temp1.ScalarProduct(temp2)/temp2.NormSquared();
    206204  else
    207205    s = 0.;
    208   Log() << Verbose(1) << "Factor s is " << temp1.ScalarProduct(temp2) << "/" << temp2.NormSquared() << " = " << s << "." << endl;
     206  Log() << Verbose(6) << "Factor s is " << temp1.ScalarProduct(temp2) << "/" << temp2.NormSquared() << " = " << s << "." << endl;
    209207
    210208  // construct intersection
     
    212210  res.Scale(s);
    213211  res += Line1a;
    214   Log() << Verbose(1) << "Intersection is at " << res << "." << endl;
     212  Log() << Verbose(5) << "Intersection is at " << res << "." << endl;
    215213
    216214  return res;
  • configure.ac

    r3b1798 r0516fd  
    207207BOOST_ITERATOR
    208208BOOST_MULTIARRAY
     209BOOST_MULTIINDEXCONTAINER
    209210BOOST_MPL
    210211BOOST_PREPROCESSOR
  • doc/userguide/userguide.xml

    r3b1798 r0516fd  
    24052405          Non-convex envelope</title>
    24062406         
    2407           <para>This will create a non-convex envelope for a molecule.</para>
     2407          <para>This will create a non-convex envelope for a molecule and store
     2408          it to a file for viewing with external programs.</para>
    24082409
    24092410          <programlisting>
     
    24142415          <para>This tesselation file can be conveniently viewed with
    24152416          <productname>TecPlot</productname> or with one of the Tcl script
    2416           in the util folder with <productname>VMD</productname>.</para>
     2417          in the util folder with <productname>VMD</productname>. Also,
     2418          still pictures can be produced with <productname>Raster3D
     2419          </productname>.
     2420          <note>The required file header.r3d can be found in a subfolder of
     2421          the util folder.</note>
     2422          </para>
    24172423        </section>
    24182424
     
    24212427          envelope</title>
    24222428         
    2423           <para>This will create a convex envelope for a molecule.</para>
     2429          <para>This will create a convex envelope for a molecule and give the
     2430          volumes of both the non-convex and the convex envelope. This is good
     2431          for measuring the space a molecule takes up, e.g. when filling a
     2432          domain and taking care of correct densities.</para>
    24242433
    24252434          <programlisting>
     
    24282437          </programlisting>
    24292438
    2430           <para>This tesselation file can be conveniently viewed with
     2439          <para>This tesselation file can be likewise viewed with
    24312440          <productname>TecPlot</productname> or with one of the Tcl script
    24322441          in the util folder with <productname>VMD</productname>.</para>
  • m4/boost.m4

    r3b1798 r0516fd  
    814814[BOOST_FIND_HEADER([boost/multi_array.hpp])])
    815815
     816# BOOST_MULTIINDEXCCONTAINER()
     817# ------------------
     818# Look for Boost.MultiIndexContainer
     819BOOST_DEFUN([MultiIndexContainer],
     820[BOOST_FIND_HEADER([boost/multi_index_container.hpp])])
     821
    816822
    817823# BOOST_NUMERIC_UBLAS()
  • src/Actions/ActionQueue.cpp

    r3b1798 r0516fd  
    9898void ActionQueue::queueAction(const Action * const _action, enum Action::QueryOptions state)
    9999{
    100   OBSERVE;
    101   NOTIFY(ActionQueued);
    102100  Action *newaction = _action->clone(state);
    103101  newaction->prepare(state);
     
    123121    std::cerr << "ActionQueue cleared." << std::endl;
    124122  }
     123  if (lastActionOk) {
     124    OBSERVE;
     125    NOTIFY(ActionQueued);
     126    _lastchangedaction = newaction;
     127  }
    125128#else
    126129  {
     
    130133  mtx_queue.unlock();
    131134#endif
    132   _lastchangedaction = newaction;
    133135}
    134136
     
    193195        CurrentAction = (size_t)-1;
    194196      }
     197      if (lastActionOk) {
     198        OBSERVE;
     199        NOTIFY(ActionQueued);
     200        _lastchangedaction = actionqueue[CurrentAction];
     201      }
    195202      // access actionqueue, hence using mutex
    196203      mtx_queue.lock();
  • src/Actions/TesselationAction/ConvexEnvelopeAction.cpp

    r3b1798 r0516fd  
    6868    LOG(1, "Storing tecplot non-convex data in " << params.filenameNonConvex.get() << ".");
    6969    PointCloudAdaptor<molecule> cloud(mol, mol->name);
    70     LCList = new LinkedCell_deprecated(cloud, 100.);
     70    LCList = new LinkedCell_deprecated(cloud, 2.*params.SphereRadius.get());
    7171    //Boundaries *BoundaryPoints = NULL;
    7272    //FindConvexBorder(mol, BoundaryPoints, TesselStruct, LCList, argv[argptr]);
    7373    // TODO: Beide Funktionen sollten streams anstelle des Filenamen benutzen, besser fuer unit tests
    74     Success &= FindNonConvexBorder(mol, TesselStruct, LCList, 50., params.filenameNonConvex.get().string().c_str());
     74    Success &= FindNonConvexBorder(mol, TesselStruct, LCList, params.SphereRadius.get(), params.filenameNonConvex.get().string().c_str());
    7575    //RemoveAllBoundaryPoints(TesselStruct, mol, argv[argptr]);
    76     const double volumedifference = ConvexizeNonconvexEnvelope(TesselStruct, mol, params.filenameConvex.get().string().c_str());
     76    const double volumedifference =
     77        ConvexizeNonconvexEnvelope(TesselStruct, mol, params.filenameConvex.get().string().c_str(),
     78            params.DoOutputEveryStep.get());
     79    // check whether tesselated structure is truly convex
     80    if (!TesselStruct->isConvex()) {
     81      ELOG(1, "Tesselated surface has not been properly convexized.");
     82        Success = false;
     83    } else {
     84      LOG(2, "DEBUG: We do have a convex surface tesselation now.");
     85    }
     86    // we check whether all molecule's atoms are still inside
     87    std::vector<std::string> outside_atoms;
     88    for(molecule::const_iterator iter = mol->begin(); iter != mol->end(); ++iter)
     89      if (!TesselStruct->IsInnerPoint((*iter)->getPosition(), LCList))
     90        outside_atoms.push_back((*iter)->getName());
     91    if (outside_atoms.empty())
     92      LOG(2, "DEBUG: All molecule's atoms are inside the tesselated, convex surface.");
     93    else {
     94      ELOG(1, "The following atoms are not inside the tesselated, convex surface:"
     95          << outside_atoms);
     96      Success = false;
     97    }
     98
    7799    const double clustervolume = TesselStruct->getVolumeOfConvexEnvelope(configuration->GetIsAngstroem());
    78100    LOG(0, "The tesselated volume area is " << clustervolume << " " << (configuration->GetIsAngstroem() ? "angstrom" : "atomiclength") << "^3.");
     
    84106    return Action::success;
    85107  else {
    86     STATUS("Failed to find the non convex border.");
     108    STATUS(std::string("Failed to find the non convex border")
     109        +std::string("containing all atoms")
     110        +std::string("."));
    87111    return Action::failure;
    88112  }
  • src/Actions/TesselationAction/ConvexEnvelopeAction.def

    r3b1798 r0516fd  
    99class TesselationListClass;
    1010
     11#include "Parameters/Validators/DummyValidator.hpp"
    1112#include "Parameters/Validators/Ops_Validator.hpp"
     13#include "Parameters/Validators/Specific/BoxLengthValidator.hpp"
    1214#include "Parameters/Validators/Specific/FilePresentValidator.hpp"
    1315
     
    1517// ValueStorage by the token "Z" -> first column: int, Z, "Z"
    1618// "undefine" if no parameters are required, use (NOPARAM_DEFAULT) for each (undefined) default value
    17 #define paramtypes (boost::filesystem::path)(boost::filesystem::path)
    18 #define paramtokens ("convex-file")("nonconvex-file")
    19 #define paramdescriptions ("filename of the convex envelope")("filename of the non-convex envelope")
    20 #undef paramdefaults
    21 #define paramreferences (filenameConvex)(filenameNonConvex)
     19#define paramtypes (double)(boost::filesystem::path)(boost::filesystem::path)(bool)
     20#define paramtokens ("convex-envelope")("convex-file")("nonconvex-file")("DoOutputEveryStep")
     21#define paramdescriptions ("radius of the rolling sphere")("filename of the convex envelope")("filename of the non-convex envelope")("whether to write an extra file for debugging of each convexization step")
     22#define paramdefaults (NOPARAM_DEFAULT)(NOPARAM_DEFAULT)(NOPARAM_DEFAULT)(PARAM_DEFAULT(0))
     23#define paramreferences (SphereRadius)(filenameConvex)(filenameNonConvex)(DoOutputEveryStep)
    2224#define paramvalids \
     25(BoxLengthValidator()) \
    2326(!FilePresentValidator()) \
    24 (!FilePresentValidator())
     27(!FilePresentValidator()) \
     28(DummyValidator<bool>())
    2529
    2630#undef statetypes
  • src/Potentials/Specifics/ConstantPotential.cpp

    r3b1798 r0516fd  
    6363    ;
    6464const std::string ConstantPotential::potential_token("constant");
    65 Coordinator::ptr ConstantPotential::coordinator(new OneBody_Constant());
     65Coordinator::ptr ConstantPotential::coordinator(Memory::ignore(new OneBody_Constant()));
    6666
    6767ConstantPotential::ConstantPotential() :
  • src/Potentials/Specifics/FourBodyPotential_Improper.cpp

    r3b1798 r0516fd  
    4949    ;
    5050const std::string FourBodyPotential_Improper::improper_token("improper");
    51 Coordinator::ptr FourBodyPotential_Improper::coordinator(new FourBody_ImproperAngle());
     51Coordinator::ptr FourBodyPotential_Improper::coordinator(Memory::ignore(new FourBody_ImproperAngle()));
    5252
    5353FourBodyPotential_Improper::FourBodyPotential_Improper() :
  • src/Potentials/Specifics/FourBodyPotential_Torsion.cpp

    r3b1798 r0516fd  
    6464    ;
    6565const std::string FourBodyPotential_Torsion::potential_token("torsion");
    66 Coordinator::ptr FourBodyPotential_Torsion::coordinator(new FourBody_TorsionAngle());
     66Coordinator::ptr FourBodyPotential_Torsion::coordinator(Memory::ignore(new FourBody_TorsionAngle()));
    6767
    6868FourBodyPotential_Torsion::FourBodyPotential_Torsion() :
  • src/Potentials/Specifics/ManyBodyPotential_Tersoff.cpp

    r3b1798 r0516fd  
    8080    ;
    8181const std::string ManyBodyPotential_Tersoff::potential_token("tersoff");
    82 Coordinator::ptr ManyBodyPotential_Tersoff::coordinator(new OneBody_Constant());
     82Coordinator::ptr ManyBodyPotential_Tersoff::coordinator(Memory::ignore(new OneBody_Constant()));
    8383
    8484ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff() :
  • src/Potentials/Specifics/PairPotential_Harmonic.cpp

    r3b1798 r0516fd  
    6565    ;
    6666const std::string PairPotential_Harmonic::potential_token("harmonic_bond");
    67 Coordinator::ptr PairPotential_Harmonic::coordinator(new TwoBody_Length());
     67Coordinator::ptr PairPotential_Harmonic::coordinator(Memory::ignore(new TwoBody_Length()));
    6868
    6969PairPotential_Harmonic::PairPotential_Harmonic() :
  • src/Potentials/Specifics/PairPotential_LennardJones.cpp

    r3b1798 r0516fd  
    6565    ;
    6666const std::string PairPotential_LennardJones::potential_token("lennardjones");
    67 Coordinator::ptr PairPotential_LennardJones::coordinator(new TwoBody_Length());
     67Coordinator::ptr PairPotential_LennardJones::coordinator(Memory::ignore(new TwoBody_Length()));
    6868
    6969void PairPotential_LennardJones::setDefaultParameters()
  • src/Potentials/Specifics/PairPotential_Morse.cpp

    r3b1798 r0516fd  
    6767    ;
    6868const std::string PairPotential_Morse::potential_token("morse");
    69 Coordinator::ptr PairPotential_Morse::coordinator(new TwoBody_Length());
     69Coordinator::ptr PairPotential_Morse::coordinator(Memory::ignore(new TwoBody_Length()));
    7070
    7171PairPotential_Morse::PairPotential_Morse() :
  • src/Potentials/Specifics/ThreeBodyPotential_Angle.cpp

    r3b1798 r0516fd  
    6565    ;
    6666const std::string ThreeBodyPotential_Angle::potential_token("harmonic_angle");
    67 Coordinator::ptr ThreeBodyPotential_Angle::coordinator(new ThreeBody_Angle());
     67Coordinator::ptr ThreeBodyPotential_Angle::coordinator(Memory::ignore(new ThreeBody_Angle()));
    6868
    6969ThreeBodyPotential_Angle::ThreeBodyPotential_Angle() :
  • src/Tesselation/BoundaryLineSet.cpp

    r3b1798 r0516fd  
    309309ostream & operator <<(ostream &ost, const BoundaryLineSet &a)
    310310{
    311   ost << "[" << a.Nr << "|" << a.endpoints[0]->node->getName() << " at " << a.endpoints[0]->node->getPosition() << "," << a.endpoints[1]->node->getName() << " at " << a.endpoints[1]->node->getPosition() << "]";
     311  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->getName() << "," << a.endpoints[1]->node->getName() << "]";
     312  //ost << "[" << a.Nr << "|" << a.endpoints[0]->node->getName() << " at " << a.endpoints[0]->node->getPosition() << "," << a.endpoints[1]->node->getName() << " at " << a.endpoints[1]->node->getPosition() << "]";
    312313  return ost;
    313314}
  • src/Tesselation/BoundaryPointSet.cpp

    r3b1798 r0516fd  
    133133ostream & operator <<(ostream &ost, const BoundaryPointSet &a)
    134134{
    135   ost << "[" << a.Nr << "|" << a.getName() << " at " << a.getPosition() << "]";
     135  ost << "[" << a.Nr << "|" << a.getName() << "]"; // " at " << a.getPosition() << "]";
    136136  return ost;
    137137}
  • src/Tesselation/BoundaryTriangleSet.cpp

    r3b1798 r0516fd  
    9494  // set endpoints
    9595  int Counter = 0;
    96   LOG(4, "DEBUG: New triangle " << Nr << " with end points: ");
     96  LOG(4, "DEBUG: New triangle " << Nr << " with end points ... and lines:");
    9797  for (PointMap::iterator runner = OrderMap.begin(); runner != OrderMap.end(); runner++) {
    9898    endpoints[Counter] = runner->second;
    99     LOG(4, "DEBUG:    " << *endpoints[Counter]);
     99    LOG(4, "DEBUG:    " << *endpoints[Counter] << "\t\t" << *lines[Counter]);
    100100    Counter++;
    101101  }
     
    246246
    247247  // 1. get intersection with plane
    248   LOG(3, "DEBUG: Looking for closest point of triangle " << *this << " to " << x << ".");
    249   LOG(3, "DEBUG: endpoints are " << endpoints[0]->node->getPosition() << ","
     248  LOG(4, "DEBUG: Looking for closest point of triangle " << *this << " to " << x << ".");
     249  LOG(5, "DEBUG: endpoints are " << endpoints[0]->node->getPosition() << ","
    250250      << endpoints[1]->node->getPosition() << ", and " << endpoints[2]->node->getPosition() << ".");
    251251  try {
     
    256256  }
    257257  Vector InPlane(ClosestPoint); // points from plane intersection to straight-down point
    258   LOG(4, "DEBUG: Closest point on triangle plane is " << ClosestPoint << ".");
     258  LOG(5, "DEBUG: Closest point on triangle plane is " << ClosestPoint << ".");
    259259
    260260  // 2. Calculate in plane part of line (x, intersection)
     
    269269    CrossPoint[i] = l.getClosestPoint(InPlane);
    270270    // NOTE: direction of line is normalized, hence s must not necessarily be in [0,1] for the baseline
    271     LOG(4, "DEBUG: Closest point on line from " << (endpoints[(i+1)%3]->node->getPosition())
     271    LOG(5, "DEBUG: Closest point on line from " << (endpoints[(i+1)%3]->node->getPosition())
    272272        << " to " << (endpoints[i%3]->node->getPosition()) << " is " << CrossPoint[i] << ".");
    273273    CrossPoint[i] -= (endpoints[(i+1)%3]->node->getPosition());  // cross point was returned as absolute vector
    274274    const double s = CrossPoint[i].ScalarProduct(Direction)/Direction.NormSquared();
    275     LOG(5, "DEBUG: Factor s is " << s << ".");
     275    LOG(6, "DEBUG: Factor s is " << s << ".");
    276276    if ((s >= -MYEPSILON) && ((s-1.) <= MYEPSILON)) {
    277277      CrossPoint[i] += (endpoints[(i+1)%3]->node->getPosition());  // make cross point absolute again
    278       LOG(5, "DEBUG: Crosspoint is " << CrossPoint[i] << ", intersecting BoundaryLine between "
     278      LOG(6, "DEBUG: Crosspoint is " << CrossPoint[i] << ", intersecting BoundaryLine between "
    279279          << endpoints[i % 3]->node->getPosition() << " and "
    280280          << endpoints[(i + 1) % 3]->node->getPosition() << ".");
     
    285285      else
    286286        CrossPoint[i] = (endpoints[i%3]->node->getPosition());
    287       LOG(5, "DEBUG: Crosspoint is " << CrossPoint[i] << ", intersecting outside of BoundaryLine between "
     287      LOG(6, "DEBUG: Crosspoint is " << CrossPoint[i] << ", intersecting outside of BoundaryLine between "
    288288          << endpoints[i % 3]->node->getPosition() << " and "
    289289          << endpoints[(i + 1) % 3]->node->getPosition() << ".");
     
    312312    ShortestDistance = InPlane.DistanceSquared(x);
    313313  }
    314   LOG(3, "DEBUG: Closest Point is " << ClosestPoint << " with shortest squared distance is " << ShortestDistance << ".");
     314  LOG(4, "DEBUG: Closest Point is " << ClosestPoint << " with shortest squared distance is " << ShortestDistance << ".");
    315315
    316316  return ShortestDistance;
     
    367367{
    368368  //Info FunctionInfo(__func__);
    369   LOG(1, "INFO: Checking " << Points[0] << "," << Points[1] << "," << Points[2] << " against " << endpoints[0] << "," << endpoints[1] << "," << endpoints[2] << ".");
    370   return (((endpoints[0] == Points[0]) || (endpoints[0] == Points[1]) || (endpoints[0] == Points[2])) && ((endpoints[1] == Points[0]) || (endpoints[1] == Points[1]) || (endpoints[1] == Points[2])) && ((endpoints[2] == Points[0]) || (endpoints[2] == Points[1]) || (endpoints[2] == Points[2])
     369  LOG(5, "DEBUG: Checking " << *Points[0] << "," << *Points[1] << "," << *Points[2]
     370      << " against " << *this); //*endpoints[0] << "," << *endpoints[1] << "," << *endpoints[2] << ".");
     371  return (((endpoints[0] == Points[0]) || (endpoints[0] == Points[1]) || (endpoints[0] == Points[2]))
     372      && ((endpoints[1] == Points[0]) || (endpoints[1] == Points[1]) || (endpoints[1] == Points[2]))
     373      && ((endpoints[2] == Points[0]) || (endpoints[2] == Points[1]) || (endpoints[2] == Points[2])
    371374
    372375  ));
  • src/Tesselation/CandidateForTesselation.cpp

    r3b1798 r0516fd  
    108108
    109109  if (!pointlist.empty())
    110     LOG(3, "DEBUG: Checking whether sphere contains candidate list and baseline " << *BaseLine->endpoints[0] << "<->" << *BaseLine->endpoints[1] << " only ...");
     110    LOG(3, "DEBUG: Checking validity whether sphere contains candidate list and baseline " << *BaseLine->endpoints[0] << "<->" << *BaseLine->endpoints[1] << " only ...");
    111111  else
    112     LOG(3, "DEBUG: Checking whether sphere with no candidates contains baseline " << *BaseLine->endpoints[0] << "<->" << *BaseLine->endpoints[1] << " only ...");
     112    LOG(3, "DEBUG: Checking validity whether sphere with no candidates contains baseline " << *BaseLine->endpoints[0] << "<->" << *BaseLine->endpoints[1] << " only ...");
    113113  // check baseline for OptCenter and OtherOptCenter being on sphere's surface
    114114  for (list<const Vector *>::const_iterator VRunner = VectorList.begin(); VRunner != VectorList.end(); ++VRunner) {
     
    131131        return false;
    132132      } else {
    133         LOG(3, "DEBUG: Candidate " << *Walker << " is inside by " << distance << ".");
     133        LOG(4, "DEBUG: Candidate " << *Walker << " is inside by " << distance << ".");
    134134      }
    135135    }
    136136  }
    137137
    138   LOG(2, "DEBUG: Checking whether sphere contains no others points ...");
     138  LOG(3, "DEBUG: Checking validity whether sphere contains no others points ...");
    139139  bool flag = true;
    140140  for (list<const Vector *>::const_iterator VRunner = VectorList.begin(); VRunner != VectorList.end(); ++VRunner) {
     
    143143
    144144    {
    145       LOG(3, "DEBUG: The following atoms are inside sphere at " << (*VRunner) << ":");
     145      LOG(4, "DEBUG: The following atoms are inside sphere at " << (*VRunner) << ":");
    146146      for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner)
    147         LOG(3, "DEBUG:  " << *(*Runner) << " with distance " << (*Runner)->distance(*(*VRunner)) << ".");
     147        LOG(4, "DEBUG:  " << *(*Runner) << " with distance " << (*Runner)->distance(*(*VRunner)) << ".");
    148148    }
    149149
    150150    // remove baseline's endpoints and candidates
    151151    for (int i = 0; i < 2; i++) {
    152       LOG(3, "DEBUG: removing baseline tesselpoint " << *BaseLine->endpoints[i]->node << ".");
     152      LOG(5, "DEBUG: removing baseline tesselpoint " << *BaseLine->endpoints[i]->node << ".");
    153153      ListofPoints->remove(BaseLine->endpoints[i]->node);
    154154    }
    155155    for (TesselPointList::const_iterator Runner = pointlist.begin(); Runner != pointlist.end(); ++Runner) {
    156       LOG(3, "DEBUG: removing candidate tesselpoint " << *(*Runner) << ".");
     156      LOG(5, "DEBUG: removing candidate tesselpoint " << *(*Runner) << ".");
    157157      ListofPoints->remove(*Runner);
    158158    }
  • src/Tesselation/boundary.cpp

    r3b1798 r0516fd  
    513513 * \return volume difference between the non- and the created convex envelope
    514514 */
    515 double ConvexizeNonconvexEnvelope(class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename)
     515double ConvexizeNonconvexEnvelope(
     516    Tesselation *&TesselStruct,
     517    const molecule * const mol,
     518    const char * const filename,
     519    bool DebugOutputEveryStep)
    516520{
    517521        //Info FunctionInfo(__func__);
     
    535539  }
    536540
    537   // First step: RemovePointFromTesselatedSurface
     541  LOG(1, "INFO: Making tesselated surface with " << TesselStruct->TrianglesOnBoundaryCount
     542      << " convex ...");
     543
     544  // first purge all degenerate triangles
     545  TesselStruct->RemoveDegeneratedTriangles();
     546
    538547  do {
    539548    Concavity = false;
    540     sprintf(dummy, "-first-%d", run);
    541     //CalculateConcavityPerBoundaryPoint(TesselStruct);
    542     StoreTrianglesinFile(mol, (const Tesselation *&)TesselStruct, filename, dummy);
    543 
     549
     550    if (DebugOutputEveryStep) {
     551      sprintf(dummy, "-%d", run++);
     552      //CalculateConcavityPerBoundaryPoint(TesselStruct);
     553      LOG(1, "INFO: Writing " << run << "th tesselation file.");
     554      StoreTrianglesinFile(mol, (const Tesselation *&)TesselStruct, filename, dummy);
     555    }
     556
     557    // first step: remove all full-concave point
    544558    PointRunner = TesselStruct->PointsOnBoundary.begin();
    545559    PointAdvance = PointRunner; // we need an advanced point, as the PointRunner might get removed
     
    547561      PointAdvance++;
    548562      point = PointRunner->second;
    549       LOG(1, "INFO: Current point is " << *point << ".");
    550       for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) {
    551         line = LineRunner->second;
    552         LOG(1, "INFO: Current line of point " << *point << " is " << *line << ".");
    553         if (!line->CheckConvexityCriterion()) {
    554           // remove the point if needed
    555           LOG(1, "... point " << *point << " cannot be on convex envelope.");
    556           volume += TesselStruct->RemovePointFromTesselatedSurface(point);
    557           sprintf(dummy, "-first-%d", ++run);
    558           StoreTrianglesinFile(mol, (const Tesselation *&)TesselStruct, filename, dummy);
     563      LOG(2, "INFO: Current point is " << *point << ".");
     564      // check that at least a single line is concave
     565      LineMap::iterator LineRunner = point->lines.begin();
     566      for (; LineRunner != point->lines.end(); LineRunner++) {
     567        const BoundaryLineSet * line = LineRunner->second;
     568        LOG(3, "INFO: Current line of point " << *point << " is " << *line << ".");
     569        if (!line->CheckConvexityCriterion())
     570          break;
     571      }
     572      // remove the point if needed
     573      if (LineRunner != point->lines.end()) {
     574        const double tmp = TesselStruct->RemoveFullConcavePointFromTesselatedSurface(point);
     575        if (tmp > 0.) {
     576          volume += tmp;
    559577          Concavity = true;
    560           break;
    561578        }
    562579      }
     
    564581    }
    565582
    566     sprintf(dummy, "-second-%d", run);
    567     //CalculateConcavityPerBoundaryPoint(TesselStruct);
    568     StoreTrianglesinFile(mol, (const Tesselation *&)TesselStruct, filename, dummy);
    569 
    570     // second step: PickFarthestofTwoBaselines
     583    if (DebugOutputEveryStep) {
     584      sprintf(dummy, "-%d", run++);
     585      //CalculateConcavityPerBoundaryPoint(TesselStruct);
     586      LOG(1, "INFO: Writing " << run << "th tesselation file.");
     587      StoreTrianglesinFile(mol, (const Tesselation *&)TesselStruct, filename, dummy);
     588    }
     589
     590    // second step: flip baselines, i.e. add general tetraeder at concave lines
     591    // when the tetraeder does not intersect with other already present triangles
    571592    LineRunner = TesselStruct->LinesOnBoundary.begin();
    572593    LineAdvance = LineRunner;  // we need an advanced line, as the LineRunner might get removed
     594    std::map<double, std::pair<BoundaryLineSet *, double> > GainMap;
    573595    while (LineRunner != TesselStruct->LinesOnBoundary.end()) {
    574596      LineAdvance++;
    575597      line = LineRunner->second;
    576       LOG(1, "INFO: Picking farthest baseline for line is " << *line << ".");
    577       // take highest of both lines
    578       if (TesselStruct->IsConvexRectangle(line) == NULL) {
    579         const double tmp = TesselStruct->PickFarthestofTwoBaselines(line);
    580         volume += tmp;
    581         if (tmp != 0.) {
    582           TesselStruct->FlipBaseline(line);
    583           Concavity = true;
     598      if (!line->CheckConvexityCriterion()) {
     599        LOG(2, "INFO: concave line is " << *line << ".");
     600        // gather the other points
     601        BoundaryPointSet *BPS[4];
     602        int m = 0;
     603        {
     604          for (TriangleMap::iterator runner = line->triangles.begin(); runner != line->triangles.end(); runner++)
     605            for (int j = 0; j < 3; j++) // all of their endpoints and baselines
     606              if (!line->ContainsBoundaryPoint(runner->second->endpoints[j])) // and neither of its endpoints
     607                BPS[m++] = runner->second->endpoints[j];
     608        }
     609        BPS[2] = line->endpoints[0];
     610        BPS[3] = line->endpoints[1];
     611        LOG(3, "DEBUG: other line would consist of " << *BPS[0] << " and "
     612            << *BPS[1] << ".");
     613
     614        // check for already present (third) side of the tetraeder as we then
     615        // would create a degenerate triangle
     616        bool TetraederSidePresent = false;
     617        {
     618          class TesselPoint *TriangleCandidates[3];
     619          TriangleCandidates[0] = BPS[0]->node;
     620          TriangleCandidates[1] = BPS[1]->node;
     621          TriangleCandidates[2] = BPS[2]->node;
     622          if ((TesselStruct->GetPresentTriangle(TriangleCandidates) != NULL)) {
     623            LOG(2, "REJECT: Triangle side " << *TriangleCandidates[0] << ","
     624                << *TriangleCandidates[1] << "," << *TriangleCandidates[2] << " present.");
     625            TetraederSidePresent = true;
     626          }
     627          TriangleCandidates[2] = BPS[3]->node;
     628          if ((TesselStruct->GetPresentTriangle(TriangleCandidates) != NULL)) {
     629            LOG(2, "REJECT: Triangle side " << *TriangleCandidates[0] << ","
     630                << *TriangleCandidates[1] << "," << *TriangleCandidates[2] << " present.");
     631            TetraederSidePresent = true;
     632          }
     633        }
     634
     635        if ((BPS[0] != BPS[1]) && (m == 2) && (!TetraederSidePresent)) {
     636          // check whether all adjacent triangles do not intersect with new line
     637          bool no_line_intersects = true;
     638          Vector Intersection;
     639          TriangleSet triangles;
     640          TriangleSet *firsttriangles = TesselStruct->GetAllTriangles(line->endpoints[0]);
     641          TriangleSet *secondtriangles = TesselStruct->GetAllTriangles(line->endpoints[1]);
     642          triangles.insert( firsttriangles->begin(), firsttriangles->end() );
     643          triangles.insert( secondtriangles->begin(), secondtriangles->end() );
     644          delete firsttriangles;
     645          delete secondtriangles;
     646          for (TriangleSet::const_iterator triangleiter = triangles.begin();
     647              triangleiter != triangles.end(); ++triangleiter) {
     648            const BoundaryTriangleSet * triangle = *triangleiter;
     649            bool line_intersects = triangle->GetIntersectionInsideTriangle(
     650                BPS[0]->node->getPosition(),
     651                BPS[1]->node->getPosition(),
     652                Intersection);
     653            // switch result when coinciding with endpoint
     654            bool concave_adjacent_line = false;
     655            bool intersection_is_endnode = false;
     656            for (int j=0;j<2;++j) {
     657              if (Intersection.DistanceSquared(BPS[j]->node->getPosition()) < MYEPSILON) {
     658                intersection_is_endnode = true;
     659                // check whether its an adjacent triangle and if it's concavely connected
     660                // only then are we in danger of cutting through it and need to check
     661                // sign of normal vector and intersecting line
     662                for (int i=0;i<2;++i)
     663                  for (int lineindex=0;lineindex < 3;++lineindex)
     664                    if ((triangle->lines[lineindex]->ContainsBoundaryPoint(line->endpoints[i]))
     665                        && (triangle->lines[lineindex]->ContainsBoundaryPoint(BPS[j]))) {
     666                      concave_adjacent_line = !triangle->lines[lineindex]->CheckConvexityCriterion();
     667                  }
     668                if (concave_adjacent_line) {
     669                  const Vector intersector =
     670                      BPS[(j+1)%2]->node->getPosition() - Intersection;
     671                  if (triangle->NormalVector.ScalarProduct(intersector) >= -MYEPSILON) {
     672                    LOG(4, "ACCEPT: Intersection coincides with first endpoint "
     673                        << *BPS[j] << ".");
     674                    line_intersects = false;
     675                  } else {
     676                    LOG(4, "REJECT: Intersection ends on wrong side of triangle.");
     677                  }
     678                } else {
     679                  LOG(4, "ACCEPT: Intersection coincides with first endpoint "
     680                      << *BPS[j] << ".");
     681                  line_intersects = false;
     682                }
     683              }
     684            }
     685            // if we have an intersection, check that it is within either
     686            // endpoint, i.e. check that scalar product between vectors going
     687            // from intersction to either endpoint has negative sign (both
     688            // vectors point in opposite directions)
     689            if (!intersection_is_endnode && line_intersects) {
     690              const Vector firstvector = BPS[0]->node->getPosition() - Intersection;
     691              const Vector secondvector = BPS[1]->node->getPosition() - Intersection;
     692              if (firstvector.ScalarProduct(secondvector) >= 0)
     693                line_intersects = false;
     694            }
     695            no_line_intersects &= !line_intersects;
     696          }
     697
     698          if (no_line_intersects) {
     699            // calculate the volume
     700            const double tmp = line->CalculateConvexity();
     701            const double gain =
     702              CalculateVolumeofGeneralTetraeder(
     703                  BPS[0]->node->getPosition(),
     704                  BPS[1]->node->getPosition(),
     705                  BPS[2]->node->getPosition(),
     706                  BPS[3]->node->getPosition());
     707
     708            GainMap.insert(std::make_pair(tmp, std::make_pair(line,gain) ));
     709            LOG(2, "DEBUG: Adding concave line " << *line << " with gain of "
     710                << gain << ".");
     711          } else {
     712            // if 2 or 3 don't
     713            LOG(2, "DEBUG: We don't added concave line " << *line
     714                << " as other line intersects with adjacent triangles.");
     715          }
    584716        }
    585717      }
    586718      LineRunner = LineAdvance;
    587719    }
    588     run++;
    589   } while (Concavity);
    590   //CalculateConcavityPerBoundaryPoint(TesselStruct);
    591   //StoreTrianglesinFile(mol, filename, "-third");
    592 
    593   // third step: IsConvexRectangle
    594 //  LineRunner = TesselStruct->LinesOnBoundary.begin();
    595 //  LineAdvance = LineRunner;  // we need an advanced line, as the LineRunner might get removed
    596 //  while (LineRunner != TesselStruct->LinesOnBoundary.end()) {
    597 //    LineAdvance++;
    598 //    line = LineRunner->second;
    599 //    LOG(1, "INFO: Current line is " << *line << ".");
    600 //    //if (LineAdvance != TesselStruct->LinesOnBoundary.end())
    601 //      //LOG(1, "INFO: Next line will be " << *(LineAdvance->second) << ".");
    602 //    if (!line->CheckConvexityCriterion(out)) {
    603 //      LOG(1, "INFO: ... line " << *line << " is concave, flipping it.");
    604 //
    605 //      // take highest of both lines
    606 //      point = TesselStruct->IsConvexRectangle(line);
    607 //      if (point != NULL)
    608 //        volume += TesselStruct->RemovePointFromTesselatedSurface(point);
    609 //    }
    610 //    LineRunner = LineAdvance;
    611 //  }
     720    // flip line with most gain
     721    if (!GainMap.empty()) {
     722      line = GainMap.begin()->second.first;
     723      const double tmp = GainMap.begin()->second.second;
     724      volume += tmp;
     725
     726//      GainMap.clear();
     727
     728      // and flip the line
     729      LOG(1, "INFO: Flipping current most concave line " << *line << " with gain of "
     730          << tmp << ".");
     731      TesselStruct->FlipBaseline(line);
     732      Concavity = true;
     733    }
     734  } while ((Concavity)); // && (run < 100)
    612735
    613736  CalculateConcavityPerBoundaryPoint(TesselStruct);
     
    615738
    616739  // end
    617   LOG(0, "Volume is " << volume << ".");
     740  LOG(0, "RESULT: Added volume in convexization is " << volume << ".");
    618741  return volume;
    619742};
     
    766889//  status = CheckListOfBaselines(TesselStruct);
    767890
    768   cout << "before correction" << endl;
     891//  cout << "before correction" << endl;
    769892
    770893  // store before correction
     
    779902  // write final envelope
    780903  CalculateConcavityPerBoundaryPoint(TesselStruct);
    781   cout << "after correction" << endl;
     904//  cout << "after correction" << endl;
    782905  StoreTrianglesinFile(mol, TesselStruct, filename, "");
    783906
  • src/Tesselation/boundary.hpp

    r3b1798 r0516fd  
    3939/********************************************** declarations *******************************/
    4040
    41 double ConvexizeNonconvexEnvelope(class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename);
     41double ConvexizeNonconvexEnvelope(class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename, bool DebugOutputEveryStep = false);
    4242void FindConvexBorder(const molecule* const mol, Boundaries *BoundaryPts, Tesselation *&TesselStruct, const LinkedCell_deprecated *LCList, const char *filename);
    4343Vector* FindEmbeddingHole(MoleculeListClass *mols, molecule *srcmol);
  • src/Tesselation/tesselation.cpp

    r3b1798 r0516fd  
    3535#include "CodePatterns/MemDebug.hpp"
    3636
     37#include <algorithm>
     38#include <boost/foreach.hpp>
    3739#include <fstream>
    3840#include <iomanip>
     41#include <iterator>
    3942#include <sstream>
    4043
     
    6669class molecule;
    6770
    68 const char *TecplotSuffix=".dat";
    69 const char *Raster3DSuffix=".r3d";
    70 const char *VRMLSUffix=".wrl";
    71 
    72 const double ParallelEpsilon=1e-3;
     71const char *TecplotSuffix = ".dat";
     72const char *Raster3DSuffix = ".r3d";
     73const char *VRMLSUffix = ".wrl";
     74
     75const double ParallelEpsilon = 1e-3;
    7376const double Tesselation::HULLEPSILON = 1e-9;
    7477
     
    7679 */
    7780Tesselation::Tesselation() :
    78   PointsOnBoundaryCount(0),
    79   LinesOnBoundaryCount(0),
    80   TrianglesOnBoundaryCount(0),
    81   LastTriangle(NULL),
    82   TriangleFilesWritten(0),
    83   InternalPointer(PointsOnBoundary.begin())
     81    PointsOnBoundaryCount(0), LinesOnBoundaryCount(0), TrianglesOnBoundaryCount(0), LastTriangle(NULL), TriangleFilesWritten(0), InternalPointer(PointsOnBoundary.begin())
    8482{
    8583  //Info FunctionInfo(__func__);
     
    113111{
    114112  // create linkedcell
    115         LinkedCell_deprecated *LinkedList = new LinkedCell_deprecated(cloud, 2.*SPHERERADIUS);
    116 
    117         // check for at least three points
    118         {
    119           bool ThreePointsFound = true;
    120           cloud.GoToFirst();
    121     for (size_t i=0;i<3;++i, cloud.GoToNext())
     113  LinkedCell_deprecated *LinkedList = new LinkedCell_deprecated(cloud, 2. * SPHERERADIUS);
     114
     115  // check for at least three points
     116  {
     117    bool ThreePointsFound = true;
     118    cloud.GoToFirst();
     119    for (size_t i = 0; i < 3; ++i, cloud.GoToNext())
    122120      ThreePointsFound &= (!cloud.IsEnd());
    123121    cloud.GoToFirst();
     
    126124      return;
    127125    }
    128         }
    129 
    130         // find a starting triangle
     126  }
     127
     128  // find a starting triangle
    131129  FindStartingTriangle(SPHERERADIUS, LinkedList);
    132130
     
    142140        //the line is there, so there is a triangle, but only one.
    143141        const bool TesselationFailFlag = FindNextSuitableTriangle(*baseline, *T, SPHERERADIUS, LinkedList);
    144         ASSERT( TesselationFailFlag,
    145             "Tesselation::operator() - no suitable candidate triangle found.");
     142        ASSERT(TesselationFailFlag, "Tesselation::operator() - no suitable candidate triangle found.");
    146143      }
    147144    }
    148145
    149146    // 2b. search for smallest ShortestAngle among all candidates
    150     double ShortestAngle = 4.*M_PI;
     147    double ShortestAngle = 4. * M_PI;
    151148    for (CandidateMap::iterator Runner = OpenLines.begin(); Runner != OpenLines.end(); Runner++) {
    152149      if (Runner->second->ShortestAngle < ShortestAngle) {
     
    155152      }
    156153    }
    157     if ((ShortestAngle == 4.*M_PI) || (baseline->pointlist.empty()))
     154    if ((ShortestAngle == 4. * M_PI) || (baseline->pointlist.empty()))
    158155      OneLoopWithoutSuccessFlag = false;
    159156    else {
     
    172169double Tesselation::getVolumeOfConvexEnvelope(const bool IsAngstroem) const
    173170{
     171  // calculate center of gravity
     172  Vector center;
     173  if (!PointsOnBoundary.empty()) {
     174    for (PointMap::const_iterator iter = PointsOnBoundary.begin();
     175        iter != PointsOnBoundary.end(); ++iter)
     176      center += iter->second->node->getPosition();
     177    center *= 1./(double)PointsOnBoundary.size();
     178  }
     179
     180  // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
    174181  double volume = 0.;
    175   Vector x;
    176   Vector y;
    177 
    178   // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
    179   for (TriangleMap::const_iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++)
    180     { // go through every triangle, calculate volume of its pyramid with CoG as peak
    181       x = runner->second->getEndpoint(0) - runner->second->getEndpoint(1);
    182       const double G = runner->second->getArea();
    183       x = runner->second->getPlane().getNormal();
    184       x.Scale(runner->second->getEndpoint(1).ScalarProduct(x));
    185       const double h = x.Norm(); // distance of CoG to triangle
    186       const double PyramidVolume = (1. / 3.) * G * h; // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)
    187       LOG(1, "INFO: Area of triangle is " << setprecision(10) << G << " "
    188           << (IsAngstroem ? "angstrom" : "atomiclength") << "^2, height is "
    189           << h << " and the volume is " << PyramidVolume << " "
    190           << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
    191       volume += PyramidVolume;
    192     }
    193   LOG(0, "RESULT: The summed volume is " << setprecision(6)
    194       << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
     182  for (TriangleMap::const_iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) { // go through every triangle, calculate volume of its pyramid with CoG as peak
     183    const double TetrahedronVolume = CalculateVolumeofGeneralTetraeder(
     184        runner->second->endpoints[0]->getPosition(),
     185        runner->second->endpoints[1]->getPosition(),
     186        runner->second->endpoints[2]->getPosition(),
     187        center);
     188    LOG(1, "INFO: volume of tetrahedron is " << setprecision(10) << TetrahedronVolume
     189        << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
     190    volume += TetrahedronVolume;
     191  }
     192  LOG(0, "RESULT: The summed volume is " << setprecision(6) << volume
     193      << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
    195194
    196195  return volume;
     
    209208
    210209  // 6a. Every triangle forms a pyramid with the center of gravity as its peak, sum up the volumes
    211   for (TriangleMap::const_iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++)
    212     { // go through every triangle, calculate volume of its pyramid with CoG as peak
    213                 const double area = runner->second->getArea();
    214                 LOG(1, "INFO: Area of triangle is " << setprecision(10) << area << " "
    215           << (IsAngstroem ? "angstrom" : "atomiclength") << "^2.");
    216       surfacearea += area;
    217     }
    218   LOG(0, "RESULT: The summed surface area is " << setprecision(6)
    219       << surfacearea << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
     210  for (TriangleMap::const_iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) { // go through every triangle, calculate volume of its pyramid with CoG as peak
     211    const double area = runner->second->getArea();
     212    LOG(1, "INFO: Area of triangle is " << setprecision(10) << area << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^2.");
     213    surfacearea += area;
     214  }
     215  LOG(0, "RESULT: The summed surface area is " << setprecision(6) << surfacearea << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3.");
    220216
    221217  return surfacearea;
    222218}
    223 
    224219
    225220/** Gueses first starting triangle of the convex envelope.
     
    253248        tmp = B->second->node->DistanceSquared(C->second->node->getPosition());
    254249        distance += tmp * tmp;
    255         DistanceMMap.insert(DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator> (B, C)));
     250        DistanceMMap.insert(DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator>(B, C)));
    256251      }
    257252    }
     
    273268    // 2. next, we have to check whether all points reside on only one side of the triangle
    274269    // 3. construct plane vector
    275     PlaneVector = Plane(A->second->node->getPosition(),
    276                         baseline->second.first->second->node->getPosition(),
    277                         baseline->second.second->second->node->getPosition()).getNormal();
     270    PlaneVector = Plane(A->second->node->getPosition(), baseline->second.first->second->node->getPosition(), baseline->second.second->second->node->getPosition()).getNormal();
    278271    LOG(2, "Plane vector of candidate triangle is " << PlaneVector);
    279272    // 4. loop over all points
     
    390383        // prepare some auxiliary vectors
    391384        Vector BaseLineCenter, BaseLine;
    392         BaseLineCenter = 0.5 * ((baseline->second->endpoints[0]->node->getPosition()) +
    393                                 (baseline->second->endpoints[1]->node->getPosition()));
     385        BaseLineCenter = 0.5 * ((baseline->second->endpoints[0]->node->getPosition()) + (baseline->second->endpoints[1]->node->getPosition()));
    394386        BaseLine = (baseline->second->endpoints[0]->node->getPosition()) - (baseline->second->endpoints[1]->node->getPosition());
    395387
     
    409401        // vector in propagation direction (out of triangle)
    410402        // project center vector onto triangle plane (points from intersection plane-NormalVector to plane-CenterVector intersection)
    411         PropagationVector = Plane(BaseLine, NormalVector,0).getNormal();
     403        PropagationVector = Plane(BaseLine, NormalVector, 0).getNormal();
    412404        TempVector = CenterVector - (baseline->second->endpoints[0]->node->getPosition()); // TempVector is vector on triangle plane pointing from one baseline egde towards center!
    413405        //LOG(0, "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << ".");
     
    462454            // in case NOT both were found, create virtually this triangle, get its normal vector, calculate angle
    463455            flag = true;
    464             VirtualNormalVector = Plane((baseline->second->endpoints[0]->node->getPosition()),
    465                                         (baseline->second->endpoints[1]->node->getPosition()),
    466                                         (target->second->node->getPosition())).getNormal();
    467             TempVector = (1./3.) * ((baseline->second->endpoints[0]->node->getPosition()) +
    468                                     (baseline->second->endpoints[1]->node->getPosition()) +
    469                                     (target->second->node->getPosition()));
     456            VirtualNormalVector = Plane((baseline->second->endpoints[0]->node->getPosition()), (baseline->second->endpoints[1]->node->getPosition()), (target->second->node->getPosition())).getNormal();
     457            TempVector = (1. / 3.) * ((baseline->second->endpoints[0]->node->getPosition()) + (baseline->second->endpoints[1]->node->getPosition()) + (target->second->node->getPosition()));
    470458            TempVector -= (*Center);
    471459            // make it always point outward
     
    479467              winner = target;
    480468              LOG(5, "DEBUG: New winner " << *winner->second->node << " due to smaller angle between normal vectors.");
    481             } else if (fabs(SmallestAngle - TempAngle) < MYEPSILON) { // check the angle to propagation, both possible targets are in one plane! (their normals have same angle)
    482               // hence, check the angles to some normal direction from our base line but in this common plane of both targets...
    483               helper = (target->second->node->getPosition()) - BaseLineCenter;
    484               helper.ProjectOntoPlane(BaseLine);
    485               // ...the one with the smaller angle is the better candidate
    486               TempVector = (target->second->node->getPosition()) - BaseLineCenter;
    487               TempVector.ProjectOntoPlane(VirtualNormalVector);
    488               TempAngle = TempVector.Angle(helper);
    489               TempVector = (winner->second->node->getPosition()) - BaseLineCenter;
    490               TempVector.ProjectOntoPlane(VirtualNormalVector);
    491               if (TempAngle < TempVector.Angle(helper)) {
    492                 TempAngle = NormalVector.Angle(VirtualNormalVector);
    493                 SmallestAngle = TempAngle;
    494                 winner = target;
    495                 LOG(5, "DEBUG: New winner " << *winner->second->node << " due to smaller angle " << TempAngle << " to propagation direction.");
     469            } else
     470              if (fabs(SmallestAngle - TempAngle) < MYEPSILON) { // check the angle to propagation, both possible targets are in one plane! (their normals have same angle)
     471                // hence, check the angles to some normal direction from our base line but in this common plane of both targets...
     472                helper = (target->second->node->getPosition()) - BaseLineCenter;
     473                helper.ProjectOntoPlane(BaseLine);
     474                // ...the one with the smaller angle is the better candidate
     475                TempVector = (target->second->node->getPosition()) - BaseLineCenter;
     476                TempVector.ProjectOntoPlane(VirtualNormalVector);
     477                TempAngle = TempVector.Angle(helper);
     478                TempVector = (winner->second->node->getPosition()) - BaseLineCenter;
     479                TempVector.ProjectOntoPlane(VirtualNormalVector);
     480                if (TempAngle < TempVector.Angle(helper)) {
     481                  TempAngle = NormalVector.Angle(VirtualNormalVector);
     482                  SmallestAngle = TempAngle;
     483                  winner = target;
     484                  LOG(5, "DEBUG: New winner " << *winner->second->node << " due to smaller angle " << TempAngle << " to propagation direction.");
     485                } else
     486                  LOG(5, "DEBUG: Keeping old winner " << *winner->second->node << " due to smaller angle to propagation direction.");
    496487              } else
    497                 LOG(5, "DEBUG: Keeping old winner " << *winner->second->node << " due to smaller angle to propagation direction.");
    498             } else
    499               LOG(5, "DEBUG: Keeping old winner " << *winner->second->node << " due to smaller angle between normal vectors.");
     488                LOG(5, "DEBUG: Keeping old winner " << *winner->second->node << " due to smaller angle between normal vectors.");
    500489          }
    501490        } // end of loop over all boundary points
     
    564553
    565554  cloud.GoToFirst();
    566   PointCloudAdaptor< Tesselation, MapValueIterator<Tesselation::iterator> > newcloud(this, cloud.GetName());
     555  PointCloudAdaptor<Tesselation, MapValueIterator<Tesselation::iterator> > newcloud(this, cloud.GetName());
    567556  BoundaryPoints = new LinkedCell_deprecated(newcloud, 5.);
    568557  while (!cloud.IsEnd()) { // we only have to go once through all points, as boundary can become only bigger
     
    731720 * @param *b second endpoint
    732721 * @param n index of Tesselation::BLS giving the line with both endpoints
    733  */
    734 void Tesselation::AddTesselationLine(const Vector * const OptCenter, const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n)
     722 * @return true - inserted a new line, false - present line used
     723 */
     724bool Tesselation::AddTesselationLine(const Vector * const OptCenter, const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n)
    735725{
    736726  bool insertNewLine = true;
     
    748738      if (FindLine->second->triangles.size() == 1) {
    749739        CandidateMap::iterator Finder = OpenLines.find(FindLine->second);
    750         if (!Finder->second->pointlist.empty())
    751           LOG(4, "DEBUG: line " << *(FindLine->second) << " is open with candidate " << **(Finder->second->pointlist.begin()) << ".");
    752         else
    753           LOG(4, "DEBUG: line " << *(FindLine->second) << " is open with no candidate.");
    754         // get open line
    755         for (TesselPointList::const_iterator CandidateChecker = Finder->second->pointlist.begin(); CandidateChecker != Finder->second->pointlist.end(); ++CandidateChecker) {
    756           if ((*(CandidateChecker) == candidate->node) && (OptCenter == NULL || OptCenter->DistanceSquared(Finder->second->OptCenter) < MYEPSILON )) { // stop searching if candidate matches
    757             LOG(4, "ACCEPT: Candidate " << *(*CandidateChecker) << " has the right center " << Finder->second->OptCenter << ".");
     740        ASSERT(Finder != OpenLines.end(), "Tesselation::AddTesselationLine() - " + toString(*FindLine->second) + " is not a new line and not in OpenLines.");
     741        if (Finder->second != NULL) {
     742          if (!Finder->second->pointlist.empty())
     743            LOG(4, "DEBUG: line " << *(FindLine->second) << " is open with candidate " << **(Finder->second->pointlist.begin()) << ".");
     744          else {
     745            LOG(4, "ACCEPT: line " << *(FindLine->second) << " is open with no candidate.");
    758746            insertNewLine = false;
    759747            WinningLine = FindLine->second;
    760             break;
    761           } else {
    762             LOG(5, "REJECT: Candidate " << *(*CandidateChecker) << "'s center " << Finder->second->OptCenter << " does not match desired on " << *OptCenter << ".");
    763748          }
     749          // get open line
     750          for (TesselPointList::const_iterator CandidateChecker = Finder->second->pointlist.begin(); CandidateChecker != Finder->second->pointlist.end(); ++CandidateChecker) {
     751            if ((*(CandidateChecker) == candidate->node) && (OptCenter == NULL || OptCenter->DistanceSquared(Finder->second->OptCenter) < MYEPSILON)) { // stop searching if candidate matches
     752              LOG(4, "ACCEPT: Candidate " << *(*CandidateChecker) << " has the right center " << Finder->second->OptCenter << ".");
     753              insertNewLine = false;
     754              WinningLine = FindLine->second;
     755              break;
     756            } else {
     757              LOG(5, "REJECT: Candidate " << *(*CandidateChecker) << "'s center " << Finder->second->OptCenter << " does not match desired on " << *OptCenter << ".");
     758            }
     759          }
     760        } else {
     761          LOG(4, "ACCEPT: There are no candidates for present open line, use what we have.");
     762          insertNewLine = false;
     763          WinningLine = FindLine->second;
    764764        }
    765765      }
     
    772772    AddExistingTesselationTriangleLine(WinningLine, n);
    773773  }
     774
     775  return insertNewLine;
    774776}
    775777;
     
    796798  // also add to open lines
    797799  CandidateForTesselation *CFT = new CandidateForTesselation(BLS[n]);
    798   OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *> (BLS[n], CFT));
     800  OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *>(BLS[n], CFT));
    799801}
    800802;
     
    885887      } else {
    886888        output << "still attached to another triangle: ";
    887         OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *> (triangle->lines[i], NULL));
    888889        for (TriangleMap::iterator TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); TriangleRunner++)
    889890          output << "\t[" << (TriangleRunner->second)->Nr << "|" << *((TriangleRunner->second)->endpoints[0]) << ", " << *((TriangleRunner->second)->endpoints[1]) << ", " << *((TriangleRunner->second)->endpoints[2]) << "] \t";
     891        OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *>(triangle->lines[i], NULL));
    890892      }
    891893      LOG(3, "DEBUG: " << output.str());
     
    921923  else
    922924    Numbers[1] = -1;
     925
     926  // erase from OpenLines if present
     927  {
     928    CandidateMap::iterator openlineiter = OpenLines.find(line);
     929    if (openlineiter != OpenLines.end())
     930      OpenLines.erase(openlineiter);
     931  }
    923932
    924933  for (int i = 0; i < 2; i++) {
     
    939948        LOG(4, "DEBUG: " << *line->endpoints[i] << " has no more lines it's attached to, erasing.");
    940949        RemoveTesselationPoint(line->endpoints[i]);
    941       } else if (DoLog(0)) {
    942         std::stringstream output;
    943         output << "DEBUG: " << *line->endpoints[i] << " has still lines it's attached to: ";
    944         for (LineMap::iterator LineRunner = line->endpoints[i]->lines.begin(); LineRunner != line->endpoints[i]->lines.end(); LineRunner++)
    945           output << "[" << *(LineRunner->second) << "] \t";
    946         LOG(4, output.str());
    947       }
     950      } else
     951        if (DoLog(0)) {
     952          std::stringstream output;
     953          output << "DEBUG: " << *line->endpoints[i] << " has still lines it's attached to: ";
     954          for (LineMap::iterator LineRunner = line->endpoints[i]->lines.begin(); LineRunner != line->endpoints[i]->lines.end(); LineRunner++)
     955            output << "[" << *(LineRunner->second) << "] \t";
     956          LOG(4, output.str());
     957        }
    948958      line->endpoints[i] = NULL; // free'd or not: disconnect
    949959    } else
     
    987997  //Info FunctionInfo(__func__);
    988998
    989   LOG(3, "DEBUG: Checking whether sphere contains no others points ...");
     999  LOG(3, "DEBUG: Checking degeneracy by whether sphere contains no others points ...");
    9901000  bool flag = true;
    9911001
     
    9941004  TesselPointList *ListofPoints = LC->GetPointsInsideSphere(RADIUS, &CandidateLine.OtherOptCenter);
    9951005
    996   LOG(3, "DEBUG: The following atoms are inside sphere at " << CandidateLine.OtherOptCenter << ":");
     1006  LOG(3, "DEBUG: CheckDegeneracy: There are " << ListofPoints->size() << " points inside the sphere.");
     1007  LOG(4, "DEBUG: The following atoms are inside sphere at " << CandidateLine.OtherOptCenter << ":");
    9971008  for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner)
    998     LOG(3, "DEBUG:   " << *(*Runner) << " with distance " << (*Runner)->distance(CandidateLine.OtherOptCenter) << ".");
     1009    LOG(4, "DEBUG:   " << *(*Runner) << " with distance " << (*Runner)->distance(CandidateLine.OtherOptCenter) << ".");
    9991010
    10001011  // remove triangles's endpoints
     
    10101021    LOG(3, "DEBUG: CheckDegeneracy: There are still " << ListofPoints->size() << " points inside the sphere.");
    10111022    flag = false;
    1012     LOG(3, "DEBUG: External atoms inside of sphere at " << CandidateLine.OtherOptCenter << ":");
     1023    LOG(4, "DEBUG: External atoms inside of sphere at " << CandidateLine.OtherOptCenter << ":");
    10131024    for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner)
    1014       LOG(3, "DEBUG:   " << *(*Runner) << " with distance " << (*Runner)->distance(CandidateLine.OtherOptCenter) << ".");
     1025      LOG(4, "DEBUG:   " << *(*Runner) << " with distance " << (*Runner)->distance(CandidateLine.OtherOptCenter) << ".");
    10151026  }
    10161027  delete ListofPoints;
     
    11571168
    11581169  // 1. searching topmost point with respect to each axis
     1170  LOG(2, "INFO: Searching for topmost pointer from each axis.");
    11591171  for (int i = 0; i < NDIM; i++) { // each axis
    11601172    LC->n[i] = LC->N[i] - 1; // current axis is topmost cell
     
    11781190  }
    11791191
    1180   if (DoLog(1)) {
     1192  if (DoLog(3)) {
    11811193    std::stringstream output;
    11821194    output << "Found maximum coordinates: ";
     
    11921204    BaseLine = new BoundaryLineSet();
    11931205    BaseLine->endpoints[0] = new BoundaryPointSet(MaxPoint[k]);
    1194     LOG(2, "DEBUG: Coordinates of start node at " << *BaseLine->endpoints[0]->node << ".");
     1206    LOG(2, "INFO: Coordinates of start node at " << *BaseLine->endpoints[0]->node << ".");
    11951207
    11961208    double ShortestAngle;
     
    12051217    }
    12061218    BaseLine->endpoints[1] = new BoundaryPointSet(Temporary);
    1207     LOG(1, "INFO: Second node is at " << *Temporary << ".");
     1219    LOG(2, "INFO: Second node is at " << *Temporary << ".");
    12081220
    12091221    // construct center of circle
    12101222    CircleCenter = 0.5 * ((BaseLine->endpoints[0]->node->getPosition()) + (BaseLine->endpoints[1]->node->getPosition()));
    1211     LOG(1, "INFO: CircleCenter is at " << CircleCenter << ".");
     1223    LOG(4, "DEBUG: CircleCenter is at " << CircleCenter << ".");
    12121224
    12131225    // construct normal vector of circle
    12141226    CirclePlaneNormal = (BaseLine->endpoints[0]->node->getPosition()) - (BaseLine->endpoints[1]->node->getPosition());
    1215     LOG(1, "INFO: CirclePlaneNormal is at " << CirclePlaneNormal << ".");
     1227    LOG(4, "DEBUG: CirclePlaneNormal is at " << CirclePlaneNormal << ".");
    12161228
    12171229    double radius = CirclePlaneNormal.NormSquared();
     
    12201232    NormalVector.ProjectOntoPlane(CirclePlaneNormal);
    12211233    NormalVector.Normalize();
    1222     LOG(1, "INFO: NormalVector is at " << NormalVector << ".");
     1234    LOG(4, "DEBUG: NormalVector is at " << NormalVector << ".");
    12231235    ShortestAngle = 2. * M_PI; // This will indicate the quadrant.
    12241236
    1225     SphereCenter = (CircleRadius * NormalVector) +  CircleCenter;
     1237    SphereCenter = (CircleRadius * NormalVector) + CircleCenter;
    12261238    // Now, NormalVector and SphereCenter are two orthonormalized vectors in the plane defined by CirclePlaneNormal (not normalized)
    12271239
    12281240    // look in one direction of baseline for initial candidate
    12291241    try {
    1230       SearchDirection = Plane(CirclePlaneNormal, NormalVector,0).getNormal();  // whether we look "left" first or "right" first is not important ...
    1231     } catch(LinearAlgebraException) {
    1232       ELOG(1, "Vectors are linear dependent: "
    1233           << CirclePlaneNormal << ", " << NormalVector << ".");
     1242      SearchDirection = Plane(CirclePlaneNormal, NormalVector, 0).getNormal(); // whether we look "left" first or "right" first is not important ...
     1243    } catch (LinearAlgebraException &e) {
     1244      ELOG(1, "Vectors are linear dependent: " << CirclePlaneNormal << ", " << NormalVector << ".");
    12341245      delete BaseLine;
    12351246      continue;
     
    12371248
    12381249    // adding point 1 and point 2 and add the line between them
    1239     LOG(2, "DEBUG: Found second point is at " << *BaseLine->endpoints[1]->node << ".");
     1250    LOG(3, "DEBUG: Found second point is at " << *BaseLine->endpoints[1]->node << ".");
    12401251
    12411252    //LOG(1, "INFO: OldSphereCenter is at " << helper << ".");
     
    12461257      for (TesselPointList::iterator it = OptCandidates.pointlist.begin(); it != OptCandidates.pointlist.end(); it++)
    12471258        output << *(*it);
    1248       LOG(2, "DEBUG: List of third Points is: " << output.str());
     1259      LOG(3, "DEBUG: List of third Points is: " << output.str());
    12491260    }
    12501261    if (!OptCandidates.pointlist.empty()) {
     
    14081419//  return result;
    14091420//};
    1410 
    14111421/** This function finds a triangle to a line, adjacent to an existing one.
    14121422 * @param out output stream for debugging
     
    14401450
    14411451  // construct center of circle
    1442   CircleCenter = 0.5 * ((CandidateLine.BaseLine->endpoints[0]->node->getPosition()) +
    1443                         (CandidateLine.BaseLine->endpoints[1]->node->getPosition()));
     1452  CircleCenter = 0.5 * ((CandidateLine.BaseLine->endpoints[0]->node->getPosition()) + (CandidateLine.BaseLine->endpoints[1]->node->getPosition()));
    14441453
    14451454  // construct normal vector of circle
    1446   CirclePlaneNormal = (CandidateLine.BaseLine->endpoints[0]->node->getPosition()) -
    1447                       (CandidateLine.BaseLine->endpoints[1]->node->getPosition());
     1455  CirclePlaneNormal = (CandidateLine.BaseLine->endpoints[0]->node->getPosition()) - (CandidateLine.BaseLine->endpoints[1]->node->getPosition());
    14481456
    14491457  // calculate squared radius of circle
     
    14551463    CircleRadius = RADIUS * RADIUS - radius / 4.;
    14561464    CirclePlaneNormal.Normalize();
    1457     LOG(3, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
    1458 
    1459     LOG(3, "DEBUG: OldSphereCenter is at " << T.SphereCenter << ".");
     1465    LOG(4, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
     1466
     1467    LOG(4, "DEBUG: OldSphereCenter is at " << T.SphereCenter << ".");
    14601468
    14611469    // construct SearchDirection and an "outward pointer"
    1462     SearchDirection = Plane(RelativeSphereCenter, CirclePlaneNormal,0).getNormal();
     1470    SearchDirection = Plane(RelativeSphereCenter, CirclePlaneNormal, 0).getNormal();
    14631471    helper = CircleCenter - (ThirdPoint->node->getPosition());
    1464     if (helper.ScalarProduct(SearchDirection) < -HULLEPSILON)// ohoh, SearchDirection points inwards!
     1472    if (helper.ScalarProduct(SearchDirection) < -HULLEPSILON) // ohoh, SearchDirection points inwards!
    14651473      SearchDirection.Scale(-1.);
    1466     LOG(3, "DEBUG: SearchDirection is " << SearchDirection << ".");
     1474    LOG(4, "DEBUG: SearchDirection is " << SearchDirection << ".");
    14671475    if (fabs(RelativeSphereCenter.ScalarProduct(SearchDirection)) > HULLEPSILON) {
    14681476      // rotated the wrong way!
     
    14741482
    14751483  } else {
    1476     LOG(3, "DEBUG: Circumcircle for base line " << *CandidateLine.BaseLine << " and base triangle " << T << " is too big!");
     1484    LOG(4, "DEBUG: Circumcircle for base line " << *CandidateLine.BaseLine << " and base triangle " << T << " is too big!");
    14771485  }
    14781486
     
    15071515    baseline = Runner->second;
    15081516    if (baseline->pointlist.empty()) {
    1509       ASSERT((baseline->BaseLine->triangles.size() == 1),"Open line without exactly one attached triangle");
     1517      ASSERT((baseline->BaseLine->triangles.size() == 1), "Open line without exactly one attached triangle");
    15101518      T = (((baseline->BaseLine->triangles.begin()))->second);
    15111519      LOG(4, "DEBUG: Finding best candidate for open line " << *baseline->BaseLine << " of triangle " << *T);
     
    15401548  TesselPointList *connectedClosestPoints = GetCircleOfSetOfPoints(&SetOfNeighbours, TurningPoint, CandidateLine.BaseLine->endpoints[1]->node->getPosition());
    15411549
    1542   {
     1550  if (DoLog(3)) {
    15431551    std::stringstream output;
    15441552    for (TesselPointList::iterator TesselRunner = connectedClosestPoints->begin(); TesselRunner != connectedClosestPoints->end(); ++TesselRunner)
    15451553      output << **TesselRunner;
    1546     LOG(3, "DEBUG: List of Candidates for Turning Point " << *TurningPoint << ":");
     1554    LOG(3, "DEBUG: List of Candidates for Turning Point " << *TurningPoint << ":" << output.str());
    15471555  }
    15481556
     
    15851593  }
    15861594  delete (connectedClosestPoints);
    1587 };
     1595}
     1596;
    15881597
    15891598/** for polygons (multiple candidates for a baseline) sets internal edges to the correct next candidate.
     
    16051614      else {
    16061615        LOG(4, "DEBUG: line " << *(FindLine->second) << " is open with no candidate, setting to next Sprinter" << (*Sprinter));
    1607         Finder->second->T = BTS;  // is last triangle
     1616        Finder->second->T = BTS; // is last triangle
    16081617        Finder->second->pointlist.push_back(Sprinter);
    16091618        Finder->second->ShortestAngle = 0.;
     
    16121621    }
    16131622  }
    1614 };
     1623}
     1624;
    16151625
    16161626/** If a given \a *triangle is degenerated, this adds both sides.
     
    16481658  // give some verbose output about the whole procedure
    16491659  if (CandidateLine.T != NULL)
    1650     LOG(2, "DEBUG: --> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << ".");
     1660    LOG(2, "INFO: --> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << ".");
    16511661  else
    1652     LOG(2, "DEBUG: --> New starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle.");
     1662    LOG(2, "INFO: --> New starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle.");
    16531663  triangle = BTS;
    16541664
     
    17341744;
    17351745
     1746bool Tesselation::isConvex() const
     1747{
     1748  bool status = true;
     1749  // go through all lines on boundary
     1750  for (LineMap::const_iterator lineiter = LinesOnBoundary.begin();
     1751      lineiter != LinesOnBoundary.end(); ++lineiter) {
     1752    if (!lineiter->second->CheckConvexityCriterion()) {
     1753      LOG(2, "DEBUG: Line " << *lineiter->second << " is not convex.");
     1754      status = false;
     1755    }
     1756  }
     1757  return status;
     1758}
     1759
    17361760/** Checks whether the quadragon of the two triangles connect to \a *Base is convex.
    17371761 * We look whether the closest point on \a *Base with respect to the other baseline is outside
     
    18701894    }
    18711895    for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {
    1872     LOG(4, "DEBUG: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << ".");
     1896      LOG(4, "DEBUG: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << ".");
    18731897      BaseLineNormal += (runner->second->NormalVector);
    18741898    }
     
    18991923  class BoundaryLineSet *OldLines[4], *NewLine;
    19001924  class BoundaryPointSet *OldPoints[2];
    1901   Vector BaseLineNormal;
     1925  Vector BaseLineNormal[2];
     1926  Vector OtherEndpoint[2]; // fourth point to either triangle
    19021927  int OldTriangleNrs[2], OldBaseLineNr;
    19031928  int i, m;
    19041929
    19051930  // calculate NormalVector for later use
    1906   BaseLineNormal.Zero();
    19071931  if (Base->triangles.size() < 2) {
    19081932    ELOG(1, "Less than two triangles are attached to this baseline!");
    19091933    return NULL;
    19101934  }
    1911   for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {
    1912     LOG(1, "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << ".");
    1913     BaseLineNormal += (runner->second->NormalVector);
    1914   }
    1915   BaseLineNormal.Scale(-1. / 2.); // has to point inside for BoundaryTriangleSet::GetNormalVector()
     1935  {
     1936    int i=0;
     1937    for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {
     1938      LOG(5, "INFO: Adding NormalVector " << runner->second->NormalVector << " of triangle " << *(runner->second) << ".");
     1939      OtherEndpoint[(i+1)%2] = runner->second->GetThirdEndpoint(Base)->node->getPosition();
     1940      BaseLineNormal[i++] = (runner->second->NormalVector);
     1941      ASSERT( i <= 2,
     1942          "Tesselation::FlipBaseline() - not exactly two triangles found.");
     1943    }
     1944  }
    19161945
    19171946  // get the two triangles
     
    19431972
    19441973  // index OldLines and OldPoints
     1974  // note that oldlines[0,1] belong to first triangle and hence first normal
     1975  // vector and oldlines[2,3] belong to second triangle and its normal vector
    19451976  for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++)
    19461977    for (int j = 0; j < 3; j++) // all of their endpoints and baselines
     
    19521983        OldPoints[m++] = runner->second->endpoints[j];
    19531984
     1985  Vector BasePoints[2]; // endpoints of Base
     1986  if (OldLines[0]->ContainsBoundaryPoint(Base->endpoints[0])) {
     1987    BasePoints[0] = Base->endpoints[0]->node->getPosition();
     1988    BasePoints[1] = Base->endpoints[1]->node->getPosition();
     1989  } else {
     1990    BasePoints[0] = Base->endpoints[1]->node->getPosition();
     1991    BasePoints[1] = Base->endpoints[0]->node->getPosition();
     1992  }
    19541993  // check whether everything is in place to create new lines and triangles
    19551994  if (i < 4) {
     
    19672006      return NULL;
    19682007    }
     2008
     2009  // construct plane of first triangle for calculating normal vectors later
     2010  const Plane triangleplane = Base->triangles.begin()->second->getPlane();
     2011  // get fourth point projected down onto this plane
     2012  const Vector Intersection = triangleplane.getClosestPoint(OtherEndpoint[0]);
    19692013
    19702014  // remove triangles and baseline removes itself
     
    19732017  m = 0;
    19742018  // first obtain all triangle to delete ... (otherwise we pull the carpet (Base) from under the for-loop's feet)
    1975   list <BoundaryTriangleSet *> TrianglesOfBase;
     2019  list<BoundaryTriangleSet *> TrianglesOfBase;
    19762020  for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); ++runner)
    19772021    TrianglesOfBase.push_back(runner->second);
    19782022  // .. then delete each triangle (which deletes the line as well)
    1979   for (list <BoundaryTriangleSet *>::iterator runner = TrianglesOfBase.begin(); !TrianglesOfBase.empty(); runner = TrianglesOfBase.begin()) {
     2023  for (list<BoundaryTriangleSet *>::iterator runner = TrianglesOfBase.begin(); !TrianglesOfBase.empty(); runner = TrianglesOfBase.begin()) {
    19802024    LOG(3, "DEBUG: Deleting triangle " << *(*runner) << ".");
    19812025    OldTriangleNrs[m++] = (*runner)->Nr;
     
    19902034  LinesOnBoundary.insert(LinePair(OldBaseLineNr, NewLine)); // no need for check for unique insertion as NewLine is definitely a new one
    19912035  LOG(3, "DEBUG: Created new baseline " << *NewLine << ".");
     2036
     2037  // Explanation for normal vector choice:
     2038  // Decisive for the normal vector of the new triangle is whether the fourth
     2039  // endpoint is with respect to the joining boundary line on one side or on
     2040  // the other with respect to the endpoint of the plane triangle that is not
     2041  // contained in the joining boundary line.
    19922042
    19932043  // construct new triangles with flipped baseline
     
    20022052    BLS[2] = NewLine;
    20032053    BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[0]);
    2004     BTS->GetNormalVector(BaseLineNormal);
     2054    {
     2055      Line joiningline = makeLineThrough(
     2056          OldLines[0]->endpoints[0]->node->getPosition(),
     2057          OldLines[0]->endpoints[1]->node->getPosition());
     2058      // BasePoints[1] is not contained in OldLines[0], hence is third endpoint
     2059      // of plane triangle. BasePoints[0] is in the joining OldLines[0] and
     2060      // we check whether Intersection is on same side as BasePoints[1] or not.
     2061      const Vector pointinginside =
     2062          joiningline.getClosestPoint(BasePoints[1]) - BasePoints[1];
     2063      const Vector pointingtointersection =
     2064          joiningline.getClosestPoint(Intersection) - Intersection;
     2065      const double sign_of_intersection =
     2066          pointingtointersection.ScalarProduct(pointinginside);
     2067      LOG(4, "DEBUG: Sign of SKP between both lines w.r.t " << *OldLines[0]
     2068          << " is " << sign_of_intersection << ".");
     2069      const double sign_of_normal = (sign_of_intersection >= 0) ? -1. : +1.;
     2070      LOG(4, "DEBUG: Opposite normal direction is "
     2071          << sign_of_normal * BaseLineNormal[0] << ".");
     2072      BTS->GetNormalVector(sign_of_normal * BaseLineNormal[0]);
     2073    }
    20052074    AddTesselationTriangle(OldTriangleNrs[0]);
    20062075    LOG(3, "DEBUG: Created new triangle " << *BTS << ".");
     
    20102079    BLS[2] = NewLine;
    20112080    BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[1]);
    2012     BTS->GetNormalVector(BaseLineNormal);
     2081    {
     2082      Line joiningline = makeLineThrough(
     2083          OldLines[1]->endpoints[0]->node->getPosition(),
     2084          OldLines[1]->endpoints[1]->node->getPosition());
     2085      // BasePoints[0] is not contained in OldLines[1], hence is third endpoint
     2086      // of plane triangle. BasePoints[1] is in th1e joining OldLines[1] and
     2087      // we check whether Intersection is on same side as BasePoints[0] or not.
     2088      const Vector pointinginside =
     2089          joiningline.getClosestPoint(BasePoints[0]) - BasePoints[0];
     2090      const Vector pointingtointersection =
     2091          joiningline.getClosestPoint(Intersection) - Intersection;
     2092      const double sign_of_intersection =
     2093          pointingtointersection.ScalarProduct(pointinginside);
     2094      LOG(4, "DEBUG: Sign of SKP between both lines w.r.t " << *OldLines[1]
     2095          << " is " << sign_of_intersection << ".");
     2096      const double sign_of_normal = (sign_of_intersection >= 0) ? -1. : +1.;
     2097      LOG(4, "DEBUG: Opposite normal direction is "
     2098          << sign_of_normal * BaseLineNormal[0] << ".");
     2099      BTS->GetNormalVector(sign_of_normal * BaseLineNormal[0]);
     2100    }
    20132101    AddTesselationTriangle(OldTriangleNrs[1]);
    20142102    LOG(3, "DEBUG: Created new triangle " << *BTS << ".");
     
    21572245  TesselPoint *Candidate = NULL;
    21582246
    2159   LOG(3, "DEBUG: NormalVector of BaseTriangle is " << NormalVector << ".");
     2247  LOG(4, "DEBUG: NormalVector of BaseTriangle is " << NormalVector << ".");
    21602248
    21612249  // copy old center
     
    21652253
    21662254  // construct center of circle
    2167   CircleCenter = 0.5 * ((CandidateLine.BaseLine->endpoints[0]->node->getPosition()) +
    2168                         (CandidateLine.BaseLine->endpoints[1]->node->getPosition()));
     2255  CircleCenter = 0.5 * ((CandidateLine.BaseLine->endpoints[0]->node->getPosition()) + (CandidateLine.BaseLine->endpoints[1]->node->getPosition()));
    21692256
    21702257  // construct normal vector of circle
    2171   CirclePlaneNormal = (CandidateLine.BaseLine->endpoints[0]->node->getPosition()) -
    2172                       (CandidateLine.BaseLine->endpoints[1]->node->getPosition());
     2258  CirclePlaneNormal = (CandidateLine.BaseLine->endpoints[0]->node->getPosition()) - (CandidateLine.BaseLine->endpoints[1]->node->getPosition());
    21732259
    21742260  RelativeOldSphereCenter = OldSphereCenter - CircleCenter;
     
    21792265    CircleRadius = RADIUS * RADIUS - radius;
    21802266    CirclePlaneNormal.Normalize();
    2181     LOG(3, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
     2267    LOG(4, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
    21822268
    21832269    // test whether old center is on the band's plane
     
    21882274    radius = RelativeOldSphereCenter.NormSquared();
    21892275    if (fabs(radius - CircleRadius) < HULLEPSILON) {
    2190       LOG(3, "DEBUG: RelativeOldSphereCenter is at " << RelativeOldSphereCenter << ".");
     2276      LOG(4, "DEBUG: RelativeOldSphereCenter is at " << RelativeOldSphereCenter << ".");
    21912277
    21922278      // check SearchDirection
    2193       LOG(3, "DEBUG: SearchDirection is " << SearchDirection << ".");
     2279      LOG(4, "DEBUG: SearchDirection is " << SearchDirection << ".");
    21942280      if (fabs(RelativeOldSphereCenter.ScalarProduct(SearchDirection)) > HULLEPSILON) { // rotated the wrong way!
    21952281        ELOG(1, "SearchDirection and RelativeOldSphereCenter are not orthogonal!");
     
    22322318                  // find center on the plane
    22332319                  GetCenterofCircumcircle(NewPlaneCenter, CandidateLine.BaseLine->endpoints[0]->node->getPosition(), CandidateLine.BaseLine->endpoints[1]->node->getPosition(), Candidate->getPosition());
    2234                   LOG(3, "DEBUG: NewPlaneCenter is " << NewPlaneCenter << ".");
     2320                  LOG(5, "DEBUG: NewPlaneCenter is " << NewPlaneCenter << ".");
    22352321
    22362322                  try {
    2237                     NewNormalVector = Plane((CandidateLine.BaseLine->endpoints[0]->node->getPosition()),
    2238                                             (CandidateLine.BaseLine->endpoints[1]->node->getPosition()),
    2239                                             (Candidate->getPosition())).getNormal();
    2240                     LOG(3, "DEBUG: NewNormalVector is " << NewNormalVector << ".");
     2323                    NewNormalVector = Plane((CandidateLine.BaseLine->endpoints[0]->node->getPosition()), (CandidateLine.BaseLine->endpoints[1]->node->getPosition()), (Candidate->getPosition())).getNormal();
     2324                    LOG(5, "DEBUG: NewNormalVector is " << NewNormalVector << ".");
    22412325                    radius = CandidateLine.BaseLine->endpoints[0]->node->DistanceSquared(NewPlaneCenter);
    2242                     LOG(3, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
    2243                     LOG(3, "DEBUG: SearchDirection is " << SearchDirection << ".");
    2244                     LOG(3, "DEBUG: Radius of CircumCenterCircle is " << radius << ".");
     2326                    LOG(5, "DEBUG: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << ".");
     2327                    LOG(5, "DEBUG: SearchDirection is " << SearchDirection << ".");
     2328                    LOG(5, "DEBUG: Radius of CircumCenterCircle is " << radius << ".");
    22452329                    if (radius < RADIUS * RADIUS) {
    22462330                      otherradius = CandidateLine.BaseLine->endpoints[1]->node->DistanceSquared(NewPlaneCenter);
     
    22482332                        // construct both new centers
    22492333                        NewSphereCenter = NewPlaneCenter;
    2250                         OtherNewSphereCenter= NewPlaneCenter;
     2334                        OtherNewSphereCenter = NewPlaneCenter;
    22512335                        helper = NewNormalVector;
    22522336                        helper.Scale(sqrt(RADIUS * RADIUS - radius));
    2253                         LOG(4, "DEBUG: Distance of NewPlaneCenter " << NewPlaneCenter << " to either NewSphereCenter is " << helper.Norm() << " of vector " << helper << " with sphere radius " << RADIUS << ".");
     2337                        LOG(5, "DEBUG: Distance of NewPlaneCenter " << NewPlaneCenter << " to either NewSphereCenter is " << helper.Norm() << " of vector " << helper << " with sphere radius " << RADIUS << ".");
    22542338                        NewSphereCenter += helper;
    2255                         LOG(4, "DEBUG: NewSphereCenter is at " << NewSphereCenter << ".");
     2339                        LOG(5, "DEBUG: NewSphereCenter is at " << NewSphereCenter << ".");
    22562340                        // OtherNewSphereCenter is created by the same vector just in the other direction
    22572341                        helper.Scale(-1.);
    22582342                        OtherNewSphereCenter += helper;
    2259                         LOG(4, "DEBUG: OtherNewSphereCenter is at " << OtherNewSphereCenter << ".");
     2343                        LOG(5, "DEBUG: OtherNewSphereCenter is at " << OtherNewSphereCenter << ".");
    22602344                        alpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, NewSphereCenter, OldSphereCenter, NormalVector, SearchDirection, HULLEPSILON);
    22612345                        Otheralpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, OtherNewSphereCenter, OldSphereCenter, NormalVector, SearchDirection, HULLEPSILON);
     
    22782362                          if ((CandidateLine.ShortestAngle - HULLEPSILON) < alpha) {
    22792363                            CandidateLine.pointlist.push_back(Candidate);
    2280                             LOG(2, "ACCEPT: We have found an equally good candidate: " << *(Candidate) << " with " << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << ".");
     2364                            LOG(3, "ACCEPT: We have found an equally good candidate: " << *(Candidate) << " with " << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << ".");
    22812365                          } else {
    22822366                            // remove all candidates from the list and then the list itself
    22832367                            CandidateLine.pointlist.clear();
    22842368                            CandidateLine.pointlist.push_back(Candidate);
    2285                             LOG(2, "ACCEPT: We have found a better candidate: " << *(Candidate) << " with " << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << ".");
     2369                            LOG(3, "ACCEPT: We have found a better candidate: " << *(Candidate) << " with " << alpha << " and circumsphere's center at " << CandidateLine.OptCenter << ".");
    22862370                          }
    22872371                          CandidateLine.ShortestAngle = alpha;
    2288                           LOG(2, "DEBUG: There are " << CandidateLine.pointlist.size() << " candidates in the list now.");
     2372                          LOG(4, "DEBUG: There are " << CandidateLine.pointlist.size() << " candidates in the list now.");
    22892373                        } else {
    22902374                          if ((Candidate != NULL) && (CandidateLine.pointlist.begin() != CandidateLine.pointlist.end())) {
    2291                             LOG(3, "REJECT: Old candidate " << *(*CandidateLine.pointlist.begin()) << " with " << CandidateLine.ShortestAngle << " is better than new one " << *Candidate << " with " << alpha << " .");
     2375                            LOG(4, "REJECT: Old candidate " << *(*CandidateLine.pointlist.begin()) << " with " << CandidateLine.ShortestAngle << " is better than new one " << *Candidate << " with " << alpha << " .");
    22922376                          } else {
    2293                             LOG(3, "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected.");
     2377                            LOG(4, "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected.");
    22942378                          }
    22952379                        }
    22962380                      } else {
    2297                         ELOG(0, "REJECT: Distance to center of circumcircle is not the same from each corner of the triangle: " << fabs(radius - otherradius));
     2381                        ASSERT(0, std::string("FindThirdPointForTesselation() - ") + std::string("REJECT: Distance to center of circumcircle is not the same from each corner of the triangle: ") + toString(fabs(radius - otherradius)));
    22982382                      }
    22992383                    } else {
    2300                       LOG(3, "REJECT: NewSphereCenter " << NewSphereCenter << " for " << *Candidate << " is too far away: " << radius << ".");
     2384                      LOG(4, "REJECT: NewSphereCenter " << NewSphereCenter << " for " << *Candidate << " is too far away: " << radius << ".");
    23012385                    }
    2302                   }
    2303                   catch (LinearDependenceException &excp){
    2304                     LOG(3, boost::diagnostic_information(excp));
    2305                     LOG(3, "REJECT: Three points from " << *CandidateLine.BaseLine << " and Candidate " << *Candidate << " are linear-dependent.");
     2386                  } catch (LinearDependenceException &excp) {
     2387                    LOG(4, boost::diagnostic_information(excp));
     2388                    LOG(4, "REJECT: Three points from " << *CandidateLine.BaseLine << " and Candidate " << *Candidate << " are linear-dependent.");
    23062389                  }
    23072390                } else {
    23082391                  if (ThirdPoint != NULL) {
    2309                     LOG(3, "REJECT: Base triangle " << *CandidateLine.BaseLine << " and " << *ThirdPoint << " contains Candidate " << *Candidate << ".");
     2392                    LOG(4, "REJECT: Base triangle " << *CandidateLine.BaseLine << " and " << *ThirdPoint << " contains Candidate " << *Candidate << ".");
    23102393                  } else {
    2311                     LOG(3, "REJECT: Base triangle " << *CandidateLine.BaseLine << " contains Candidate " << *Candidate << ".");
     2394                    LOG(4, "REJECT: Base triangle " << *CandidateLine.BaseLine << " contains Candidate " << *Candidate << ".");
    23122395                  }
    23132396                }
     
    23202403  } else {
    23212404    if (ThirdPoint != NULL)
    2322       LOG(3, "Circumcircle for base line " << *CandidateLine.BaseLine << " and third node " << *ThirdPoint << " is too big!");
     2405      LOG(4, "DEBUG: Circumcircle for base line " << *CandidateLine.BaseLine << " and third node " << *ThirdPoint << " is too big!");
    23232406    else
    2324       LOG(3, "Circumcircle for base line " << *CandidateLine.BaseLine << " is too big!");
    2325   }
    2326 
    2327   LOG(2, "DEBUG: Sorting candidate list ...");
     2407      LOG(4, "DEBUG: Circumcircle for base line " << *CandidateLine.BaseLine << " is too big!");
     2408  }
     2409
     2410  LOG(5, "DEBUG: Sorting candidate list ...");
    23282411  if (CandidateLine.pointlist.size() > 1) {
    23292412    CandidateLine.pointlist.unique();
     
    23312414  }
    23322415
    2333   if ((!CandidateLine.pointlist.empty()) && (!CandidateLine.CheckValidity(RADIUS, LC))) {
    2334     ELOG(0, "There were other points contained in the rolling sphere as well!");
    2335     performCriticalExit();
    2336   }
     2416  ASSERT(CandidateLine.pointlist.empty() || (CandidateLine.CheckValidity(RADIUS, LC)), std::string("Tesselation::FindThirdPointForTesselation()") + std::string("There were other points contained in the rolling sphere as well!"));
    23372417}
    23382418;
     
    23462426{
    23472427  //Info FunctionInfo(__func__);
    2348   const BoundaryLineSet * lines[2] = { line1, line2 };
     2428  const BoundaryLineSet * lines[2] = {line1, line2};
    23492429  class BoundaryPointSet *node = NULL;
    23502430  PointMap OrderMap;
     
    23532433    // for both lines
    23542434    for (int j = 0; j < 2; j++) { // for both endpoints
    2355       OrderTest = OrderMap.insert(pair<int, class BoundaryPointSet *> (lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j]));
     2435      OrderTest = OrderMap.insert(pair<int, class BoundaryPointSet *>(lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j]));
    23562436      if (!OrderTest.second) { // if insertion fails, we have common endpoint
    23572437        node = OrderTest.first->second;
     
    24022482              // we should make sure that both triangles end up in the same entry
    24032483              // in the distance multimap. Hence, we round to 6 digit precision.
    2404               const double distance =
    2405                   1e-6*floor(FindPoint->second->node->DistanceSquared(x)*1e+6);
     2484              const double distance = 1e-6 * floor(FindPoint->second->node->DistanceSquared(x) * 1e+6);
    24062485              points->insert(DistanceToPointPair(distance, FindPoint->second));
    24072486              LOG(3, "DEBUG: Putting " << *FindPoint->second << " into the list.");
     
    24482527    for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) {
    24492528      // calculate closest point on line to desired point
    2450       helper = 0.5 * (((LineRunner->second)->endpoints[0]->node->getPosition()) +
    2451                       ((LineRunner->second)->endpoints[1]->node->getPosition()));
     2529      helper = 0.5 * (((LineRunner->second)->endpoints[0]->node->getPosition()) + ((LineRunner->second)->endpoints[1]->node->getPosition()));
    24522530      Center = (x) - helper;
    2453       BaseLine = ((LineRunner->second)->endpoints[0]->node->getPosition()) -
    2454                  ((LineRunner->second)->endpoints[1]->node->getPosition());
     2531      BaseLine = ((LineRunner->second)->endpoints[0]->node->getPosition()) - ((LineRunner->second)->endpoints[1]->node->getPosition());
    24552532      Center.ProjectOntoPlane(BaseLine);
    24562533      const double distance = Center.NormSquared();
     
    25092586    for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) {
    25102587
    2511       BaseLine = ((LineRunner->second)->endpoints[0]->node->getPosition()) -
    2512                  ((LineRunner->second)->endpoints[1]->node->getPosition());
     2588      BaseLine = ((LineRunner->second)->endpoints[0]->node->getPosition()) - ((LineRunner->second)->endpoints[1]->node->getPosition());
    25132589      const double lengthBase = BaseLine.NormSquared();
    25142590
     
    25262602          MinDistance = lengthEnd;
    25272603          LOG(1, "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[0]->node << " is closer with " << lengthEnd << ".");
    2528         } else if (fabs(lengthEnd - MinDistance) < MYEPSILON) { // additional best candidate
    2529           ClosestLines.insert(LineRunner->second);
    2530           LOG(1, "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[1]->node << " is equally good with " << lengthEnd << ".");
    2531         } else { // line is worse
    2532           LOG(1, "REJECT: Line " << *LineRunner->second << " to either endpoints is further away than present closest line candidate: " << lengthEndA << ", " << lengthEndB << ", and distance is longer than baseline:" << lengthBase << ".");
    2533         }
     2604        } else
     2605          if (fabs(lengthEnd - MinDistance) < MYEPSILON) { // additional best candidate
     2606            ClosestLines.insert(LineRunner->second);
     2607            LOG(1, "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[1]->node << " is equally good with " << lengthEnd << ".");
     2608          } else { // line is worse
     2609            LOG(1, "REJECT: Line " << *LineRunner->second << " to either endpoints is further away than present closest line candidate: " << lengthEndA << ", " << lengthEndB << ", and distance is longer than baseline:" << lengthBase << ".");
     2610          }
    25342611      } else { // intersection is closer, calculate
    25352612        // calculate closest point on line to desired point
     
    26572734  double distance = 0.;
    26582735
    2659   if (triangle == NULL) {// is boundary point or only point in point cloud?
     2736  if (triangle == NULL) { // is boundary point or only point in point cloud?
    26602737    LOG(1, "No triangle given!");
    26612738    return -1.;
     
    27662843      takePoint = true;
    27672844      current = findLines->second->endpoints[1]->node;
    2768     } else if (findLines->second->endpoints[1]->Nr == Point->getNr()) {
    2769       takePoint = true;
    2770       current = findLines->second->endpoints[0]->node;
    2771     }
     2845    } else
     2846      if (findLines->second->endpoints[1]->Nr == Point->getNr()) {
     2847        takePoint = true;
     2848        current = findLines->second->endpoints[0]->node;
     2849      }
    27722850
    27732851    if (takePoint) {
     
    28092887  Vector OrthogonalVector;
    28102888  Vector helper;
    2811   const TesselPoint * const TrianglePoints[3] = { Point, NULL, NULL };
     2889  const TesselPoint * const TrianglePoints[3] = {Point, NULL, NULL};
    28122890  TriangleList *triangles = NULL;
    28132891
     
    28202898  // calculate central point
    28212899  triangles = FindTriangles(TrianglePoints);
    2822   if ((triangles != NULL) && (!triangles->empty())) {
    2823     for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++)
    2824       PlaneNormal += (*Runner)->NormalVector;
    2825   } else {
    2826     ELOG(0, "Could not find any triangles for point " << *Point << ".");
    2827     performCriticalExit();
    2828   }
     2900  ASSERT((triangles == NULL) || (triangles->empty()), std::string("Tesselation::GetCircleOfConnectedTriangles()") + std::string("Could not find any triangles for point " + toString(*Point) + "."));
     2901  for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++)
     2902    PlaneNormal += (*Runner)->NormalVector;
    28292903  PlaneNormal.Scale(1.0 / triangles->size());
    28302904  LOG(4, "DEBUG: Calculated PlaneNormal of all circle points is " << PlaneNormal << ".");
     
    28382912    AngleZero = ((*SetOfNeighbours->begin())->getPosition()) - (Point->getPosition());
    28392913    AngleZero.ProjectOntoPlane(PlaneNormal);
    2840     if (AngleZero.NormSquared() < MYEPSILON) {
    2841       ELOG(0, "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!");
    2842       performCriticalExit();
    2843     }
     2914    ASSERT(AngleZero.NormSquared() > MYEPSILON, std::string("Tesselation::GetCircleOfConnectedTriangles() - ") + std::string("AngleZero is 0 even with alternative reference.") + std::string("The algorithm has to be changed here!"));
    28442915  }
    28452916  LOG(4, "DEBUG: Reference vector on this plane representing angle 0 is " << AngleZero << ".");
    28462917  if (AngleZero.NormSquared() > MYEPSILON)
    2847     OrthogonalVector = Plane(PlaneNormal, AngleZero,0).getNormal();
     2918    OrthogonalVector = Plane(PlaneNormal, AngleZero, 0).getNormal();
    28482919  else
    28492920    OrthogonalVector.MakeNormalTo(PlaneNormal);
     
    28562927    double angle = GetAngle(helper, AngleZero, OrthogonalVector);
    28572928    LOG(4, "DEBUG" << angle << " for point " << **listRunner << ".");
    2858     anglesOfPoints.insert(pair<double, TesselPoint*> (angle, (*listRunner)));
     2929    anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner)));
    28592930  }
    28602931
     
    29112982  int counter = 0;
    29122983  while (TesselC != SetOfNeighbours->end()) {
    2913     helper = Plane(((*TesselA)->getPosition()),
    2914                    ((*TesselB)->getPosition()),
    2915                    ((*TesselC)->getPosition())).getNormal();
     2984    helper = Plane(((*TesselA)->getPosition()), ((*TesselB)->getPosition()), ((*TesselC)->getPosition())).getNormal();
    29162985    LOG(5, "DEBUG: Making normal vector out of " << *(*TesselA) << ", " << *(*TesselB) << " and " << *(*TesselC) << ":" << helper);
    29172986    counter++;
     
    29222991  }
    29232992  //LOG(0, "Summed vectors " << center << "; number of points " << connectedPoints.size() << "; scale factor " << counter);
    2924   PlaneNormal.Scale(1.0 / (double) counter);
     2993  PlaneNormal.Scale(1.0 / (double)counter);
    29252994  //  LOG(1, "INFO: Calculated center of all circle points is " << center << ".");
    29262995  //
     
    29363005    AngleZero.ProjectOntoPlane(PlaneNormal);
    29373006  }
    2938   if ((Reference.IsZero()) || (AngleZero.NormSquared() < MYEPSILON )) {
     3007  if ((Reference.IsZero()) || (AngleZero.NormSquared() < MYEPSILON)) {
    29393008    LOG(4, "DEBUG: Using alternatively " << (*SetOfNeighbours->begin())->getPosition() << " as angle 0 referencer.");
    29403009    AngleZero = ((*SetOfNeighbours->begin())->getPosition()) - (Point->getPosition());
    29413010    AngleZero.ProjectOntoPlane(PlaneNormal);
    2942     if (AngleZero.NormSquared() < MYEPSILON) {
    2943       ELOG(0, "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!");
    2944       performCriticalExit();
    2945     }
     3011    ASSERT(AngleZero.NormSquared() > MYEPSILON, std::string("Tesselation::GetCircleOfSetOfPoints() - ") + std::string("AngleZero is 0 even with alternative reference.") + std::string("The algorithm has to be changed here!"));
    29463012  }
    29473013  LOG(4, "DEBUG: Reference vector on this plane representing angle 0 is " << AngleZero << ".");
    29483014  if (AngleZero.NormSquared() > MYEPSILON)
    2949     OrthogonalVector = Plane(PlaneNormal, AngleZero,0).getNormal();
     3015    OrthogonalVector = Plane(PlaneNormal, AngleZero, 0).getNormal();
    29503016  else
    29513017    OrthogonalVector.MakeNormalTo(PlaneNormal);
     
    29613027      angle = 2. * M_PI - angle;
    29623028    LOG(4, "DEBUG: Calculated angle between " << helper << " and " << AngleZero << " is " << angle << " for point " << **listRunner << ".");
    2963     InserterTest = anglesOfPoints.insert(pair<double, TesselPoint*> (angle, (*listRunner)));
    2964     if (!InserterTest.second) {
    2965       ELOG(0, "GetCircleOfSetOfPoints() got two atoms with same angle: " << *((InserterTest.first)->second) << " and " << (*listRunner));
    2966       performCriticalExit();
    2967     }
     3029    InserterTest = anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner)));
     3030    ASSERT(InserterTest.second, std::string("Tesselation::GetCircleOfSetOfPoints() - ") + std::string("got two atoms with same angle " + toString(*((InserterTest.first)->second))) + std::string(" and " + toString((*listRunner))));
    29683031  }
    29693032
     
    29853048  //Info FunctionInfo(__func__);
    29863049  map<double, TesselPoint*> anglesOfPoints;
    2987   list<TesselPointList *> *ListOfPaths = new list<TesselPointList *> ;
     3050  list<TesselPointList *> *ListOfPaths = new list<TesselPointList *>;
    29883051  TesselPointList *connectedPath = NULL;
    29893052  Vector center;
     
    30113074  map<class BoundaryTriangleSet *, bool>::iterator TriangleRunner;
    30123075  for (LineMap::iterator Runner = ReferencePoint->lines.begin(); Runner != ReferencePoint->lines.end(); Runner++) {
    3013     TouchedLine.insert(pair<class BoundaryLineSet *, bool> (Runner->second, false));
    3014     for (TriangleMap::iterator Sprinter = Runner->second->triangles.begin(); Sprinter != Runner->second->triangles.end(); Sprinter++)
    3015       TouchedTriangle.insert(pair<class BoundaryTriangleSet *, bool> (Sprinter->second, false));
     3076    LOG(4, "DEBUG: Adding " << *Runner->second << " to TouchedLine map.");
     3077    TouchedLine.insert(pair<class BoundaryLineSet *, bool>(Runner->second, false));
     3078    for (TriangleMap::iterator Sprinter = Runner->second->triangles.begin(); Sprinter != Runner->second->triangles.end(); Sprinter++) {
     3079      LOG(4, "DEBUG: Adding " << *Sprinter->second << " to TouchedTriangle map.");
     3080      TouchedTriangle.insert(pair<class BoundaryTriangleSet *, bool>(Sprinter->second, false));
     3081    }
    30163082  }
    30173083  if (!ReferencePoint->lines.empty()) {
     
    30203086      if (LineRunner == TouchedLine.end()) {
    30213087        ELOG(1, "I could not find " << *runner->second << " in the touched list.");
    3022       } else if (!LineRunner->second) {
    3023         LineRunner->second = true;
    3024         connectedPath = new TesselPointList;
    3025         triangle = NULL;
    3026         CurrentLine = runner->second;
    3027         StartLine = CurrentLine;
    3028         CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
    3029         LOG(1, "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << ".");
    3030         do {
    3031           // push current one
    3032           LOG(1, "INFO: Putting " << *CurrentPoint << " at end of path.");
    3033           connectedPath->push_back(CurrentPoint->node);
    3034 
    3035           // find next triangle
    3036           for (TriangleMap::iterator Runner = CurrentLine->triangles.begin(); Runner != CurrentLine->triangles.end(); Runner++) {
    3037             LOG(1, "INFO: Inspecting triangle " << *Runner->second << ".");
    3038             if ((Runner->second != triangle)) { // look for first triangle not equal to old one
    3039               triangle = Runner->second;
    3040               TriangleRunner = TouchedTriangle.find(triangle);
    3041               if (TriangleRunner != TouchedTriangle.end()) {
    3042                 if (!TriangleRunner->second) {
    3043                   TriangleRunner->second = true;
    3044                   LOG(1, "INFO: Connecting triangle is " << *triangle << ".");
    3045                   break;
     3088      } else
     3089        if (!LineRunner->second) {
     3090          LineRunner->second = true;
     3091          connectedPath = new TesselPointList;
     3092          triangle = NULL;
     3093          CurrentLine = runner->second;
     3094          StartLine = CurrentLine;
     3095          CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
     3096          LOG(3, "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << ".");
     3097          do {
     3098            // push current one
     3099            LOG(3, "INFO: Putting " << *CurrentPoint << " at end of path.");
     3100            connectedPath->push_back(CurrentPoint->node);
     3101
     3102            // find next triangle
     3103            for (TriangleMap::iterator Runner = CurrentLine->triangles.begin(); Runner != CurrentLine->triangles.end(); Runner++) {
     3104              LOG(4, "DEBUG: Inspecting triangle " << *Runner->second << ".");
     3105              if ((Runner->second != triangle)) { // look for first triangle not equal to old one
     3106                triangle = Runner->second;
     3107                TriangleRunner = TouchedTriangle.find(triangle);
     3108                if (TriangleRunner != TouchedTriangle.end()) {
     3109                  if (!TriangleRunner->second) {
     3110                    TriangleRunner->second = true;
     3111                    LOG(4, "DEBUG: Connecting triangle is " << *triangle << ".");
     3112                    break;
     3113                  } else {
     3114                    LOG(4, "DEBUG: Skipping " << *triangle << ", as we have already visited it.");
     3115                    triangle = NULL;
     3116                  }
    30463117                } else {
    3047                   LOG(1, "INFO: Skipping " << *triangle << ", as we have already visited it.");
     3118                  ELOG(1, "I could not find " << *triangle << " in the touched list.");
    30483119                  triangle = NULL;
    30493120                }
    30503121              } else {
    3051                 ELOG(1, "I could not find " << *triangle << " in the touched list.");
     3122                // as we have stumbled upon the same triangle, we don't need the check anymore
    30523123                triangle = NULL;
    30533124              }
    30543125            }
     3126            if (triangle == NULL)
     3127              break;
     3128            // find next line
     3129            for (int i = 0; i < 3; i++) {
     3130              if ((triangle->lines[i] != CurrentLine) && (triangle->lines[i]->ContainsBoundaryPoint(ReferencePoint))) { // not the current line and still containing Point
     3131                CurrentLine = triangle->lines[i];
     3132                LOG(3, "INFO: Connecting line is " << *CurrentLine << ".");
     3133                break;
     3134              }
     3135            }
     3136            LineRunner = TouchedLine.find(CurrentLine);
     3137            if (LineRunner == TouchedLine.end())
     3138              ELOG(1, "I could not find " << *CurrentLine << " in the touched list.");
     3139            else
     3140              LineRunner->second = true;
     3141            // find next point
     3142            CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
     3143
     3144          } while (CurrentLine != StartLine);
     3145          // last point is missing, as it's on start line
     3146          if (StartLine->GetOtherEndpoint(ReferencePoint)->node != connectedPath->back()) {
     3147            LOG(3, "INFO: Putting " << *CurrentPoint << " at end of path to close it.");
     3148            connectedPath->push_back(StartLine->GetOtherEndpoint(ReferencePoint)->node);
    30553149          }
    3056           if (triangle == NULL)
    3057             break;
    3058           // find next line
    3059           for (int i = 0; i < 3; i++) {
    3060             if ((triangle->lines[i] != CurrentLine) && (triangle->lines[i]->ContainsBoundaryPoint(ReferencePoint))) { // not the current line and still containing Point
    3061               CurrentLine = triangle->lines[i];
    3062               LOG(1, "INFO: Connecting line is " << *CurrentLine << ".");
    3063               break;
    3064             }
    3065           }
    3066           LineRunner = TouchedLine.find(CurrentLine);
    3067           if (LineRunner == TouchedLine.end())
    3068             ELOG(1, "I could not find " << *CurrentLine << " in the touched list.");
    3069           else
    3070             LineRunner->second = true;
    3071           // find next point
    3072           CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
    3073 
    3074         } while (CurrentLine != StartLine);
    3075         // last point is missing, as it's on start line
    3076         LOG(1, "INFO: Putting " << *CurrentPoint << " at end of path.");
    3077         if (StartLine->GetOtherEndpoint(ReferencePoint)->node != connectedPath->back())
    3078           connectedPath->push_back(StartLine->GetOtherEndpoint(ReferencePoint)->node);
    3079 
    3080         ListOfPaths->push_back(connectedPath);
    3081       } else {
    3082         LOG(1, "INFO: Skipping " << *runner->second << ", as we have already visited it.");
    3083       }
     3150
     3151          ListOfPaths->push_back(connectedPath);
     3152        } else {
     3153          LOG(3, "DEBUG: Skipping " << *runner->second << ", as we have already visited it.");
     3154        }
    30843155    }
    30853156  } else {
     
    31003171  //Info FunctionInfo(__func__);
    31013172  list<TesselPointList *> *ListofPaths = GetPathsOfConnectedPoints(Point);
    3102   list<TesselPointList *> *ListofClosedPaths = new list<TesselPointList *> ;
     3173  list<TesselPointList *> *ListofClosedPaths = new list<TesselPointList *>;
    31033174  TesselPointList *connectedPath = NULL;
    31043175  TesselPointList *newPath = NULL;
     
    31103181    connectedPath = *ListRunner;
    31113182
    3112     LOG(1, "INFO: Current path is " << connectedPath << ".");
     3183    if (DoLog(2)) {
     3184      std::stringstream output;
     3185      output << "INFO: Current path is ";
     3186      BOOST_FOREACH(const TesselPoint * const item, *connectedPath) {
     3187        output << *item << " ";
     3188      }
     3189      LOG(1, output.str());
     3190    }
    31133191
    31143192    // go through list, look for reappearance of starting Point and count
     
    31193197      if ((*CircleRunner == *CircleStart) && (CircleRunner != CircleStart)) { // is not the very first point
    31203198        // we have a closed circle from Marker to new Marker
    3121         if (DoLog(1)) {
     3199        if (DoLog(3)) {
    31223200          std::stringstream output;
    3123           output << count + 1 << ". closed path consists of: ";
    3124           for (TesselPointList::iterator CircleSprinter = Marker;
    3125               CircleSprinter != CircleRunner;
    3126               CircleSprinter++)
     3201          output << "DEBUG: " << count + 1 << ". closed path consists of: ";
     3202          for (TesselPointList::iterator CircleSprinter = Marker; CircleSprinter != CircleRunner; CircleSprinter++)
    31273203            output << (**CircleSprinter) << " <-> ";
    31283204          LOG(1, output.str());
     
    31403216    }
    31413217  }
    3142   LOG(1, "INFO: " << count << " closed additional path(s) have been created.");
     3218  LOG(2, "DEBUG: " << count << " closed additional path(s) have been created.");
    31433219
    31443220  // delete list of paths
     
    31783254}
    31793255;
     3256
     3257struct CloserToPiHalf
     3258{
     3259  bool operator()(double angle, double smallestangle)
     3260  {
     3261    return (fabs(angle - M_PI / 2.) < fabs(smallestangle - M_PI / 2.));
     3262  }
     3263};
     3264
     3265bool Tesselation::IsPointBelowSurroundingPolygon(const BoundaryPointSet *_point) const
     3266{
     3267  // check for NULL
     3268  if (_point == NULL) {
     3269    return false;
     3270  }
     3271
     3272  // get list of connected points
     3273  if (_point->lines.empty()) {
     3274    LOG(1, "INFO: point " << *_point << " is not connected to any lines.");
     3275    return false;
     3276  }
     3277  bool PointIsBelow = true;
     3278
     3279  // create Orthogonal vector as reference for angle (pointing into [pi,2pi) interval)
     3280  Vector OrthogonalVector;
     3281  for (LineMap::const_iterator lineiter = _point->lines.begin();
     3282      lineiter != _point->lines.end(); ++lineiter)
     3283    for (TriangleMap::const_iterator triangleiter = lineiter->second->triangles.begin();
     3284        triangleiter != lineiter->second->triangles.end();
     3285        ++triangleiter)
     3286        OrthogonalVector += triangleiter->second->NormalVector;
     3287  OrthogonalVector.Normalize();
     3288
     3289  // go through all closed paths for this point
     3290  typedef list<TesselPointList *> TPL_list_t;
     3291  const TPL_list_t *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(_point->node);
     3292  for (TPL_list_t::const_iterator closedpathsiter = ListOfClosedPaths->begin();
     3293      (closedpathsiter != ListOfClosedPaths->end()) && PointIsBelow;
     3294      ++closedpathsiter) {
     3295    const TesselPointList *connectedPath = *closedpathsiter;
     3296
     3297    TesselPointList::const_iterator ListAdvance = connectedPath->begin(); // gives angle direction
     3298    TesselPointList::const_iterator ListRunner = ListAdvance++;
     3299    for (; (ListAdvance != connectedPath->end()) && PointIsBelow;
     3300        ListRunner = ListAdvance++) { // go through all closed paths
     3301      LOG(2, "DEBUG: Current reference node is " << **ListRunner
     3302          << ", advanced node is " << **ListAdvance);
     3303
     3304      // reference vector to point to check for this point of connected path
     3305      const Vector Reference =
     3306          ((*ListAdvance)->getPosition()) - ((*ListRunner)->getPosition());
     3307
     3308      // go through all other points in this connected path
     3309      for (TesselPointList::const_iterator OtherRunner = ListAdvance;
     3310          (OtherRunner != ListRunner) && PointIsBelow;
     3311          ++OtherRunner == connectedPath->end() ?
     3312              OtherRunner = connectedPath->begin() :
     3313              OtherRunner) {
     3314        if (OtherRunner == ListAdvance)
     3315          continue;
     3316        LOG(3, "DEBUG: Current other node is " << **OtherRunner);
     3317
     3318        // build the plane with normal vector
     3319        const Vector onebeam =
     3320            ((*OtherRunner)->getPosition()) - ((*ListAdvance)->getPosition());
     3321        Vector NormalVector = Reference;
     3322        NormalVector.VectorProduct(onebeam);
     3323        // needs to point in same general direction as average NormalVector of all triangles
     3324        if (NormalVector.ScalarProduct(OrthogonalVector) < 0)
     3325          NormalVector *= -1.;
     3326        try {
     3327          Plane plane(NormalVector, ((*ListRunner)->getPosition()));
     3328
     3329          // check whether point is below
     3330          if (plane.SignedDistance(_point->node->getPosition()) > 0) {
     3331            LOG(2, "DEBUG: For plane " << plane << " point " << *_point
     3332                << " would remain above.");
     3333            PointIsBelow = false;
     3334          }
     3335        } catch (ZeroVectorException &e) {
     3336          ELOG(3, "Vectors are linear dependent, skipping.");
     3337        }
     3338      }
     3339    }
     3340  }
     3341  delete ListOfClosedPaths;
     3342
     3343  return PointIsBelow;
     3344}
     3345
     3346double Tesselation::RemovePointSurroundedByPolygon(
     3347    TesselPointList *connectedPath,
     3348    BoundaryPointSet *point)
     3349{
     3350  double volume = 0.;
     3351  const Vector OldPoint = point->node->getPosition();
     3352
     3353  TesselPoint *oldNode = point->node;
     3354  // remove present triangles for this connectedPath
     3355  unsigned int count = 0;
     3356  for (TesselPointList::const_iterator iter = connectedPath->begin();
     3357      iter != connectedPath->end(); ++iter)
     3358    LOG(4, "DEBUG: Node in connectedPath is " << **iter);
     3359
     3360  {
     3361    TesselPointList::iterator FirstNode, SecondNode;
     3362    SecondNode = connectedPath->begin();
     3363    FirstNode = SecondNode++;
     3364    for (;FirstNode != connectedPath->end(); ++SecondNode, ++FirstNode) {
     3365      LOG(3, "DEBUG: MiddleNode is " << **FirstNode << ".");
     3366      if (SecondNode == connectedPath->end())
     3367        SecondNode = connectedPath->begin();
     3368      TesselPoint *TriangleCandidates[3];
     3369      TriangleCandidates[0] = *FirstNode;
     3370      TriangleCandidates[1] = *SecondNode;
     3371      TriangleCandidates[2] = oldNode;
     3372      BoundaryTriangleSet *triangle = GetPresentTriangle(TriangleCandidates);
     3373      ASSERT( triangle != NULL,
     3374          "Tesselation::RemovePointSurroundedByPolygon() - triangle to points "
     3375          +toString((**SecondNode))+", "+toString((**FirstNode))+" and "
     3376          +toString(*oldNode)+" does not exist.");
     3377      LOG(3, "DEBUG: Removing triangle " << *triangle << ".");
     3378      RemoveTesselationTriangle(triangle);
     3379      ++count;
     3380    }
     3381    LOG(2, "INFO: " << count << " triangles were removed.");
     3382  }
     3383
     3384  // re-create all triangles by going through connected points list
     3385  LineList NewLines;
     3386  typedef std::vector<double> angles_t;
     3387  angles_t angles;
     3388  count = 0;
     3389  for (; !connectedPath->empty();) {
     3390    // search middle node with widest angle to next neighbours
     3391    TesselPointList::iterator StartNode, MiddleNode, EndNode;
     3392    for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) {
     3393      LOG(3, "INFO: MiddleNode is " << **MiddleNode << ".");
     3394      // construct vectors to next and previous neighbour
     3395      StartNode = MiddleNode;
     3396      if (StartNode == connectedPath->begin())
     3397        StartNode = connectedPath->end();
     3398      StartNode--;
     3399      //LOG(3, "INFO: StartNode is " << **StartNode << ".");
     3400      const Vector Point = ((*StartNode)->getPosition()) - ((*MiddleNode)->getPosition());
     3401      EndNode = MiddleNode;
     3402      EndNode++;
     3403      if (EndNode == connectedPath->end())
     3404        EndNode = connectedPath->begin();
     3405      //LOG(3, "INFO: EndNode is " << **StartNode << ".");
     3406      const Vector Reference = ((*EndNode)->getPosition()) - ((*MiddleNode)->getPosition());
     3407      Vector OrthogonalVector = ((*MiddleNode)->getPosition()) - OldPoint;
     3408      OrthogonalVector.MakeNormalTo(Reference);
     3409      angles.push_back(GetAngle(Point, Reference, OrthogonalVector));
     3410    }
     3411    ASSERT( !angles.empty(),
     3412        "Tesselation::RemovePointSurroundedByPolygon() - angles empty");
     3413    const angles_t::const_iterator maxiter = std::max_element(angles.begin(), angles.end());
     3414    angles_t::const_iterator miniter = angles.begin();
     3415    // distinguish between convex and nonconvex polygon
     3416    if (*maxiter > M_PI) {
     3417      // connectedPath is not convex: The idea is to fill any kinks pointing
     3418      // inside into the connectedPath close to this concave spot first, making
     3419      // it eventually become convex.
     3420      // Hence, use adjacent (and convex) fill-in point
     3421      miniter = (maxiter == angles.begin()) ? angles.end()-1 : maxiter-1;
     3422      if (*miniter > M_PI) {
     3423        miniter = (maxiter+1 == angles.end()) ? angles.begin() : maxiter+1;
     3424        if (*miniter > M_PI) {
     3425          miniter = std::min_element(angles.begin(), angles.end());
     3426        }
     3427      }
     3428    } else {
     3429      // is convex
     3430      miniter = std::min_element(angles.begin(), angles.end(), CloserToPiHalf());
     3431    }
     3432    MiddleNode = connectedPath->begin();
     3433    std::advance(MiddleNode, std::distance(const_cast<const angles_t &>(angles).begin(), miniter));
     3434
     3435    ASSERT(MiddleNode != connectedPath->end(),
     3436        "Tesselation::RemovePointSurroundedByPolygon() - Could not find a smallest angle!");
     3437    angles.clear();
     3438    StartNode = MiddleNode;
     3439    EndNode = MiddleNode;
     3440    if (StartNode == connectedPath->begin())
     3441      StartNode = connectedPath->end();
     3442    StartNode--;
     3443    EndNode++;
     3444    if (EndNode == connectedPath->end())
     3445      EndNode = connectedPath->begin();
     3446    LOG(2, "INFO: StartNode is " << **StartNode << ".");
     3447    LOG(2, "INFO: MiddleNode is " << **MiddleNode << ".");
     3448    LOG(2, "INFO: EndNode is " << **EndNode << ".");
     3449    LOG(1, "INFO: Attempting to create triangle " << (*StartNode)->getName() << ", " << (*MiddleNode)->getName() << " and " << (*EndNode)->getName() << ".");
     3450    TesselPoint *TriangleCandidates[3];
     3451    TriangleCandidates[0] = *StartNode;
     3452    TriangleCandidates[1] = *MiddleNode;
     3453    TriangleCandidates[2] = *EndNode;
     3454    BoundaryTriangleSet *triangle = GetPresentTriangle(TriangleCandidates);
     3455    if (triangle != NULL) {
     3456      const Vector center = 1./3. * ((*StartNode)->getPosition()
     3457              + (*MiddleNode)->getPosition()
     3458              + (*EndNode)->getPosition());
     3459      const Vector NormalVector = OldPoint - center;
     3460      // check orientation of normal vector (that points inside)
     3461      ASSERT( triangle->NormalVector.ScalarProduct(NormalVector) > std::numeric_limits<double>::epsilon()*1e2,
     3462          "Tesselation::RemovePointSurroundedByPolygon() - New triangle with same orientation already present as "
     3463          +toString(*triangle)+"!");
     3464    }
     3465
     3466    LOG(3, "DEBUG: Adding new triangle points.");
     3467    AddTesselationPoint(*StartNode, 0);
     3468    AddTesselationPoint(*MiddleNode, 1);
     3469    AddTesselationPoint(*EndNode, 2);
     3470    LOG(3, "DEBUG: Adding new triangle lines.");
     3471    AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0);
     3472    // line between start and end must be new (except for very last triangle)
     3473    if (AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1))
     3474      NewLines.push_back(BLS[1]);
     3475    AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2);
     3476    BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     3477    const Vector center = 1./3. * ((*StartNode)->getPosition()
     3478            + (*MiddleNode)->getPosition()
     3479            + (*EndNode)->getPosition());
     3480    const Vector NormalVector = OldPoint - center;
     3481    BTS->GetNormalVector(NormalVector);
     3482    AddTesselationTriangle();
     3483    // calculate volume summand as a general tetraeder
     3484    volume += CalculateVolumeofGeneralTetraeder(
     3485        TPS[0]->node->getPosition(),
     3486        TPS[1]->node->getPosition(),
     3487        TPS[2]->node->getPosition(),
     3488        OldPoint);
     3489    // advance number
     3490    ++count;
     3491
     3492    // prepare nodes for next triangle
     3493    LOG(3, "DEBUG: Removing " << **MiddleNode << " from closed path.");
     3494    connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles)
     3495    LOG(3, "DEBUG: Remaining points: " << connectedPath->size() << ".");
     3496    ASSERT(connectedPath->size() >= 2,
     3497        "Tesselation::RemovePointSurroundedByPolygon() - There are only two endpoints left!");
     3498    if (connectedPath->size() == 2) { // we are done
     3499      connectedPath->remove(*StartNode); // remove the start node
     3500      connectedPath->remove(*EndNode); // remove the end node
     3501    }
     3502  }
     3503  LOG(1, "INFO: " << count << " triangles were created.");
     3504
     3505  return volume;
     3506}
    31803507
    31813508/** Removes a boundary point from the envelope while keeping it closed.
     
    31923519double Tesselation::RemovePointFromTesselatedSurface(class BoundaryPointSet *point)
    31933520{
    3194   class BoundaryLineSet *line = NULL;
    3195   class BoundaryTriangleSet *triangle = NULL;
    3196   Vector OldPoint, NormalVector;
    31973521  double volume = 0;
    3198   int count = 0;
    31993522
    32003523  if (point == NULL) {
     
    32043527    LOG(4, "DEBUG: Removing point " << *point << " from tesselated boundary ...");
    32053528
    3206   // copy old location for the volume
    3207   OldPoint = (point->node->getPosition());
    3208 
    32093529  // get list of connected points
    32103530  if (point->lines.empty()) {
     
    32143534
    32153535  list<TesselPointList *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(point->node);
    3216   TesselPointList *connectedPath = NULL;
    3217 
    3218   // gather all triangles
    3219   for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++)
    3220     count += LineRunner->second->triangles.size();
    3221   TriangleMap Candidates;
    3222   for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) {
    3223     line = LineRunner->second;
    3224     for (TriangleMap::iterator TriangleRunner = line->triangles.begin(); TriangleRunner != line->triangles.end(); TriangleRunner++) {
    3225       triangle = TriangleRunner->second;
    3226       Candidates.insert(TrianglePair(triangle->Nr, triangle));
    3227     }
    3228   }
    3229 
    3230   // remove all triangles
    3231   count = 0;
    3232   NormalVector.Zero();
    3233   for (TriangleMap::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) {
    3234     LOG(1, "INFO: Removing triangle " << *(Runner->second) << ".");
    3235     NormalVector -= Runner->second->NormalVector; // has to point inward
    3236     RemoveTesselationTriangle(Runner->second);
    3237     count++;
    3238   }
    3239   LOG(1, count << " triangles were removed.");
    3240 
     3536  list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin();
     3537  list<TesselPointList *>::iterator ListRunner = ListAdvance;
     3538//  TriangleMap::iterator NumberRunner = Candidates.begin();
     3539  Vector Point, Reference, OrthogonalVector;
     3540  for (; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths
     3541    if (ListAdvance != ListOfClosedPaths->end())
     3542      ListAdvance++;
     3543
     3544    TesselPointList *connectedPath = *ListRunner;
     3545
     3546    volume += RemovePointSurroundedByPolygon(connectedPath, point);
     3547
     3548    ListOfClosedPaths->remove(connectedPath);
     3549    delete (connectedPath);
     3550  }
     3551  delete (ListOfClosedPaths);
     3552
     3553  LOG(1, "INFO: Removed volume is " << volume << ".");
     3554
     3555  return volume;
     3556}
     3557;
     3558
     3559bool Tesselation::CheckAllConcaveInPolygon(
     3560    const TesselPointList *connectedPath,
     3561    const BoundaryPointSet *point
     3562    )
     3563{
     3564  // check whether lines in this path to point to remove are all concave
     3565  bool all_lines_concave = true;
     3566  if (connectedPath->size() >= 2) {
     3567    TesselPointList::const_iterator StartNode, MiddleNode, EndNode;
     3568    // have nearest neighbors to a middle node to know adjacent triangles
     3569    for (MiddleNode = connectedPath->begin();
     3570        all_lines_concave && (MiddleNode != connectedPath->end());
     3571        MiddleNode++) {
     3572      LOG(3, "INFO: MiddleNode is " << **MiddleNode << ".");
     3573      EndNode = MiddleNode;
     3574      if (EndNode == connectedPath->begin())
     3575        EndNode = connectedPath->end();
     3576      --EndNode;
     3577      StartNode = MiddleNode;
     3578      ++StartNode;
     3579      if (StartNode == connectedPath->end())
     3580        StartNode = connectedPath->begin();
     3581
     3582      AddTesselationPoint(point->node, 0);
     3583      AddTesselationPoint(*MiddleNode, 1);
     3584
     3585      ASSERT( point->lines.find((*MiddleNode)->getNr()) != point->lines.end(),
     3586          "Tesselation::CheckAllConcaveInPolygon() - MiddleNode "
     3587          +toString(**MiddleNode)+" not present in "
     3588          +toString(*point)+"'s lines.");
     3589
     3590      // get line between Node and point and check
     3591      std::pair<LineMap::const_iterator, LineMap::const_iterator> FindPair =
     3592          point->lines.equal_range((*MiddleNode)->getNr());
     3593      LineMap::const_iterator FindLine = FindPair.first;
     3594      for (; FindLine != FindPair.second; ++FindLine) {
     3595        // line  has got two triangles, check whether they resemble those
     3596        // with start and endnode
     3597        const BoundaryLineSet *currentline = FindLine->second;
     3598        unsigned int matching_triangles = 0;
     3599        for (TriangleMap::const_iterator triangleiter = currentline->triangles.begin();
     3600            triangleiter != currentline->triangles.end(); ++triangleiter) {
     3601          const BoundaryTriangleSet *triangle = triangleiter->second;
     3602          AddTesselationPoint(*StartNode, 2);
     3603          if (triangle->IsPresentTupel(TPS))
     3604            ++matching_triangles;
     3605          AddTesselationPoint(*EndNode, 2);
     3606          if (triangle->IsPresentTupel(TPS))
     3607            ++matching_triangles;
     3608        }
     3609        if (matching_triangles == 2)
     3610          break;
     3611      }
     3612      if (FindLine != FindPair.second) {
     3613        LOG(3, "INFO: Current line of point " << *point << " is " << *FindLine->second << ".");
     3614        all_lines_concave &= !FindLine->second->CheckConvexityCriterion();
     3615      }
     3616    }
     3617  } else {
     3618    // check the single line
     3619    if (connectedPath->empty())
     3620      return false;
     3621    LineMap::const_iterator FindLine = point->lines.find((*connectedPath->begin())->getNr());
     3622    ASSERT( FindLine != point->lines.end(),
     3623        "Tesselation::CheckAllConcaveInPolygon() - point "
     3624        +toString((*connectedPath->begin())->getNr())+" not present in "
     3625        +toString(*point)+"'s lines.");
     3626    return !FindLine->second->CheckConvexityCriterion();
     3627  }
     3628
     3629  return all_lines_concave;
     3630}
     3631
     3632/** Removes a boundary point from the envelope while keeping it closed.
     3633 * We remove the old triangles connected to the point and re-create new triangles to close the surface following this ansatz:
     3634 *  -# a closed path(s) of boundary points surrounding the point to be removed is constructed
     3635 *  -# on each closed path, we pick three adjacent points, create a triangle with them and subtract the middle point from the path
     3636 *  -# we advance two points (i.e. the next triangle will start at the ending point of the last triangle) and continue as before
     3637 *  -# the surface is closed, when the path is empty
     3638 * Thereby, we (hopefully) make sure that the removed points remains beneath the surface (this is checked via IsInnerPoint eventually).
     3639 * \param *out output stream for debugging
     3640 * \param *point point to be removed
     3641 * \return volume added to the volume inside the tesselated surface by the removal
     3642 */
     3643double Tesselation::RemoveFullConcavePointFromTesselatedSurface(class BoundaryPointSet *point)
     3644{
     3645  double volume = 0;
     3646
     3647  if (point == NULL) {
     3648    ELOG(1, "Cannot remove the point " << point << ", it's NULL!");
     3649    return 0.;
     3650  } else
     3651    LOG(4, "DEBUG: Removing point " << *point << " from tesselated boundary ...");
     3652
     3653  // get list of connected points
     3654  if (point->lines.empty()) {
     3655    ELOG(1, "Cannot remove the point " << *point << ", it's connected to no lines!");
     3656    return 0.;
     3657  }
     3658
     3659  list<TesselPointList *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(point->node);
    32413660  list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin();
    32423661  list<TesselPointList *>::iterator ListRunner = ListAdvance;
    32433662//  TriangleMap::iterator NumberRunner = Candidates.begin();
    32443663  TesselPointList::iterator StartNode, MiddleNode, EndNode;
    3245   double angle;
    3246   double smallestangle;
    32473664  Vector Point, Reference, OrthogonalVector;
    3248   if (count > 2) { // less than three triangles, then nothing will be created
    3249     class TesselPoint *TriangleCandidates[3];
    3250     count = 0;
    3251     for (; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths
    3252       if (ListAdvance != ListOfClosedPaths->end())
    3253         ListAdvance++;
    3254 
    3255       connectedPath = *ListRunner;
    3256       // re-create all triangles by going through connected points list
    3257       LineList NewLines;
    3258       for (; !connectedPath->empty();) {
    3259         // search middle node with widest angle to next neighbours
    3260         EndNode = connectedPath->end();
    3261         smallestangle = 0.;
    3262         for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) {
    3263           LOG(1, "INFO: MiddleNode is " << **MiddleNode << ".");
    3264           // construct vectors to next and previous neighbour
    3265           StartNode = MiddleNode;
    3266           if (StartNode == connectedPath->begin())
    3267             StartNode = connectedPath->end();
    3268           StartNode--;
    3269           //LOG(3, "INFO: StartNode is " << **StartNode << ".");
    3270           Point = ((*StartNode)->getPosition()) - ((*MiddleNode)->getPosition());
    3271           StartNode = MiddleNode;
    3272           StartNode++;
    3273           if (StartNode == connectedPath->end())
    3274             StartNode = connectedPath->begin();
    3275           //LOG(3, "INFO: EndNode is " << **StartNode << ".");
    3276           Reference = ((*StartNode)->getPosition()) - ((*MiddleNode)->getPosition());
    3277           OrthogonalVector = ((*MiddleNode)->getPosition()) - OldPoint;
    3278           OrthogonalVector.MakeNormalTo(Reference);
    3279           angle = GetAngle(Point, Reference, OrthogonalVector);
    3280           //if (angle < M_PI)  // no wrong-sided triangles, please?
    3281           if (fabs(angle - M_PI) < fabs(smallestangle - M_PI)) { // get straightest angle (i.e. construct those triangles with smallest area first)
    3282             smallestangle = angle;
    3283             EndNode = MiddleNode;
    3284           }
    3285         }
    3286         MiddleNode = EndNode;
    3287         if (MiddleNode == connectedPath->end()) {
    3288           ELOG(0, "CRITICAL: Could not find a smallest angle!");
    3289           performCriticalExit();
    3290         }
    3291         StartNode = MiddleNode;
    3292         if (StartNode == connectedPath->begin())
    3293           StartNode = connectedPath->end();
    3294         StartNode--;
    3295         EndNode++;
    3296         if (EndNode == connectedPath->end())
    3297           EndNode = connectedPath->begin();
    3298         LOG(2, "INFO: StartNode is " << **StartNode << ".");
    3299         LOG(2, "INFO: MiddleNode is " << **MiddleNode << ".");
    3300         LOG(2, "INFO: EndNode is " << **EndNode << ".");
    3301         LOG(1, "INFO: Attempting to create triangle " << (*StartNode)->getName() << ", " << (*MiddleNode)->getName() << " and " << (*EndNode)->getName() << ".");
    3302         TriangleCandidates[0] = *StartNode;
    3303         TriangleCandidates[1] = *MiddleNode;
    3304         TriangleCandidates[2] = *EndNode;
    3305         triangle = GetPresentTriangle(TriangleCandidates);
    3306         if (triangle != NULL) {
    3307           ELOG(0, "New triangle already present, skipping!");
    3308           StartNode++;
    3309           MiddleNode++;
    3310           EndNode++;
    3311           if (StartNode == connectedPath->end())
    3312             StartNode = connectedPath->begin();
    3313           if (MiddleNode == connectedPath->end())
    3314             MiddleNode = connectedPath->begin();
    3315           if (EndNode == connectedPath->end())
    3316             EndNode = connectedPath->begin();
    3317           continue;
    3318         }
    3319         LOG(3, "Adding new triangle points.");
    3320         AddTesselationPoint(*StartNode, 0);
    3321         AddTesselationPoint(*MiddleNode, 1);
    3322         AddTesselationPoint(*EndNode, 2);
    3323         LOG(3, "Adding new triangle lines.");
    3324         AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0);
    3325         AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1);
    3326         NewLines.push_back(BLS[1]);
    3327         AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2);
    3328         BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    3329         BTS->GetNormalVector(NormalVector);
    3330         AddTesselationTriangle();
    3331         // calculate volume summand as a general tetraeder
    3332         volume += CalculateVolumeofGeneralTetraeder(TPS[0]->node->getPosition(), TPS[1]->node->getPosition(), TPS[2]->node->getPosition(), OldPoint);
    3333         // advance number
    3334         count++;
    3335 
    3336         // prepare nodes for next triangle
    3337         StartNode = EndNode;
    3338         LOG(2, "Removing " << **MiddleNode << " from closed path, remaining points: " << connectedPath->size() << ".");
    3339         connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles)
    3340         if (connectedPath->size() == 2) { // we are done
    3341           connectedPath->remove(*StartNode); // remove the start node
    3342           connectedPath->remove(*EndNode); // remove the end node
    3343           break;
    3344         } else if (connectedPath->size() < 2) { // something's gone wrong!
    3345           ELOG(0, "CRITICAL: There are only two endpoints left!");
    3346           performCriticalExit();
    3347         } else {
    3348           MiddleNode = StartNode;
    3349           MiddleNode++;
    3350           if (MiddleNode == connectedPath->end())
    3351             MiddleNode = connectedPath->begin();
    3352           EndNode = MiddleNode;
    3353           EndNode++;
    3354           if (EndNode == connectedPath->end())
    3355             EndNode = connectedPath->begin();
    3356         }
    3357       }
    3358       // maximize the inner lines (we preferentially created lines with a huge angle, which is for the tesselation not wanted though useful for the closing)
    3359       if (NewLines.size() > 1) {
    3360         LineList::iterator Candidate;
    3361         class BoundaryLineSet *OtherBase = NULL;
    3362         double tmp, maxgain;
    3363         do {
    3364           maxgain = 0;
    3365           for (LineList::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) {
    3366             tmp = PickFarthestofTwoBaselines(*Runner);
    3367             if (maxgain < tmp) {
    3368               maxgain = tmp;
    3369               Candidate = Runner;
    3370             }
    3371           }
    3372           if (maxgain != 0) {
    3373             volume += maxgain;
    3374             LOG(1, "Flipping baseline with highest volume" << **Candidate << ".");
    3375             OtherBase = FlipBaseline(*Candidate);
    3376             NewLines.erase(Candidate);
    3377             NewLines.push_back(OtherBase);
    3378           }
    3379         } while (maxgain != 0.);
    3380       }
    3381 
    3382       ListOfClosedPaths->remove(connectedPath);
    3383       delete (connectedPath);
    3384     }
    3385     LOG(1, "INFO: " << count << " triangles were created.");
    3386   } else {
    3387     while (!ListOfClosedPaths->empty()) {
    3388       ListRunner = ListOfClosedPaths->begin();
    3389       connectedPath = *ListRunner;
    3390       ListOfClosedPaths->remove(connectedPath);
    3391       delete (connectedPath);
    3392     }
    3393     LOG(3, "DEBUG: No need to create any triangles.");
     3665  for (; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) { // go through all closed paths
     3666    if (ListAdvance != ListOfClosedPaths->end())
     3667      ListAdvance++;
     3668
     3669    TesselPointList *connectedPath = *ListRunner;
     3670
     3671    if (CheckAllConcaveInPolygon(connectedPath, point)) {
     3672      LOG(1, "INFO: ... point " << *point << " cannot be on convex envelope, all lines concave.");
     3673      volume += RemovePointSurroundedByPolygon(connectedPath, point);
     3674    }
     3675
     3676    ListOfClosedPaths->remove(connectedPath);
     3677    delete (connectedPath);
    33943678  }
    33953679  delete (ListOfClosedPaths);
    33963680
    3397   LOG(1, "INFO: Removed volume is " << volume << ".");
     3681  if (volume > 0.)
     3682    LOG(1, "INFO: Removed volume is " << volume << ".");
    33983683
    33993684  return volume;
     
    34393724            if (TrianglePoints[j] != NULL) {
    34403725              for (FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->getNr()); // is a multimap!
    3441               (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->getNr()); FindLine++) {
     3726                  (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->getNr()); FindLine++) {
    34423727                for (FindTriangle = FindLine->second->triangles.begin(); FindTriangle != FindLine->second->triangles.end(); FindTriangle++) {
    34433728                  if (FindTriangle->second->IsPresentTupel(TrianglePoints)) {
     
    34603745          break;
    34613746      for (FindLine = TrianglePoints[(i + 1) % 3]->lines.find(TrianglePoints[(i + 2) % 3]->node->getNr()); // is a multimap!
    3462       (FindLine != TrianglePoints[(i + 1) % 3]->lines.end()) && (FindLine->first == TrianglePoints[(i + 2) % 3]->node->getNr()); FindLine++) {
     3747          (FindLine != TrianglePoints[(i + 1) % 3]->lines.end()) && (FindLine->first == TrianglePoints[(i + 2) % 3]->node->getNr()); FindLine++) {
    34633748        for (FindTriangle = FindLine->second->triangles.begin(); FindTriangle != FindLine->second->triangles.end(); FindTriangle++) {
    34643749          if (FindTriangle->second->IsPresentTupel(TrianglePoints)) {
     
    34893774    }
    34903775    default:
    3491       ELOG(0, "Number of wildcards is greater than 3, cannot happen!");
    3492       performCriticalExit();
     3776      ASSERT(0, "Tesselation::FindTriangles() - Number of wildcards is greater than 3, cannot happen!");
    34933777      break;
    34943778  }
     
    35163800    if (a->endpoints[lowerNra] < b->endpoints[lowerNrb])
    35173801      return true;
    3518     else if (a->endpoints[lowerNra] > b->endpoints[lowerNrb])
    3519       return false;
    3520     else { // both lower-numbered endpoints are the same ...
    3521       if (a->endpoints[(lowerNra + 1) % 2] < b->endpoints[(lowerNrb + 1) % 2])
    3522         return true;
    3523       else if (a->endpoints[(lowerNra + 1) % 2] > b->endpoints[(lowerNrb + 1) % 2])
     3802    else
     3803      if (a->endpoints[lowerNra] > b->endpoints[lowerNrb])
    35243804        return false;
    3525     }
     3805      else { // both lower-numbered endpoints are the same ...
     3806        if (a->endpoints[(lowerNra + 1) % 2] < b->endpoints[(lowerNrb + 1) % 2])
     3807          return true;
     3808        else
     3809          if (a->endpoints[(lowerNra + 1) % 2] > b->endpoints[(lowerNrb + 1) % 2])
     3810            return false;
     3811      }
    35263812    return false;
    35273813  }
     
    35443830
    35453831  // sanity check
    3546   if (LinesOnBoundary.empty()) {
    3547     ELOG(2, "FindAllDegeneratedTriangles() was called without any tesselation structure.");
    3548     return DegeneratedLines;
    3549   }
    3550   LineMap::iterator LineRunner1;
    3551   pair<UniqueLines::iterator, bool> tester;
     3832      if (LinesOnBoundary.empty()) {
     3833        ELOG(2, "FindAllDegeneratedTriangles() was called without any tesselation structure.");
     3834        return DegeneratedLines;
     3835      }
     3836      LineMap::iterator LineRunner1;
     3837      pair<UniqueLines::iterator, bool> tester;
    35523838  for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) {
    35533839    tester = AllLines.insert(LineRunner1->second);
     
    35663852    const LineMap::const_iterator Line2 = LinesOnBoundary.find((*it).second);
    35673853    if (Line1 != LinesOnBoundary.end() && Line2 != LinesOnBoundary.end())
    3568       LOG(3, "DEBUG: " << *Line1->second << " => " << *Line2->second);
     3854    LOG(3, "DEBUG: " << *Line1->second << " => " << *Line2->second);
    35693855    else
    3570       ELOG(1, "Either " << (*it).first << " or " << (*it).second << " are not in LinesOnBoundary!");
     3856    ELOG(1, "Either " << (*it).first << " or " << (*it).second << " are not in LinesOnBoundary!");
    35713857  }
    35723858
     
    36003886      for (TriangleRunner2 = line2->triangles.begin(); TriangleRunner2 != line2->triangles.end(); ++TriangleRunner2) {
    36013887        if ((TriangleRunner1->second != TriangleRunner2->second) && (TriangleRunner1->second->IsPresentTupel(TriangleRunner2->second))) {
    3602           DegeneratedTriangles->insert(pair<int, int> (TriangleRunner1->second->Nr, TriangleRunner2->second->Nr));
    3603           DegeneratedTriangles->insert(pair<int, int> (TriangleRunner2->second->Nr, TriangleRunner1->second->Nr));
     3888          DegeneratedTriangles->insert(pair<int, int>(TriangleRunner1->second->Nr, TriangleRunner2->second->Nr));
     3889          DegeneratedTriangles->insert(pair<int, int>(TriangleRunner2->second->Nr, TriangleRunner1->second->Nr));
    36043890        }
    36053891      }
     
    36283914
    36293915  // iterate over all degenerated triangles
    3630   for (IndexToIndex::iterator TriangleKeyRunner = DegeneratedTriangles->begin(); !DegeneratedTriangles->empty(); TriangleKeyRunner = DegeneratedTriangles->begin()) {
     3916  for (IndexToIndex::iterator TriangleKeyRunner = DegeneratedTriangles->begin();
     3917      !DegeneratedTriangles->empty();
     3918      TriangleKeyRunner = DegeneratedTriangles->begin()) {
    36313919    LOG(3, "DEBUG: Checking presence of triangles " << TriangleKeyRunner->first << " and " << TriangleKeyRunner->second << ".");
    36323920    // both ways are stored in the map, only use one
     
    36693957//                OtherpartnerTriangle = TriangleRunner->second;
    36703958//              }
    3671             /// interchanges their lines so that triangle->lines[i] == partnerTriangle->lines[j]
    3672             // the line of triangle receives the degenerated ones
    3673             triangle->lines[i]->triangles.erase(Othertriangle->Nr);
     3959              /// interchanges their lines so that triangle->lines[i] == partnerTriangle->lines[j]
     3960              // the line of triangle receives the degenerated ones
     3961              triangle->lines[i]->triangles.erase(Othertriangle->Nr);
    36743962            triangle->lines[i]->triangles.insert(TrianglePair(partnerTriangle->Nr, partnerTriangle));
    36753963            for (int k = 0; k < 3; k++)
     
    36853973
    36863974      // erase the pair
    3687       count += (int) DegeneratedTriangles->erase(triangle->Nr);
     3975      count += (int)DegeneratedTriangles->erase(triangle->Nr);
    36883976      LOG(4, "DEBUG: RemoveDegeneratedTriangles() removes triangle " << *triangle << ".");
    36893977      RemoveTesselationTriangle(triangle);
    3690       count += (int) DegeneratedTriangles->erase(partnerTriangle->Nr);
     3978      count += (int)DegeneratedTriangles->erase(partnerTriangle->Nr);
    36913979      LOG(4, "DEBUG: RemoveDegeneratedTriangles() removes triangle " << *partnerTriangle << ".");
    36923980      RemoveTesselationTriangle(partnerTriangle);
    36933981    } else {
    36943982      LOG(4, "DEBUG: RemoveDegeneratedTriangles() does not remove triangle " << *triangle << " and its partner " << *partnerTriangle << " because it is essential for at" << " least one of the endpoints to be kept in the tesselation structure.");
     3983      // we need to remove them from the list nonetheless
     3984      DegeneratedTriangles->erase(triangle->Nr);
     3985      DegeneratedTriangles->erase(partnerTriangle->Nr);
    36953986    }
    36963987  }
     
    37364027  class BoundaryLineSet *BestLine = NULL;
    37374028  for (LineMap::iterator Runner = NearestBoundaryPoint->lines.begin(); Runner != NearestBoundaryPoint->lines.end(); Runner++) {
    3738     BaseLine = (Runner->second->endpoints[0]->node->getPosition()) -
    3739                (Runner->second->endpoints[1]->node->getPosition());
    3740     CenterToPoint = 0.5 * ((Runner->second->endpoints[0]->node->getPosition()) +
    3741                            (Runner->second->endpoints[1]->node->getPosition()));
     4029    BaseLine = (Runner->second->endpoints[0]->node->getPosition()) - (Runner->second->endpoints[1]->node->getPosition());
     4030    CenterToPoint = 0.5 * ((Runner->second->endpoints[0]->node->getPosition()) + (Runner->second->endpoints[1]->node->getPosition()));
    37424031    CenterToPoint -= (point->getPosition());
    37434032    angle = CenterToPoint.Angle(BaseLine);
    3744     if (fabs(angle - M_PI/2.) < fabs(BestAngle - M_PI/2.)) {
     4033    if (fabs(angle - M_PI / 2.) < fabs(BestAngle - M_PI / 2.)) {
    37454034      BestAngle = angle;
    37464035      BestLine = Runner->second;
     
    37914080  for (int i = 0; i < 3; i++) { // look for the same line as BestLine (only it's its degenerated companion)
    37924081    if ((BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[0])) && (BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[1]))) {
    3793       if (BestLine == BTS->lines[i]) {
    3794         ELOG(0, "BestLine is same as found line, something's wrong here!");
    3795         performCriticalExit();
    3796       }
    3797       BTS->lines[i]->triangles.insert(pair<int, class BoundaryTriangleSet *> (TempTriangle->Nr, TempTriangle));
     4082      ASSERT(BestLine != BTS->lines[i], std::string("Tesselation::AddBoundaryPointByDegeneratedTriangle() - ") + std::string("BestLine is same as found line, something's wrong here!"));
     4083      BTS->lines[i]->triangles.insert(pair<int, class BoundaryTriangleSet *>(TempTriangle->Nr, TempTriangle));
    37984084      TempTriangle->lines[nr] = BTS->lines[i];
    37994085      break;
     
    38174103  if (LastTriangle != NULL) {
    38184104    stringstream sstr;
    3819     sstr << "-"<< TrianglesOnBoundary.size() << "-" << LastTriangle->getEndpointName(0) << "_" << LastTriangle->getEndpointName(1) << "_" << LastTriangle->getEndpointName(2);
     4105    sstr << "-" << TrianglesOnBoundary.size() << "-" << LastTriangle->getEndpointName(0) << "_" << LastTriangle->getEndpointName(1) << "_" << LastTriangle->getEndpointName(2);
    38204106    NumberName = sstr.str();
    38214107    if (DoTecplotOutput) {
     
    38594145    if (s1->endpoints.size() < s2->endpoints.size())
    38604146      return true;
    3861     else if (s1->endpoints.size() > s2->endpoints.size())
    3862       return false;
    3863     else { // equality of number of endpoints
    3864       PointSet::const_iterator Walker1 = s1->endpoints.begin();
    3865       PointSet::const_iterator Walker2 = s2->endpoints.begin();
    3866       while ((Walker1 != s1->endpoints.end()) || (Walker2 != s2->endpoints.end())) {
    3867         if ((*Walker1)->Nr < (*Walker2)->Nr)
    3868           return true;
    3869         else if ((*Walker1)->Nr > (*Walker2)->Nr)
    3870           return false;
    3871         Walker1++;
    3872         Walker2++;
     4147    else
     4148      if (s1->endpoints.size() > s2->endpoints.size())
     4149        return false;
     4150      else { // equality of number of endpoints
     4151        PointSet::const_iterator Walker1 = s1->endpoints.begin();
     4152        PointSet::const_iterator Walker2 = s2->endpoints.begin();
     4153        while ((Walker1 != s1->endpoints.end()) || (Walker2 != s2->endpoints.end())) {
     4154          if ((*Walker1)->Nr < (*Walker2)->Nr)
     4155            return true;
     4156          else
     4157            if ((*Walker1)->Nr > (*Walker2)->Nr)
     4158              return false;
     4159          Walker1++;
     4160          Walker2++;
     4161        }
     4162        return false;
    38734163      }
    3874       return false;
    3875     }
    38764164  }
    38774165};
     
    38984186      for (TriangleMap::const_iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) {
    38994187        if (DegeneratedTriangles->find(TriangleRunner->second->Nr) == DegeneratedTriangles->end()) {
    3900           TriangleInsertionTester = TriangleVectors.insert(pair<int, Vector *> ((TriangleRunner->second)->Nr, &((TriangleRunner->second)->NormalVector)));
     4188          TriangleInsertionTester = TriangleVectors.insert(pair<int, Vector *>((TriangleRunner->second)->Nr, &((TriangleRunner->second)->NormalVector)));
    39014189          if (TriangleInsertionTester.second)
    39024190            LOG(5, "DEBUG:  Adding triangle " << *(TriangleRunner->second) << " to triangles to check-list.");
     
    39114199        if (VectorWalker != VectorRunner) { // skip equals
    39124200          const double SCP = VectorWalker->second->ScalarProduct(*VectorRunner->second); // ScalarProduct should result in -1. for degenerated triangles
    3913           LOG(4, "DEBUG: Checking " << *VectorWalker->second << " against " << *VectorRunner->second << ": " << SCP);
     4201          LOG(4, "DEBUG: Checking " << *(VectorWalker->second) << " against " << *(VectorRunner->second) << ": " << SCP);
    39144202          if (fabs(SCP + 1.) < ParallelEpsilon) {
    39154203            InsertionTester = EndpointCandidateList.insert((Runner->second));
     
    39934281    // The Problem is probably due to two degenerated polygons being connected by a bridging, non-degenerated polygon, as somehow one node has
    39944282    // connections to either polygon ...
    3995     if (T->size() % 2 != 0) {
    3996       ELOG(0, " degenerated polygon contains an odd number of triangles, probably contains bridging non-degenerated ones, too!");
    3997       performCriticalExit();
    3998     }
     4283    ASSERT(T->size() % 2 == 0, std::string("Tesselation::CorrectAllDegeneratedPolygons() - ") + std::string(" degenerated polygon contains an odd number of triangles,") + std::string(" probably contains bridging non-degenerated ones, too!"));
    39994284    TriangleSet::iterator TriangleWalker = T->begin(); // is the inner iterator
    40004285    /// 4a. Get NormalVector for one side (this is "front")
  • src/Tesselation/tesselation.hpp

    r3b1798 r0516fd  
    7676    void AddTesselationPoint(TesselPoint* Candidate, const int n);
    7777    void SetTesselationPoint(TesselPoint* Candidate, const int n) const;
    78     void AddTesselationLine(const Vector * OptCenter, const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n);
     78    bool AddTesselationLine(const Vector * OptCenter, const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n);
    7979    void AddNewTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n);
    8080    void AddExistingTesselationTriangleLine(class BoundaryLineSet *FindLine, int n);
     
    8888    void RemoveTesselationPoint(class BoundaryPointSet *point);
    8989    bool CheckDegeneracy(CandidateForTesselation &CandidateLine, const double RADIUS, const LinkedCell_deprecated *LC) const;
    90 
     90    bool isConvex() const;
    9191
    9292    // concave envelope
     
    103103    void GuessStartingTriangle();
    104104    bool InsertStraddlingPoints(IPointCloud & cloud, const LinkedCell_deprecated *LC);
     105    double RemovePointSurroundedByPolygon(
     106        TesselPointList *connectedPath,
     107        BoundaryPointSet *point);
     108    bool CheckAllConcaveInPolygon(
     109        const TesselPointList *connectedPath,
     110        const BoundaryPointSet *point
     111        );
     112    double RemoveFullConcavePointFromTesselatedSurface(class BoundaryPointSet *point);
    105113    double RemovePointFromTesselatedSurface(class BoundaryPointSet *point);
    106114    class BoundaryLineSet * FlipBaseline(class BoundaryLineSet *Base);
     
    131139    DistanceToPointMap * FindClosestBoundaryPointsToVector(const Vector &x, const LinkedCell_deprecated* LC) const;
    132140    BoundaryLineSet * FindClosestBoundaryLineToVector(const Vector &x, const LinkedCell_deprecated* LC) const;
     141
     142    bool IsPointBelowSurroundingPolygon(const BoundaryPointSet *_point) const;
    133143
    134144    // print for debugging
  • src/Tesselation/tesselationhelpers.cpp

    r3b1798 r0516fd  
    235235  if (helper.ScalarProduct(SearchDirection) < -HULLEPSILON)  // acos is not unique on [0, 2.*M_PI), hence extra check to decide between two half intervals
    236236    alpha = 2.*M_PI - alpha;
    237   LOG(3, "DEBUG: RelativeNewSphereCenter is " << helper << ", RelativeOldSphereCenter is " << RelativeOldSphereCenter << " and resulting angle is " << alpha << ".");
     237  LOG(5, "DEBUG: RelativeNewSphereCenter is " << helper << ", RelativeOldSphereCenter is " << RelativeOldSphereCenter << " and resulting angle is " << alpha << ".");
    238238  radius = helper.distance(RelativeOldSphereCenter);
    239239  helper.ProjectOntoPlane(NormalVector);
    240240  // check whether new center is somewhat away or at least right over the current baseline to prevent intersecting triangles
    241241  if ((radius > HULLEPSILON) || (helper.Norm() < HULLEPSILON)) {
    242     LOG(4, "DEBUG: Distance between old and new center is " << radius << " and between new center and baseline center is " << helper.Norm() << ".");
     242    LOG(6, "DEBUG: Distance between old and new center is " << radius << " and between new center and baseline center is " << helper.Norm() << ".");
    243243    return alpha;
    244244  } else {
    245     LOG(3, "DEBUG: NewSphereCenter " << RelativeNewSphereCenter << " is too close to RelativeOldSphereCenter" << RelativeOldSphereCenter << ".");
     245    LOG(5, "DEBUG: NewSphereCenter " << RelativeNewSphereCenter << " is too close to RelativeOldSphereCenter" << RelativeOldSphereCenter << ".");
    246246    return 2.*M_PI;
    247247  }
     
    278278  }
    279279
    280   LOG(1, "INFO: " << point << " has angle " << phi << " with respect to reference " << reference << ".");
     280  LOG(4, "INFO: " << point << " has angle " << phi << " with respect to reference " << reference << ".");
    281281
    282282  return phi;
     
    289289 * \param *c third vector
    290290 * \param *d fourth vector
    291  * \return \f$ \frac{1}{6} \cdot ((a-d) \times (a-c) \cdot  (a-b)) \f$
     291 * \return \f$ \frac{1}{6} | (a-d) \cdot  \bigl ( (b-d) \times (c-d) \bigr ) | \f$
    292292 */
    293293double CalculateVolumeofGeneralTetraeder(const Vector &a, const Vector &b, const Vector &c, const Vector &d)
     
    302302  for (int j=0;j<3;j++)
    303303    TetraederVector[j].SubtractVector(d);
    304   Point = TetraederVector[0];
    305   Point.VectorProduct(TetraederVector[1]);
    306   volume = 1./6. * fabs(Point.ScalarProduct(TetraederVector[2]));
     304  Point = TetraederVector[1];
     305  Point.VectorProduct(TetraederVector[2]);
     306  volume = 1./6. * fabs(Point.ScalarProduct(TetraederVector[0]));
    307307  return volume;
    308308};
     
    545545  Normal.VectorProduct(OtherBaseline);
    546546  Normal.Normalize();
    547   LOG(1, "First direction is " << Baseline << ", second direction is " << OtherBaseline << ", normal of intersection plane is " << Normal << ".");
     547  LOG(3, "First direction is " << Baseline << ", second direction is " << OtherBaseline << ", normal of intersection plane is " << Normal << ".");
    548548
    549549  // project one offset point of OtherBase onto this plane (and add plane offset vector)
     
    559559  *Intersection = line1.getIntersection(line2);
    560560  Normal = (*Intersection) - (Base->endpoints[0]->node->getPosition());
    561   LOG(1, "Found closest point on " << *Base << " at " << *Intersection << ", factor in line is " << fabs(Normal.ScalarProduct(Baseline)/Baseline.NormSquared()) << ".");
     561  LOG(3, "Found closest point on " << *Base << " at " << *Intersection << ", factor in line is " << fabs(Normal.ScalarProduct(Baseline)/Baseline.NormSquared()) << ".");
    562562
    563563  return Intersection;
     
    751751    *tecplot << endl;
    752752    // print connectivity
    753     LOG(1, "The following triangles were created:");
     753    LOG(4, "DEBUG: The following triangles were created:");
    754754    for (TriangleMap::const_iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) {
    755       LOG(1, " " << runner->second->endpoints[0]->node->getName() << "<->" << runner->second->endpoints[1]->node->getName() << "<->" << runner->second->endpoints[2]->node->getName());
     755      LOG(4, " " << runner->second->endpoints[0]->node->getName() << "<->" << runner->second->endpoints[1]->node->getName() << "<->" << runner->second->endpoints[2]->node->getName());
    756756      *tecplot << LookupList[runner->second->endpoints[0]->node->getNr()] << " " << LookupList[runner->second->endpoints[1]->node->getNr()] << " " << LookupList[runner->second->endpoints[2]->node->getNr()] << endl;
    757757    }
     
    778778  for (PointMap::const_iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) {
    779779    point = PointRunner->second;
    780     LOG(1, "INFO: Current point is " << *point << ".");
     780    LOG(2, "INFO: Current point is " << *point << ".");
    781781
    782782    // calculate mean concavity over all connected line
  • src/Tesselation/triangleintersectionlist.cpp

    r3b1798 r0516fd  
    132132    // if we have found one, check Scalarproduct between the vector
    133133    Vector TestVector = (Point) - (*(*runner).second);
    134     LOG(1, "INFO: Distance vector between point " << Point
     134    LOG(4, "DEBUG: Distance vector between point " << Point
    135135        << " and triangle intersection at " << (*(*runner).second) << " is "
    136136        << TestVector << ".");
    137137    if (fabs(TestVector.NormSquared()) < MYEPSILON)  {//
    138       LOG(1, "ACCEPT: Point is on the intersected triangle.");
     138      LOG(3, "ACCEPT: Point is on the intersected triangle.");
    139139      return true;
    140140    }
    141141    const double sign = (*runner).first->NormalVector.ScalarProduct(TestVector);
    142     LOG(1, "INFO: Checking sign of SKP between Distance vector and triangle's NormalVector "
     142    LOG(4, "DEBUG: Checking sign of SKP between Distance vector and triangle's NormalVector "
    143143        << (*runner).first->NormalVector << ": " << sign << ".");
    144144    if (sign < 0) {
    145       LOG(1, "ACCEPT: Point lies on inner side of intersected triangle.");
     145      LOG(3, "ACCEPT: Point lies on inner side of intersected triangle.");
    146146      return true;
    147147    } else {
    148       LOG(1, "REJECT: Point lies on outer side of intersected triangle.");
     148      LOG(3, "REJECT: Point lies on outer side of intersected triangle.");
    149149      return false;
    150150    }
     
    224224      for (DistanceTriangleMap::const_iterator iter = DistanceRange.first;
    225225          iter != DistanceRange.second; ++iter) {
    226         LOG(3, "DEBUG: " << *(iter->second) << " is in the list with " << iter->first << ".");
     226        LOG(4, "DEBUG: " << *(iter->second) << " is in the list with " << iter->first << ".");
    227227        ++count;
    228228      }
    229       LOG(1, "INFO: There are " << count << " possible triangles at the smallest distance.");
     229      LOG(3, "INFO: There are " << count << " possible triangles at the smallest distance.");
    230230    }
    231231    // if there is more than one, check all of their normal vectors
     
    233233    // would be truely inside, all of the closest triangles would have to show
    234234    // their inner side
    235     LOG(1, "INFO: Looking for first SKP greater than zero ...");
     235    LOG(4, "DEBUG: Looking for first SKP greater than zero ...");
    236236    for (DistanceTriangleMap::const_iterator iter = DistanceRange.first;
    237237        iter != DistanceRange.second; ++iter) {
     
    241241      // construct SKP
    242242      const double sign = (*iter).second->NormalVector.ScalarProduct(TestVector);
    243       LOG(1, "INFO: Checking SKP of closest triangle " << *(iter->second) << " = " << sign << ".");
     243      LOG(4, "DEBUG: Checking SKP of closest triangle " << *(iter->second) << " = " << sign << ".");
    244244      // if positive return
    245245      if (sign > 0)
  • src/UIElements/Views/Qt4/Plotting/QSeisPlotPage.cpp

    r3b1798 r0516fd  
    3939QSeisPlotPage::~QSeisPlotPage()
    4040{
     41  if (layoutInitialized)
    4142    deinitializeLayout();
    4243}
  • src/documentation/constructs/tesselation.dox

    r3b1798 r0516fd  
    2020 * to such a surface.
    2121 *
    22  * \section tesselation-procedure
     22 * \section tesselation-procedure Tesselation procedure
    2323 *
    2424 * In the tesselation all atoms act as possible hindrance to a rolling sphere
     
    3434 * other (although the code for that is not yet fully implemented).
    3535 *
    36  * \section tesselation-extension
     36 * \section tesselation-convexization Making a surface convex
     37 *
     38 * A closed surface created by the aforementioned procedure can be made convex
     39 * by a combination of the following two ways:
     40 * -# Removing a point from the surface that is connected to other points only
     41 *    by concave lines. This might also be imagined as removing bumps or
     42 *    craters in the surface.
     43 * -# flipping a base line or rather adding a general tetrahedron to remove a
     44 *    concave line on the surface.
     45 *
     46 * With the first way one has to pay attention to possible degenerated lines
     47 * and triangles. That's why prior to the this convexization procedure all
     48 * possible degenerated triangles are removed. Furthermore, when looking at
     49 * a removal candidate and its connected points, all these points are split
     50 * up into so-called connected paths. The crater to be removed or filled-up
     51 * has a low point -- the point to be removed -- and a rim, defined by all
     52 * points connected by concave lines to the low point. However, when a point
     53 * has degenerated lines attached to it (i.e. two lines with the same
     54 * endpoints), it may have multiple rims (imagine two craters on either
     55 * side of the surface and the volume being so small/slim that they reach
     56 * through to the same low point). We have to discern between these multiple
     57 * rims, therefore the connected points are placed into different closed
     58 * rings, so-called polygons. The point is the removed and the polygon re-
     59 * tesselated which essentially fills the crater.
     60 *
     61 * With the second way, we have to pay attention that the filled-in tetrahedron
     62 * does not intersect already present triangles. The baseline defines two
     63 * points and as the tesselated surface is closed, it must be connected to two
     64 * triangles. These together define a set of four points that make up the
     65 * tetrahedron. Naturally, two sides of the tetrahedron are always present
     66 * already (and will become removed in place of the other two, effectively
     67 * adding more volume to the tesselation).
     68 * Now first, we only flip base lines that are concave. Second, none of the two
     69 * other sides of the tetrahedron must be present. And lastly, we must check
     70 * for all surrounding triangles that the new baseline (formed by point 3
     71 * and 4) does not intersect these. Essentially, if we imagine a plane
     72 * containing this new baseline, then each possibly intersecting triangle shows
     73 * up as a brief line segment. We have to make sure that all of these segments
     74 * remain below the new baseline in this plane. Also, things are complicated
     75 * as the first and last line segment will always intersect with the baseline
     76 * at the endpoint. There, we basically have to make sure that the line segment
     77 * goes off in the right direction, namely outward.
     78 *
     79 * \section tesselation-volume Measuring the volume contained
     80 *
     81 * There is no straight-forward way to measure the volume contained in a
     82 * non-convex tesselated surface. However, there is for a convex surface
     83 * because convexity means that a line between any inner point and a point on
     84 * the boundary will not intersect the surface anywhere else. Hence, we may
     85 * use the center of gravity of all boundary points (by the same argument it
     86 * must be an inner point) and calculate the volume of the general tetrahedron
     87 * by looking at each of the tesselation's triangles in turn and summing up.
     88 *
     89 * We can calculate the volume of the original non-convex tesselation because
     90 * the two ways mentioned above -- removing points and flipping baselines --
     91 * both involve just addding general tetrahedron whose volume we may easily
     92 * calculate. By bookkeeping of how much volume is added and calculating the
     93 * total convex volume in the end, we also get the volume contained in the
     94 * prior non-convex surface.
     95 *
     96 * \section tesselation-extension Issues whebn extended a tesselated surface
    3797 *
    3898 * The main problem for extending the mesh to match with the normal sense is
     
    47107 * from a combination of spheres with van der Waals radii.
    48108 *
    49  * \date 2014-03-10
     109 * \date 2014-10-09
    50110 *
    51111 */
  • tests/Python/AllActions/options.dat

    r3b1798 r0516fd  
    4242change-element  "1"
    4343change-molname  "water"
     44convex-envelope "50."
    4445convex-file     "convexfile"
    4546copy-molecule   "0"
     
    6263DoCyclesFull    "0"
    6364DoLongrange     "0"
     65DoOutputEveryStep       "0"
    6466DoPrintDebug    "0"
    6567DoRotate        "0"
  • tests/Tesselations/Makefile.am

    r3b1798 r0516fd  
    77        molecuilder.in \
    88        package.m4 \
    9         $(srcdir)/1_2-dimethoxyethane \
    10         $(srcdir)/1_2-dimethylbenzene \
    11         $(srcdir)/2-methylcyclohexanone \
    12         $(srcdir)/benzene \
    13         $(srcdir)/cholesterol \
    14         $(srcdir)/cycloheptane \
    15         $(srcdir)/dimethyl_bromomalonate \
    16         $(srcdir)/glucose \
    17         $(srcdir)/heptan \
    18         $(srcdir)/isoleucine \
    19         $(srcdir)/neohexane \
    20         $(srcdir)/N_N-dimethylacetamide \
    21         $(srcdir)/proline \
    22         $(srcdir)/putrescine \
    23         $(srcdir)/tartaric_acid
     9        $(srcdir)/Convex/1_2-dimethoxyethane \
     10        $(srcdir)/Convex/1_2-dimethylbenzene \
     11        $(srcdir)/Convex/2-methylcyclohexanone \
     12        $(srcdir)/Convex/amylose \
     13        $(srcdir)/Convex/benzene \
     14        $(srcdir)/Convex/cholesterol \
     15        $(srcdir)/Convex/cycloheptane \
     16        $(srcdir)/Convex/dimethyl_bromomalonate \
     17        $(srcdir)/Convex/glucose \
     18        $(srcdir)/Convex/heptan \
     19        $(srcdir)/Convex/isoleucine \
     20        $(srcdir)/Convex/neohexane \
     21        $(srcdir)/Convex/N_N-dimethylacetamide \
     22        $(srcdir)/Convex/proline \
     23        $(srcdir)/Convex/putrescine \
     24        $(srcdir)/Convex/tartaric_acid \
     25        $(srcdir)/NonConvex/1_2-dimethoxyethane \
     26        $(srcdir)/NonConvex/1_2-dimethylbenzene \
     27        $(srcdir)/NonConvex/2-methylcyclohexanone \
     28        $(srcdir)/NonConvex/benzene \
     29        $(srcdir)/NonConvex/cholesterol \
     30        $(srcdir)/NonConvex/cycloheptane \
     31        $(srcdir)/NonConvex/dimethyl_bromomalonate \
     32        $(srcdir)/NonConvex/glucose \
     33        $(srcdir)/NonConvex/heptan \
     34        $(srcdir)/NonConvex/isoleucine \
     35        $(srcdir)/NonConvex/neohexane \
     36        $(srcdir)/NonConvex/N_N-dimethylacetamide \
     37        $(srcdir)/NonConvex/proline \
     38        $(srcdir)/NonConvex/putrescine \
     39        $(srcdir)/NonConvex/tartaric_acid
    2440
    2541TESTSUITE = $(srcdir)/testsuite
     
    2844
    2945TESTSCRIPTS = \
    30         benzene/testsuite-benzene.at \
    31         1_2-dimethoxyethane/testsuite-1_2-dimethoxyethane.at \
    32         1_2-dimethylbenzene/testsuite-1_2-dimethylbenzene.at \
    33         2-methylcyclohexanone/testsuite-2-methylcyclohexanone.at \
    34         cholesterol/testsuite-cholesterol.at \
    35         cycloheptane/testsuite-cycloheptane.at \
    36         dimethyl_bromomalonate/testsuite-dimethyl_bromomalonate.at \
    37         glucose/testsuite-glucose.at \
    38         isoleucine/testsuite-isoleucine.at \
    39         neohexane/testsuite-neohexane.at \
    40         N_N-dimethylacetamide/testsuite-N_N-dimethylacetamide.at \
    41         proline/testsuite-proline.at \
    42         putrescine/testsuite-putrescine.at \
    43         tartaric_acid/testsuite-tartaric_acid.at
     46        Convex/1_2-dimethoxyethane/testsuite-1_2-dimethoxyethane.at \
     47        Convex/1_2-dimethylbenzene/testsuite-1_2-dimethylbenzene.at \
     48        Convex/2-methylcyclohexanone/testsuite-2-methylcyclohexanone.at \
     49        Convex/benzene/testsuite-benzene.at \
     50        Convex/amylose/testsuite-amylose.at \
     51        Convex/cholesterol/testsuite-cholesterol.at \
     52        Convex/cycloheptane/testsuite-cycloheptane.at \
     53        Convex/dimethyl_bromomalonate/testsuite-dimethyl_bromomalonate.at \
     54        Convex/glucose/testsuite-glucose.at \
     55        Convex/isoleucine/testsuite-isoleucine.at \
     56        Convex/neohexane/testsuite-neohexane.at \
     57        Convex/N_N-dimethylacetamide/testsuite-N_N-dimethylacetamide.at \
     58        Convex/proline/testsuite-proline.at \
     59        Convex/putrescine/testsuite-putrescine.at \
     60        Convex/tartaric_acid/testsuite-tartaric_acid.at \
     61        NonConvex/1_2-dimethoxyethane/testsuite-1_2-dimethoxyethane.at \
     62        NonConvex/1_2-dimethylbenzene/testsuite-1_2-dimethylbenzene.at \
     63        NonConvex/2-methylcyclohexanone/testsuite-2-methylcyclohexanone.at \
     64        NonConvex/benzene/testsuite-benzene.at \
     65        NonConvex/cholesterol/testsuite-cholesterol.at \
     66        NonConvex/cycloheptane/testsuite-cycloheptane.at \
     67        NonConvex/dimethyl_bromomalonate/testsuite-dimethyl_bromomalonate.at \
     68        NonConvex/glucose/testsuite-glucose.at \
     69        NonConvex/isoleucine/testsuite-isoleucine.at \
     70        NonConvex/neohexane/testsuite-neohexane.at \
     71        NonConvex/N_N-dimethylacetamide/testsuite-N_N-dimethylacetamide.at \
     72        NonConvex/proline/testsuite-proline.at \
     73        NonConvex/putrescine/testsuite-putrescine.at \
     74        NonConvex/tartaric_acid/testsuite-tartaric_acid.at
     75
    4476
    4577max_jobs = 4
  • tests/Tesselations/testsuite.at

    r3b1798 r0516fd  
    2727m4_ifdef([AT_COLOR_TESTS], [AT_COLOR_TESTS])
    2828
     29### NONCONVEX TESSELATION
     30
    2931# tesselation of 1_2-dimethoxyethane
    30 m4_include(1_2-dimethoxyethane/testsuite-1_2-dimethoxyethane.at)
     32m4_include(NonConvex/1_2-dimethoxyethane/testsuite-1_2-dimethoxyethane.at)
    3133
    3234# tesselation of 1_2-dimethylbenzene
    33 m4_include(1_2-dimethylbenzene/testsuite-1_2-dimethylbenzene.at)
     35m4_include(NonConvex/1_2-dimethylbenzene/testsuite-1_2-dimethylbenzene.at)
    3436
    3537# tesselation of 2-methylcyclohexanone
    36 m4_include(2-methylcyclohexanone/testsuite-2-methylcyclohexanone.at)
     38m4_include(NonConvex/2-methylcyclohexanone/testsuite-2-methylcyclohexanone.at)
    3739
    3840# tesselation of benzene
    39 m4_include(benzene/testsuite-benzene.at)
     41m4_include(NonConvex/benzene/testsuite-benzene.at)
    4042
    4143# tesselation of cholesterol
    42 m4_include(cholesterol/testsuite-cholesterol.at)
     44m4_include(NonConvex/cholesterol/testsuite-cholesterol.at)
    4345
    4446# tesselation of cycloheptane
    45 m4_include(cycloheptane/testsuite-cycloheptane.at)
     47m4_include(NonConvex/cycloheptane/testsuite-cycloheptane.at)
    4648
    4749# tesselation of dimethyl_bromomalonate
    48 m4_include(dimethyl_bromomalonate/testsuite-dimethyl_bromomalonate.at)
     50m4_include(NonConvex/dimethyl_bromomalonate/testsuite-dimethyl_bromomalonate.at)
    4951
    5052# tesselation of glucose
    51 m4_include(glucose/testsuite-glucose.at)
     53m4_include(NonConvex/glucose/testsuite-glucose.at)
    5254
    5355# tesselation of heptan
    54 m4_include(heptan/testsuite-heptan.at)
     56m4_include(NonConvex/heptan/testsuite-heptan.at)
    5557
    5658# tesselation of isoleucine
    57 m4_include(isoleucine/testsuite-isoleucine.at)
     59m4_include(NonConvex/isoleucine/testsuite-isoleucine.at)
    5860
    5961# tesselation of neohexane
    60 m4_include(neohexane/testsuite-neohexane.at)
     62m4_include(NonConvex/neohexane/testsuite-neohexane.at)
    6163
    6264# tesselation of N_N-dimethylacetamide
    63 m4_include(N_N-dimethylacetamide/testsuite-N_N-dimethylacetamide.at)
     65m4_include(NonConvex/N_N-dimethylacetamide/testsuite-N_N-dimethylacetamide.at)
    6466
    6567# tesselation of proline
    66 m4_include(proline/testsuite-proline.at)
     68m4_include(NonConvex/proline/testsuite-proline.at)
    6769
    6870# tesselation of putrescine
    69 m4_include(putrescine/testsuite-putrescine.at)
     71m4_include(NonConvex/putrescine/testsuite-putrescine.at)
    7072
    7173# tesselation of tartaric_acid
    72 m4_include(tartaric_acid/testsuite-tartaric_acid.at)
     74m4_include(NonConvex/tartaric_acid/testsuite-tartaric_acid.at)
     75
     76### NONCONVEX TESSELATION
     77
     78# tesselation of 1_2-dimethoxyethane
     79m4_include(Convex/1_2-dimethoxyethane/testsuite-1_2-dimethoxyethane.at)
     80
     81# tesselation of 1_2-dimethylbenzene
     82m4_include(Convex/1_2-dimethylbenzene/testsuite-1_2-dimethylbenzene.at)
     83
     84# tesselation of 2-methylcyclohexanone
     85m4_include(Convex/2-methylcyclohexanone/testsuite-2-methylcyclohexanone.at)
     86
     87# tesselation of amylose
     88m4_include(Convex/amylose/testsuite-amylose.at)
     89
     90# tesselation of benzene
     91m4_include(Convex/benzene/testsuite-benzene.at)
     92
     93# tesselation of cholesterol
     94m4_include(Convex/cholesterol/testsuite-cholesterol.at)
     95
     96# tesselation of cycloheptane
     97m4_include(Convex/cycloheptane/testsuite-cycloheptane.at)
     98
     99# tesselation of dimethyl_bromomalonate
     100m4_include(Convex/dimethyl_bromomalonate/testsuite-dimethyl_bromomalonate.at)
     101
     102# tesselation of glucose
     103m4_include(Convex/glucose/testsuite-glucose.at)
     104
     105# tesselation of heptan
     106m4_include(Convex/heptan/testsuite-heptan.at)
     107
     108# tesselation of isoleucine
     109m4_include(Convex/isoleucine/testsuite-isoleucine.at)
     110
     111# tesselation of neohexane
     112m4_include(Convex/neohexane/testsuite-neohexane.at)
     113
     114# tesselation of N_N-dimethylacetamide
     115m4_include(Convex/N_N-dimethylacetamide/testsuite-N_N-dimethylacetamide.at)
     116
     117# tesselation of proline
     118m4_include(Convex/proline/testsuite-proline.at)
     119
     120# tesselation of putrescine
     121m4_include(Convex/putrescine/testsuite-putrescine.at)
     122
     123# tesselation of tartaric_acid
     124m4_include(Convex/tartaric_acid/testsuite-tartaric_acid.at)
  • tests/regression/Tesselation/BigConvex/testsuite-tesselation-big-convex-envelope.at

    r3b1798 r0516fd  
    2020AT_SETUP([Tesselation - big convex Envelope])
    2121AT_KEYWORDS([Tesselation convex convex-envelope])
    22 AT_XFAIL_IF([/bin/true])
    2322
    2423file=test.conf
    25 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Tesselation/BigConvex/pre/test./conf $file], 0)
     24AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Tesselation/BigConvex/pre/test.conf $file], 0)
    2625convexfile=ConvexEnvelope
    27 AT_CHECK([../../molecuilder -i $file  --select-molecule-by-id 0 --convex-envelope --convex-file $convexfile --nonconvex-file NonConvexEnvelope], 0, [stdout], [stderr])
     26AT_CHECK([../../molecuilder -i $file  --select-molecule-by-id 0 --convex-envelope 5. --convex-file $convexfile --nonconvex-file NonConvexEnvelope], 0, [stdout], [stderr])
    2827AT_CHECK([diff ${convexfile}.dat ${abs_top_srcdir}/tests/regression/Tesselation/BigConvex/post/ConvexEnvelope.dat], 0, [ignore], [ignore])
    2928#AT_CHECK([diff ${convexfile}.r3d ${abs_top_srcdir}/tests/regression/Tesselation/BigConvex/post/ConvexEnvelope.r3d], 0, [ignore], [ignore])
    30 AT_CHECK([fgrep "tesselated volume area is 16.4016 angstrom^3" stdout], 0, [ignore], [ignore])
     29AT_CHECK([fgrep "tesselated volume area is 223.577 angstrom^3" stdout], 0, [ignore], [ignore])
    3130
    3231AT_CLEANUP
  • tests/regression/Tesselation/Convex/testsuite-tesselation-convex-envelope.at

    r3b1798 r0516fd  
    2424AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Tesselation/Convex/pre/test.conf $file], 0)
    2525convexfile=ConvexEnvelope
    26 AT_CHECK([../../molecuilder -i $file  --select-molecule-by-id 0 --convex-envelope --convex-file $convexfile --nonconvex-file NonConvexEnvelope], 0, [stdout], [stderr])
     26AT_CHECK([../../molecuilder -i $file  --select-molecule-by-id 0 --convex-envelope 50. --convex-file $convexfile --nonconvex-file NonConvexEnvelope], 0, [stdout], [stderr])
    2727AT_CHECK([diff ${convexfile}.dat ${abs_top_srcdir}/tests/regression/Tesselation/Convex/post/ConvexEnvelope.dat], 0, [ignore], [ignore])
    2828#AT_CHECK([diff ${convexfile}.r3d ${abs_top_srcdir}/tests/regression/Tesselation/Convex/post/ConvexEnvelope.r3d], 0, [ignore], [ignore])
    29 AT_CHECK([fgrep "tesselated volume area is 16.4016 angstrom^3" stdout], 0, [ignore], [ignore])
     29AT_CHECK([fgrep "tesselated volume area is 8.89109 angstrom^3" stdout], 0, [ignore], [ignore])
    3030AT_CHECK([diff ConvexEnvelope.dat NonConvexEnvelope.dat], 0, [ignore], [ignore])
    3131
Note: See TracChangeset for help on using the changeset viewer.