ITK  4.2.0
Insight Segmentation and Registration Toolkit
itkCleanQuadEdgeMeshFilter.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef __itkCleanQuadEdgeMeshFilter_h
19 #define __itkCleanQuadEdgeMeshFilter_h
20 
21 #include "itkIntTypes.h"
23 #include "itkBoundingBox.h"
24 
27 
28 namespace itk
29 {
35 template< class TInput, class TOutput=TInput >
36 class ITK_EXPORT CleanQuadEdgeMeshFilter:
37  public QuadEdgeMeshToQuadEdgeMeshFilter< TInput, TOutput >
38 {
39 public:
44 
47 
49  itkNewMacro(Self);
50 
51  typedef TInput InputMeshType;
52  typedef typename Superclass::InputMeshPointer InputMeshPointer;
53  typedef typename Superclass::InputCoordRepType InputCoordRepType;
54  typedef typename Superclass::InputPointType InputPointType;
55  typedef typename Superclass::InputPointIdentifier InputPointIdentifier;
56  typedef typename Superclass::InputQEPrimal InputQEPrimal;
57  typedef typename Superclass::InputVectorType InputVectorType;
58 
59  typedef typename Superclass::InputEdgeCellType InputEdgeCellType;
60  typedef typename Superclass::InputPolygonCellType InputPolygonCellType;
61  typedef typename Superclass::InputPointIdList InputPointIdList;
62  typedef typename Superclass::InputCellTraits InputCellTraits;
63  typedef typename Superclass::InputPointsIdInternalIterator InputPointsIdInternalIterator;
64  typedef typename Superclass::InputQEIterator InputQEIterator;
65 
66  typedef typename InputMeshType::PointsContainer InputPointsContainer;
67  typedef typename InputMeshType::PointsContainerPointer InputPointsContainerPointer;
68  typedef typename InputMeshType::PointsContainerIterator InputPointsContainerIterator;
69 
70  typedef typename InputMeshType::CellsContainerIterator InputCellsContainerIterator;
71 
72  itkStaticConstMacro(PointDimension, unsigned int, InputMeshType::PointDimension);
73 
74  typedef TOutput OutputMeshType;
75  typedef typename Superclass::OutputMeshPointer OutputMeshPointer;
76  typedef typename Superclass::OutputCoordRepType OutputCoordRepType;
77  typedef typename Superclass::OutputPointType OutputPointType;
78  typedef typename Superclass::OutputPointIdentifier OutputPointIdentifier;
79  typedef typename Superclass::OutputQEPrimal OutputQEPrimal;
80  typedef typename Superclass::OutputVectorType OutputVectorType;
81 
82  typedef typename OutputMeshType::QEType OutputQEType;
83  typedef typename OutputMeshType::PointsContainer OutputPointsContainer;
84  typedef typename OutputMeshType::PointsContainerPointer OutputPointsContainerPointer;
85  typedef typename OutputMeshType::PointsContainerIterator OutputPointsContainerIterator;
86 
87  typedef typename OutputMeshType::CellsContainerIterator OutputCellsContainerIterator;
88 
89  typedef BoundingBox< InputPointIdentifier, itkGetStaticConstMacro(PointDimension),
91 
93 
96 
101 
102  itkSetMacro(AbsoluteTolerance, InputCoordRepType);
103  itkSetMacro(RelativeTolerance, InputCoordRepType);
104 protected:
106  {
107  this->m_AbsoluteTolerance2 = itk::NumericTraits< InputCoordRepType >::Zero;
108  this->m_AbsoluteTolerance = itk::NumericTraits< InputCoordRepType >::Zero;
109  this->m_RelativeTolerance = itk::NumericTraits< InputCoordRepType >::Zero;
110  }
111 
113 
117 
118  void GenerateData()
119  {
121 
122  if ( ( m_AbsoluteTolerance == zeroValue ) && ( m_RelativeTolerance != zeroValue ) )
123  {
124  itkAssertOrThrowMacro( ( m_RelativeTolerance > zeroValue ) && ( m_RelativeTolerance < 1. ),
125  "Relative tolerance out of range" );
126  BoundingBoxPointer bounding_box = BoundingBoxType::New();
127  bounding_box->SetPoints( this->GetInput()->GetPoints() );
128  bounding_box->ComputeBoundingBox();
129 
130  m_AbsoluteTolerance2 = m_RelativeTolerance * m_RelativeTolerance
131  * bounding_box->GetDiagonalLength2();
132  }
133 
134  if ( m_AbsoluteTolerance != zeroValue )
135  {
136  m_AbsoluteTolerance2 = m_AbsoluteTolerance * m_AbsoluteTolerance;
137  }
138 
139  this->MergePoints();
140  this->CleanPoints();
141  }
142 
143  void MergePoints()
144  {
145  OutputMeshPointer output = this->GetOutput();
146 
147  CriterionPointer criterion = CriterionType::New();
148 
149  criterion->SetTopologicalChange(false);
150  criterion->SetMeasureBound(m_AbsoluteTolerance2);
151 
152  DecimationPointer decimate = DecimationType::New();
153  decimate->SetInput( this->GetInput() );
154  decimate->SetCriterion(criterion);
155  decimate->Update();
156 
157  InputMeshPointer temp = decimate->GetOutput();
158 
159  InputPointsContainerIterator p_it = temp->GetPoints()->Begin();
160  InputPointsContainerIterator p_end = temp->GetPoints()->End();
161 
162  OutputPointType pOut;
163 
164  while ( p_it != p_end )
165  {
166  pOut.CastFrom( p_it.Value() );
167  output->SetPoint(p_it.Index(), pOut);
168  ++p_it;
169  }
170 
171  // Copy Edge Cells
172  InputCellsContainerIterator c_it = temp->GetEdgeCells()->Begin();
173  InputCellsContainerIterator c_end = temp->GetEdgeCells()->End();
174  InputEdgeCellType * qe;
175  InputQEPrimal * QEGeom;
176 
177  while ( c_it != c_end )
178  {
179  qe = dynamic_cast< InputEdgeCellType * >( c_it.Value() );
180  QEGeom = qe->GetQEGeom();
181  output->AddEdgeWithSecurePointList( QEGeom->GetOrigin(),
182  QEGeom->GetDestination() );
183  ++c_it;
184  }
185 
186  // Copy cells
187  c_it = temp->GetCells()->Begin();
188  c_end = temp->GetCells()->End();
190 
191  while ( c_it != c_end )
192  {
193  pe = dynamic_cast< InputPolygonCellType * >( c_it.Value() );
194  if ( pe )
195  {
196  InputPointIdList points;
197 
198  for ( InputPointsIdInternalIterator pit = pe->InternalPointIdsBegin();
199  pit != pe->InternalPointIdsEnd(); ++pit )
200  {
201  points.push_back( ( *pit ) );
202  }
203  output->AddFaceWithSecurePointList(points);
204  }
205  ++c_it;
206  }
207  }
208 
209  void CleanPoints()
210  {
211  OutputMeshPointer output = this->GetOutput();
212 
213  OutputPointsContainerIterator p_it = output->GetPoints()->Begin();
214  OutputPointsContainerIterator p_end = output->GetPoints()->End();
215  OutputPointIdentifier id(0);
216 
217  while ( p_it != p_end )
218  {
219  id = p_it->Index();
220  if ( output->FindEdge(id) == 0 )
221  {
222  output->DeletePoint(id);
223  }
224  ++p_it;
225  }
226 
227  output->SqueezePointsIds();
228  }
229 
230  void PrintSelf(std::ostream & os, Indent indent) const
231  {
232  Superclass::PrintSelf(os, indent);
233  os << indent << "AbsoluteTolerance2: " << m_AbsoluteTolerance2 << std::endl;
234  os << indent << "AbsoluteTolerance: " << m_AbsoluteTolerance << std::endl;
235  os << indent << "RelativeTolerance: " << m_RelativeTolerance << std::endl;
236  }
237 
238 private:
239  CleanQuadEdgeMeshFilter(const Self &);
240  void operator=(const Self &);
241 };
242 }
243 #endif
244