00001
00015 #ifndef MDS_DELAUNAYTRI_H
00016 #define MDS_DELAUNAYTRI_H
00017
00018 #include "mdsTriData.h"
00019
00020
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
00027 #include <VectorEntity/mctris.h>
00028
00029
00030 #include <vector>
00031
00032
00033 namespace mds
00034 {
00035 namespace seg
00036 {
00037
00038
00039
00040
00041
00042
00044
00045
00046
00047
00048
00049
00053 class CDelaunayTri : public mds::base::CObject, public mds::mod::CSerializable
00054 {
00055 public:
00058 MDS_SHAREDPTR(CDelaunayTri);
00059
00061 MDS_ENTITY_NAME("DelaunayTri");
00062
00064 MDS_ENTITY_COMPRESSION(mds::mod::CC_RAW);
00065
00067 MDS_ENTITY_BLOCK_SIZE(4096);
00068
00070 static const tSize DEFAULT_NUMBER_OF_NODES;
00071
00073 static const double DEFAULT_MIN_EDGE_LENGTH;
00074
00076 static const double MAX_MOVEMENT;
00077
00079 enum
00080 {
00081 XMIN_BOUNDARY = 16,
00082 YMIN_BOUNDARY = 32,
00083 XMAX_BOUNDARY = 64,
00084 YMAX_BOUNDARY = 128,
00085 BOUNDARY_FLAGS = XMIN_BOUNDARY | YMIN_BOUNDARY | XMAX_BOUNDARY | YMAX_BOUNDARY,
00086 };
00087
00089 typedef void (*tTriangleFunc)(vctl::MCTri *pTriangle, CDelaunayTri *pMesh);
00090
00091 public:
00093 CDelaunayTri();
00094
00096 virtual ~CDelaunayTri() { clear(); }
00097
00098
00100 vctl::MCVertex *newVertex(double x, double y)
00101 {
00102 return m_pVertices->New(x, y, 0.0);
00103 }
00104 vctl::MCVertex *newVertex(vctl::MCPoint3D *pPoint)
00105 {
00106 return m_pVertices->New(*pPoint);
00107 }
00108
00110 vctl::MCVertex *randomVertex(vctl::MCPoint3D *pPoint, double dMax = MAX_MOVEMENT)
00111 {
00112 return randomVertex(pPoint->GetX(), pPoint->GetY(), dMax);
00113 }
00114
00116 vctl::MCVertex *randomVertex(double x, double y, double dMax = MAX_MOVEMENT);
00117
00119 vctl::MCVerticeS *getVertices() { return m_pVertices; }
00120
00122 int getNumOfVertices() { return m_pVertices->GetNumber(); }
00123
00126 vctl::MCVertex *getFirstVertex() { return (vctl::MCVertex *)m_pVertices->GetFirst(); }
00127
00129 vctl::MCTriS *getTriangles() { return &m_Triangles; }
00130
00132 int getNumOfTriangles() { return m_Triangles.GetNumber(); }
00133
00136 vctl::MCTri *getFirstTriangle() { return (vctl::MCTri *)m_Triangles.GetFirst(); }
00137
00138
00143 bool init(vctl::MCPoint3D *pMin,
00144 vctl::MCPoint3D *pMax,
00145 mds::tSize NumOfNodes = DEFAULT_NUMBER_OF_NODES,
00146 double dMinEdgeLength = DEFAULT_MIN_EDGE_LENGTH
00147 );
00148
00155 bool construct();
00156
00161 bool addVertex(vctl::MCVertex *pVertex,
00162 int bBoundaryVertex = 0,
00163 tTriangleFunc InsertFunc = NULL,
00164 tTriangleFunc RemoveFunc = NULL
00165 );
00166
00172 bool normalize(double dMinQuality, double dMinEdgeLength);
00173
00175 void clear();
00176
00177
00179 bool getMinCoordinates(double& dX, double& dY);
00180
00182 bool getMaxCoordinates(double& dX, double& dY);
00183
00184
00186 template <class S>
00187 void serialize(mds::mod::CChannelSerializer<S>& Writer)
00188 {
00189
00190
00191
00192
00193 m_Triangles.serialize(Writer);
00194 }
00195
00197 template <class S>
00198 void deserialize(mds::mod::CChannelSerializer<S>& Reader)
00199 {
00200
00201 clear();
00202
00203
00204 m_Triangles.deserialize(Reader);
00205
00206
00207 vctl::MCTri *pTriangle = getFirstTriangle();
00208 for( ; pTriangle; pTriangle = pTriangle->GetNext() )
00209 {
00210
00211 STriangleInfo *pInfo = new STriangleInfo;
00212 pTriangle->SetValuePtr(pInfo);
00213
00214
00215 vctl::MCVertex *pVertices[3];
00216 pTriangle->GetVerticeS(pVertices);
00217
00218
00219 try {
00220 pInfo->Circumsphere.MakeSphereTri(pVertices[0], pVertices[1], pVertices[2]);
00221 }
00222 catch( ... )
00223 {
00224
00225 MDS_LOG_NOTE("CDelaunayTri::deserialize(): Failed to compute triangle circumsphere!");
00226 return;
00227 }
00228 }
00229
00230
00231 getMinCoordinates(m_dMinX, m_dMinY);
00232 getMaxCoordinates(m_dMaxX, m_dMaxY);
00233 }
00234
00235 protected:
00237 typedef std::vector<vctl::MCTri *> tTriangles;
00238
00240 typedef std::vector<vctl::MCVertex *> tVertices;
00241
00242 protected:
00244 vctl::MCTriS m_Triangles;
00245
00248 vctl::MCVerticeS *m_pVertices;
00249
00251 mds::math::CUniformPRNG m_Random;
00252
00254 double m_dMinX, m_dMinY;
00255
00257 double m_dMaxX, m_dMaxY;
00258
00259 protected:
00264 vctl::MCTri *addTriangle(vctl::MCVertex *pV0,
00265 vctl::MCVertex *pV1,
00266 vctl::MCVertex *pV2
00267 );
00268
00270 void removeTriangle(vctl::MCTri *pTriangle, bool bEraseVertices = false);
00271
00273 bool checkFlatness(vctl::MCVertex *pV0,
00274 vctl::MCVertex *pV1,
00275 vctl::MCVertex *pV2
00276 );
00277
00281 int checkBoundary(vctl::MCPoint3D *pPoint);
00282
00286 vctl::MCTri *findBaseTriangle(vctl::MCPoint3D *pPoint);
00287
00293 bool findCavity(vctl::MCPoint3D *pPoint, tTriangles& Cavity);
00294
00300 bool findCavityEnvelope(const tTriangles& Cavity, tVertices& Envelope);
00301
00303 void clearFlags();
00304
00306 void clearFlags(const tTriangles& Triangles);
00307
00308 private:
00310 vctl::MCTri *findBaseTriangle(vctl::MCPoint3D *pPoint,
00311 vctl::MCTri *pTriangle
00312 );
00313
00315 bool findCavity(vctl::MCPoint3D *pPoint,
00316 tTriangles& Cavity,
00317 vctl::MCTri *pTriangle
00318 );
00319
00320 private:
00324 static double getTriangleQuality(vctl::MCTri *pTriangle);
00325
00327 static void normInsertFunc(vctl::MCTri *pTriangle, CDelaunayTri* pMesh);
00328
00330 static void normRemoveFunc(vctl::MCTri *pTriangle, CDelaunayTri* pMesh);
00331 };
00332
00333
00334
00335
00336
00337
00338
00339
00341 typedef CDelaunayTri::tSmartPtr CDelaunayTriPtr;
00342
00343
00344 }
00345 }
00346
00347 #endif // MDS_DELAUNAYTRI_H
00348