Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-26 09:02:46

0001 // Created on: 2016-06-23
0002 // Copyright (c) 2016 OPEN CASCADE SAS
0003 // Created by: Oleg AGASHIN
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef _BRepMesh_ModelHealer_HeaderFile
0017 #define _BRepMesh_ModelHealer_HeaderFile
0018 
0019 #include <IMeshTools_ModelAlgo.hxx>
0020 #include <IMeshTools_Parameters.hxx>
0021 #include <IMeshData_Model.hxx>
0022 #include <TopoDS_Vertex.hxx>
0023 
0024 //! Class implements functionality of model healer tool.
0025 //! Iterates over model's faces and checks consistency of their wires,
0026 //! i.e.whether wires are closed and do not contain self - intersections.
0027 //! In case if wire contains disconnected parts, ends of adjacent edges
0028 //! forming the gaps are connected in parametric space forcibly. The notion
0029 //! of this operation is to create correct discrete model defined relatively
0030 //! parametric space of target face taking into account connectivity and
0031 //! tolerances of 3D space only. This means that there are no specific
0032 //! computations are made for the sake of determination of U and V tolerance.
0033 //! Registers intersections on edges forming the face's shape and tries to
0034 //! amplify discrete representation by decreasing of deflection for the target edge.
0035 //! Checks can be performed in parallel mode.
0036 class BRepMesh_ModelHealer : public IMeshTools_ModelAlgo
0037 {
0038 public:
0039   //! Constructor.
0040   Standard_EXPORT BRepMesh_ModelHealer();
0041 
0042   //! Destructor.
0043   Standard_EXPORT ~BRepMesh_ModelHealer() override;
0044 
0045   //! Functor API to discretize the given edge.
0046   void operator()(const int theEdgeIndex) const { process(theEdgeIndex); }
0047 
0048   //! Functor API to discretize the given edge.
0049   void operator()(const IMeshData::IFaceHandle& theDFace) const { process(theDFace); }
0050 
0051   DEFINE_STANDARD_RTTIEXT(BRepMesh_ModelHealer, IMeshTools_ModelAlgo)
0052 
0053 protected:
0054   //! Performs processing of edges of the given model.
0055   Standard_EXPORT bool performInternal(const occ::handle<IMeshData_Model>& theModel,
0056                                        const IMeshTools_Parameters&        theParameters,
0057                                        const Message_ProgressRange&        theRange) override;
0058 
0059 private:
0060   //! Checks existing discretization of the face and updates data model.
0061   void process(const int theFaceIndex) const
0062   {
0063     const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
0064     process(aDFace);
0065   }
0066 
0067   //! Checks existing discretization of the face and updates data model.
0068   void process(const IMeshData::IFaceHandle& theDFace) const;
0069 
0070   //! Amplifies discretization of edges in case if self-intersection problem has been found.
0071   void amplifyEdges();
0072 
0073   //! Returns common vertex of two edges or null ptr in case if there is no such vertex.
0074   TopoDS_Vertex getCommonVertex(const IMeshData::IEdgeHandle& theEdge1,
0075                                 const IMeshData::IEdgeHandle& theEdge2) const;
0076 
0077   //! Connects pcurves of previous and current edge on the specified face
0078   //! according to topological connectivity. Uses next edge in order to
0079   //! identify closest point in case of single vertex shared between both
0080   //! ends of edge (degenerative edge)
0081   bool connectClosestPoints(const IMeshData::IPCurveHandle& thePrevDEdge,
0082                             const IMeshData::IPCurveHandle& theCurrDEdge,
0083                             const IMeshData::IPCurveHandle& theNextDEdge) const;
0084 
0085   //! Chooses the most closest point to reference one from the given pair.
0086   //! Returns square distance between reference point and closest one as
0087   //! well as pointer to closest point.
0088   double closestPoint(gp_Pnt2d&  theRefPnt,
0089                       gp_Pnt2d&  theFristPnt,
0090                       gp_Pnt2d&  theSecondPnt,
0091                       gp_Pnt2d*& theClosestPnt) const
0092   {
0093     // Find the most closest end-points.
0094     const double aSqDist1 = theRefPnt.SquareDistance(theFristPnt);
0095     const double aSqDist2 = theRefPnt.SquareDistance(theSecondPnt);
0096     if (aSqDist1 < aSqDist2)
0097     {
0098       theClosestPnt = &theFristPnt;
0099       return aSqDist1;
0100     }
0101 
0102     theClosestPnt = &theSecondPnt;
0103     return aSqDist2;
0104   }
0105 
0106   //! Chooses the most closest points among the given to reference one from the given pair.
0107   //! Returns square distance between reference point and closest one as
0108   //! well as pointer to closest point.
0109   double closestPoints(gp_Pnt2d&  theFirstPnt1,
0110                        gp_Pnt2d&  theSecondPnt1,
0111                        gp_Pnt2d&  theFirstPnt2,
0112                        gp_Pnt2d&  theSecondPnt2,
0113                        gp_Pnt2d*& theClosestPnt1,
0114                        gp_Pnt2d*& theClosestPnt2) const
0115   {
0116     gp_Pnt2d *   aCurrPrevUV1 = nullptr, *aCurrPrevUV2 = nullptr;
0117     const double aSqDist1 = closestPoint(theFirstPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV1);
0118     const double aSqDist2 = closestPoint(theSecondPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV2);
0119     if (aSqDist1 - aSqDist2 < gp::Resolution())
0120     {
0121       theClosestPnt1 = &theFirstPnt1;
0122       theClosestPnt2 = aCurrPrevUV1;
0123       return aSqDist1;
0124     }
0125 
0126     theClosestPnt1 = &theSecondPnt1;
0127     theClosestPnt2 = aCurrPrevUV2;
0128     return aSqDist2;
0129   }
0130 
0131   //! Adjusts the given pair of points supposed to be the same.
0132   //! In addition, adjusts another end-point of an edge in order
0133   //! to perform correct matching in case of gap.
0134   void adjustSamePoints(gp_Pnt2d*& theMajorSamePnt1,
0135                         gp_Pnt2d*& theMinorSamePnt1,
0136                         gp_Pnt2d*& theMajorSamePnt2,
0137                         gp_Pnt2d*& theMinorSamePnt2,
0138                         gp_Pnt2d&  theMajorFirstPnt,
0139                         gp_Pnt2d&  theMajorLastPnt,
0140                         gp_Pnt2d&  theMinorFirstPnt,
0141                         gp_Pnt2d&  theMinorLastPnt) const
0142   {
0143     if (theMajorSamePnt2 == theMajorSamePnt1)
0144     {
0145       theMajorSamePnt2 =
0146         (theMajorSamePnt2 == &theMajorFirstPnt) ? &theMajorLastPnt : &theMajorFirstPnt;
0147       closestPoint(*theMajorSamePnt2, theMinorFirstPnt, theMinorLastPnt, theMinorSamePnt2);
0148     }
0149 
0150     *theMajorSamePnt1 = *theMinorSamePnt1;
0151     *theMajorSamePnt2 = *theMinorSamePnt2;
0152   }
0153 
0154   //! Connects ends of pcurves of face's wires according to topological coherency.
0155   void fixFaceBoundaries(const IMeshData::IFaceHandle& theDFace) const;
0156 
0157   //! Returns True if check can be done in parallel.
0158   bool isParallel() const { return (myParameters.InParallel && myModel->FacesNb() > 1); }
0159 
0160   //! Collects unique edges to be updated from face map. Clears data stored in face map.
0161   bool popEdgesToUpdate(IMeshData::MapOfIEdgePtr& theEdgesToUpdate);
0162 
0163 private:
0164   occ::handle<IMeshData_Model>                     myModel;
0165   IMeshTools_Parameters                            myParameters;
0166   Handle(IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs) myFaceIntersectingEdges;
0167 };
0168 
0169 #endif