Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:03:14

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 
0040   //! Constructor.
0041   Standard_EXPORT BRepMesh_ModelHealer();
0042 
0043   //! Destructor.
0044   Standard_EXPORT virtual ~BRepMesh_ModelHealer();
0045 
0046   //! Functor API to discretize the given edge.
0047   void operator() (const Standard_Integer theEdgeIndex) const {
0048     process(theEdgeIndex);
0049   }
0050 
0051   //! Functor API to discretize the given edge.
0052   void operator() (const IMeshData::IFaceHandle& theDFace) const {
0053     process(theDFace);
0054   }
0055 
0056   DEFINE_STANDARD_RTTIEXT(BRepMesh_ModelHealer, IMeshTools_ModelAlgo)
0057 
0058 protected:
0059 
0060   //! Performs processing of edges of the given model.
0061   Standard_EXPORT virtual Standard_Boolean performInternal (
0062     const Handle(IMeshData_Model)& theModel,
0063     const IMeshTools_Parameters&   theParameters,
0064     const Message_ProgressRange&   theRange) Standard_OVERRIDE;
0065 
0066 private:
0067 
0068   //! Checks existing discretization of the face and updates data model.
0069   void process(const Standard_Integer theFaceIndex) const
0070   {
0071     const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
0072     process(aDFace);
0073   }
0074 
0075   //! Checks existing discretization of the face and updates data model.
0076   void process(const IMeshData::IFaceHandle& theDFace) const;
0077 
0078   //! Amplifies discretization of edges in case if self-intersection problem has been found.
0079   void amplifyEdges();
0080 
0081   //! Returns common vertex of two edges or null ptr in case if there is no such vertex.
0082   TopoDS_Vertex getCommonVertex(
0083     const IMeshData::IEdgeHandle& theEdge1,
0084     const IMeshData::IEdgeHandle& theEdge2) const;
0085 
0086   //! Connects pcurves of previous and current edge on the specified face 
0087   //! according to topological connectivity. Uses next edge in order to
0088   //! identify closest point in case of single vertex shared between both
0089   //! ends of edge (degenerative edge)
0090   Standard_Boolean connectClosestPoints(
0091     const IMeshData::IPCurveHandle& thePrevDEdge,
0092     const IMeshData::IPCurveHandle& theCurrDEdge,
0093     const IMeshData::IPCurveHandle& theNextDEdge) const;
0094 
0095   //! Chooses the most closest point to reference one from the given pair.
0096   //! Returns square distance between reference point and closest one as 
0097   //! well as pointer to closest point.
0098   Standard_Real closestPoint(
0099     gp_Pnt2d&  theRefPnt,
0100     gp_Pnt2d&  theFristPnt,
0101     gp_Pnt2d&  theSecondPnt,
0102     gp_Pnt2d*& theClosestPnt) const
0103   {
0104     // Find the most closest end-points.
0105     const Standard_Real aSqDist1 = theRefPnt.SquareDistance(theFristPnt);
0106     const Standard_Real aSqDist2 = theRefPnt.SquareDistance(theSecondPnt);
0107     if (aSqDist1 < aSqDist2)
0108     {
0109       theClosestPnt = &theFristPnt;
0110       return aSqDist1;
0111     }
0112 
0113     theClosestPnt = &theSecondPnt;
0114     return aSqDist2;
0115   }
0116 
0117   //! Chooses the most closest points among the given to reference one from the given pair.
0118   //! Returns square distance between reference point and closest one as 
0119   //! well as pointer to closest point.
0120   Standard_Real closestPoints(
0121     gp_Pnt2d&  theFirstPnt1,
0122     gp_Pnt2d&  theSecondPnt1,
0123     gp_Pnt2d&  theFirstPnt2,
0124     gp_Pnt2d&  theSecondPnt2,
0125     gp_Pnt2d*& theClosestPnt1,
0126     gp_Pnt2d*& theClosestPnt2) const
0127   {
0128     gp_Pnt2d *aCurrPrevUV1 = NULL, *aCurrPrevUV2 = NULL;
0129     const Standard_Real aSqDist1 = closestPoint(theFirstPnt1,  theFirstPnt2, theSecondPnt2, aCurrPrevUV1);
0130     const Standard_Real aSqDist2 = closestPoint(theSecondPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV2);
0131     if (aSqDist1 - aSqDist2 < gp::Resolution())
0132     {
0133       theClosestPnt1 = &theFirstPnt1;
0134       theClosestPnt2 = aCurrPrevUV1;
0135       return aSqDist1;
0136     }
0137 
0138     theClosestPnt1 = &theSecondPnt1;
0139     theClosestPnt2 = aCurrPrevUV2;
0140     return aSqDist2;
0141   }
0142 
0143   //! Adjusts the given pair of points supposed to be the same.
0144   //! In addition, adjusts another end-point of an edge in order
0145   //! to perform correct matching in case of gap.
0146   void adjustSamePoints(
0147     gp_Pnt2d*& theMajorSamePnt1,
0148     gp_Pnt2d*& theMinorSamePnt1,
0149     gp_Pnt2d*& theMajorSamePnt2,
0150     gp_Pnt2d*& theMinorSamePnt2,
0151     gp_Pnt2d&  theMajorFirstPnt,
0152     gp_Pnt2d&  theMajorLastPnt,
0153     gp_Pnt2d&  theMinorFirstPnt,
0154     gp_Pnt2d&  theMinorLastPnt) const
0155   {
0156     if (theMajorSamePnt2 == theMajorSamePnt1)
0157     {
0158       theMajorSamePnt2 = (theMajorSamePnt2 == &theMajorFirstPnt) ? &theMajorLastPnt : &theMajorFirstPnt;
0159       closestPoint(*theMajorSamePnt2, theMinorFirstPnt, theMinorLastPnt, theMinorSamePnt2);
0160     }
0161 
0162     *theMajorSamePnt1 = *theMinorSamePnt1;
0163     *theMajorSamePnt2 = *theMinorSamePnt2;
0164   }
0165 
0166   //! Connects ends of pcurves of face's wires according to topological coherency.
0167   void fixFaceBoundaries(const IMeshData::IFaceHandle& theDFace) const;
0168 
0169   //! Returns True if check can be done in parallel.
0170   Standard_Boolean isParallel() const
0171   {
0172     return (myParameters.InParallel && myModel->FacesNb() > 1);
0173   }
0174 
0175   //! Collects unique edges to be updated from face map. Clears data stored in face map.
0176   Standard_Boolean popEdgesToUpdate(IMeshData::MapOfIEdgePtr& theEdgesToUpdate);
0177 
0178 private:
0179 
0180   Handle(IMeshData_Model)                           myModel;
0181   IMeshTools_Parameters                             myParameters;
0182   Handle(IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs)  myFaceIntersectingEdges;
0183 };
0184 
0185 #endif