/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkQuadEdgeMeshEulerOperatorDeleteCenterVertexFunction_hxx #define itkQuadEdgeMeshEulerOperatorDeleteCenterVertexFunction_hxx namespace itk { template auto QuadEdgeMeshEulerOperatorDeleteCenterVertexFunction::Evaluate(QEType * g) -> OutputType { if (!g) { itkDebugMacro("Input is not an edge."); return ((QEType *)nullptr); } if (!this->m_Mesh) { itkDebugMacro("No mesh present."); return ((QEType *)nullptr); } if (!g->IsInternal()) { itkDebugMacro("The edge is either border or wire."); return ((QEType *)nullptr); } // None of the incident facets of g->GetDestination() is a hole. // one-ring std::vector pList; QEType * g_sym = g->GetSym(); using QEIterator = typename QEType::IteratorGeom; for (QEIterator it = g_sym->BeginGeomOnext(); it != g_sym->EndGeomOnext(); ++it) { QEType * one_edge = it.Value(); if (!one_edge->IsInternal()) { itkDebugMacro("DeleteVertex requires a full one-ring, i.e. no holes."); return ((QEType *)nullptr); } pList.push_back(one_edge->GetDestination()); } // Condition: There are at least two distinct facets incident to the facets // that are incident to g->GetDestination().(This prevents the operation // from collapsing a volume into two facets glued together with opposite // orientations, such as would happen with any vertex of a tetrahedron.) PointIdentifier PointId1, PointId2; PointId1 = pList.back(); pList.pop_back(); PointId2 = pList.back(); pList.pop_back(); FaceRefType FirstFace = this->m_Mesh->FindEdge(PointId1, PointId2)->GetLeft(); bool SecondFaceFound = false; while ((pList.size()) && (!SecondFaceFound)) { PointId1 = PointId2; PointId2 = pList.back(); pList.pop_back(); if (this->m_Mesh->FindEdge(PointId1, PointId2)->GetLeft() != FirstFace) { SecondFaceFound = true; } } if (!SecondFaceFound) { itkDebugMacro("DeleteVertex requires at least two distinct facets incident to the facets that are incident to " "g->GetDestination()."); return ((QEType *)nullptr); } // let's do the job now. QEType * h = g->GetLprev(); QEType * temp; this->m_OldPointID = g->GetDestination(); this->m_Mesh->LightWeightDeleteEdge(g); g = h->GetLnext(); while (g != h) { while ((g->GetDestination() != this->m_OldPointID) && (g != h)) { g = g->GetLnext(); } if (g != h) { temp = g->GetLprev(); this->m_Mesh->LightWeightDeleteEdge(g); g = temp; } } this->m_Mesh->AddFace(h); return (h); } } // end namespace itk #endif