mdsDelaunayTetra.h

Go to the documentation of this file.
00001 //==============================================================================
00015 #ifndef MDS_DELAUNAYTETRA_H
00016 #define MDS_DELAUNAYTETRA_H
00017 
00018 #include "mdsTetraData.h"
00019 
00020 // MDSTk
00021 #include <MDSTk/Base/mdsGlobalLog.h>
00022 #include <MDSTk/Base/mdsSharedPtr.h>
00023 #include <MDSTk/Math/mdsRandom.h>
00024 #include <MDSTk/Module/mdsSerialization.h>
00025 
00026 // VCTL
00027 #include <VectorEntity/mctetras.h>
00028 
00029 // STL
00030 #include <vector>
00031 
00032 
00033 namespace mds
00034 {
00035 namespace seg
00036 {
00037 
00038 //==============================================================================
00039 /*
00040  * Global definitions.
00041  */
00042 
00044 //#ifndef MDS_SEG_LOGGING_ENABLED
00045 //#    define MDS_SEG_LOGGING_ENABLED
00046 //#endif
00047 
00049 //#ifndef MDS_CHECK_TETRAHEDRONS
00050 //#    define MDS_CHECK_TETRAHEDRONS
00051 //#endif
00052 
00054 #ifndef MDS_CHECK_MIN_EDGE_LENGTH
00055 #    define MDS_CHECK_MIN_EDGE_LENGTH
00056 #endif
00057 
00058 
00059 //==============================================================================
00063 class CDelaunayTetra : public mds::base::CObject, public mds::mod::CSerializable
00064 {
00065 public:
00068     MDS_SHAREDPTR(CDelaunayTetra);
00069 
00071     MDS_ENTITY_NAME("DelaunayTetra");
00072 
00074     MDS_ENTITY_COMPRESSION(mds::mod::CC_RAW);
00075 
00077     MDS_ENTITY_BLOCK_SIZE(4096);
00078 
00080     static const mds::tSize DEFAULT_NUMBER_OF_NODES;
00081 
00083     static const double DEFAULT_MIN_EDGE_LENGTH;
00084 
00086     static const double DEFAULT_MIN_DIHEDRAL_ANGLE;
00087 
00089     static const double MAX_MOVEMENT;
00090 
00092     enum
00093     {
00094         XMIN_BOUNDARY   = 1 << 4,
00095         YMIN_BOUNDARY   = 1 << 5,
00096         ZMIN_BOUNDARY   = 1 << 6,
00097         XMAX_BOUNDARY   = 1 << 7,
00098         YMAX_BOUNDARY   = 1 << 8,
00099         ZMAX_BOUNDARY   = 1 << 9,
00100         BOUNDARY_FLAGS  = XMIN_BOUNDARY | YMIN_BOUNDARY | ZMIN_BOUNDARY
00101                         | XMAX_BOUNDARY | YMAX_BOUNDARY | ZMAX_BOUNDARY,
00102     };
00103 
00105     typedef void (*tTetrahedronFunc)(vctl::MCTetra *pTetrahedron, CDelaunayTetra *pMesh);
00106 
00108     typedef bool (*tMinEdgeLengthFunc)(vctl::MCPoint3D *p1, vctl::MCPoint3D *p2, CDelaunayTetra *pMesh);
00109 
00111     typedef bool (*tConstraintFunc)(vctl::MCPoint3D *p1, vctl::MCPoint3D *p2, vctl::MCPoint3D *p3, CDelaunayTetra *pMesh);
00112 
00113 public:
00115     CDelaunayTetra();
00116 
00118     virtual ~CDelaunayTetra() { clear(); }
00119 
00121     double getMinEdgeLength() { return m_dMinEdgeLength; }
00122 
00124     void setMinEdgeLength(double dValue = DEFAULT_MIN_EDGE_LENGTH)
00125     {
00126         MDS_CHECK(dValue > 0.0, return);
00127 
00128         m_dMinEdgeLength = dValue;
00129     }
00130 
00132     double getMinDihedralAngle() { return m_dMinDihedralAngle; }
00133 
00135     void setMinDihedralAngle(double dValue = DEFAULT_MIN_DIHEDRAL_ANGLE)
00136     {
00137         MDS_CHECK(dValue > 0.0, return);
00138 
00139         m_dMinDihedralAngle = dValue;
00140     }
00141 
00143     void setMinEdgeLengthFunc(tMinEdgeLengthFunc MinEdgeLengthFunc)
00144     {
00145         MDS_CHECK(MinEdgeLengthFunc, return);
00146 
00147         m_MinEdgeLengthFunc = MinEdgeLengthFunc;
00148     }
00149 
00151     void setDefaultMinEdgeLengthFunc() { m_MinEdgeLengthFunc = checkMinEdgeLengthFunc; }
00152 
00153 
00155     void setConstraintFunc(tConstraintFunc ConstraintFunc)
00156     {
00157         MDS_CHECK(ConstraintFunc, return);
00158 
00159         m_ConstraintFunc = ConstraintFunc;
00160     }
00161 
00163     void setDefaultConstraintFunc() { m_ConstraintFunc = checkConstraintFunc; }
00164 
00165 
00167     virtual bool attractVertex(vctl::MCPoint3D *pPoint);
00168 
00170     vctl::MCVertex *newVertex(vctl::MCPoint3D *pPoint, int iFlags = 0)
00171     {
00172         vctl::MCVertex *pVertex = m_pVertices->New(pPoint->GetX(),
00173                                                    pPoint->GetY(),
00174                                                    pPoint->GetZ()
00175                                                    );
00176         pVertex->SetFlag(iFlags);
00177         return pVertex;
00178     }
00179 
00181     vctl::MCVertex *newVertex(double x, double y, double z, int iFlags = 0)
00182     {
00183         vctl::MCVertex *pVertex = m_pVertices->New(x, y, z);
00184         pVertex->SetFlag(iFlags);
00185         return pVertex;
00186     }
00187 
00189     vctl::MCVertex *randomVertex(vctl::MCPoint3D *pPoint, double dMax = MAX_MOVEMENT)
00190     {
00191         return randomVertex(pPoint->GetX(), pPoint->GetY(), pPoint->GetZ(), dMax);
00192     }
00193 
00195     vctl::MCVertex *randomVertex(double x, double y, double z, double dMax = MAX_MOVEMENT);
00196 
00197 
00199     vctl::MCVerticeS *getVertices() { return m_pVertices; }
00200 
00202     int getNumOfVertices() { return m_pVertices->GetNumber(); }
00203 
00206     vctl::MCVertex *getFirstVertex() { return (vctl::MCVertex *)m_pVertices->GetFirst(); }
00207 
00209     vctl::MCTetraS *getTetrahedra() { return &m_Tetrahedra; }
00210 
00212     int getNumOfTetrahedra() { return m_Tetrahedra.GetNumber(); }
00213 
00216     vctl::MCTetra *getFirstTetrahedron() { return (vctl::MCTetra *)m_Tetrahedra.GetFirst(); }
00217 
00218 
00220     template <class Function>
00221     inline Function forEachVertex(Function Func)
00222     {
00223         vctl::MCVertex *pVertex = getFirstVertex();
00224         while( pVertex )
00225         {
00226             Func(*pVertex);
00227             pVertex = pVertex->GetNext();
00228         }
00229         return Func;
00230     }
00231 
00233     template <class Function>
00234     inline Function forEachTetrahedron(Function Func)
00235     {
00236         vctl::MCTetra *pTetrahedron = getFirstTetrahedron();
00237         while( pTetrahedron )
00238         {
00239             Func(*pTetrahedron);
00240             pTetrahedron = pTetrahedron->GetNext();
00241         }
00242         return Func;
00243     }
00244 
00245 
00250     bool init(vctl::MCPoint3D *pMin,
00251               vctl::MCPoint3D *pMax,
00252               mds::tSize NumOfNodes = DEFAULT_NUMBER_OF_NODES
00253               );
00254 
00259     bool construct();
00260 
00265     bool addVertex(vctl::MCVertex *pVertex,
00266                    int iBoundaryVertex = 0,
00267                    tTetrahedronFunc InsertFunc = NULL,
00268                    tTetrahedronFunc RemoveFunc = NULL
00269                    );
00270 
00274     bool optimizeByVertexAdding(double dMinQuality, bool bRandomPosition = true);
00275 
00277     void clear();
00278 
00279 
00281     bool getMinCoordinates(double& dX, double& dY, double& dZ);
00282 
00284     bool getMaxCoordinates(double& dX, double& dY, double& dZ);
00285 
00286 
00288     template <class S>
00289     void serialize(mds::mod::CChannelSerializer<S>& Writer)
00290     {
00291         // Remove all unused vertices
00292 //        m_Tetrahedra.EraseVerticesNoTetras();
00293 
00294         // Serialize the triangular mesh
00295         m_Tetrahedra.serialize(Writer);
00296     }
00297 
00299     template <class S>
00300     void deserialize(mds::mod::CChannelSerializer<S>& Reader)
00301     {
00302         // Clear the current mesh
00303         clear();
00304 
00305         // Deserialize the tetrahedral mesh
00306         m_Tetrahedra.deserialize(Reader);
00307 
00308         // Create info structs
00309         vctl::MCTetra *pTetra = getFirstTetrahedron();
00310         for( ; pTetra; pTetra = pTetra->GetNext() )
00311         {
00312             // Create the info struct
00313             STetrahedronInfo *pInfo = new STetrahedronInfo;
00314             pTetra->SetValuePtr(pInfo);
00315 
00316             // Get tetrahedron vertices
00317             vctl::MCVertex *pVertices[4];
00318             pTetra->GetVerticeS(pVertices);
00319 
00320             // Compute circumpshere
00321             try {
00322                 pInfo->Circumsphere.MakeSphereTetra(pVertices[0], pVertices[1], pVertices[2], pVertices[3]);
00323             }
00324             catch( ... )
00325             {
00326                 // Failed to compute circumsphere
00327                 MDS_LOG_NOTE("CDelaunayTetra::deserialize(): Failed to compute tetrahedron circumsphere!");
00328                 continue;
00329             }
00330         }
00331 
00332         // Minimal and maximal coordinates
00333         getMinCoordinates(m_dMinX, m_dMinY, m_dMinZ);
00334         getMaxCoordinates(m_dMaxX, m_dMaxY, m_dMaxZ);
00335     }
00336 
00337 protected:
00339     typedef std::vector<vctl::MCTetra *> tTetrahedra;
00340 
00342     typedef std::vector<vctl::MCVertex *> tVertices;
00343 
00344 protected:
00346     vctl::MCTetraS m_Tetrahedra;
00347 
00350     vctl::MCVerticeS *m_pVertices;
00351 
00353     mds::math::CUniformPRNG m_Random;
00354 
00356     double m_dMinX, m_dMinY, m_dMinZ;
00357 
00359     double m_dMaxX, m_dMaxY, m_dMaxZ;
00360 
00362     double m_dMinEdgeLength;
00363 
00365     double m_dMinDihedralAngle;
00366 
00368     tMinEdgeLengthFunc m_MinEdgeLengthFunc;
00369 
00371     tConstraintFunc m_ConstraintFunc;
00372 
00373 protected:
00378     vctl::MCTetra *addTetrahedron(vctl::MCVertex *pV0,
00379                                   vctl::MCVertex *pV1,
00380                                   vctl::MCVertex *pV2,
00381                                   vctl::MCVertex *pV3
00382                                   );
00383 
00385     void removeTetrahedron(vctl::MCTetra *pTetrahedron, bool bEraseVertices = false);
00386 
00389     bool checkFlatness(vctl::MCVertex *pV0,
00390                        vctl::MCVertex *pV1,
00391                        vctl::MCVertex *pV2,
00392                        vctl::MCVertex *pV3
00393                        );
00394 
00397     bool checkTetrahedron(vctl::MCTetra *pTetrahedron);
00398 
00402     int checkBoundary(vctl::MCPoint3D *pPoint);
00403 
00407     vctl::MCTetra *findBaseTetrahedron(vctl::MCPoint3D *pPoint);
00408 
00415     bool findCavity(vctl::MCPoint3D *pPoint, tTetrahedra& Cavity);
00416 
00422     bool findCavityEnvelope(const tTetrahedra& Cavity, tVertices& Envelope);
00423 
00425     void clearFlags();
00426 
00428     void clearFlags(const tTetrahedra& Tetrahedra);
00429 
00433     static double getTetrahedronQuality(vctl::MCTetra *pTetrahedron);
00434 
00437     vctl::MCVertex *findNearestVertex(vctl::MCPoint3D *pPoint, bool bStartFromPrevious = false);
00438 
00439 private:
00441     vctl::MCTetra *findBaseTetrahedron(vctl::MCPoint3D *pPoint,
00442                                        vctl::MCTetra *pTetrahedron
00443                                        );
00444 
00447     vctl::MCTetra *findBaseTetrahedronBruteForce(vctl::MCPoint3D *pPoint);
00448 
00452     bool findCavity(vctl::MCPoint3D *pPoint,
00453                     tTetrahedra& Cavity,
00454                     vctl::MCTetra *pTetrahedron
00455                     );
00456 
00459     bool findBase(vctl::MCPoint3D *pPoint,
00460                   tTetrahedra& Base,
00461                   vctl::MCTetra *pTetrahedron
00462                   );
00463 
00468     bool findCavityFromBase(vctl::MCPoint3D *pPoint,
00469                             tTetrahedra& Cavity,
00470                             const tTetrahedra& Base
00471                             );
00472 
00473 private:
00475     static void normInsertFunc(vctl::MCTetra *pTetrahedron, CDelaunayTetra* pMesh);
00476 
00478     static void normRemoveFunc(vctl::MCTetra *pTetrahedron, CDelaunayTetra* pMesh);
00479 
00482     static bool checkMinEdgeLengthFunc(vctl::MCPoint3D *p1,
00483                                        vctl::MCPoint3D *p2,
00484                                        CDelaunayTetra* pMesh
00485                                        );
00486 
00488     static bool checkConstraintFunc(vctl::MCPoint3D *p1,
00489                                     vctl::MCPoint3D *p2,
00490                                     vctl::MCPoint3D *p3,
00491                                     CDelaunayTetra* pMesh
00492                                     );
00493 };
00494 
00495 
00496 //=============================================================================
00497 /*
00498  * Basic template instances and type definitions.
00499  * - Using smart pointers.
00500  */
00501 
00503 typedef CDelaunayTetra::tSmartPtr   CDelaunayTetraPtr;
00504 
00505 
00506 } // namespace seg
00507 } // namespace mds
00508 
00509 #endif // MDS_DELAUNAYTETRA_H
00510 

Generated on Thu Mar 11 10:35:44 2010 for MDSTk Extension Libraries by  doxygen 1.4.6-NO