1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
/*=========================================================================
*
* 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 <typename TMesh, typename TQEType>
auto
QuadEdgeMeshEulerOperatorDeleteCenterVertexFunction<TMesh, TQEType>::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<PointIdentifier> 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
|