18 #ifndef __itkQuadEdgeMeshEdgeMergeDecimationFilter_txx
19 #define __itkQuadEdgeMeshEdgeMergeDecimationFilter_txx
26 template<
class TInput,
class TOutput,
class TCriterion >
29 m_Relocate( true ), m_CheckOrientation( false )
35 template<
class TInput,
class TOutput,
class TCriterion >
41 while( !m_PriorityQueue->Empty() )
43 edge = m_PriorityQueue->Peek()->m_Element;
44 m_PriorityQueue->Pop();
48 m_QueueMapper.erase( it );
52 template<
class TInput,
class TOutput,
class TCriterion >
58 m_JoinVertexFunction->SetInput( output );
71 PushElement( edge->GetQEGeom( ) );
77 template<
class TInput,
class TOutput,
class TCriterion >
85 OutputQEType* temp = ( id_org < id_dest ) ? iEdge : iEdge->GetSym();
91 m_QueueMapper[ temp ] = qi;
92 m_PriorityQueue->Push( qi );
95 template<
class TInput,
class TOutput,
class TCriterion >
99 IsEdgeOKToBeProcessed( OutputQEType* iEdge )
107 itkDebugMacro(
"iEdge == 0, at iteration: " <<this->m_Iteration );
112 if ( id_org == iEdge->m_NoPoint )
114 itkDebugMacro(
"id_org == iEdge->m_NoPoint, at iteration: "
115 <<this->m_Iteration );
120 if ( output->FindEdge( id_org ) == 0 )
122 itkDebugMacro(
"output->FindEdge( id_org ) == 0, at iteration: "
123 <<this->m_Iteration );
126 if ( iEdge->GetSym() == 0 )
128 itkDebugMacro(
"iEdge->GetSym() == 0, at iteration: "
129 <<this->m_Iteration );
134 if ( id_dest == iEdge->m_NoPoint )
136 itkDebugMacro(
"id_dest == iEdge->m_NoPoint, at iteration: "
137 <<this->m_Iteration );
140 if ( output->FindEdge( id_dest ) == 0 )
142 itkDebugMacro(
"output->FindEdge( id_dest ) == 0, at iteration: "
143 <<this->m_Iteration );
146 if ( output->FindEdge( id_org, id_dest ) == 0 )
148 itkDebugMacro(
"output->FindEdge( id_org, id_dest ) == 0, at iteration: "
149 <<this->m_Iteration );
157 template<
class TInput,
class TOutput,
class TCriterion >
166 m_Element = m_PriorityQueue->Peek( )->m_Element;
167 m_Priority = m_PriorityQueue->Peek( )->m_Priority;
169 m_PriorityQueue->Pop();
172 m_QueueMapper.erase( it );
173 }
while ( !IsEdgeOKToBeProcessed( m_Element ) );
176 template<
class TInput,
class TOutput,
class TCriterion >
183 OutputQEType* temp = ( iEdge->GetOrigin() < iEdge->GetDestination() ) ?
184 iEdge : iEdge->GetSym();
187 if ( map_it != m_QueueMapper.end() )
189 if( !map_it->second->m_Priority.first )
191 m_PriorityQueue->DeleteElement( map_it->second );
192 delete map_it->second;
193 m_QueueMapper.erase( map_it );
199 template<
class TInput,
class TOutput,
class TCriterion >
206 if ( temp->GetOrigin() > temp->GetDestination() )
208 temp = temp->GetSym();
214 if ( map_it != m_QueueMapper.end() )
216 if( !map_it->second->m_Priority.first )
218 map_it->second->m_Priority.second = measure;
219 m_PriorityQueue->Update( map_it->second );
226 m_QueueMapper[ temp ] = qi;
227 m_PriorityQueue->Push( qi );
232 template<
class TInput,
class TOutput,
class TCriterion >
238 status = m_JoinVertexFunction->GetEdgeStatus();
242 case OperatorType::EDGE_NULL:
243 case OperatorType::MESH_NULL:
244 case OperatorType::FACE_ISOLATED:
246 case OperatorType::EDGE_ISOLATED:
247 itkDebugMacro(
"EDGE_ISOLATED, at iteration: " <<this->m_Iteration );
248 TagElementOut( m_Element );
251 case OperatorType::TOO_MANY_COMMON_VERTICES:
252 itkDebugMacro(
"TOO_MANY_COMMON_VERTICES, at iteration "
253 <<this->m_Iteration );
254 itkDebugMacro( <<m_Element->GetOrigin() <<
" -> "
255 <<m_Element->GetDestination() );
256 this->TagElementOut( m_Element );
260 case OperatorType::TETRAHEDRON_CONFIG:
261 itkDebugMacro(
"TETRAHEDRON_CONFIG, at iteration " << this->m_Iteration );
263 this->TagElementOut( m_Element );
264 this->TagElementOut( m_Element->GetOnext() );
265 this->TagElementOut( m_Element->GetOprev() );
266 this->TagElementOut( m_Element->GetSym() );
267 this->TagElementOut( m_Element->GetSym()->GetOnext() );
268 this->TagElementOut( m_Element->GetSym()->GetOprev() );
269 this->TagElementOut( m_Element->GetOnext()->GetLnext() );
273 case OperatorType::SAMOSA_CONFIG:
274 itkDebugMacro(
"SAMOSA_CONFIG, at iteration " << this->m_Iteration );
275 this->RemoveSamosa();
279 case OperatorType::EYE_CONFIG:
280 itkDebugMacro(
"EYE_CONFIG, at iteration " << this->m_Iteration );
283 case OperatorType::EDGE_JOINING_DIFFERENT_BORDERS:
284 itkDebugMacro(
"EDGE_JOINING_DIFFERENT_BORDERS, at iteration " <<
286 this->TagElementOut( m_Element );
291 template<
class TInput,
class TOutput,
class TCriterion >
298 this->GetOutput()->DeletePoint( iIdToBeDeleted );
301 template<
class TInput,
class TOutput,
class TCriterion >
313 bool to_be_processed(
true );
317 pt = Relocate( m_Element );
321 pt = output->GetPoint( idx );
328 if( !to_be_processed )
333 std::list< OutputQEType* > list_qe_to_be_deleted;
336 while( temp != m_Element )
338 list_qe_to_be_deleted.push_back( temp );
339 temp = temp->GetOnext();
342 temp = m_Element->GetSym()->GetOnext();
343 while( temp != m_Element->GetSym() )
345 list_qe_to_be_deleted.push_back( temp );
346 temp = temp->GetOnext();
349 typename std::list< OutputQEType* >::iterator
350 it = list_qe_to_be_deleted.begin();
352 while( it != list_qe_to_be_deleted.end() )
354 DeleteElement( *it );
358 if ( !m_JoinVertexFunction->Evaluate( m_Element ) )
360 it = list_qe_to_be_deleted.begin();
362 while( it != list_qe_to_be_deleted.end() )
364 PushOrUpdateElement( *it );
375 DeletePoint( old_id, new_id );
380 itkDebugMacro(
"edge == 0, at iteration " <<this->m_Iteration );
387 output->SetPoint( new_id, pt );
394 PushOrUpdateElement( temp );
395 temp = temp->GetOnext();
397 while ( temp != edge );
403 template<
class TInput,
class TOutput,
class TCriterion >
411 bool LeftIsTriangle = qe->IsLnextOfTriangle( );
412 bool RightIsTriangle = qe->GetSym( )->IsLnextOfTriangle( );
414 if( LeftIsTriangle || RightIsTriangle )
416 if( LeftIsTriangle && RightIsTriangle )
419 bool OriginOrderIsTwo = ( qe->GetOrder( ) == 2 );
420 bool DestinationOrderIsTwo = ( qe_sym->GetOrder( ) == 2 );
422 if( OriginOrderIsTwo || DestinationOrderIsTwo )
424 if( OriginOrderIsTwo && DestinationOrderIsTwo )
429 itkDebugMacro(
"RemoveSamosa" );
439 itkDebugMacro(
"RemoveEye" );
445 if( NumberOfCommonVerticesIn0Ring( ) > 2 )
448 itkDebugMacro(
"NumberOfCommonVerticesIn0Ring( ) > 2" );
459 if( NumberOfCommonVerticesIn0Ring( ) > 1 )
461 itkDebugMacro(
"NumberOfCommonVerticesIn0Ring( ) > 1" );
466 if( RightIsTriangle )
479 if( NumberOfCommonVerticesIn0Ring( ) > 0 )
492 template<
class TInput,
class TOutput,
class TCriterion >
497 if( m_Priority.first )
502 ProcessWithoutAnyTopologicalGuarantee();
506 template<
class TInput,
class TOutput,
class TCriterion >
514 std::list< OutputPointIdentifier > dir_list, sym_list, intersection_list;
517 dir_list.push_back( e_it->GetDestination() );
518 e_it = e_it->GetOnext();
519 }
while( e_it != qe );
526 sym_list.push_back( e_it->GetDestination() );
527 e_it = e_it->GetOnext();
528 }
while( e_it != qe );
533 std::set_intersection( dir_list.begin(), dir_list.end(),
534 sym_list.begin(), sym_list.end(),
535 std::back_inserter( intersection_list ) );
537 return intersection_list.size();
541 template<
class TInput,
class TOutput,
class TCriterion >
546 DeleteElement( m_Element->GetLnext( ) );
547 DeleteElement( m_Element->GetLprev( ) );
548 DeleteElement( m_Element->GetRnext( ) );
549 DeleteElement( m_Element->GetRprev( ) );
552 template<
class TInput,
class TOutput,
class TCriterion >
559 if( map_it != m_QueueMapper.end() )
561 map_it->second->m_Priority.first =
true;
562 map_it->second->m_Priority.second =
static_cast< MeasureType >( 0. );
563 m_PriorityQueue->Update( map_it->second );
568 PriorityType(
true, static_cast< MeasureType >( 0. ) ) );
570 m_QueueMapper[ iEdge ] = qi;
571 m_PriorityQueue->Push( qi );
575 template<
class TInput,
class TOutput,
class TCriterion >
583 if( qe->GetSym( )->GetOrder( ) == 2 )
589 TagElementOut( qe->GetOnext( ) );
590 TagElementOut( qe->GetSym( )->GetOnext( ) );
591 TagElementOut( qe->GetSym( )->GetOprev( ) );
594 template<
class TInput,
class TOutput,
class TCriterion >
599 if( m_PriorityQueue->Empty() )
605 return this->m_Criterion->is_satisfied( this->GetOutput(), 0, m_Priority.second );