00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __itkQuadEdgeMeshEdgeMergeDecimationFilter_h
00019 #define __itkQuadEdgeMeshEdgeMergeDecimationFilter_h
00020
00021 #include <list>
00022 #include <map>
00023 #include <algorithm>
00024
00025 #include <itkQuadEdgeMeshEulerOperatorJoinVertexFunction.h>
00026 #include <itkQuadEdgeMeshPolygonCell.h>
00027
00028 #include "itkQuadEdgeMeshDecimationFilter.h"
00029 #include "itkPriorityQueueContainer.h"
00030 #include "itkTriangleHelper.h"
00031
00032 namespace itk
00033 {
00038 template< class TInput, class TOutput, class TCriterion >
00039 class QuadEdgeMeshEdgeMergeDecimationFilter :
00040 public QuadEdgeMeshDecimationFilter< TInput, TOutput, TCriterion >
00041 {
00042 public:
00043 typedef QuadEdgeMeshEdgeMergeDecimationFilter Self;
00044 typedef SmartPointer< Self > Pointer;
00045 typedef SmartPointer< const Self > ConstPointer;
00046 typedef QuadEdgeMeshDecimationFilter<
00047 TInput, TOutput, TCriterion > Superclass;
00048
00050 itkTypeMacro( QuadEdgeMeshEdgeMergeDecimationFilter, QuadEdgeMeshDecimationFilter );
00051
00052 typedef TInput InputMeshType;
00053 typedef typename InputMeshType::Pointer InputMeshPointer;
00054
00055 typedef TOutput OutputMeshType;
00056 typedef typename OutputMeshType::Pointer OutputMeshPointer;
00057 typedef typename OutputMeshType::PointIdentifier OutputPointIdentifier;
00058 typedef typename OutputMeshType::PointType OutputPointType;
00059 typedef typename OutputPointType::VectorType OutputVectorType;
00060 typedef typename OutputMeshType::QEType OutputQEType;
00061 typedef typename OutputMeshType::EdgeCellType OutputEdgeCellType;
00062 typedef typename OutputMeshType::CellType OutputCellType;
00063 typedef typename OutputMeshType::CellIdentifier OutputCellIdentifier;
00064 typedef typename OutputMeshType::CellsContainerPointer OutputCellsContainerPointer;
00065 typedef typename OutputMeshType::CellsContainerIterator OutputCellsContainerIterator;
00066
00067 typedef QuadEdgeMeshPolygonCell< OutputCellType > OutputPolygonType;
00068
00069 typedef TCriterion CriterionType;
00070 typedef typename CriterionType::Pointer CriterionPointer;
00071 typedef typename CriterionType::MeasureType MeasureType;
00072 typedef typename CriterionType::PriorityType PriorityType;
00073 typedef typename CriterionType::PriorityQueueWrapperType PriorityQueueItemType;
00074
00075 typedef PriorityQueueContainer< PriorityQueueItemType*,
00076 ElementWrapperPointerInterface< PriorityQueueItemType* >,
00077 PriorityType > PriorityQueueType;
00078 typedef typename PriorityQueueType::Pointer PriorityQueuePointer;
00079
00080 typedef std::map< OutputQEType*, PriorityQueueItemType* > QueueMapType;
00081 typedef typename QueueMapType::iterator QueueMapIterator;
00082
00083 typedef QuadEdgeMeshEulerOperatorJoinVertexFunction<
00084 OutputMeshType, OutputQEType > OperatorType;
00085 typedef typename OperatorType::Pointer OperatorPointer;
00086
00087 protected:
00088
00089 QuadEdgeMeshEdgeMergeDecimationFilter();
00090 virtual ~QuadEdgeMeshEdgeMergeDecimationFilter();
00091
00092 bool m_Verbose;
00093 bool m_Relocate;
00094 bool m_CheckOrientation;
00095
00096 PriorityQueuePointer m_PriorityQueue;
00097 QueueMapType m_QueueMapper;
00098 OutputQEType* m_Element;
00099 PriorityType m_Priority;
00100 OperatorPointer m_JoinVertexFunction;
00101
00107 virtual MeasureType MeasureEdge( OutputQEType* iEdge ) = 0;
00108
00112 void FillPriorityQueue();
00113
00118 void PushElement( OutputQEType* iEdge );
00119
00125 bool IsEdgeOKForPopping( OutputQEType* iEdge );
00126
00130 void Extract();
00131
00136 void DeleteElement( OutputQEType* iEdge );
00137
00138 virtual void DeletePoint( const OutputPointIdentifier& iIdToBeDeleted,
00139 const OutputPointIdentifier& iRemaing );
00140
00146 virtual void PushOrUpdateElement( OutputQEType* iEdge );
00147
00151 virtual void JoinVertexFailed( );
00152
00156 virtual bool ProcessWithoutAnyTopologicalGuarantee();
00157
00162 virtual unsigned int CheckQEProcessingStatus( );
00163
00168 virtual bool ProcessWithTopologicalGuarantee();
00169
00173 size_t NumberOfCommonVerticesIn0Ring( );
00174
00178 void RemoveSamosa();
00179
00184 void TagElementOut( OutputQEType* iEdge );
00185
00189 void RemoveEye();
00190
00196 virtual OutputPointType Relocate( OutputQEType* iEdge ) = 0;
00197
00202 bool CheckOrientation( OutputQEType* iEdge,
00203 const OutputPointIdentifier& iId,
00204 const OutputPointType& iPt )
00205 {
00206 OutputMeshPointer output = this->GetOutput();
00207 OutputCellsContainerPointer cells = output->GetCells();
00209
00210 std::list< OutputCellIdentifier > r1, r2, elements_to_be_tested;
00211 OutputQEType* qe = iEdge;
00212 OutputQEType* qe_it = qe->GetOnext();
00213
00214 do
00215 {
00216 r1.push_back( qe_it->GetLeft() );
00217 qe_it = qe_it->GetOnext();
00218 }while( qe_it != qe );
00219
00220 qe = iEdge->GetSym();
00221 qe_it = qe->GetOnext();
00222
00223 do
00224 {
00225 r2.push_back( qe_it->GetLeft() );
00226 qe_it = qe_it->GetOnext();
00227 }while( qe_it != qe );
00228
00229 r1.sort();
00230 r2.sort();
00231
00232 std::set_symmetric_difference( r1.begin(), r1.end(),
00233 r2.begin(), r2.end(),
00234 std::back_inserter( elements_to_be_tested ) );
00235
00236 typename std::list< OutputCellIdentifier >::iterator
00237 it = elements_to_be_tested.begin();
00238
00239 typedef TriangleHelper< OutputPointType > TriangleType;
00240
00241 bool orientation_ok( true );
00242 OutputCellIdentifier c_id( 0 );
00243 OutputPolygonType* poly;
00244 OutputPointIdentifier p_id;
00245
00246 int k( 0 ), replace_k( 0 );
00247 OutputPointType pt[3];
00248
00249 OutputVectorType n_bef, n_aft;
00250
00251 while( ( it != elements_to_be_tested.end() ) && orientation_ok )
00252 {
00253 c_id = *it;
00254 poly = dynamic_cast< OutputPolygonType* >( cells->GetElement( c_id ) );
00255
00256 qe = poly->GetEdgeRingEntry( );
00257 qe_it = qe;
00258 k = 0;
00259
00260 do
00261 {
00262 p_id = qe_it->GetOrigin( );
00263 if( p_id == iId )
00264 replace_k = k;
00265 pt[k++] = output->GetPoint( p_id );
00266 qe_it = qe_it->GetLnext( );
00267 }while( qe_it != qe );
00268
00269 n_bef = TriangleType::ComputeNormal( pt[0], pt[1], pt[2] );
00270 switch( replace_k )
00271 {
00272 default:
00273 case 0:
00274 n_aft = TriangleType::ComputeNormal( iPt, pt[1], pt[2] );
00275 break;
00276 case 1:
00277 n_aft = TriangleType::ComputeNormal( pt[0], iPt, pt[2] );
00278 break;
00279 case 2:
00280 n_aft = TriangleType::ComputeNormal( pt[0], pt[1], iPt );
00281 break;
00282 }
00283
00284 orientation_ok = ( n_bef * n_aft ) < 0.;
00285 ++it;
00286 }
00287
00288 return orientation_ok;
00289 }
00290
00295 bool IsCriterionSatisfied();
00296
00297 private:
00298 QuadEdgeMeshEdgeMergeDecimationFilter( const Self& );
00299 void operator = ( const Self& );
00300 };
00301 }
00302
00303 #include "itkQuadEdgeMeshEdgeMergeDecimationFilter.txx"
00304 #endif
00305