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_Relocate;
00093 bool m_CheckOrientation;
00094
00095 PriorityQueuePointer m_PriorityQueue;
00096 QueueMapType m_QueueMapper;
00097 OutputQEType* m_Element;
00098 PriorityType m_Priority;
00099 OperatorPointer m_JoinVertexFunction;
00100
00106 virtual MeasureType MeasureEdge( OutputQEType* iEdge ) = 0;
00107
00111 void FillPriorityQueue();
00112
00117 void PushElement( OutputQEType* iEdge );
00118
00124 bool IsEdgeOKToBeProcessed( OutputQEType* iEdge );
00125
00129 void Extract();
00130
00135 void DeleteElement( OutputQEType* iEdge );
00136
00137 virtual void DeletePoint( const OutputPointIdentifier& iIdToBeDeleted,
00138 const OutputPointIdentifier& iRemaing );
00139
00145 virtual void PushOrUpdateElement( OutputQEType* iEdge );
00146
00150 virtual void JoinVertexFailed( );
00151
00155 virtual bool ProcessWithoutAnyTopologicalGuarantee();
00156
00161 virtual unsigned int CheckQEProcessingStatus( );
00162
00167 virtual bool ProcessWithTopologicalGuarantee();
00168
00172 size_t NumberOfCommonVerticesIn0Ring( );
00173
00177 void RemoveSamosa();
00178
00183 void TagElementOut( OutputQEType* iEdge );
00184
00188 void RemoveEye();
00189
00195 virtual OutputPointType Relocate( OutputQEType* iEdge ) = 0;
00196
00201 bool CheckOrientation( OutputQEType* iEdge,
00202 const OutputPointIdentifier& iId,
00203 const OutputPointType& iPt )
00204 {
00205 OutputMeshPointer output = this->GetOutput();
00206 OutputCellsContainerPointer cells = output->GetCells();
00208
00209 std::list< OutputCellIdentifier > r1, r2, elements_to_be_tested;
00210 OutputQEType* qe = iEdge;
00211 OutputQEType* qe_it = qe->GetOnext();
00212
00213 do
00214 {
00215 r1.push_back( qe_it->GetLeft() );
00216 qe_it = qe_it->GetOnext();
00217 }while( qe_it != qe );
00218
00219 qe = iEdge->GetSym();
00220 qe_it = qe->GetOnext();
00221
00222 do
00223 {
00224 r2.push_back( qe_it->GetLeft() );
00225 qe_it = qe_it->GetOnext();
00226 }while( qe_it != qe );
00227
00228 r1.sort();
00229 r2.sort();
00230
00231 std::set_symmetric_difference( r1.begin(), r1.end(),
00232 r2.begin(), r2.end(),
00233 std::back_inserter( elements_to_be_tested ) );
00234
00235 typename std::list< OutputCellIdentifier >::iterator
00236 it = elements_to_be_tested.begin();
00237
00238 typedef TriangleHelper< OutputPointType > TriangleType;
00239
00240 bool orientation_ok( true );
00241 OutputCellIdentifier c_id( 0 );
00242 OutputPolygonType* poly;
00243 OutputPointIdentifier p_id;
00244
00245 int k( 0 ), replace_k( 0 );
00246 OutputPointType pt[3];
00247
00248 OutputVectorType n_bef, n_aft;
00249
00250 while( ( it != elements_to_be_tested.end() ) && orientation_ok )
00251 {
00252 c_id = *it;
00253 poly = dynamic_cast< OutputPolygonType* >( cells->GetElement( c_id ) );
00254
00255 qe = poly->GetEdgeRingEntry( );
00256 qe_it = qe;
00257 k = 0;
00258
00259 do
00260 {
00261 p_id = qe_it->GetOrigin( );
00262 if( p_id == iId )
00263 replace_k = k;
00264 pt[k++] = output->GetPoint( p_id );
00265 qe_it = qe_it->GetLnext( );
00266 }while( qe_it != qe );
00267
00268 n_bef = TriangleType::ComputeNormal( pt[0], pt[1], pt[2] );
00269 switch( replace_k )
00270 {
00271 default:
00272 case 0:
00273 n_aft = TriangleType::ComputeNormal( iPt, pt[1], pt[2] );
00274 break;
00275 case 1:
00276 n_aft = TriangleType::ComputeNormal( pt[0], iPt, pt[2] );
00277 break;
00278 case 2:
00279 n_aft = TriangleType::ComputeNormal( pt[0], pt[1], iPt );
00280 break;
00281 }
00282
00283 orientation_ok = ( n_bef * n_aft ) < 0.;
00284 ++it;
00285 }
00286
00287 return orientation_ok;
00288 }
00289
00294 bool IsCriterionSatisfied();
00295
00296 private:
00297 QuadEdgeMeshEdgeMergeDecimationFilter( const Self& );
00298 void operator = ( const Self& );
00299 };
00300 }
00301
00302 #include "itkQuadEdgeMeshEdgeMergeDecimationFilter.txx"
00303 #endif
00304