00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _SimplexMeshAdaptTopologyFilter_h
00018 #define _SimplexMeshAdaptTopologyFilter_h
00019
00020 #include "itkMesh.h"
00021 #include "itkPolygonCell.h"
00022 #include "itkMapContainer.h"
00023 #include "itkCellInterfaceVisitor.h"
00024
00025 #include "itkSimplexMesh.h"
00026 #include "itkSimplexMeshGeometry.h"
00027 #include "itkMeshToMeshFilter.h"
00028 #include "itkVectorContainer.h"
00029
00030 #include <vxl_version.h>
00031 #if VXL_VERSION_DATE_FULL > 20040406
00032 # include <vnl/vnl_cross.h>
00033 # define itk_cross_3d vnl_cross_3d
00034 #else
00035 # define itk_cross_3d cross_3d
00036 #endif
00037
00038 namespace itk
00039 {
00050 template <class TInputMesh, class TOutputMesh>
00051 class SimplexMeshAdaptTopologyFilter : public MeshToMeshFilter<TInputMesh, TOutputMesh>
00052 {
00053
00054 public:
00056 typedef SimplexMeshAdaptTopologyFilter Self;
00057
00059 typedef MeshToMeshFilter<TInputMesh, TOutputMesh> Superclass;
00060
00062 typedef SmartPointer<Self> Pointer;
00064 typedef SmartPointer<const Self> ConstPointer;
00065
00067 itkNewMacro(Self);
00068
00070 itkTypeMacro(SimplexMeshAdaptTopologyFilter,MeshToMeshFilter);
00071
00072 typedef TInputMesh InputMeshType;
00073 typedef typename InputMeshType::Pointer InputMeshPointer;
00074 typedef typename InputMeshType::PointType InputPointType;
00075 typedef typename InputMeshType::VectorType InputVectorType;
00076 typedef typename InputMeshType::PixelType InputPixelType;
00077 typedef typename InputMeshType::MeshTraits::CellTraits InputCellTraitsType;
00078 typedef typename InputMeshType::CellType InputCellType;
00079 typedef typename InputCellType::PointIdIterator InputCellPointIdIterator;
00080 typedef typename InputCellType::CellAutoPointer InputCellAutoPointer;
00081 typedef typename InputMeshType::CellAutoPointer CellAutoPointer;
00082 typedef itk::PolygonCell<InputCellType> InputPolygonType;
00083 typedef typename InputPolygonType::PointIdIterator InputPolygonPointIdIterator;
00084
00085
00086 typedef TOutputMesh OutputMeshType;
00087 typedef typename OutputMeshType::Pointer OutputMeshPointer;
00088 typedef typename OutputMeshType::CellType OutputCellType;
00089 typedef itk::PolygonCell<OutputCellType> OutputPolygonType;
00090
00091 typedef itk::MapContainer<unsigned long, double> DoubleValueMapType;
00092 typedef typename DoubleValueMapType::Iterator DoubleContainerIterator;
00093
00094
00101 class SimplexCellVisitor
00102 {
00103
00104 public:
00105 InputMeshPointer mesh;
00106 double totalArea;
00107 double totalCurvature;
00108 double minCellSize;
00109 double maxCellSize;
00110 DoubleValueMapType::Pointer areaMap;
00111 DoubleValueMapType::Pointer curvatureMap;
00112
00113 double minCurvature;
00114 double maxCurvature;
00115
00116 SimplexCellVisitor()
00117 {
00118 areaMap = DoubleValueMapType::New();
00119 curvatureMap = DoubleValueMapType::New();
00120 totalArea = 0;
00121 totalCurvature = 0;
00122 minCellSize = NumericTraits<double>::max();
00123 maxCellSize = 0;
00124 minCurvature = NumericTraits<double>::max();
00125 maxCurvature = 0;
00126 }
00127
00128
00132 void Visit(unsigned long cellId, InputPolygonType * poly)
00133 {
00134 typename InputPolygonType::PointIdIterator it = poly->PointIdsBegin();
00135
00136 double meanCurvature = 0;
00137 unsigned long refPoint = *it;
00138 double val = mesh->GetMeanCurvature(*it++);
00139 meanCurvature += vcl_abs(val);
00140
00141 unsigned long id1 = *it;
00142 val = mesh->GetMeanCurvature(*it++);
00143 meanCurvature += vcl_abs(val);
00144
00145 unsigned long id2;
00146
00147 double area = 0;
00148
00149 int cnt = 0;
00150
00151 while ( it != poly->PointIdsEnd() )
00152 {
00153 id2 = *it;
00154 area += ComputeArea(refPoint,id1,id2);
00155 id1 = id2;
00156 val = mesh->GetMeanCurvature(*it);
00157 meanCurvature += vcl_abs(val);
00158 cnt++;
00159 it++;
00160 }
00161
00162 meanCurvature /= (double)cnt;
00163 totalArea += area;
00164 totalCurvature += meanCurvature;
00165
00166 areaMap->InsertElement(cellId, area);
00167 curvatureMap->InsertElement(cellId, meanCurvature);
00168
00169 if (area > maxCellSize ) maxCellSize = area;
00170 if (area < minCellSize ) minCellSize = area;
00171 if (meanCurvature > maxCurvature ) maxCurvature = meanCurvature;
00172 if (meanCurvature < minCurvature ) minCurvature = meanCurvature;
00173 }
00174
00175 double ComputeArea(unsigned long p1,unsigned long p2, unsigned long p3)
00176 {
00177 InputPointType v1,v2,v3;
00178 mesh->GetPoint(p1, &v1);
00179 mesh->GetPoint(p2, &v2);
00180 mesh->GetPoint(p3, &v3);
00181 return vcl_abs (itk_cross_3d((v2-v1).GetVnlVector(), (v3-v1).GetVnlVector()).two_norm() /2.0);
00182 }
00183
00184 DoubleValueMapType::Pointer GetAreaMap()
00185 {
00186 return areaMap;
00187 }
00188
00189 DoubleValueMapType::Pointer GetCurvatureMap()
00190 {
00191 return curvatureMap;
00192 }
00193
00194 double GetTotalMeshArea()
00195 {
00196 return totalArea;
00197 }
00198
00199 double GetTotalMeanCurvature()
00200 {
00201 return totalCurvature/(curvatureMap->Size());
00202 }
00203
00204 double GetMaximumCellSize()
00205 {
00206 return maxCellSize;
00207 }
00208
00209 double GetMinimumCellSize()
00210 {
00211 return minCellSize;
00212 }
00213 double GetMaximumCurvature()
00214 {
00215 return maxCurvature;
00216 }
00217
00218 double GetMinimumCurvature()
00219 {
00220 return minCurvature;
00221 }
00222
00223 };
00224
00225
00226 typedef itk::CellInterfaceVisitorImplementation<InputPixelType,
00227 InputCellTraitsType,
00228 InputPolygonType,
00229 SimplexCellVisitor>
00230 SimplexVisitorInterfaceType;
00231
00232 typedef typename SimplexVisitorInterfaceType::Pointer SimplexVisitorInterfacePointer;
00233 typedef typename InputCellType::MultiVisitor CellMultiVisitorType;
00234 typedef typename CellMultiVisitorType::Pointer CellMultiVisitorPointer;
00235
00236
00237 itkSetMacro(Threshold, double);
00238 itkGetMacro(Threshold, double);
00239
00240 itkSetMacro(SelectionMethod, int);
00241 itkGetMacro(SelectionMethod, int);
00242
00243 itkGetMacro(ModifiedCount, int);
00244
00245
00246 protected:
00247
00248 SimplexMeshAdaptTopologyFilter();
00249
00250 ~SimplexMeshAdaptTopologyFilter();
00251
00252 SimplexMeshAdaptTopologyFilter(const Self&)
00253 {
00254 }
00255
00256 void operator=(const Self&)
00257 {
00258 }
00259
00260 void PrintSelf(std::ostream& os, Indent indent) const;
00261
00262 virtual void GenerateData();
00263
00264
00268 void Initialize();
00269
00275 void ComputeCellParameters();
00276
00280 void InsertNewCells();
00281
00287 void ModifyNeighborCells(unsigned long id1, unsigned long id2, unsigned long insertPointId);
00288
00289
00293 InputPointType ComputeCellCenter(InputCellAutoPointer &simplexCell);
00294
00295
00299 unsigned long m_IdOffset;
00300
00301
00306 double m_Threshold;
00307
00311 int m_SelectionMethod;
00312
00317 int m_ModifiedCount;
00318
00323 OutputMeshPointer m_Output;
00324
00325 InputCellAutoPointer NewSimplexCellPointer;
00326
00327 };
00328
00329 }
00330
00331 #ifndef ITK_MANUAL_INSTANTIATION
00332 #include "itkSimplexMeshAdaptTopologyFilter.txx"
00333 #endif
00334
00335 #endif //_SimplexMeshAdaptTopologyFilter_h
00336