00001
00015 #ifndef MDS_TETRAMESH_H
00016 #define MDS_TETRAMESH_H
00017
00018 #include "mdsDelaunayTetra.h"
00019 #include "mdsTetraFeatures.h"
00020 #include "mdsTetraScaling.h"
00021 #include "mdsTetraSimilarityMeasure.h"
00022 #include "mdsTetraHomogeneityMeasure.h"
00023
00024
00025 #include <vector>
00026
00027
00028 namespace mds
00029 {
00030 namespace seg
00031 {
00032
00033
00034
00035
00036
00037
00039
00040
00041
00042
00043
00044
00048 class CTetraMesh : public CDelaunayTetra, public CTetraScaling, public CTetraBase
00049 {
00050 public:
00053 MDS_SHAREDPTR(CTetraMesh);
00054
00056 MDS_ENTITY_NAME("TetraMesh");
00057
00059 MDS_ENTITY_COMPRESSION(mds::mod::CC_RAW);
00060
00062 MDS_ENTITY_BLOCK_SIZE(4096);
00063
00065 enum
00066 {
00068 MARKED = 1 << 10,
00069
00071 DOMAIN_BOUNDARY = 1 << 11,
00072 };
00073
00075 typedef std::vector<CTetraFeatures> tSegments;
00076
00078 static const tSize DEFAULT_CELL;
00079 static const tSize DEFAULT_CELL_MARGIN;
00080 static const tSize DEFAULT_VERTEX_NEIGHBOURHOOD;
00081 static const double DEFAULT_INIT_THRESHOLD;
00082 static const double DEFAULT_SPLITTING_THRESHOLD;
00083 static const double DEFAULT_DISTANCE_THRESHOLD;
00084 static const double MIN_TETRAHEDRON_VOLUME;
00085 static const double DEFAULT_DELTA_THRESHOLD;
00086 static const double DEFAULT_CORNER_MIN_EDGE_LENGTH;
00087 static const double DEFAULT_AVG_TETRA_SIZE;
00088 static const double DEFAULT_K;
00089
00090 public:
00092 CTetraMesh();
00093
00095 virtual ~CTetraMesh();
00096
00098 double getVertexNeighbourhood() { return m_VertexNeighbourhood; }
00099
00101 void setVertexNeighbourhood(tSize Value = DEFAULT_VERTEX_NEIGHBOURHOOD)
00102 {
00103 MDS_CHECK(Value >= 0, return);
00104
00105 m_VertexNeighbourhood = Value;
00106 }
00107
00109 double getCornerMinEdgeLength() { return m_dCornerMinEdgeLength; }
00110
00112 void setCornerMinEdgeLength(double dValue = DEFAULT_CORNER_MIN_EDGE_LENGTH)
00113 {
00114 MDS_CHECK(dValue > 0.0, return);
00115
00116 m_dCornerMinEdgeLength = dValue;
00117 }
00118
00119
00121 mds::img::CDensityVolume *getVolumePtr() { return m_spVolume; }
00122
00124 void setVolume(mds::img::CDensityVolume *pVolume);
00125
00127 mds::img::CDensityVolume *getEdgeVolumePtr() { return m_spEdgeVolume; }
00128
00130 void setEdgeVolume(mds::img::CDensityVolume *pEdgeVolume);
00131
00132
00134 mds::img::CDensityVolume *getControlSpacePtr() { return m_spControlSpace; }
00135
00137 void setControlSpace(mds::img::CDensityVolume *pControlSpace);
00138
00141 bool prepareControlSpace(double dK = DEFAULT_K,
00142 double dAvgTetrahedronSize = DEFAULT_AVG_TETRA_SIZE
00143 );
00144
00145
00147 int getNumOfSegments() const { return m_iNumOfSegments; }
00148
00150 void setNumOfSegments(int i) { m_iNumOfSegments = i; }
00151
00153 tSegments& getSegments() { return m_Segments; }
00154
00155
00159 virtual bool attractVertex(vctl::MCPoint3D *pPoint);
00160
00164 bool subpixelAttractVertex(vctl::MCPoint3D *pPoint);
00165
00170 bool isotropicAttractVertex(vctl::MCPoint3D *pPoint);
00171
00172
00177 bool init(double dThreshold = DEFAULT_INIT_THRESHOLD,
00178 tSize CellSize = DEFAULT_CELL,
00179 tSize NumOfNodes = DEFAULT_NUMBER_OF_NODES
00180 );
00181
00184 bool evaluateFeatures(bool bSkipSmall = true);
00185
00189 bool evaluateSegmentFeatures(bool bSkipSmall = true);
00190
00194 bool edgeSplitting(double dOrientThreshold = DEFAULT_SPLITTING_THRESHOLD);
00195
00199 bool isotropicEdgeSplitting(double dThreshold, bool bBoundaryEdges = false);
00200
00205 bool isotropicVertexMoving();
00206
00210 bool subpixelVertexMoving();
00211
00214 bool approachEdges(bool bCheckIsotropicMinEdgeLength = false);
00215
00219 bool variationalMeshing(bool bCheckIsotropicMinEdgeLength = false);
00220
00221
00224
00225
00229 bool tetrahedronSplitting(CTetraHomogeneityMeasure& Measure);
00230
00238 bool optimizeByVertexMoving(double dMinQuality);
00239
00244 bool regionGrowing(CTetraSimilarityMeasure& Measure,
00245 double dBThreshold = DEFAULT_DISTANCE_THRESHOLD
00246 );
00247
00251 bool regionMerging(CTetraSimilarityMeasure& Measure,
00252 double dBThreshold = DEFAULT_DISTANCE_THRESHOLD,
00253 double dDeltaThreshold = DEFAULT_DELTA_THRESHOLD,
00254 tSize NumOfRegions = -1,
00255 bool bMergeAdjacent = true
00256 );
00257
00260 void findIsolatedRegions();
00261
00263 void changeRegion(int iMinIndex, int iMaxIndex = -1, int iFinalRegion = -1);
00264
00267 void reassignRegions();
00268
00272 bool classifyAdjacent(double dBThreshold = DEFAULT_DISTANCE_THRESHOLD);
00273
00277 bool noiseReduction();
00278
00281 void visualize(mds::img::CDVolume *pVolume);
00282
00283
00288 bool markBoundaryVertices();
00289
00294 bool isBoundaryTriangle(vctl::MCVertex *p0,
00295 vctl::MCVertex *p1,
00296 vctl::MCVertex *p2
00297 );
00298
00299
00301 vctl::MCTriS *getTriangles() { return m_Tetrahedra.GetTriS(); }
00302
00304 int getNumOfTriangles() { return m_Tetrahedra.GetTriS()->GetNumber(); }
00305
00308 vctl::MCTri *getFirstTriangle() { return (vctl::MCTri *)m_Tetrahedra.GetTriS()->GetFirst(); }
00309
00313 void createTriangles(int iRegion = -1, bool bBoundary = false);
00314
00318 void createTriangles(double a, double b, double c, double d, int iRegion = -1);
00319
00322 void createTriangles(double dQuality, int iRegion = -1);
00323
00325 void clearTriangles();
00326
00329 bool saveSTL(mds::mod::CChannel& Channel);
00330
00334 bool saveVRML(mds::mod::CChannel& Channel);
00335
00336
00338 template <class S>
00339 void serialize(mds::mod::CChannelSerializer<S>& Writer)
00340 {
00341
00342 CDelaunayTetra::serialize(Writer);
00343 }
00344
00346 template <class S>
00347 void deserialize(mds::mod::CChannelSerializer<S>& Reader)
00348 {
00349
00350 CDelaunayTetra::deserialize(Reader);
00351
00352
00353 int iMaxRegion = -1;
00354 vctl::MCTetra *pTetra = getFirstTetrahedron();
00355 for( ; pTetra; pTetra = pTetra->GetNext() )
00356 {
00357
00358 int iRegion = getTetrahedronRegion(pTetra);
00359 if( iRegion > iMaxRegion )
00360 {
00361 iMaxRegion = iRegion;
00362 }
00363 }
00364
00365
00366 m_iNumOfSegments = iMaxRegion + 1;
00367 }
00368
00369 protected:
00371 typedef std::vector<vctl::MCPoint3D> tPoints;
00372
00373 protected:
00375 mds::img::CDensityVolumePtr m_spVolume;
00376
00378 mds::img::CDensityVolumePtr m_spEdgeVolume;
00379
00381 mds::img::CDensityVolumePtr m_spControlSpace;
00382
00384 int m_iNumOfSegments;
00385
00387 tSegments m_Segments;
00388
00390 mds::tSize m_VertexNeighbourhood;
00391
00393 double m_dCornerMinEdgeLength;
00394
00396 CTetraHomogeneityMeasure *m_pHomogeneityMeasure;
00397
00398
00399 public:
00401 bool checkTetrahedronVolume(vctl::MCTetra *pTetra);
00402
00405 bool checkBoundaryEdge(vctl::MCEdge *pEdge,
00406 vctl::MCVector3D *pNormal,
00407 double dThreshold = DEFAULT_DISTANCE_THRESHOLD
00408 );
00409
00412 bool checkBoundaryTriangle(vctl::MCPoint3D *p0,
00413 vctl::MCPoint3D *p1,
00414 vctl::MCPoint3D *p2,
00415 double dThreshold = DEFAULT_DISTANCE_THRESHOLD
00416 );
00417
00418 int evalEdgeDistancePoint(vctl::MCPoint3D *pPoint,
00419 mds::img::CPoint3D& Normal,
00420 int iMaxDistance
00421 );
00422
00425 bool splitEdge(vctl::MCEdge *pEdge,
00426 double dThreshold,
00427 tPoints& Points
00428 );
00429
00431 static void edgeSplittingInsertFunc(vctl::MCTetra *pTetrahedron, CDelaunayTetra *pMesh);
00432
00434 static void edgeSplittingRemoveFunc(vctl::MCTetra *pTetrahedron, CDelaunayTetra *pMesh);
00435
00438 bool isotropicSplitEdge(vctl::MCVertex *pV0,
00439 vctl::MCVertex *pV1,
00440 double dThreshold,
00441 tPoints& EdgePoints,
00442 tPoints& Points,
00443 bool bBoundary = false
00444 );
00445
00448 bool isotropicSplitSubEdge(vctl::MCPoint3D &p1,
00449 vctl::MCPoint3D &p2,
00450 double dThreshold,
00451 double dRestrictedZone,
00452 tPoints& Points
00453 );
00454
00456 static void isotropicEdgeSplittingInsertFunc(vctl::MCTetra *pTetrahedron, CDelaunayTetra *pMesh);
00457
00459 static void isotropicEdgeSplittingRemoveFunc(vctl::MCTetra *pTetrahedron, CDelaunayTetra *pMesh);
00460
00462 double getControlSpaceLength(vctl::MCPoint3D& p1, vctl::MCPoint3D& p2);
00463
00465 double getControlSpaceValue(const mds::img::CPoint3D& Point);
00466
00469 bool splitTetrahedron(vctl::MCTetra *pTetrahedron);
00470
00473 static void tetrahedronSplittingInsertFunc(vctl::MCTetra *pTetrahedron,
00474 CDelaunayTetra *pMesh
00475 );
00476
00478 static void tetrahedronSplittingRemoveFunc(vctl::MCTetra *pTetrahedron,
00479 CDelaunayTetra *pMesh
00480 );
00481
00482 public:
00484 static bool checkIsotropicMinEdgeLengthFunc(vctl::MCPoint3D *p1,
00485 vctl::MCPoint3D *p2,
00486 CDelaunayTetra* pMesh
00487 );
00488 static bool checkIsotropicMinEdgeLengthFunc2(vctl::MCPoint3D *p1,
00489 vctl::MCPoint3D *p2,
00490 CDelaunayTetra* pMesh
00491 );
00492
00494 static bool checkNoImageEdgeIntersectionFunc(vctl::MCPoint3D *p1,
00495 vctl::MCPoint3D *p2,
00496 CDelaunayTetra* pMesh
00497 );
00498
00501 static bool checkBoundaryFacetFunc(vctl::MCPoint3D *p1,
00502 vctl::MCPoint3D *p2,
00503 vctl::MCPoint3D *p3,
00504 CDelaunayTetra* pMesh
00505 );
00506 };
00507
00508
00509
00510
00511
00512
00513
00514
00516 typedef CTetraMesh::tSmartPtr CTetraMeshPtr;
00517
00518
00519 }
00520 }
00521
00522 #endif // MDS_TETRAMESH_H
00523