00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkSimplexMeshAdaptTopologyFilter_h
00018 #define __itkSimplexMeshAdaptTopologyFilter_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 #include <itkCovariantVector.h>
00030
00031 #include <vxl_version.h>
00032 #if VXL_VERSION_DATE_FULL > 20040406
00033 # include <vnl/vnl_cross.h>
00034 # define itk_cross_3d vnl_cross_3d
00035 #else
00036 # define itk_cross_3d cross_3d
00037 #endif
00038
00039 namespace itk
00040 {
00051 template <class TInputMesh, class TOutputMesh>
00052 class SimplexMeshAdaptTopologyFilter : public MeshToMeshFilter<TInputMesh, TOutputMesh>
00053 {
00054
00055 public:
00057 typedef SimplexMeshAdaptTopologyFilter Self;
00058
00060 typedef MeshToMeshFilter<TInputMesh, TOutputMesh> Superclass;
00061
00063 typedef SmartPointer<Self> Pointer;
00064
00066 typedef SmartPointer<const Self> ConstPointer;
00067
00069 itkNewMacro(Self);
00070
00072 itkTypeMacro(SimplexMeshAdaptTopologyFilter,MeshToMeshFilter);
00073
00074 typedef TInputMesh InputMeshType;
00075 typedef typename InputMeshType::Pointer InputMeshPointer;
00076 typedef typename InputMeshType::PointType InputPointType;
00077 typedef typename InputMeshType::VectorType InputVectorType;
00078 typedef typename InputMeshType::PixelType InputPixelType;
00079 typedef typename InputMeshType::MeshTraits::CellTraits InputCellTraitsType;
00080 typedef typename InputMeshType::CellType InputCellType;
00081 typedef typename InputCellType::PointIdIterator InputCellPointIdIterator;
00082 typedef typename InputCellType::CellAutoPointer InputCellAutoPointer;
00083 typedef typename InputMeshType::CellAutoPointer CellAutoPointer;
00084 typedef itk::PolygonCell<InputCellType> InputPolygonType;
00085 typedef typename InputPolygonType::PointIdIterator InputPolygonPointIdIterator;
00086
00087 typedef CovariantVector<
00088 typename InputVectorType::ValueType, 3 > CovariantVectorType;
00089 typedef TOutputMesh OutputMeshType;
00090 typedef typename OutputMeshType::Pointer OutputMeshPointer;
00091 typedef typename OutputMeshType::CellType OutputCellType;
00092 typedef itk::PolygonCell<OutputCellType> OutputPolygonType;
00093
00094 typedef itk::MapContainer<unsigned long, double> DoubleValueMapType;
00095 typedef typename DoubleValueMapType::Iterator DoubleContainerIterator;
00096
00097
00104 class SimplexCellVisitor
00105 {
00106
00107 public:
00108 InputMeshPointer mesh;
00109 double totalArea;
00110 double totalCurvature;
00111 double minCellSize;
00112 double maxCellSize;
00113 DoubleValueMapType::Pointer areaMap;
00114 DoubleValueMapType::Pointer curvatureMap;
00115
00116 double minCurvature;
00117 double maxCurvature;
00118
00119 SimplexCellVisitor()
00120 {
00121 areaMap = DoubleValueMapType::New();
00122 curvatureMap = DoubleValueMapType::New();
00123 totalArea = 0;
00124 totalCurvature = 0;
00125 minCellSize = NumericTraits<double>::max();
00126 maxCellSize = 0;
00127 minCurvature = NumericTraits<double>::max();
00128 maxCurvature = 0;
00129 }
00130
00131
00135 void Visit(unsigned long cellId, InputPolygonType * poly)
00136 {
00137 typename InputPolygonType::PointIdIterator it = poly->PointIdsBegin();
00138
00139 double meanCurvature = 0;
00140 unsigned long refPoint = *it;
00141 double val = mesh->GetMeanCurvature(*it++);
00142 meanCurvature += vcl_abs(val);
00143
00144 unsigned long id1 = *it;
00145 val = mesh->GetMeanCurvature(*it++);
00146 meanCurvature += vcl_abs(val);
00147
00148 unsigned long id2;
00149
00150 double area = 0;
00151
00152 int cnt = 0;
00153
00154 while ( it != poly->PointIdsEnd() )
00155 {
00156 id2 = *it;
00157 area += ComputeArea(refPoint,id1,id2);
00158 id1 = id2;
00159 val = mesh->GetMeanCurvature(*it);
00160 meanCurvature += vcl_abs(val);
00161 cnt++;
00162 it++;
00163 }
00164
00165 meanCurvature /= (double)cnt;
00166 totalArea += area;
00167 totalCurvature += meanCurvature;
00168
00169 areaMap->InsertElement(cellId, area);
00170 curvatureMap->InsertElement(cellId, meanCurvature);
00171
00172 if (area > maxCellSize ) maxCellSize = area;
00173 if (area < minCellSize ) minCellSize = area;
00174 if (meanCurvature > maxCurvature ) maxCurvature = meanCurvature;
00175 if (meanCurvature < minCurvature ) minCurvature = meanCurvature;
00176 }
00177
00178 double ComputeArea(unsigned long p1,unsigned long p2, unsigned long p3)
00179 {
00180 InputPointType v1,v2,v3;
00181 mesh->GetPoint(p1, &v1);
00182 mesh->GetPoint(p2, &v2);
00183 mesh->GetPoint(p3, &v3);
00184 return vcl_abs (itk_cross_3d((v2-v1).GetVnlVector(), (v3-v1).GetVnlVector()).two_norm() /2.0);
00185 }
00186
00187 DoubleValueMapType::Pointer GetAreaMap()
00188 {
00189 return areaMap;
00190 }
00191
00192 DoubleValueMapType::Pointer GetCurvatureMap()
00193 {
00194 return curvatureMap;
00195 }
00196
00197 double GetTotalMeshArea()
00198 {
00199 return totalArea;
00200 }
00201
00202 double GetTotalMeanCurvature()
00203 {
00204 return totalCurvature/(curvatureMap->Size());
00205 }
00206
00207 double GetMaximumCellSize()
00208 {
00209 return maxCellSize;
00210 }
00211
00212 double GetMinimumCellSize()
00213 {
00214 return minCellSize;
00215 }
00216 double GetMaximumCurvature()
00217 {
00218 return maxCurvature;
00219 }
00220
00221 double GetMinimumCurvature()
00222 {
00223 return minCurvature;
00224 }
00225
00226 };
00227
00228
00229 typedef itk::CellInterfaceVisitorImplementation<InputPixelType,
00230 InputCellTraitsType,
00231 InputPolygonType,
00232 SimplexCellVisitor>
00233 SimplexVisitorInterfaceType;
00234
00235 typedef typename SimplexVisitorInterfaceType::Pointer SimplexVisitorInterfacePointer;
00236 typedef typename InputCellType::MultiVisitor CellMultiVisitorType;
00237 typedef typename CellMultiVisitorType::Pointer CellMultiVisitorPointer;
00238
00239
00240 itkSetMacro(Threshold, double);
00241 itkGetMacro(Threshold, double);
00242
00243 itkSetMacro(SelectionMethod, int);
00244 itkGetMacro(SelectionMethod, int);
00245
00246 itkGetMacro(ModifiedCount, int);
00247
00248
00249 protected:
00250
00251 SimplexMeshAdaptTopologyFilter();
00252
00253 ~SimplexMeshAdaptTopologyFilter();
00254
00255 SimplexMeshAdaptTopologyFilter(const Self&)
00256 {
00257 }
00258
00259 void operator=(const Self&)
00260 {
00261 }
00262
00263 void PrintSelf(std::ostream& os, Indent indent) const;
00264
00265 virtual void GenerateData();
00266
00267
00271 void Initialize();
00272
00278 void ComputeCellParameters();
00279
00283 void InsertNewCells();
00284
00290 void ModifyNeighborCells(unsigned long id1, unsigned long id2, unsigned long insertPointId);
00291
00292
00296 InputPointType ComputeCellCenter(InputCellAutoPointer &simplexCell);
00297
00298
00302 unsigned long m_IdOffset;
00303
00304
00309 double m_Threshold;
00310
00314 int m_SelectionMethod;
00315
00320 int m_ModifiedCount;
00321
00326 OutputMeshPointer m_Output;
00327
00328 InputCellAutoPointer NewSimplexCellPointer;
00329
00330 };
00331
00332 }
00333
00334 #ifndef ITK_MANUAL_INSTANTIATION
00335 #include "itkSimplexMeshAdaptTopologyFilter.txx"
00336 #endif
00337
00338 #endif // __itkSimplexMeshAdaptTopologyFilter_h
00339
00340