/*========================================================================= * * 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 itkQuadEdgeMeshEulerOperatorJoinVertexFunction_h #define itkQuadEdgeMeshEulerOperatorJoinVertexFunction_h #include "itkQuadEdgeMeshFunctionBase.h" #include namespace itk { /** * \class QuadEdgeMeshEulerOperatorJoinVertexFunction * * \brief Collapse a given edge by joining its dest and its org. * * Collapse the argument edge e of Evaluate * by joining the two vertices incident to e (i.e. its endpoints). * The destination vertex of e is set aside (i.e. disconnected from its * edge entry and no edge has this vertex as endpoint). Note that the * vertex itself is not removed from the container (and hence there is no * loss of geometrical information). On success JoinVertex returns the Id * of the disconnected vertex (i.e. the destination of e) and it is up to * the caller to "take care" of it. * * Precondition: the edge should be adjacent at least to an other edge * (i.e. not be isolated at both endpoints). * * \warning JoinVertex.Evaluate( h) and JoinVertex.Evaluate( h->GetSym() ) * are topologically identical. But their differ in their geometrical * result, since JoinVertex removes the destination vertex of the * incoming argument. A simple way to visualize this difference is to * imagine a mesh constituted of squares laid out on a regular grid * and for each such square an added diagonal. No imagine what happens * when one operates JoinVertex on a diagonal edge of a corner square * (and how it differs with feeding JoinVertex with the opposite edge). * * \ingroup QEMeshModifierFunctions * \ingroup ITKQuadEdgeMesh */ template class ITK_TEMPLATE_EXPORT QuadEdgeMeshEulerOperatorJoinVertexFunction : public QuadEdgeMeshFunctionBase { public: ITK_DISALLOW_COPY_AND_MOVE(QuadEdgeMeshEulerOperatorJoinVertexFunction); /** Standard class type aliases. */ using Self = QuadEdgeMeshEulerOperatorJoinVertexFunction; using Pointer = SmartPointer; using ConstPointer = SmartPointer; using Superclass = QuadEdgeMeshFunctionBase; itkNewMacro(Self); /** \see LightObject::GetNameOfClass() */ itkOverrideGetNameOfClassMacro(QuadEdgeMeshEulerOperatorJoinVertexFunction); /** Type of QuadEdge with which to apply slicing. */ using QEType = TQEType; using typename Superclass::MeshType; using typename Superclass::OutputType; using PointIdentifier = typename MeshType::PointIdentifier; using CellIdentifier = typename MeshType::CellIdentifier; using FaceRefType = typename MeshType::FaceRefType; /** Evaluate at the specified input position */ virtual OutputType Evaluate(QEType * e); enum EdgeStatusType { STANDARD_CONFIG = 0, EDGE_NULL, // 1 MESH_NULL, // 2 EDGE_ISOLATED, // 3 TOO_MANY_COMMON_VERTICES, // 4 TETRAHEDRON_CONFIG, // 5 QUADEDGE_ISOLATED, // 6 FACE_ISOLATED, // 7 SAMOSA_CONFIG, // 8 EYE_CONFIG, // 9 EDGE_JOINING_DIFFERENT_BORDERS // 10 }; itkGetConstMacro(OldPointID, PointIdentifier); itkGetConstMacro(EdgeStatus, EdgeStatusType); protected: QuadEdgeMeshEulerOperatorJoinVertexFunction(); ~QuadEdgeMeshEulerOperatorJoinVertexFunction() override = default; void PrintSelf(std::ostream & os, Indent indent) const override; PointIdentifier m_OldPointID{}; EdgeStatusType m_EdgeStatus{}; /** * \brief * \param[in] e * \return The number of common vertices in the 0-ring of e->GetOrigin() and * e->GetDestination() */ PointIdentifier CommonVertexNeighboor(QEType * e); /** * \brief * \param[in] e * \return true if it is a tetrahedron * \return false else */ bool IsTetrahedron(QEType * e); /** * \brief * \param[in] e * \param[in] iWasLeftFace * \param[out] oToBeDeleted * \return true if the face is isolated * \return false else */ bool IsFaceIsolated(QEType * e, const bool iWasLeftFace, std::stack & oToBeDeleted); bool IsSamosa(QEType * e); bool IsEye(QEType * e); bool IsEdgeLinkingTwoDifferentBorders(QEType * e); EdgeStatusType CheckStatus(QEType * e, std::stack & oToBeDeleted); QEType * Process(QEType * e); QEType * ProcessIsolatedQuadEdge(QEType * e); QEType * ProcessIsolatedFace(QEType * e, std::stack & EdgesToBeDeleted); }; } // end namespace itk #include "itkQuadEdgeMeshEulerOperatorJoinVertexFunction.hxx" #endif