20 #ifndef __itkSimplexMeshAdaptTopologyFilter_txx
21 #define __itkSimplexMeshAdaptTopologyFilter_txx
28 template <
typename TInputMesh,
typename TOutputMesh>
31 m_Output = TOutputMesh::New();
35 m_SelectionMethod = 0;
39 template <
typename TInputMesh,
typename TOutputMesh>
46 template <
typename TInputMesh,
typename TOutputMesh>
51 this->ComputeCellParameters();
52 this->InsertNewCells();
56 template <
typename TInputMesh,
typename TOutputMesh>
63 template <
typename TInputMesh,
typename TOutputMesh>
74 nonConstInput->SetCellsAllocationMethod( TInputMesh::CellsAllocatedDynamicallyCellByCell );
77 simplexVisitor->mesh = nonConstInput;
79 mv->AddVisitor(simplexVisitor);
80 this->GetInput(0)->Accept(mv);
88 double averageCurvature = simplexVisitor->GetTotalMeanCurvature();
90 double rangeCellSize = simplexVisitor->GetMaximumCellSize() - simplexVisitor->GetMinimumCellSize();
91 double rangeCurvature = simplexVisitor->GetMaximumCurvature() - simplexVisitor->GetMinimumCurvature();
93 while ( curvatureIt != curvatures->End())
95 bool doRefinement =
false;
97 const bool conditionA1 = ( m_SelectionMethod == 0 );
98 const bool conditionA2 = ( curvatureIt.
Value() > averageCurvature );
100 const double limit1 = 0.05 * rangeCellSize + simplexVisitor->GetMinimumCellSize();
101 const double limit2 = m_Threshold * rangeCellSize + simplexVisitor->GetMinimumCellSize();
103 const bool conditionA3 = ( areaIt.
Value() > limit1 );
104 const bool conditionA4 = ( areaIt.
Value() > limit2 );
106 if( conditionA1 && ( ( conditionA2 && conditionA3 ) || conditionA4 ) )
112 const bool conditionB1 = ( m_SelectionMethod == 1 );
113 const bool conditionB2 = curvatureIt.
Value() > m_Threshold * rangeCurvature;
114 const bool conditionB3 = areaIt.
Value() > 0.05 * rangeCellSize;
115 const bool conditionB4 = areaIt.
Value() > m_Threshold * rangeCellSize;
117 if( conditionB1 && ( ( conditionB2 && conditionB3 ) || conditionB4 ) )
128 inputMesh->GetCell(curvatureIt.
Index(), poly);
132 typename InputPolygonType::PointIdIterator pointIds = poly->PointIdsBegin();
134 unsigned long lineOneFirstIdx = *pointIds;
136 unsigned long lineOneSecondIdx = *pointIds;
138 unsigned short cnt = 0;
140 while (cnt < poly->GetNumberOfPoints()/2 - 1)
145 unsigned long lineTwoFirstIdx = *pointIds;
147 unsigned long lineTwoSecondIdx = *pointIds;
149 unsigned long newPointId = inputMesh->GetNumberOfPoints();
150 unsigned long firstNewIndex = newPointId;
151 unsigned long secondNewIndex = newPointId+1;
158 inputMesh->GetPoint(lineOneFirstIdx, &p1);
159 inputMesh->GetPoint(lineOneSecondIdx, &p2);
161 helperPoint.SetToMidPoint(p1,p2);
162 newMidPoint.SetToMidPoint( helperPoint, cellCenter );
165 nonConstInput->SetPoint( firstNewIndex , newMidPoint);
168 nonConstInput->ReplaceNeighbor( lineOneFirstIdx, lineOneSecondIdx, firstNewIndex);
169 nonConstInput->ReplaceNeighbor( lineOneSecondIdx, lineOneFirstIdx, firstNewIndex);
173 inputMesh->GetPoint(lineTwoFirstIdx, &p1);
174 inputMesh->GetPoint(lineTwoSecondIdx, &p2);
176 helperPoint.SetToMidPoint(p1,p2);
177 newMidPoint.SetToMidPoint( helperPoint, cellCenter );
179 nonConstInput->SetPoint( secondNewIndex , newMidPoint );
182 nonConstInput->ReplaceNeighbor( lineTwoFirstIdx, lineTwoSecondIdx, secondNewIndex);
183 nonConstInput->ReplaceNeighbor( lineTwoSecondIdx, lineTwoFirstIdx, secondNewIndex);
185 nonConstInput->AddNeighbor(firstNewIndex, secondNewIndex);
186 nonConstInput->AddNeighbor(firstNewIndex, lineOneFirstIdx);
187 nonConstInput->AddNeighbor(firstNewIndex, lineOneSecondIdx);
189 nonConstInput->AddNeighbor(secondNewIndex, lineTwoSecondIdx);
190 nonConstInput->AddNeighbor(secondNewIndex, firstNewIndex);
191 nonConstInput->AddNeighbor(secondNewIndex, lineTwoFirstIdx);
207 nonConstInput->SwapNeighbors( firstNewIndex, lineOneFirstIdx, lineOneSecondIdx);
208 firstNewNormal = inputMesh->ComputeNormal(firstNewIndex);
214 nonConstInput->SwapNeighbors( secondNewIndex, lineTwoFirstIdx, lineTwoSecondIdx);
215 secondNewNormal = inputMesh->ComputeNormal(secondNewIndex);
218 nonConstInput->AddEdge( firstNewIndex, secondNewIndex );
221 unsigned long newPointIndex = 0;
223 m_NewSimplexCellPointer.TakeOwnership( polygon );
226 unsigned long firstPointId = *pointIds++;
228 while (*pointIds != lineTwoSecondIdx )
230 m_NewSimplexCellPointer->SetPointId( newPointIndex++, *pointIds++ );
233 m_NewSimplexCellPointer->SetPointId( newPointIndex++, secondNewIndex );
234 m_NewSimplexCellPointer->SetPointId( newPointIndex++, firstNewIndex );
235 nonConstInput->ReplaceFace( curvatureIt.
Index(), m_NewSimplexCellPointer );
238 m_NewSimplexCellPointer.TakeOwnership( polygon2 );
241 while ( pointIds != poly->PointIdsEnd() )
243 m_NewSimplexCellPointer->
SetPointId( newPointIndex++, *pointIds++ );
245 m_NewSimplexCellPointer->SetPointId( newPointIndex++, firstPointId );
246 m_NewSimplexCellPointer->SetPointId( newPointIndex++, firstNewIndex );
247 m_NewSimplexCellPointer->SetPointId( newPointIndex++, secondNewIndex );
248 nonConstInput->AddFace( m_NewSimplexCellPointer );
250 nonConstInput->BuildCellLinks();
252 this->ModifyNeighborCells(lineOneFirstIdx, lineOneSecondIdx, firstNewIndex);
253 this->ModifyNeighborCells(lineTwoFirstIdx, lineTwoSecondIdx, secondNewIndex);
255 if( inputMesh->GetCellsAllocationMethod() == TInputMesh::CellsAllocatedDynamicallyCellByCell )
257 delete poly.GetPointer();
267 template <
typename TInputMesh,
typename TOutputMesh>
271 typename TOutputMesh::Pointer output = TOutputMesh::New();
272 this->CopyInputMeshToOutputMeshPoints();
273 this->CopyInputMeshToOutputMeshPointData();
274 this->CopyInputMeshToOutputMeshCellData();
275 this->CopyInputMeshToOutputMeshCells();
276 output->SetGeometryData(this->GetInput(0)->GetGeometryData());
277 output->SetLastCellId( this->GetInput(0)->GetLastCellId() );
281 template <
typename TInputMesh,
typename TOutputMesh>
286 std::set<unsigned long> cells1 = this->GetInput(0)->GetCellLinks()->GetElement(id1);
287 std::set<unsigned long> cells2 = this->GetInput(0)->GetCellLinks()->GetElement(id2);
288 std::set<unsigned long>::iterator cellIt = cells1.begin();
290 std::set<unsigned long> result;
298 while (cellIt != cells1.end() )
300 std::set<unsigned long>::iterator found = std::find(cells2.begin(), cells2.end(), *cellIt);
301 if ( found != cells2.end() )
303 result.insert(*cellIt);
308 cellIt = result.begin();
310 while ( cellIt != result.end() )
313 this->GetInput(0)->GetCell(*cellIt, nextCell );
315 if ( nextCell->GetNumberOfPoints() == 2 )
318 unsigned long first= *lineIt++;
319 unsigned long second= *lineIt;
321 nonConstInput->AddEdge( first, insertPointId );
322 nonConstInput->AddEdge( insertPointId, second );
323 nonConstInput->GetCells()->DeleteIndex( *cellIt );
325 else if ( nextCell->GetNumberOfPoints() > 3 )
329 unsigned long cnt = 0;
330 unsigned long first = *pointIt++;
331 unsigned long startId = first;
333 unsigned long second = 0;
335 while ( pointIt != nextCell->PointIdsEnd() )
337 m_NewSimplexCellPointer->SetPointId( cnt++, first );
340 if ( ( id1 == first && id2 == second ) || ( id2 == first && id1 == second ) )
342 m_NewSimplexCellPointer->SetPointId( cnt++, insertPointId );
348 m_NewSimplexCellPointer->SetPointId( cnt++, second );
349 if ( ( id1 == second && id2 == startId ) || ( id2 == second && id1 == startId ) )
351 m_NewSimplexCellPointer->SetPointId( cnt++, insertPointId );
354 nonConstInput->ReplaceFace( *cellIt, m_NewSimplexCellPointer );
360 this->GetInput(0)->BuildCellLinks();
364 template <
typename TInputMesh,
typename TOutputMesh>
369 Superclass::PrintSelf(os,indent);
370 os << indent <<
"Threshold: " << m_Threshold << std::endl;
371 os << indent <<
"SelectionMethod: " << m_SelectionMethod << std::endl;
372 os << indent <<
"ModifiedCount: " << m_ModifiedCount << std::endl;
377 template <
typename TInputMesh,
typename TOutputMesh>
390 while ( pointIt != simplexCell->PointIdsEnd() )
392 this->GetInput(0)->GetPoint(*pointIt, &p1);
393 cellCenter += p1.GetVectorFromOrigin();
397 tmp.SetVnlVector( cellCenter.GetVnlVector()/simplexCell->GetNumberOfPoints() );
398 cellCenter.Fill(0.0);
407 #endif // __itkSimplexMeshAdaptTopologyFilter_txx