ITK
4.1.0
Insight Segmentation and Registration Toolkit
|
00001 /*========================================================================= 00002 * 00003 * Copyright Insight Software Consortium 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0.txt 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 *=========================================================================*/ 00018 #ifndef __itkCleanQuadEdgeMeshFilter_h 00019 #define __itkCleanQuadEdgeMeshFilter_h 00020 00021 #include "itkIntTypes.h" 00022 #include "itkQuadEdgeMeshToQuadEdgeMeshFilter.h" 00023 #include "itkBoundingBox.h" 00024 00025 #include "itkSquaredEdgeLengthDecimationQuadEdgeMeshFilter.h" 00026 #include "itkQuadEdgeMeshDecimationCriteria.h" 00027 00028 namespace itk 00029 { 00035 template< class TInput, class TOutput=TInput > 00036 class ITK_EXPORT CleanQuadEdgeMeshFilter: 00037 public QuadEdgeMeshToQuadEdgeMeshFilter< TInput, TOutput > 00038 { 00039 public: 00040 typedef CleanQuadEdgeMeshFilter Self; 00041 typedef SmartPointer< Self > Pointer; 00042 typedef SmartPointer< const Self > ConstPointer; 00043 typedef QuadEdgeMeshToQuadEdgeMeshFilter< TInput, TOutput > Superclass; 00044 00046 itkTypeMacro(CleanQuadEdgeMeshFilter, QuadEdgeMeshToQuadEdgeMeshFilter); 00047 00049 itkNewMacro(Self); 00050 00051 typedef TInput InputMeshType; 00052 typedef typename Superclass::InputMeshPointer InputMeshPointer; 00053 typedef typename Superclass::InputCoordRepType InputCoordRepType; 00054 typedef typename Superclass::InputPointType InputPointType; 00055 typedef typename Superclass::InputPointIdentifier InputPointIdentifier; 00056 typedef typename Superclass::InputQEPrimal InputQEPrimal; 00057 typedef typename Superclass::InputVectorType InputVectorType; 00058 00059 typedef typename Superclass::InputEdgeCellType InputEdgeCellType; 00060 typedef typename Superclass::InputPolygonCellType InputPolygonCellType; 00061 typedef typename Superclass::InputPointIdList InputPointIdList; 00062 typedef typename Superclass::InputCellTraits InputCellTraits; 00063 typedef typename Superclass::InputPointsIdInternalIterator InputPointsIdInternalIterator; 00064 typedef typename Superclass::InputQEIterator InputQEIterator; 00065 00066 typedef typename InputMeshType::PointsContainer InputPointsContainer; 00067 typedef typename InputMeshType::PointsContainerPointer InputPointsContainerPointer; 00068 typedef typename InputMeshType::PointsContainerIterator InputPointsContainerIterator; 00069 00070 typedef typename InputMeshType::CellsContainerIterator InputCellsContainerIterator; 00071 00072 itkStaticConstMacro(PointDimension, unsigned int, InputMeshType::PointDimension); 00073 00074 typedef TOutput OutputMeshType; 00075 typedef typename Superclass::OutputMeshPointer OutputMeshPointer; 00076 typedef typename Superclass::OutputCoordRepType OutputCoordRepType; 00077 typedef typename Superclass::OutputPointType OutputPointType; 00078 typedef typename Superclass::OutputPointIdentifier OutputPointIdentifier; 00079 typedef typename Superclass::OutputQEPrimal OutputQEPrimal; 00080 typedef typename Superclass::OutputVectorType OutputVectorType; 00081 00082 typedef typename OutputMeshType::QEType OutputQEType; 00083 typedef typename OutputMeshType::PointsContainer OutputPointsContainer; 00084 typedef typename OutputMeshType::PointsContainerPointer OutputPointsContainerPointer; 00085 typedef typename OutputMeshType::PointsContainerIterator OutputPointsContainerIterator; 00086 00087 typedef typename OutputMeshType::CellsContainerIterator OutputCellsContainerIterator; 00088 00089 typedef BoundingBox< InputPointIdentifier, itkGetStaticConstMacro(PointDimension), 00090 InputCoordRepType, InputPointsContainer > BoundingBoxType; 00091 00092 typedef typename BoundingBoxType::Pointer BoundingBoxPointer; 00093 00094 typedef MaxMeasureBoundCriterion< OutputMeshType > CriterionType; 00095 typedef typename CriterionType::Pointer CriterionPointer; 00096 00097 typedef SquaredEdgeLengthDecimationQuadEdgeMeshFilter< InputMeshType, 00098 InputMeshType, 00099 CriterionType > DecimationType; 00100 typedef typename DecimationType::Pointer DecimationPointer; 00101 00102 itkSetMacro(AbsoluteTolerance, InputCoordRepType); 00103 itkSetMacro(RelativeTolerance, InputCoordRepType); 00104 protected: 00105 CleanQuadEdgeMeshFilter() 00106 { 00107 this->m_AbsoluteTolerance2 = itk::NumericTraits< InputCoordRepType >::Zero; 00108 this->m_AbsoluteTolerance = itk::NumericTraits< InputCoordRepType >::Zero; 00109 this->m_RelativeTolerance = itk::NumericTraits< InputCoordRepType >::Zero; 00110 } 00111 00112 virtual ~CleanQuadEdgeMeshFilter() {} 00113 00114 InputCoordRepType m_AbsoluteTolerance2; 00115 InputCoordRepType m_AbsoluteTolerance; 00116 InputCoordRepType m_RelativeTolerance; 00117 00118 void GenerateData() 00119 { 00120 InputCoordRepType zeroValue = itk::NumericTraits< InputCoordRepType >::Zero; 00121 00122 if ( ( m_AbsoluteTolerance == zeroValue ) && ( m_RelativeTolerance != zeroValue ) ) 00123 { 00124 itkAssertOrThrowMacro( ( m_RelativeTolerance > zeroValue ) && ( m_RelativeTolerance < 1. ), 00125 "Relative tolerance out of range" ); 00126 BoundingBoxPointer bounding_box = BoundingBoxType::New(); 00127 bounding_box->SetPoints( this->GetInput()->GetPoints() ); 00128 bounding_box->ComputeBoundingBox(); 00129 00130 m_AbsoluteTolerance2 = m_RelativeTolerance * m_RelativeTolerance 00131 * bounding_box->GetDiagonalLength2(); 00132 } 00133 00134 if ( m_AbsoluteTolerance != zeroValue ) 00135 { 00136 m_AbsoluteTolerance2 = m_AbsoluteTolerance * m_AbsoluteTolerance; 00137 } 00138 00139 this->MergePoints(); 00140 this->CleanPoints(); 00141 } 00142 00143 void MergePoints() 00144 { 00145 OutputMeshPointer output = this->GetOutput(); 00146 00147 CriterionPointer criterion = CriterionType::New(); 00148 00149 criterion->SetTopologicalChange(false); 00150 criterion->SetMeasureBound(m_AbsoluteTolerance2); 00151 00152 DecimationPointer decimate = DecimationType::New(); 00153 decimate->SetInput( this->GetInput() ); 00154 decimate->SetCriterion(criterion); 00155 decimate->Update(); 00156 00157 InputMeshPointer temp = decimate->GetOutput(); 00158 00159 InputPointsContainerIterator p_it = temp->GetPoints()->Begin(); 00160 InputPointsContainerIterator p_end = temp->GetPoints()->End(); 00161 00162 OutputPointType pOut; 00163 00164 while ( p_it != p_end ) 00165 { 00166 pOut.CastFrom( p_it.Value() ); 00167 output->SetPoint(p_it.Index(), pOut); 00168 ++p_it; 00169 } 00170 00171 // Copy Edge Cells 00172 InputCellsContainerIterator c_it = temp->GetEdgeCells()->Begin(); 00173 InputCellsContainerIterator c_end = temp->GetEdgeCells()->End(); 00174 InputEdgeCellType * qe; 00175 InputQEPrimal * QEGeom; 00176 00177 while ( c_it != c_end ) 00178 { 00179 qe = dynamic_cast< InputEdgeCellType * >( c_it.Value() ); 00180 QEGeom = qe->GetQEGeom(); 00181 output->AddEdgeWithSecurePointList( QEGeom->GetOrigin(), 00182 QEGeom->GetDestination() ); 00183 ++c_it; 00184 } 00185 00186 // Copy cells 00187 c_it = temp->GetCells()->Begin(); 00188 c_end = temp->GetCells()->End(); 00189 InputPolygonCellType *pe; 00190 00191 while ( c_it != c_end ) 00192 { 00193 pe = dynamic_cast< InputPolygonCellType * >( c_it.Value() ); 00194 if ( pe ) 00195 { 00196 InputPointIdList points; 00197 00198 for ( InputPointsIdInternalIterator pit = pe->InternalPointIdsBegin(); 00199 pit != pe->InternalPointIdsEnd(); ++pit ) 00200 { 00201 points.push_back( ( *pit ) ); 00202 } 00203 output->AddFaceWithSecurePointList(points); 00204 } 00205 ++c_it; 00206 } 00207 } 00208 00209 void CleanPoints() 00210 { 00211 OutputMeshPointer output = this->GetOutput(); 00212 00213 OutputPointsContainerIterator p_it = output->GetPoints()->Begin(); 00214 OutputPointsContainerIterator p_end = output->GetPoints()->End(); 00215 OutputPointIdentifier id(0); 00216 00217 while ( p_it != p_end ) 00218 { 00219 id = p_it->Index(); 00220 if ( output->FindEdge(id) == 0 ) 00221 { 00222 output->DeletePoint(id); 00223 } 00224 ++p_it; 00225 } 00226 00227 output->SqueezePointsIds(); 00228 } 00229 00230 void PrintSelf(std::ostream & os, Indent indent) const 00231 { 00232 Superclass::PrintSelf(os, indent); 00233 os << indent << "AbsoluteTolerance2: " << m_AbsoluteTolerance2 << std::endl; 00234 os << indent << "AbsoluteTolerance: " << m_AbsoluteTolerance << std::endl; 00235 os << indent << "RelativeTolerance: " << m_RelativeTolerance << std::endl; 00236 } 00237 00238 private: 00239 CleanQuadEdgeMeshFilter(const Self &); 00240 void operator=(const Self &); 00241 }; 00242 } 00243 #endif 00244