ITK  4.0.0
Insight Segmentation and Registration Toolkit
itkCleanQuadEdgeMeshFilter.h
Go to the documentation of this file.
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