Changes in / [3b1798:0516fd]
- Files:
-
- 172 added
- 138 deleted
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
LinearAlgebra/src/LinearAlgebra/Line.cpp
r3b1798 r0516fd 120 120 */ 121 121 Vector Line::getIntersection(const Line& otherLine) const{ 122 Info FunctionInfo(__func__);123 124 122 pointset line1Points = getPointsOnLine(); 125 123 … … 151 149 //} 152 150 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; 154 152 throw SkewException() << LinearAlgebraDeterminant(M->Determinant()) << LinearAlgebraMatrixContent(&(*M)); 155 153 } 156 154 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; 158 156 159 157 … … 163 161 Vector c = Line2a - Line1a; 164 162 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; 166 164 if ((a.NormSquared() <= LINALG_MYEPSILON()) || (b.NormSquared() <= LINALG_MYEPSILON())) { 167 165 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; 169 167 throw LinearDependenceException() << LinearAlgebraVectorPair( make_pair(&a, &b) ); 170 168 } … … 178 176 if ((factor > -LINALG_MYEPSILON()) && (factor - 1. <= LINALG_MYEPSILON())) { 179 177 res = Line2a; 180 Log() << Verbose( 1) << "Lines conincide." << endl;178 Log() << Verbose(5) << "Lines conincide." << endl; 181 179 return res; 182 180 } else { … … 185 183 if ((factor > -LINALG_MYEPSILON()) && (factor - 1. <= LINALG_MYEPSILON())) { 186 184 res = Line2b; 187 Log() << Verbose( 1) << "Lines conincide." << endl;185 Log() << Verbose(5) << "Lines conincide." << endl; 188 186 return res; 189 187 } 190 188 } 191 Log() << Verbose(1) << "Lines are parallel." << endl;189 eLog() << Verbose(2) << "Lines are parallel." << endl; 192 190 res.Zero(); 193 191 throw LinearDependenceException() << LinearAlgebraVectorPair( make_pair(&a, &b) ); … … 201 199 temp2 = a; 202 200 temp2.VectorProduct(b); 203 Log() << Verbose( 1) << "INFO: temp1 = " << temp1 << ", temp2 = " << temp2 << "." << endl;201 Log() << Verbose(7) << "INFO: temp1 = " << temp1 << ", temp2 = " << temp2 << "." << endl; 204 202 if (fabs(temp2.NormSquared()) > LINALG_MYEPSILON()) 205 203 s = temp1.ScalarProduct(temp2)/temp2.NormSquared(); 206 204 else 207 205 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; 209 207 210 208 // construct intersection … … 212 210 res.Scale(s); 213 211 res += Line1a; 214 Log() << Verbose( 1) << "Intersection is at " << res << "." << endl;212 Log() << Verbose(5) << "Intersection is at " << res << "." << endl; 215 213 216 214 return res; -
configure.ac
r3b1798 r0516fd 207 207 BOOST_ITERATOR 208 208 BOOST_MULTIARRAY 209 BOOST_MULTIINDEXCONTAINER 209 210 BOOST_MPL 210 211 BOOST_PREPROCESSOR -
doc/userguide/userguide.xml
r3b1798 r0516fd 2405 2405 Non-convex envelope</title> 2406 2406 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> 2408 2409 2409 2410 <programlisting> … … 2414 2415 <para>This tesselation file can be conveniently viewed with 2415 2416 <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> 2417 2423 </section> 2418 2424 … … 2421 2427 envelope</title> 2422 2428 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> 2424 2433 2425 2434 <programlisting> … … 2428 2437 </programlisting> 2429 2438 2430 <para>This tesselation file can be convenientlyviewed with2439 <para>This tesselation file can be likewise viewed with 2431 2440 <productname>TecPlot</productname> or with one of the Tcl script 2432 2441 in the util folder with <productname>VMD</productname>.</para> -
m4/boost.m4
r3b1798 r0516fd 814 814 [BOOST_FIND_HEADER([boost/multi_array.hpp])]) 815 815 816 # BOOST_MULTIINDEXCCONTAINER() 817 # ------------------ 818 # Look for Boost.MultiIndexContainer 819 BOOST_DEFUN([MultiIndexContainer], 820 [BOOST_FIND_HEADER([boost/multi_index_container.hpp])]) 821 816 822 817 823 # BOOST_NUMERIC_UBLAS() -
src/Actions/ActionQueue.cpp
r3b1798 r0516fd 98 98 void ActionQueue::queueAction(const Action * const _action, enum Action::QueryOptions state) 99 99 { 100 OBSERVE;101 NOTIFY(ActionQueued);102 100 Action *newaction = _action->clone(state); 103 101 newaction->prepare(state); … … 123 121 std::cerr << "ActionQueue cleared." << std::endl; 124 122 } 123 if (lastActionOk) { 124 OBSERVE; 125 NOTIFY(ActionQueued); 126 _lastchangedaction = newaction; 127 } 125 128 #else 126 129 { … … 130 133 mtx_queue.unlock(); 131 134 #endif 132 _lastchangedaction = newaction;133 135 } 134 136 … … 193 195 CurrentAction = (size_t)-1; 194 196 } 197 if (lastActionOk) { 198 OBSERVE; 199 NOTIFY(ActionQueued); 200 _lastchangedaction = actionqueue[CurrentAction]; 201 } 195 202 // access actionqueue, hence using mutex 196 203 mtx_queue.lock(); -
src/Actions/TesselationAction/ConvexEnvelopeAction.cpp
r3b1798 r0516fd 68 68 LOG(1, "Storing tecplot non-convex data in " << params.filenameNonConvex.get() << "."); 69 69 PointCloudAdaptor<molecule> cloud(mol, mol->name); 70 LCList = new LinkedCell_deprecated(cloud, 100.);70 LCList = new LinkedCell_deprecated(cloud, 2.*params.SphereRadius.get()); 71 71 //Boundaries *BoundaryPoints = NULL; 72 72 //FindConvexBorder(mol, BoundaryPoints, TesselStruct, LCList, argv[argptr]); 73 73 // 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()); 75 75 //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 77 99 const double clustervolume = TesselStruct->getVolumeOfConvexEnvelope(configuration->GetIsAngstroem()); 78 100 LOG(0, "The tesselated volume area is " << clustervolume << " " << (configuration->GetIsAngstroem() ? "angstrom" : "atomiclength") << "^3."); … … 84 106 return Action::success; 85 107 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(".")); 87 111 return Action::failure; 88 112 } -
src/Actions/TesselationAction/ConvexEnvelopeAction.def
r3b1798 r0516fd 9 9 class TesselationListClass; 10 10 11 #include "Parameters/Validators/DummyValidator.hpp" 11 12 #include "Parameters/Validators/Ops_Validator.hpp" 13 #include "Parameters/Validators/Specific/BoxLengthValidator.hpp" 12 14 #include "Parameters/Validators/Specific/FilePresentValidator.hpp" 13 15 … … 15 17 // ValueStorage by the token "Z" -> first column: int, Z, "Z" 16 18 // "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 paramdefaults21 #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) 22 24 #define paramvalids \ 25 (BoxLengthValidator()) \ 23 26 (!FilePresentValidator()) \ 24 (!FilePresentValidator()) 27 (!FilePresentValidator()) \ 28 (DummyValidator<bool>()) 25 29 26 30 #undef statetypes -
src/Potentials/Specifics/ConstantPotential.cpp
r3b1798 r0516fd 63 63 ; 64 64 const std::string ConstantPotential::potential_token("constant"); 65 Coordinator::ptr ConstantPotential::coordinator( new OneBody_Constant());65 Coordinator::ptr ConstantPotential::coordinator(Memory::ignore(new OneBody_Constant())); 66 66 67 67 ConstantPotential::ConstantPotential() : -
src/Potentials/Specifics/FourBodyPotential_Improper.cpp
r3b1798 r0516fd 49 49 ; 50 50 const std::string FourBodyPotential_Improper::improper_token("improper"); 51 Coordinator::ptr FourBodyPotential_Improper::coordinator( new FourBody_ImproperAngle());51 Coordinator::ptr FourBodyPotential_Improper::coordinator(Memory::ignore(new FourBody_ImproperAngle())); 52 52 53 53 FourBodyPotential_Improper::FourBodyPotential_Improper() : -
src/Potentials/Specifics/FourBodyPotential_Torsion.cpp
r3b1798 r0516fd 64 64 ; 65 65 const std::string FourBodyPotential_Torsion::potential_token("torsion"); 66 Coordinator::ptr FourBodyPotential_Torsion::coordinator( new FourBody_TorsionAngle());66 Coordinator::ptr FourBodyPotential_Torsion::coordinator(Memory::ignore(new FourBody_TorsionAngle())); 67 67 68 68 FourBodyPotential_Torsion::FourBodyPotential_Torsion() : -
src/Potentials/Specifics/ManyBodyPotential_Tersoff.cpp
r3b1798 r0516fd 80 80 ; 81 81 const std::string ManyBodyPotential_Tersoff::potential_token("tersoff"); 82 Coordinator::ptr ManyBodyPotential_Tersoff::coordinator( new OneBody_Constant());82 Coordinator::ptr ManyBodyPotential_Tersoff::coordinator(Memory::ignore(new OneBody_Constant())); 83 83 84 84 ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff() : -
src/Potentials/Specifics/PairPotential_Harmonic.cpp
r3b1798 r0516fd 65 65 ; 66 66 const std::string PairPotential_Harmonic::potential_token("harmonic_bond"); 67 Coordinator::ptr PairPotential_Harmonic::coordinator( new TwoBody_Length());67 Coordinator::ptr PairPotential_Harmonic::coordinator(Memory::ignore(new TwoBody_Length())); 68 68 69 69 PairPotential_Harmonic::PairPotential_Harmonic() : -
src/Potentials/Specifics/PairPotential_LennardJones.cpp
r3b1798 r0516fd 65 65 ; 66 66 const std::string PairPotential_LennardJones::potential_token("lennardjones"); 67 Coordinator::ptr PairPotential_LennardJones::coordinator( new TwoBody_Length());67 Coordinator::ptr PairPotential_LennardJones::coordinator(Memory::ignore(new TwoBody_Length())); 68 68 69 69 void PairPotential_LennardJones::setDefaultParameters() -
src/Potentials/Specifics/PairPotential_Morse.cpp
r3b1798 r0516fd 67 67 ; 68 68 const std::string PairPotential_Morse::potential_token("morse"); 69 Coordinator::ptr PairPotential_Morse::coordinator( new TwoBody_Length());69 Coordinator::ptr PairPotential_Morse::coordinator(Memory::ignore(new TwoBody_Length())); 70 70 71 71 PairPotential_Morse::PairPotential_Morse() : -
src/Potentials/Specifics/ThreeBodyPotential_Angle.cpp
r3b1798 r0516fd 65 65 ; 66 66 const std::string ThreeBodyPotential_Angle::potential_token("harmonic_angle"); 67 Coordinator::ptr ThreeBodyPotential_Angle::coordinator( new ThreeBody_Angle());67 Coordinator::ptr ThreeBodyPotential_Angle::coordinator(Memory::ignore(new ThreeBody_Angle())); 68 68 69 69 ThreeBodyPotential_Angle::ThreeBodyPotential_Angle() : -
src/Tesselation/BoundaryLineSet.cpp
r3b1798 r0516fd 309 309 ostream & operator <<(ostream &ost, const BoundaryLineSet &a) 310 310 { 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() << "]"; 312 313 return ost; 313 314 } -
src/Tesselation/BoundaryPointSet.cpp
r3b1798 r0516fd 133 133 ostream & operator <<(ostream &ost, const BoundaryPointSet &a) 134 134 { 135 ost << "[" << a.Nr << "|" << a.getName() << " at " << a.getPosition() << "]";135 ost << "[" << a.Nr << "|" << a.getName() << "]"; // " at " << a.getPosition() << "]"; 136 136 return ost; 137 137 } -
src/Tesselation/BoundaryTriangleSet.cpp
r3b1798 r0516fd 94 94 // set endpoints 95 95 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:"); 97 97 for (PointMap::iterator runner = OrderMap.begin(); runner != OrderMap.end(); runner++) { 98 98 endpoints[Counter] = runner->second; 99 LOG(4, "DEBUG: " << *endpoints[Counter] );99 LOG(4, "DEBUG: " << *endpoints[Counter] << "\t\t" << *lines[Counter]); 100 100 Counter++; 101 101 } … … 246 246 247 247 // 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() << "," 250 250 << endpoints[1]->node->getPosition() << ", and " << endpoints[2]->node->getPosition() << "."); 251 251 try { … … 256 256 } 257 257 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 << "."); 259 259 260 260 // 2. Calculate in plane part of line (x, intersection) … … 269 269 CrossPoint[i] = l.getClosestPoint(InPlane); 270 270 // 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()) 272 272 << " to " << (endpoints[i%3]->node->getPosition()) << " is " << CrossPoint[i] << "."); 273 273 CrossPoint[i] -= (endpoints[(i+1)%3]->node->getPosition()); // cross point was returned as absolute vector 274 274 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 << "."); 276 276 if ((s >= -MYEPSILON) && ((s-1.) <= MYEPSILON)) { 277 277 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 " 279 279 << endpoints[i % 3]->node->getPosition() << " and " 280 280 << endpoints[(i + 1) % 3]->node->getPosition() << "."); … … 285 285 else 286 286 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 " 288 288 << endpoints[i % 3]->node->getPosition() << " and " 289 289 << endpoints[(i + 1) % 3]->node->getPosition() << "."); … … 312 312 ShortestDistance = InPlane.DistanceSquared(x); 313 313 } 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 << "."); 315 315 316 316 return ShortestDistance; … … 367 367 { 368 368 //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]) 371 374 372 375 )); -
src/Tesselation/CandidateForTesselation.cpp
r3b1798 r0516fd 108 108 109 109 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 ..."); 111 111 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 ..."); 113 113 // check baseline for OptCenter and OtherOptCenter being on sphere's surface 114 114 for (list<const Vector *>::const_iterator VRunner = VectorList.begin(); VRunner != VectorList.end(); ++VRunner) { … … 131 131 return false; 132 132 } else { 133 LOG( 3, "DEBUG: Candidate " << *Walker << " is inside by " << distance << ".");133 LOG(4, "DEBUG: Candidate " << *Walker << " is inside by " << distance << "."); 134 134 } 135 135 } 136 136 } 137 137 138 LOG( 2, "DEBUG: Checkingwhether sphere contains no others points ...");138 LOG(3, "DEBUG: Checking validity whether sphere contains no others points ..."); 139 139 bool flag = true; 140 140 for (list<const Vector *>::const_iterator VRunner = VectorList.begin(); VRunner != VectorList.end(); ++VRunner) { … … 143 143 144 144 { 145 LOG( 3, "DEBUG: The following atoms are inside sphere at " << (*VRunner) << ":");145 LOG(4, "DEBUG: The following atoms are inside sphere at " << (*VRunner) << ":"); 146 146 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)) << "."); 148 148 } 149 149 150 150 // remove baseline's endpoints and candidates 151 151 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 << "."); 153 153 ListofPoints->remove(BaseLine->endpoints[i]->node); 154 154 } 155 155 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) << "."); 157 157 ListofPoints->remove(*Runner); 158 158 } -
src/Tesselation/boundary.cpp
r3b1798 r0516fd 513 513 * \return volume difference between the non- and the created convex envelope 514 514 */ 515 double ConvexizeNonconvexEnvelope(class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename) 515 double ConvexizeNonconvexEnvelope( 516 Tesselation *&TesselStruct, 517 const molecule * const mol, 518 const char * const filename, 519 bool DebugOutputEveryStep) 516 520 { 517 521 //Info FunctionInfo(__func__); … … 535 539 } 536 540 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 538 547 do { 539 548 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 544 558 PointRunner = TesselStruct->PointsOnBoundary.begin(); 545 559 PointAdvance = PointRunner; // we need an advanced point, as the PointRunner might get removed … … 547 561 PointAdvance++; 548 562 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; 559 577 Concavity = true; 560 break;561 578 } 562 579 } … … 564 581 } 565 582 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 571 592 LineRunner = TesselStruct->LinesOnBoundary.begin(); 572 593 LineAdvance = LineRunner; // we need an advanced line, as the LineRunner might get removed 594 std::map<double, std::pair<BoundaryLineSet *, double> > GainMap; 573 595 while (LineRunner != TesselStruct->LinesOnBoundary.end()) { 574 596 LineAdvance++; 575 597 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 } 584 716 } 585 717 } 586 718 LineRunner = LineAdvance; 587 719 } 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) 612 735 613 736 CalculateConcavityPerBoundaryPoint(TesselStruct); … … 615 738 616 739 // end 617 LOG(0, " Volumeis " << volume << ".");740 LOG(0, "RESULT: Added volume in convexization is " << volume << "."); 618 741 return volume; 619 742 }; … … 766 889 // status = CheckListOfBaselines(TesselStruct); 767 890 768 cout << "before correction" << endl;891 // cout << "before correction" << endl; 769 892 770 893 // store before correction … … 779 902 // write final envelope 780 903 CalculateConcavityPerBoundaryPoint(TesselStruct); 781 cout << "after correction" << endl;904 // cout << "after correction" << endl; 782 905 StoreTrianglesinFile(mol, TesselStruct, filename, ""); 783 906 -
src/Tesselation/boundary.hpp
r3b1798 r0516fd 39 39 /********************************************** declarations *******************************/ 40 40 41 double ConvexizeNonconvexEnvelope(class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename );41 double ConvexizeNonconvexEnvelope(class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename, bool DebugOutputEveryStep = false); 42 42 void FindConvexBorder(const molecule* const mol, Boundaries *BoundaryPts, Tesselation *&TesselStruct, const LinkedCell_deprecated *LCList, const char *filename); 43 43 Vector* FindEmbeddingHole(MoleculeListClass *mols, molecule *srcmol); -
src/Tesselation/tesselation.cpp
r3b1798 r0516fd 35 35 #include "CodePatterns/MemDebug.hpp" 36 36 37 #include <algorithm> 38 #include <boost/foreach.hpp> 37 39 #include <fstream> 38 40 #include <iomanip> 41 #include <iterator> 39 42 #include <sstream> 40 43 … … 66 69 class molecule; 67 70 68 const char *TecplotSuffix =".dat";69 const char *Raster3DSuffix =".r3d";70 const char *VRMLSUffix =".wrl";71 72 const double ParallelEpsilon =1e-3;71 const char *TecplotSuffix = ".dat"; 72 const char *Raster3DSuffix = ".r3d"; 73 const char *VRMLSUffix = ".wrl"; 74 75 const double ParallelEpsilon = 1e-3; 73 76 const double Tesselation::HULLEPSILON = 1e-9; 74 77 … … 76 79 */ 77 80 Tesselation::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()) 84 82 { 85 83 //Info FunctionInfo(__func__); … … 113 111 { 114 112 // create linkedcell 115 LinkedCell_deprecated *LinkedList = new LinkedCell_deprecated(cloud, 2.*SPHERERADIUS);116 117 118 119 120 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()) 122 120 ThreePointsFound &= (!cloud.IsEnd()); 123 121 cloud.GoToFirst(); … … 126 124 return; 127 125 } 128 129 130 126 } 127 128 // find a starting triangle 131 129 FindStartingTriangle(SPHERERADIUS, LinkedList); 132 130 … … 142 140 //the line is there, so there is a triangle, but only one. 143 141 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."); 146 143 } 147 144 } 148 145 149 146 // 2b. search for smallest ShortestAngle among all candidates 150 double ShortestAngle = 4. *M_PI;147 double ShortestAngle = 4. * M_PI; 151 148 for (CandidateMap::iterator Runner = OpenLines.begin(); Runner != OpenLines.end(); Runner++) { 152 149 if (Runner->second->ShortestAngle < ShortestAngle) { … … 155 152 } 156 153 } 157 if ((ShortestAngle == 4. *M_PI) || (baseline->pointlist.empty()))154 if ((ShortestAngle == 4. * M_PI) || (baseline->pointlist.empty())) 158 155 OneLoopWithoutSuccessFlag = false; 159 156 else { … … 172 169 double Tesselation::getVolumeOfConvexEnvelope(const bool IsAngstroem) const 173 170 { 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 174 181 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."); 195 194 196 195 return volume; … … 209 208 210 209 // 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."); 220 216 221 217 return surfacearea; 222 218 } 223 224 219 225 220 /** Gueses first starting triangle of the convex envelope. … … 253 248 tmp = B->second->node->DistanceSquared(C->second->node->getPosition()); 254 249 distance += tmp * tmp; 255 DistanceMMap.insert(DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator> 250 DistanceMMap.insert(DistanceMultiMapPair(distance, pair<PointMap::iterator, PointMap::iterator>(B, C))); 256 251 } 257 252 } … … 273 268 // 2. next, we have to check whether all points reside on only one side of the triangle 274 269 // 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(); 278 271 LOG(2, "Plane vector of candidate triangle is " << PlaneVector); 279 272 // 4. loop over all points … … 390 383 // prepare some auxiliary vectors 391 384 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())); 394 386 BaseLine = (baseline->second->endpoints[0]->node->getPosition()) - (baseline->second->endpoints[1]->node->getPosition()); 395 387 … … 409 401 // vector in propagation direction (out of triangle) 410 402 // 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(); 412 404 TempVector = CenterVector - (baseline->second->endpoints[0]->node->getPosition()); // TempVector is vector on triangle plane pointing from one baseline egde towards center! 413 405 //LOG(0, "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << "."); … … 462 454 // in case NOT both were found, create virtually this triangle, get its normal vector, calculate angle 463 455 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())); 470 458 TempVector -= (*Center); 471 459 // make it always point outward … … 479 467 winner = target; 480 468 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."); 496 487 } 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."); 500 489 } 501 490 } // end of loop over all boundary points … … 564 553 565 554 cloud.GoToFirst(); 566 PointCloudAdaptor< 555 PointCloudAdaptor<Tesselation, MapValueIterator<Tesselation::iterator> > newcloud(this, cloud.GetName()); 567 556 BoundaryPoints = new LinkedCell_deprecated(newcloud, 5.); 568 557 while (!cloud.IsEnd()) { // we only have to go once through all points, as boundary can become only bigger … … 731 720 * @param *b second endpoint 732 721 * @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 */ 724 bool Tesselation::AddTesselationLine(const Vector * const OptCenter, const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n) 735 725 { 736 726 bool insertNewLine = true; … … 748 738 if (FindLine->second->triangles.size() == 1) { 749 739 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."); 758 746 insertNewLine = false; 759 747 WinningLine = FindLine->second; 760 break;761 } else {762 LOG(5, "REJECT: Candidate " << *(*CandidateChecker) << "'s center " << Finder->second->OptCenter << " does not match desired on " << *OptCenter << ".");763 748 } 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; 764 764 } 765 765 } … … 772 772 AddExistingTesselationTriangleLine(WinningLine, n); 773 773 } 774 775 return insertNewLine; 774 776 } 775 777 ; … … 796 798 // also add to open lines 797 799 CandidateForTesselation *CFT = new CandidateForTesselation(BLS[n]); 798 OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *> 800 OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *>(BLS[n], CFT)); 799 801 } 800 802 ; … … 885 887 } else { 886 888 output << "still attached to another triangle: "; 887 OpenLines.insert(pair<BoundaryLineSet *, CandidateForTesselation *> (triangle->lines[i], NULL));888 889 for (TriangleMap::iterator TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); TriangleRunner++) 889 890 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)); 890 892 } 891 893 LOG(3, "DEBUG: " << output.str()); … … 921 923 else 922 924 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 } 923 932 924 933 for (int i = 0; i < 2; i++) { … … 939 948 LOG(4, "DEBUG: " << *line->endpoints[i] << " has no more lines it's attached to, erasing."); 940 949 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 } 948 958 line->endpoints[i] = NULL; // free'd or not: disconnect 949 959 } else … … 987 997 //Info FunctionInfo(__func__); 988 998 989 LOG(3, "DEBUG: Checking whether sphere contains no others points ...");999 LOG(3, "DEBUG: Checking degeneracy by whether sphere contains no others points ..."); 990 1000 bool flag = true; 991 1001 … … 994 1004 TesselPointList *ListofPoints = LC->GetPointsInsideSphere(RADIUS, &CandidateLine.OtherOptCenter); 995 1005 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 << ":"); 997 1008 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) << "."); 999 1010 1000 1011 // remove triangles's endpoints … … 1010 1021 LOG(3, "DEBUG: CheckDegeneracy: There are still " << ListofPoints->size() << " points inside the sphere."); 1011 1022 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 << ":"); 1013 1024 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) << "."); 1015 1026 } 1016 1027 delete ListofPoints; … … 1157 1168 1158 1169 // 1. searching topmost point with respect to each axis 1170 LOG(2, "INFO: Searching for topmost pointer from each axis."); 1159 1171 for (int i = 0; i < NDIM; i++) { // each axis 1160 1172 LC->n[i] = LC->N[i] - 1; // current axis is topmost cell … … 1178 1190 } 1179 1191 1180 if (DoLog( 1)) {1192 if (DoLog(3)) { 1181 1193 std::stringstream output; 1182 1194 output << "Found maximum coordinates: "; … … 1192 1204 BaseLine = new BoundaryLineSet(); 1193 1205 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 << "."); 1195 1207 1196 1208 double ShortestAngle; … … 1205 1217 } 1206 1218 BaseLine->endpoints[1] = new BoundaryPointSet(Temporary); 1207 LOG( 1, "INFO: Second node is at " << *Temporary << ".");1219 LOG(2, "INFO: Second node is at " << *Temporary << "."); 1208 1220 1209 1221 // construct center of circle 1210 1222 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 << "."); 1212 1224 1213 1225 // construct normal vector of circle 1214 1226 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 << "."); 1216 1228 1217 1229 double radius = CirclePlaneNormal.NormSquared(); … … 1220 1232 NormalVector.ProjectOntoPlane(CirclePlaneNormal); 1221 1233 NormalVector.Normalize(); 1222 LOG( 1, "INFO: NormalVector is at " << NormalVector << ".");1234 LOG(4, "DEBUG: NormalVector is at " << NormalVector << "."); 1223 1235 ShortestAngle = 2. * M_PI; // This will indicate the quadrant. 1224 1236 1225 SphereCenter = (CircleRadius * NormalVector) + 1237 SphereCenter = (CircleRadius * NormalVector) + CircleCenter; 1226 1238 // Now, NormalVector and SphereCenter are two orthonormalized vectors in the plane defined by CirclePlaneNormal (not normalized) 1227 1239 1228 1240 // look in one direction of baseline for initial candidate 1229 1241 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 << "."); 1234 1245 delete BaseLine; 1235 1246 continue; … … 1237 1248 1238 1249 // 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 << "."); 1240 1251 1241 1252 //LOG(1, "INFO: OldSphereCenter is at " << helper << "."); … … 1246 1257 for (TesselPointList::iterator it = OptCandidates.pointlist.begin(); it != OptCandidates.pointlist.end(); it++) 1247 1258 output << *(*it); 1248 LOG( 2, "DEBUG: List of third Points is: " << output.str());1259 LOG(3, "DEBUG: List of third Points is: " << output.str()); 1249 1260 } 1250 1261 if (!OptCandidates.pointlist.empty()) { … … 1408 1419 // return result; 1409 1420 //}; 1410 1411 1421 /** This function finds a triangle to a line, adjacent to an existing one. 1412 1422 * @param out output stream for debugging … … 1440 1450 1441 1451 // 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())); 1444 1453 1445 1454 // 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()); 1448 1456 1449 1457 // calculate squared radius of circle … … 1455 1463 CircleRadius = RADIUS * RADIUS - radius / 4.; 1456 1464 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 << "."); 1460 1468 1461 1469 // construct SearchDirection and an "outward pointer" 1462 SearchDirection = Plane(RelativeSphereCenter, CirclePlaneNormal, 0).getNormal();1470 SearchDirection = Plane(RelativeSphereCenter, CirclePlaneNormal, 0).getNormal(); 1463 1471 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! 1465 1473 SearchDirection.Scale(-1.); 1466 LOG( 3, "DEBUG: SearchDirection is " << SearchDirection << ".");1474 LOG(4, "DEBUG: SearchDirection is " << SearchDirection << "."); 1467 1475 if (fabs(RelativeSphereCenter.ScalarProduct(SearchDirection)) > HULLEPSILON) { 1468 1476 // rotated the wrong way! … … 1474 1482 1475 1483 } 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!"); 1477 1485 } 1478 1486 … … 1507 1515 baseline = Runner->second; 1508 1516 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"); 1510 1518 T = (((baseline->BaseLine->triangles.begin()))->second); 1511 1519 LOG(4, "DEBUG: Finding best candidate for open line " << *baseline->BaseLine << " of triangle " << *T); … … 1540 1548 TesselPointList *connectedClosestPoints = GetCircleOfSetOfPoints(&SetOfNeighbours, TurningPoint, CandidateLine.BaseLine->endpoints[1]->node->getPosition()); 1541 1549 1542 {1550 if (DoLog(3)) { 1543 1551 std::stringstream output; 1544 1552 for (TesselPointList::iterator TesselRunner = connectedClosestPoints->begin(); TesselRunner != connectedClosestPoints->end(); ++TesselRunner) 1545 1553 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()); 1547 1555 } 1548 1556 … … 1585 1593 } 1586 1594 delete (connectedClosestPoints); 1587 }; 1595 } 1596 ; 1588 1597 1589 1598 /** for polygons (multiple candidates for a baseline) sets internal edges to the correct next candidate. … … 1605 1614 else { 1606 1615 LOG(4, "DEBUG: line " << *(FindLine->second) << " is open with no candidate, setting to next Sprinter" << (*Sprinter)); 1607 Finder->second->T = BTS; 1616 Finder->second->T = BTS; // is last triangle 1608 1617 Finder->second->pointlist.push_back(Sprinter); 1609 1618 Finder->second->ShortestAngle = 0.; … … 1612 1621 } 1613 1622 } 1614 }; 1623 } 1624 ; 1615 1625 1616 1626 /** If a given \a *triangle is degenerated, this adds both sides. … … 1648 1658 // give some verbose output about the whole procedure 1649 1659 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 << "."); 1651 1661 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."); 1653 1663 triangle = BTS; 1654 1664 … … 1734 1744 ; 1735 1745 1746 bool 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 1736 1760 /** Checks whether the quadragon of the two triangles connect to \a *Base is convex. 1737 1761 * We look whether the closest point on \a *Base with respect to the other baseline is outside … … 1870 1894 } 1871 1895 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) << "."); 1873 1897 BaseLineNormal += (runner->second->NormalVector); 1874 1898 } … … 1899 1923 class BoundaryLineSet *OldLines[4], *NewLine; 1900 1924 class BoundaryPointSet *OldPoints[2]; 1901 Vector BaseLineNormal; 1925 Vector BaseLineNormal[2]; 1926 Vector OtherEndpoint[2]; // fourth point to either triangle 1902 1927 int OldTriangleNrs[2], OldBaseLineNr; 1903 1928 int i, m; 1904 1929 1905 1930 // calculate NormalVector for later use 1906 BaseLineNormal.Zero();1907 1931 if (Base->triangles.size() < 2) { 1908 1932 ELOG(1, "Less than two triangles are attached to this baseline!"); 1909 1933 return NULL; 1910 1934 } 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 } 1916 1945 1917 1946 // get the two triangles … … 1943 1972 1944 1973 // 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 1945 1976 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 1946 1977 for (int j = 0; j < 3; j++) // all of their endpoints and baselines … … 1952 1983 OldPoints[m++] = runner->second->endpoints[j]; 1953 1984 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 } 1954 1993 // check whether everything is in place to create new lines and triangles 1955 1994 if (i < 4) { … … 1967 2006 return NULL; 1968 2007 } 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]); 1969 2013 1970 2014 // remove triangles and baseline removes itself … … 1973 2017 m = 0; 1974 2018 // first obtain all triangle to delete ... (otherwise we pull the carpet (Base) from under the for-loop's feet) 1975 list 2019 list<BoundaryTriangleSet *> TrianglesOfBase; 1976 2020 for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); ++runner) 1977 2021 TrianglesOfBase.push_back(runner->second); 1978 2022 // .. then delete each triangle (which deletes the line as well) 1979 for (list 2023 for (list<BoundaryTriangleSet *>::iterator runner = TrianglesOfBase.begin(); !TrianglesOfBase.empty(); runner = TrianglesOfBase.begin()) { 1980 2024 LOG(3, "DEBUG: Deleting triangle " << *(*runner) << "."); 1981 2025 OldTriangleNrs[m++] = (*runner)->Nr; … … 1990 2034 LinesOnBoundary.insert(LinePair(OldBaseLineNr, NewLine)); // no need for check for unique insertion as NewLine is definitely a new one 1991 2035 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. 1992 2042 1993 2043 // construct new triangles with flipped baseline … … 2002 2052 BLS[2] = NewLine; 2003 2053 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 } 2005 2074 AddTesselationTriangle(OldTriangleNrs[0]); 2006 2075 LOG(3, "DEBUG: Created new triangle " << *BTS << "."); … … 2010 2079 BLS[2] = NewLine; 2011 2080 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 } 2013 2101 AddTesselationTriangle(OldTriangleNrs[1]); 2014 2102 LOG(3, "DEBUG: Created new triangle " << *BTS << "."); … … 2157 2245 TesselPoint *Candidate = NULL; 2158 2246 2159 LOG( 3, "DEBUG: NormalVector of BaseTriangle is " << NormalVector << ".");2247 LOG(4, "DEBUG: NormalVector of BaseTriangle is " << NormalVector << "."); 2160 2248 2161 2249 // copy old center … … 2165 2253 2166 2254 // 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())); 2169 2256 2170 2257 // 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()); 2173 2259 2174 2260 RelativeOldSphereCenter = OldSphereCenter - CircleCenter; … … 2179 2265 CircleRadius = RADIUS * RADIUS - radius; 2180 2266 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) << "."); 2182 2268 2183 2269 // test whether old center is on the band's plane … … 2188 2274 radius = RelativeOldSphereCenter.NormSquared(); 2189 2275 if (fabs(radius - CircleRadius) < HULLEPSILON) { 2190 LOG( 3, "DEBUG: RelativeOldSphereCenter is at " << RelativeOldSphereCenter << ".");2276 LOG(4, "DEBUG: RelativeOldSphereCenter is at " << RelativeOldSphereCenter << "."); 2191 2277 2192 2278 // check SearchDirection 2193 LOG( 3, "DEBUG: SearchDirection is " << SearchDirection << ".");2279 LOG(4, "DEBUG: SearchDirection is " << SearchDirection << "."); 2194 2280 if (fabs(RelativeOldSphereCenter.ScalarProduct(SearchDirection)) > HULLEPSILON) { // rotated the wrong way! 2195 2281 ELOG(1, "SearchDirection and RelativeOldSphereCenter are not orthogonal!"); … … 2232 2318 // find center on the plane 2233 2319 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 << "."); 2235 2321 2236 2322 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 << "."); 2241 2325 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 << "."); 2245 2329 if (radius < RADIUS * RADIUS) { 2246 2330 otherradius = CandidateLine.BaseLine->endpoints[1]->node->DistanceSquared(NewPlaneCenter); … … 2248 2332 // construct both new centers 2249 2333 NewSphereCenter = NewPlaneCenter; 2250 OtherNewSphereCenter = NewPlaneCenter;2334 OtherNewSphereCenter = NewPlaneCenter; 2251 2335 helper = NewNormalVector; 2252 2336 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 << "."); 2254 2338 NewSphereCenter += helper; 2255 LOG( 4, "DEBUG: NewSphereCenter is at " << NewSphereCenter << ".");2339 LOG(5, "DEBUG: NewSphereCenter is at " << NewSphereCenter << "."); 2256 2340 // OtherNewSphereCenter is created by the same vector just in the other direction 2257 2341 helper.Scale(-1.); 2258 2342 OtherNewSphereCenter += helper; 2259 LOG( 4, "DEBUG: OtherNewSphereCenter is at " << OtherNewSphereCenter << ".");2343 LOG(5, "DEBUG: OtherNewSphereCenter is at " << OtherNewSphereCenter << "."); 2260 2344 alpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, NewSphereCenter, OldSphereCenter, NormalVector, SearchDirection, HULLEPSILON); 2261 2345 Otheralpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, OtherNewSphereCenter, OldSphereCenter, NormalVector, SearchDirection, HULLEPSILON); … … 2278 2362 if ((CandidateLine.ShortestAngle - HULLEPSILON) < alpha) { 2279 2363 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 << "."); 2281 2365 } else { 2282 2366 // remove all candidates from the list and then the list itself 2283 2367 CandidateLine.pointlist.clear(); 2284 2368 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 << "."); 2286 2370 } 2287 2371 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."); 2289 2373 } else { 2290 2374 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 << " ."); 2292 2376 } else { 2293 LOG( 3, "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected.");2377 LOG(4, "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected."); 2294 2378 } 2295 2379 } 2296 2380 } 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))); 2298 2382 } 2299 2383 } 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 << "."); 2301 2385 } 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."); 2306 2389 } 2307 2390 } else { 2308 2391 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 << "."); 2310 2393 } else { 2311 LOG( 3, "REJECT: Base triangle " << *CandidateLine.BaseLine << " contains Candidate " << *Candidate << ".");2394 LOG(4, "REJECT: Base triangle " << *CandidateLine.BaseLine << " contains Candidate " << *Candidate << "."); 2312 2395 } 2313 2396 } … … 2320 2403 } else { 2321 2404 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!"); 2323 2406 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 ..."); 2328 2411 if (CandidateLine.pointlist.size() > 1) { 2329 2412 CandidateLine.pointlist.unique(); … … 2331 2414 } 2332 2415 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!")); 2337 2417 } 2338 2418 ; … … 2346 2426 { 2347 2427 //Info FunctionInfo(__func__); 2348 const BoundaryLineSet * lines[2] = { line1, line2};2428 const BoundaryLineSet * lines[2] = {line1, line2}; 2349 2429 class BoundaryPointSet *node = NULL; 2350 2430 PointMap OrderMap; … … 2353 2433 // for both lines 2354 2434 for (int j = 0; j < 2; j++) { // for both endpoints 2355 OrderTest = OrderMap.insert(pair<int, class BoundaryPointSet *> 2435 OrderTest = OrderMap.insert(pair<int, class BoundaryPointSet *>(lines[i]->endpoints[j]->Nr, lines[i]->endpoints[j])); 2356 2436 if (!OrderTest.second) { // if insertion fails, we have common endpoint 2357 2437 node = OrderTest.first->second; … … 2402 2482 // we should make sure that both triangles end up in the same entry 2403 2483 // 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); 2406 2485 points->insert(DistanceToPointPair(distance, FindPoint->second)); 2407 2486 LOG(3, "DEBUG: Putting " << *FindPoint->second << " into the list."); … … 2448 2527 for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) { 2449 2528 // 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())); 2452 2530 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()); 2455 2532 Center.ProjectOntoPlane(BaseLine); 2456 2533 const double distance = Center.NormSquared(); … … 2509 2586 for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) { 2510 2587 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()); 2513 2589 const double lengthBase = BaseLine.NormSquared(); 2514 2590 … … 2526 2602 MinDistance = lengthEnd; 2527 2603 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 } 2534 2611 } else { // intersection is closer, calculate 2535 2612 // calculate closest point on line to desired point … … 2657 2734 double distance = 0.; 2658 2735 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? 2660 2737 LOG(1, "No triangle given!"); 2661 2738 return -1.; … … 2766 2843 takePoint = true; 2767 2844 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 } 2772 2850 2773 2851 if (takePoint) { … … 2809 2887 Vector OrthogonalVector; 2810 2888 Vector helper; 2811 const TesselPoint * const TrianglePoints[3] = { Point, NULL, NULL};2889 const TesselPoint * const TrianglePoints[3] = {Point, NULL, NULL}; 2812 2890 TriangleList *triangles = NULL; 2813 2891 … … 2820 2898 // calculate central point 2821 2899 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; 2829 2903 PlaneNormal.Scale(1.0 / triangles->size()); 2830 2904 LOG(4, "DEBUG: Calculated PlaneNormal of all circle points is " << PlaneNormal << "."); … … 2838 2912 AngleZero = ((*SetOfNeighbours->begin())->getPosition()) - (Point->getPosition()); 2839 2913 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!")); 2844 2915 } 2845 2916 LOG(4, "DEBUG: Reference vector on this plane representing angle 0 is " << AngleZero << "."); 2846 2917 if (AngleZero.NormSquared() > MYEPSILON) 2847 OrthogonalVector = Plane(PlaneNormal, AngleZero, 0).getNormal();2918 OrthogonalVector = Plane(PlaneNormal, AngleZero, 0).getNormal(); 2848 2919 else 2849 2920 OrthogonalVector.MakeNormalTo(PlaneNormal); … … 2856 2927 double angle = GetAngle(helper, AngleZero, OrthogonalVector); 2857 2928 LOG(4, "DEBUG" << angle << " for point " << **listRunner << "."); 2858 anglesOfPoints.insert(pair<double, TesselPoint*> 2929 anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner))); 2859 2930 } 2860 2931 … … 2911 2982 int counter = 0; 2912 2983 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(); 2916 2985 LOG(5, "DEBUG: Making normal vector out of " << *(*TesselA) << ", " << *(*TesselB) << " and " << *(*TesselC) << ":" << helper); 2917 2986 counter++; … … 2922 2991 } 2923 2992 //LOG(0, "Summed vectors " << center << "; number of points " << connectedPoints.size() << "; scale factor " << counter); 2924 PlaneNormal.Scale(1.0 / (double) 2993 PlaneNormal.Scale(1.0 / (double)counter); 2925 2994 // LOG(1, "INFO: Calculated center of all circle points is " << center << "."); 2926 2995 // … … 2936 3005 AngleZero.ProjectOntoPlane(PlaneNormal); 2937 3006 } 2938 if ((Reference.IsZero()) || (AngleZero.NormSquared() < MYEPSILON 3007 if ((Reference.IsZero()) || (AngleZero.NormSquared() < MYEPSILON)) { 2939 3008 LOG(4, "DEBUG: Using alternatively " << (*SetOfNeighbours->begin())->getPosition() << " as angle 0 referencer."); 2940 3009 AngleZero = ((*SetOfNeighbours->begin())->getPosition()) - (Point->getPosition()); 2941 3010 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!")); 2946 3012 } 2947 3013 LOG(4, "DEBUG: Reference vector on this plane representing angle 0 is " << AngleZero << "."); 2948 3014 if (AngleZero.NormSquared() > MYEPSILON) 2949 OrthogonalVector = Plane(PlaneNormal, AngleZero, 0).getNormal();3015 OrthogonalVector = Plane(PlaneNormal, AngleZero, 0).getNormal(); 2950 3016 else 2951 3017 OrthogonalVector.MakeNormalTo(PlaneNormal); … … 2961 3027 angle = 2. * M_PI - angle; 2962 3028 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)))); 2968 3031 } 2969 3032 … … 2985 3048 //Info FunctionInfo(__func__); 2986 3049 map<double, TesselPoint*> anglesOfPoints; 2987 list<TesselPointList *> *ListOfPaths = new list<TesselPointList *> 3050 list<TesselPointList *> *ListOfPaths = new list<TesselPointList *>; 2988 3051 TesselPointList *connectedPath = NULL; 2989 3052 Vector center; … … 3011 3074 map<class BoundaryTriangleSet *, bool>::iterator TriangleRunner; 3012 3075 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 } 3016 3082 } 3017 3083 if (!ReferencePoint->lines.empty()) { … … 3020 3086 if (LineRunner == TouchedLine.end()) { 3021 3087 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 } 3046 3117 } 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."); 3048 3119 triangle = NULL; 3049 3120 } 3050 3121 } 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 3052 3123 triangle = NULL; 3053 3124 } 3054 3125 } 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); 3055 3149 } 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 } 3084 3155 } 3085 3156 } else { … … 3100 3171 //Info FunctionInfo(__func__); 3101 3172 list<TesselPointList *> *ListofPaths = GetPathsOfConnectedPoints(Point); 3102 list<TesselPointList *> *ListofClosedPaths = new list<TesselPointList *> 3173 list<TesselPointList *> *ListofClosedPaths = new list<TesselPointList *>; 3103 3174 TesselPointList *connectedPath = NULL; 3104 3175 TesselPointList *newPath = NULL; … … 3110 3181 connectedPath = *ListRunner; 3111 3182 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 } 3113 3191 3114 3192 // go through list, look for reappearance of starting Point and count … … 3119 3197 if ((*CircleRunner == *CircleStart) && (CircleRunner != CircleStart)) { // is not the very first point 3120 3198 // we have a closed circle from Marker to new Marker 3121 if (DoLog( 1)) {3199 if (DoLog(3)) { 3122 3200 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++) 3127 3203 output << (**CircleSprinter) << " <-> "; 3128 3204 LOG(1, output.str()); … … 3140 3216 } 3141 3217 } 3142 LOG( 1, "INFO: " << count << " closed additional path(s) have been created.");3218 LOG(2, "DEBUG: " << count << " closed additional path(s) have been created."); 3143 3219 3144 3220 // delete list of paths … … 3178 3254 } 3179 3255 ; 3256 3257 struct 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 3265 bool 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 3346 double 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 } 3180 3507 3181 3508 /** Removes a boundary point from the envelope while keeping it closed. … … 3192 3519 double Tesselation::RemovePointFromTesselatedSurface(class BoundaryPointSet *point) 3193 3520 { 3194 class BoundaryLineSet *line = NULL;3195 class BoundaryTriangleSet *triangle = NULL;3196 Vector OldPoint, NormalVector;3197 3521 double volume = 0; 3198 int count = 0;3199 3522 3200 3523 if (point == NULL) { … … 3204 3527 LOG(4, "DEBUG: Removing point " << *point << " from tesselated boundary ..."); 3205 3528 3206 // copy old location for the volume3207 OldPoint = (point->node->getPosition());3208 3209 3529 // get list of connected points 3210 3530 if (point->lines.empty()) { … … 3214 3534 3215 3535 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 3559 bool 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 */ 3643 double 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); 3241 3660 list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin(); 3242 3661 list<TesselPointList *>::iterator ListRunner = ListAdvance; 3243 3662 // TriangleMap::iterator NumberRunner = Candidates.begin(); 3244 3663 TesselPointList::iterator StartNode, MiddleNode, EndNode; 3245 double angle;3246 double smallestangle;3247 3664 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); 3394 3678 } 3395 3679 delete (ListOfClosedPaths); 3396 3680 3397 LOG(1, "INFO: Removed volume is " << volume << "."); 3681 if (volume > 0.) 3682 LOG(1, "INFO: Removed volume is " << volume << "."); 3398 3683 3399 3684 return volume; … … 3439 3724 if (TrianglePoints[j] != NULL) { 3440 3725 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++) { 3442 3727 for (FindTriangle = FindLine->second->triangles.begin(); FindTriangle != FindLine->second->triangles.end(); FindTriangle++) { 3443 3728 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { … … 3460 3745 break; 3461 3746 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++) { 3463 3748 for (FindTriangle = FindLine->second->triangles.begin(); FindTriangle != FindLine->second->triangles.end(); FindTriangle++) { 3464 3749 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { … … 3489 3774 } 3490 3775 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!"); 3493 3777 break; 3494 3778 } … … 3516 3800 if (a->endpoints[lowerNra] < b->endpoints[lowerNrb]) 3517 3801 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]) 3524 3804 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 } 3526 3812 return false; 3527 3813 } … … 3544 3830 3545 3831 // 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; 3552 3838 for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) { 3553 3839 tester = AllLines.insert(LineRunner1->second); … … 3566 3852 const LineMap::const_iterator Line2 = LinesOnBoundary.find((*it).second); 3567 3853 if (Line1 != LinesOnBoundary.end() && Line2 != LinesOnBoundary.end()) 3568 3854 LOG(3, "DEBUG: " << *Line1->second << " => " << *Line2->second); 3569 3855 else 3570 3856 ELOG(1, "Either " << (*it).first << " or " << (*it).second << " are not in LinesOnBoundary!"); 3571 3857 } 3572 3858 … … 3600 3886 for (TriangleRunner2 = line2->triangles.begin(); TriangleRunner2 != line2->triangles.end(); ++TriangleRunner2) { 3601 3887 if ((TriangleRunner1->second != TriangleRunner2->second) && (TriangleRunner1->second->IsPresentTupel(TriangleRunner2->second))) { 3602 DegeneratedTriangles->insert(pair<int, int> 3603 DegeneratedTriangles->insert(pair<int, int> 3888 DegeneratedTriangles->insert(pair<int, int>(TriangleRunner1->second->Nr, TriangleRunner2->second->Nr)); 3889 DegeneratedTriangles->insert(pair<int, int>(TriangleRunner2->second->Nr, TriangleRunner1->second->Nr)); 3604 3890 } 3605 3891 } … … 3628 3914 3629 3915 // 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()) { 3631 3919 LOG(3, "DEBUG: Checking presence of triangles " << TriangleKeyRunner->first << " and " << TriangleKeyRunner->second << "."); 3632 3920 // both ways are stored in the map, only use one … … 3669 3957 // OtherpartnerTriangle = TriangleRunner->second; 3670 3958 // } 3671 /// interchanges their lines so that triangle->lines[i] == partnerTriangle->lines[j]3672 // the line of triangle receives the degenerated ones3673 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); 3674 3962 triangle->lines[i]->triangles.insert(TrianglePair(partnerTriangle->Nr, partnerTriangle)); 3675 3963 for (int k = 0; k < 3; k++) … … 3685 3973 3686 3974 // erase the pair 3687 count += (int) 3975 count += (int)DegeneratedTriangles->erase(triangle->Nr); 3688 3976 LOG(4, "DEBUG: RemoveDegeneratedTriangles() removes triangle " << *triangle << "."); 3689 3977 RemoveTesselationTriangle(triangle); 3690 count += (int) 3978 count += (int)DegeneratedTriangles->erase(partnerTriangle->Nr); 3691 3979 LOG(4, "DEBUG: RemoveDegeneratedTriangles() removes triangle " << *partnerTriangle << "."); 3692 3980 RemoveTesselationTriangle(partnerTriangle); 3693 3981 } else { 3694 3982 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); 3695 3986 } 3696 3987 } … … 3736 4027 class BoundaryLineSet *BestLine = NULL; 3737 4028 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())); 3742 4031 CenterToPoint -= (point->getPosition()); 3743 4032 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.)) { 3745 4034 BestAngle = angle; 3746 4035 BestLine = Runner->second; … … 3791 4080 for (int i = 0; i < 3; i++) { // look for the same line as BestLine (only it's its degenerated companion) 3792 4081 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)); 3798 4084 TempTriangle->lines[nr] = BTS->lines[i]; 3799 4085 break; … … 3817 4103 if (LastTriangle != NULL) { 3818 4104 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); 3820 4106 NumberName = sstr.str(); 3821 4107 if (DoTecplotOutput) { … … 3859 4145 if (s1->endpoints.size() < s2->endpoints.size()) 3860 4146 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; 3873 4163 } 3874 return false;3875 }3876 4164 } 3877 4165 }; … … 3898 4186 for (TriangleMap::const_iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) { 3899 4187 if (DegeneratedTriangles->find(TriangleRunner->second->Nr) == DegeneratedTriangles->end()) { 3900 TriangleInsertionTester = TriangleVectors.insert(pair<int, Vector *> 4188 TriangleInsertionTester = TriangleVectors.insert(pair<int, Vector *>((TriangleRunner->second)->Nr, &((TriangleRunner->second)->NormalVector))); 3901 4189 if (TriangleInsertionTester.second) 3902 4190 LOG(5, "DEBUG: Adding triangle " << *(TriangleRunner->second) << " to triangles to check-list."); … … 3911 4199 if (VectorWalker != VectorRunner) { // skip equals 3912 4200 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); 3914 4202 if (fabs(SCP + 1.) < ParallelEpsilon) { 3915 4203 InsertionTester = EndpointCandidateList.insert((Runner->second)); … … 3993 4281 // The Problem is probably due to two degenerated polygons being connected by a bridging, non-degenerated polygon, as somehow one node has 3994 4282 // 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!")); 3999 4284 TriangleSet::iterator TriangleWalker = T->begin(); // is the inner iterator 4000 4285 /// 4a. Get NormalVector for one side (this is "front") -
src/Tesselation/tesselation.hpp
r3b1798 r0516fd 76 76 void AddTesselationPoint(TesselPoint* Candidate, const int n); 77 77 void SetTesselationPoint(TesselPoint* Candidate, const int n) const; 78 voidAddTesselationLine(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); 79 79 void AddNewTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n); 80 80 void AddExistingTesselationTriangleLine(class BoundaryLineSet *FindLine, int n); … … 88 88 void RemoveTesselationPoint(class BoundaryPointSet *point); 89 89 bool CheckDegeneracy(CandidateForTesselation &CandidateLine, const double RADIUS, const LinkedCell_deprecated *LC) const; 90 90 bool isConvex() const; 91 91 92 92 // concave envelope … … 103 103 void GuessStartingTriangle(); 104 104 bool InsertStraddlingPoints(IPointCloud & cloud, const LinkedCell_deprecated *LC); 105 double RemovePointSurroundedByPolygon( 106 TesselPointList *connectedPath, 107 BoundaryPointSet *point); 108 bool CheckAllConcaveInPolygon( 109 const TesselPointList *connectedPath, 110 const BoundaryPointSet *point 111 ); 112 double RemoveFullConcavePointFromTesselatedSurface(class BoundaryPointSet *point); 105 113 double RemovePointFromTesselatedSurface(class BoundaryPointSet *point); 106 114 class BoundaryLineSet * FlipBaseline(class BoundaryLineSet *Base); … … 131 139 DistanceToPointMap * FindClosestBoundaryPointsToVector(const Vector &x, const LinkedCell_deprecated* LC) const; 132 140 BoundaryLineSet * FindClosestBoundaryLineToVector(const Vector &x, const LinkedCell_deprecated* LC) const; 141 142 bool IsPointBelowSurroundingPolygon(const BoundaryPointSet *_point) const; 133 143 134 144 // print for debugging -
src/Tesselation/tesselationhelpers.cpp
r3b1798 r0516fd 235 235 if (helper.ScalarProduct(SearchDirection) < -HULLEPSILON) // acos is not unique on [0, 2.*M_PI), hence extra check to decide between two half intervals 236 236 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 << "."); 238 238 radius = helper.distance(RelativeOldSphereCenter); 239 239 helper.ProjectOntoPlane(NormalVector); 240 240 // check whether new center is somewhat away or at least right over the current baseline to prevent intersecting triangles 241 241 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() << "."); 243 243 return alpha; 244 244 } 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 << "."); 246 246 return 2.*M_PI; 247 247 } … … 278 278 } 279 279 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 << "."); 281 281 282 282 return phi; … … 289 289 * \param *c third vector 290 290 * \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$ 292 292 */ 293 293 double CalculateVolumeofGeneralTetraeder(const Vector &a, const Vector &b, const Vector &c, const Vector &d) … … 302 302 for (int j=0;j<3;j++) 303 303 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])); 307 307 return volume; 308 308 }; … … 545 545 Normal.VectorProduct(OtherBaseline); 546 546 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 << "."); 548 548 549 549 // project one offset point of OtherBase onto this plane (and add plane offset vector) … … 559 559 *Intersection = line1.getIntersection(line2); 560 560 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()) << "."); 562 562 563 563 return Intersection; … … 751 751 *tecplot << endl; 752 752 // print connectivity 753 LOG( 1, "The following triangles were created:");753 LOG(4, "DEBUG: The following triangles were created:"); 754 754 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()); 756 756 *tecplot << LookupList[runner->second->endpoints[0]->node->getNr()] << " " << LookupList[runner->second->endpoints[1]->node->getNr()] << " " << LookupList[runner->second->endpoints[2]->node->getNr()] << endl; 757 757 } … … 778 778 for (PointMap::const_iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) { 779 779 point = PointRunner->second; 780 LOG( 1, "INFO: Current point is " << *point << ".");780 LOG(2, "INFO: Current point is " << *point << "."); 781 781 782 782 // calculate mean concavity over all connected line -
src/Tesselation/triangleintersectionlist.cpp
r3b1798 r0516fd 132 132 // if we have found one, check Scalarproduct between the vector 133 133 Vector TestVector = (Point) - (*(*runner).second); 134 LOG( 1, "INFO: Distance vector between point " << Point134 LOG(4, "DEBUG: Distance vector between point " << Point 135 135 << " and triangle intersection at " << (*(*runner).second) << " is " 136 136 << TestVector << "."); 137 137 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."); 139 139 return true; 140 140 } 141 141 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 " 143 143 << (*runner).first->NormalVector << ": " << sign << "."); 144 144 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."); 146 146 return true; 147 147 } 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."); 149 149 return false; 150 150 } … … 224 224 for (DistanceTriangleMap::const_iterator iter = DistanceRange.first; 225 225 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 << "."); 227 227 ++count; 228 228 } 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."); 230 230 } 231 231 // if there is more than one, check all of their normal vectors … … 233 233 // would be truely inside, all of the closest triangles would have to show 234 234 // 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 ..."); 236 236 for (DistanceTriangleMap::const_iterator iter = DistanceRange.first; 237 237 iter != DistanceRange.second; ++iter) { … … 241 241 // construct SKP 242 242 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 << "."); 244 244 // if positive return 245 245 if (sign > 0) -
src/UIElements/Views/Qt4/Plotting/QSeisPlotPage.cpp
r3b1798 r0516fd 39 39 QSeisPlotPage::~QSeisPlotPage() 40 40 { 41 if (layoutInitialized) 41 42 deinitializeLayout(); 42 43 } -
src/documentation/constructs/tesselation.dox
r3b1798 r0516fd 20 20 * to such a surface. 21 21 * 22 * \section tesselation-procedure 22 * \section tesselation-procedure Tesselation procedure 23 23 * 24 24 * In the tesselation all atoms act as possible hindrance to a rolling sphere … … 34 34 * other (although the code for that is not yet fully implemented). 35 35 * 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 37 97 * 38 98 * The main problem for extending the mesh to match with the normal sense is … … 47 107 * from a combination of spheres with van der Waals radii. 48 108 * 49 * \date 2014- 03-10109 * \date 2014-10-09 50 110 * 51 111 */ -
tests/Python/AllActions/options.dat
r3b1798 r0516fd 42 42 change-element "1" 43 43 change-molname "water" 44 convex-envelope "50." 44 45 convex-file "convexfile" 45 46 copy-molecule "0" … … 62 63 DoCyclesFull "0" 63 64 DoLongrange "0" 65 DoOutputEveryStep "0" 64 66 DoPrintDebug "0" 65 67 DoRotate "0" -
tests/Tesselations/Makefile.am
r3b1798 r0516fd 7 7 molecuilder.in \ 8 8 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 24 40 25 41 TESTSUITE = $(srcdir)/testsuite … … 28 44 29 45 TESTSCRIPTS = \ 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 44 76 45 77 max_jobs = 4 -
tests/Tesselations/testsuite.at
r3b1798 r0516fd 27 27 m4_ifdef([AT_COLOR_TESTS], [AT_COLOR_TESTS]) 28 28 29 ### NONCONVEX TESSELATION 30 29 31 # tesselation of 1_2-dimethoxyethane 30 m4_include( 1_2-dimethoxyethane/testsuite-1_2-dimethoxyethane.at)32 m4_include(NonConvex/1_2-dimethoxyethane/testsuite-1_2-dimethoxyethane.at) 31 33 32 34 # tesselation of 1_2-dimethylbenzene 33 m4_include( 1_2-dimethylbenzene/testsuite-1_2-dimethylbenzene.at)35 m4_include(NonConvex/1_2-dimethylbenzene/testsuite-1_2-dimethylbenzene.at) 34 36 35 37 # tesselation of 2-methylcyclohexanone 36 m4_include( 2-methylcyclohexanone/testsuite-2-methylcyclohexanone.at)38 m4_include(NonConvex/2-methylcyclohexanone/testsuite-2-methylcyclohexanone.at) 37 39 38 40 # tesselation of benzene 39 m4_include( benzene/testsuite-benzene.at)41 m4_include(NonConvex/benzene/testsuite-benzene.at) 40 42 41 43 # tesselation of cholesterol 42 m4_include( cholesterol/testsuite-cholesterol.at)44 m4_include(NonConvex/cholesterol/testsuite-cholesterol.at) 43 45 44 46 # tesselation of cycloheptane 45 m4_include( cycloheptane/testsuite-cycloheptane.at)47 m4_include(NonConvex/cycloheptane/testsuite-cycloheptane.at) 46 48 47 49 # tesselation of dimethyl_bromomalonate 48 m4_include( dimethyl_bromomalonate/testsuite-dimethyl_bromomalonate.at)50 m4_include(NonConvex/dimethyl_bromomalonate/testsuite-dimethyl_bromomalonate.at) 49 51 50 52 # tesselation of glucose 51 m4_include( glucose/testsuite-glucose.at)53 m4_include(NonConvex/glucose/testsuite-glucose.at) 52 54 53 55 # tesselation of heptan 54 m4_include( heptan/testsuite-heptan.at)56 m4_include(NonConvex/heptan/testsuite-heptan.at) 55 57 56 58 # tesselation of isoleucine 57 m4_include( isoleucine/testsuite-isoleucine.at)59 m4_include(NonConvex/isoleucine/testsuite-isoleucine.at) 58 60 59 61 # tesselation of neohexane 60 m4_include( neohexane/testsuite-neohexane.at)62 m4_include(NonConvex/neohexane/testsuite-neohexane.at) 61 63 62 64 # tesselation of N_N-dimethylacetamide 63 m4_include(N _N-dimethylacetamide/testsuite-N_N-dimethylacetamide.at)65 m4_include(NonConvex/N_N-dimethylacetamide/testsuite-N_N-dimethylacetamide.at) 64 66 65 67 # tesselation of proline 66 m4_include( proline/testsuite-proline.at)68 m4_include(NonConvex/proline/testsuite-proline.at) 67 69 68 70 # tesselation of putrescine 69 m4_include( putrescine/testsuite-putrescine.at)71 m4_include(NonConvex/putrescine/testsuite-putrescine.at) 70 72 71 73 # tesselation of tartaric_acid 72 m4_include(tartaric_acid/testsuite-tartaric_acid.at) 74 m4_include(NonConvex/tartaric_acid/testsuite-tartaric_acid.at) 75 76 ### NONCONVEX TESSELATION 77 78 # tesselation of 1_2-dimethoxyethane 79 m4_include(Convex/1_2-dimethoxyethane/testsuite-1_2-dimethoxyethane.at) 80 81 # tesselation of 1_2-dimethylbenzene 82 m4_include(Convex/1_2-dimethylbenzene/testsuite-1_2-dimethylbenzene.at) 83 84 # tesselation of 2-methylcyclohexanone 85 m4_include(Convex/2-methylcyclohexanone/testsuite-2-methylcyclohexanone.at) 86 87 # tesselation of amylose 88 m4_include(Convex/amylose/testsuite-amylose.at) 89 90 # tesselation of benzene 91 m4_include(Convex/benzene/testsuite-benzene.at) 92 93 # tesselation of cholesterol 94 m4_include(Convex/cholesterol/testsuite-cholesterol.at) 95 96 # tesselation of cycloheptane 97 m4_include(Convex/cycloheptane/testsuite-cycloheptane.at) 98 99 # tesselation of dimethyl_bromomalonate 100 m4_include(Convex/dimethyl_bromomalonate/testsuite-dimethyl_bromomalonate.at) 101 102 # tesselation of glucose 103 m4_include(Convex/glucose/testsuite-glucose.at) 104 105 # tesselation of heptan 106 m4_include(Convex/heptan/testsuite-heptan.at) 107 108 # tesselation of isoleucine 109 m4_include(Convex/isoleucine/testsuite-isoleucine.at) 110 111 # tesselation of neohexane 112 m4_include(Convex/neohexane/testsuite-neohexane.at) 113 114 # tesselation of N_N-dimethylacetamide 115 m4_include(Convex/N_N-dimethylacetamide/testsuite-N_N-dimethylacetamide.at) 116 117 # tesselation of proline 118 m4_include(Convex/proline/testsuite-proline.at) 119 120 # tesselation of putrescine 121 m4_include(Convex/putrescine/testsuite-putrescine.at) 122 123 # tesselation of tartaric_acid 124 m4_include(Convex/tartaric_acid/testsuite-tartaric_acid.at) -
tests/regression/Tesselation/BigConvex/testsuite-tesselation-big-convex-envelope.at
r3b1798 r0516fd 20 20 AT_SETUP([Tesselation - big convex Envelope]) 21 21 AT_KEYWORDS([Tesselation convex convex-envelope]) 22 AT_XFAIL_IF([/bin/true])23 22 24 23 file=test.conf 25 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Tesselation/BigConvex/pre/test. /conf $file], 0)24 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Tesselation/BigConvex/pre/test.conf $file], 0) 26 25 convexfile=ConvexEnvelope 27 AT_CHECK([../../molecuilder -i $file --select-molecule-by-id 0 --convex-envelope --convex-file $convexfile --nonconvex-file NonConvexEnvelope], 0, [stdout], [stderr])26 AT_CHECK([../../molecuilder -i $file --select-molecule-by-id 0 --convex-envelope 5. --convex-file $convexfile --nonconvex-file NonConvexEnvelope], 0, [stdout], [stderr]) 28 27 AT_CHECK([diff ${convexfile}.dat ${abs_top_srcdir}/tests/regression/Tesselation/BigConvex/post/ConvexEnvelope.dat], 0, [ignore], [ignore]) 29 28 #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.4016angstrom^3" stdout], 0, [ignore], [ignore])29 AT_CHECK([fgrep "tesselated volume area is 223.577 angstrom^3" stdout], 0, [ignore], [ignore]) 31 30 32 31 AT_CLEANUP -
tests/regression/Tesselation/Convex/testsuite-tesselation-convex-envelope.at
r3b1798 r0516fd 24 24 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Tesselation/Convex/pre/test.conf $file], 0) 25 25 convexfile=ConvexEnvelope 26 AT_CHECK([../../molecuilder -i $file --select-molecule-by-id 0 --convex-envelope --convex-file $convexfile --nonconvex-file NonConvexEnvelope], 0, [stdout], [stderr])26 AT_CHECK([../../molecuilder -i $file --select-molecule-by-id 0 --convex-envelope 50. --convex-file $convexfile --nonconvex-file NonConvexEnvelope], 0, [stdout], [stderr]) 27 27 AT_CHECK([diff ${convexfile}.dat ${abs_top_srcdir}/tests/regression/Tesselation/Convex/post/ConvexEnvelope.dat], 0, [ignore], [ignore]) 28 28 #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.4016angstrom^3" stdout], 0, [ignore], [ignore])29 AT_CHECK([fgrep "tesselated volume area is 8.89109 angstrom^3" stdout], 0, [ignore], [ignore]) 30 30 AT_CHECK([diff ConvexEnvelope.dat NonConvexEnvelope.dat], 0, [ignore], [ignore]) 31 31
Note:
See TracChangeset
for help on using the changeset viewer.