// Created by: Peter KURNEV // Copyright (c) 2010-2014 OPEN CASCADE SAS // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef _BOPTools_AlgoTools_HeaderFile #define _BOPTools_AlgoTools_HeaderFile #include "Standard.hxx" #include "Standard_DefineAlloc.hxx" #include "Standard_Handle.hxx" #include "Standard_Boolean.hxx" #include "Standard_Integer.hxx" #include "Standard_Real.hxx" #include "NCollection_List.hxx" #include "BOPTools_CoupleOfShape.hxx" #include "BOPTools_ConnexityBlock.hxx" #include "NCollection_BaseAllocator.hxx" #include "TopAbs_State.hxx" #include "TopAbs_ShapeEnum.hxx" #include "TopoDS_Shape.hxx" #include "TopTools_ShapeMapHasher.hxx" #include "NCollection_IndexedDataMap.hxx" #include "NCollection_IndexedMap.hxx" #include "NCollection_Map.hxx" #include "Precision.hxx" class TopoDS_Vertex; class gp_Pnt; class IntTools_Curve; class TopoDS_Edge; class TopoDS_Face; class TopoDS_Shape; class IntTools_Context; class TopoDS_Solid; class IntTools_Range; class TopoDS_Shell; class Message_Report; //! Provides tools used in Boolean Operations algorithm: //! - Vertices intersection; //! - Vertex construction; //! - Edge construction; //! - Classification algorithms; //! - Making connexity blocks; //! - Shape validation. class BOPTools_AlgoTools { public: DEFINE_STANDARD_ALLOC public: //! @name Constants //! Additional tolerance (delta tolerance) is used in Boolean Operations //! to ensure that the tolerance of new/old entities obtained //! by intersection of two shapes is slightly bigger than the actual //! distances to these shapes. It helps to avoid numerical instability //! which may occur when comparing distances and tolerances. static double DTolerance() { return 1.e-12; } public: //! @name Intersection of the vertices //! Intersects the vertex with the point with tolerance . //! Returns the error status: //! - 0 - no error, meaning that the vertex intersects the point; //! - 1 - the distance between vertex and point is grater than the sum of tolerances. Standard_EXPORT static int ComputeVV(const TopoDS_Vertex& theV, const gp_Pnt& theP, const double theTolP); //! Intersects the given vertices with given fuzzy value. //! Returns the error status: //! - 0 - no error, meaning that the vertices interferes with given tolerance; //! - 1 - the distance between vertices is grater than the sum of their tolerances. Standard_EXPORT static int ComputeVV(const TopoDS_Vertex& theV1, const TopoDS_Vertex& theV2, const double theFuzz = Precision::Confusion()); public: //! @name Vertices construction //! Makes the vertex in the middle of given vertices with //! the tolerance covering all tolerance spheres of vertices. Standard_EXPORT static void MakeVertex(const NCollection_List& theLV, TopoDS_Vertex& theV); //! Make a vertex using 3D-point and 3D-tolerance value Standard_EXPORT static void MakeNewVertex(const gp_Pnt& aP1, const double aTol, TopoDS_Vertex& aNewVertex); //! Make a vertex using couple of vertices Standard_EXPORT static void MakeNewVertex(const TopoDS_Vertex& aV1, const TopoDS_Vertex& aV2, TopoDS_Vertex& aNewVertex); //! Make a vertex in place of intersection between two edges //! with parameters Standard_EXPORT static void MakeNewVertex(const TopoDS_Edge& aE1, const double aP1, const TopoDS_Edge& aE2, const double aP2, TopoDS_Vertex& aNewVertex); //! Make a vertex in place of intersection between the edge //! with parameter and the face Standard_EXPORT static void MakeNewVertex(const TopoDS_Edge& aE1, const double aP1, const TopoDS_Face& aF2, TopoDS_Vertex& aNewVertex); public: //! @name Updating the vertex //! Update the tolerance value for vertex //! taking into account the fact that lays on //! the curve Standard_EXPORT static void UpdateVertex(const IntTools_Curve& aIC, const double aT, const TopoDS_Vertex& aV); //! Update the tolerance value for vertex //! taking into account the fact that lays on //! the edge Standard_EXPORT static void UpdateVertex(const TopoDS_Edge& aE, const double aT, const TopoDS_Vertex& aV); //! Update the tolerance value for vertex //! taking into account the fact that should //! cover tolerance zone of Standard_EXPORT static void UpdateVertex(const TopoDS_Vertex& aVF, const TopoDS_Vertex& aVN); public: //! @name Edge construction //! Makes the edge based on the given curve with given bounding vertices. Standard_EXPORT static void MakeEdge(const IntTools_Curve& theCurve, const TopoDS_Vertex& theV1, const double theT1, const TopoDS_Vertex& theV2, const double theT2, const double theTolR3D, TopoDS_Edge& theE); //! Makes a copy of with vertices. Standard_EXPORT static TopoDS_Edge CopyEdge(const TopoDS_Edge& theEdge); //! Make the edge from base edge and two vertices //! at parameters Standard_EXPORT static void MakeSplitEdge(const TopoDS_Edge& aE1, const TopoDS_Vertex& aV1, const double aP1, const TopoDS_Vertex& aV2, const double aP2, TopoDS_Edge& aNewEdge); //! Make the edge from 3D-Curve and two vertices //! at parameters Standard_EXPORT static void MakeSectEdge(const IntTools_Curve& aIC, const TopoDS_Vertex& aV1, const double aP1, const TopoDS_Vertex& aV2, const double aP2, TopoDS_Edge& aNewEdge); public: //! @name Point/Edge/Face classification relatively solid //! Computes the 3-D state of the point thePoint //! toward solid theSolid. //! theTol - value of precision of computation //! theContext- cached geometrical tools //! Returns 3-D state. Standard_EXPORT static TopAbs_State ComputeState(const gp_Pnt& thePoint, const TopoDS_Solid& theSolid, const double theTol, const occ::handle& theContext); //! Computes the 3-D state of the vertex theVertex //! toward solid theSolid. //! theTol - value of precision of computation //! theContext- cached geometrical tools //! Returns 3-D state. Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Vertex& theVertex, const TopoDS_Solid& theSolid, const double theTol, const occ::handle& theContext); //! Computes the 3-D state of the edge theEdge //! toward solid theSolid. //! theTol - value of precision of computation //! theContext- cached geometrical tools //! Returns 3-D state. Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Edge& theEdge, const TopoDS_Solid& theSolid, const double theTol, const occ::handle& theContext); //! Computes the 3-D state of the face theFace //! toward solid theSolid. //! theTol - value of precision of computation //! theBounds - set of edges of to avoid //! theContext- cached geometrical tools //! Returns 3-D state. Standard_EXPORT static TopAbs_State ComputeState( const TopoDS_Face& theFace, const TopoDS_Solid& theSolid, const double theTol, const NCollection_IndexedMap& theBounds, const occ::handle& theContext); //! Computes the 3-D state of the shape theShape //! toward solid theSolid. //! theTol - value of precision of computation //! theContext- cached geometrical tools //! Returns 3-D state. Standard_EXPORT static TopAbs_State ComputeStateByOnePoint( const TopoDS_Shape& theShape, const TopoDS_Solid& theSolid, const double theTol, const occ::handle& theContext); public: //! @name Face classification relatively solid //! For the face theFace and its edge theEdge //! finds the face suitable to produce shell. //! theLCEF - set of faces to search. All faces //! from theLCEF must share edge theEdge Standard_EXPORT static bool GetFaceOff(const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, NCollection_List& theLCEF, TopoDS_Face& theFaceOff, const occ::handle& theContext); //! Returns True if the face theFace is inside of the //! couple of faces theFace1, theFace2. //! The faces theFace, theFace1, theFace2 must //! share the edge theEdge //! Return values: //! * 0 state is not IN //! * 1 state is IN //! * 2 state can not be found by the method of angles Standard_EXPORT static int IsInternalFace(const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, const TopoDS_Face& theFace1, const TopoDS_Face& theFace2, const occ::handle& theContext); //! Returns True if the face theFace is inside of the //! appropriate couple of faces (from the set theLF). //! The faces of the set theLF and theFace must share //! the edge theEdge //! * 0 state is not IN //! * 1 state is IN //! * 2 state can not be found by the method of angles Standard_EXPORT static int IsInternalFace(const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, NCollection_List& theLF, const occ::handle& theContext); //! Returns True if the face theFace is inside the //! solid theSolid. //! theMEF - Map Edge/Faces for theSolid //! theTol - value of precision of computation //! theContext- cached geometrical tools Standard_EXPORT static bool IsInternalFace( const TopoDS_Face& theFace, const TopoDS_Solid& theSolid, NCollection_IndexedDataMap, TopTools_ShapeMapHasher>& theMEF, const double theTol, const occ::handle& theContext); public: //! @name PCurve construction //! Makes 2d curve of the edge on the faces and . //! - storage for caching the geometrical tools Standard_EXPORT static void MakePCurve( const TopoDS_Edge& theE, const TopoDS_Face& theF1, const TopoDS_Face& theF2, const IntTools_Curve& theCurve, const bool thePC1, const bool thePC2, const occ::handle& theContext = occ::handle()); public: //! @name Wire classification relatively face //! Checks if the wire is a hole for the face. Standard_EXPORT static bool IsHole(const TopoDS_Shape& theW, const TopoDS_Shape& theF); public: //! @name Choosing correct orientation for the split shape //! Checks if the direction of the split shape is opposite to //! the direction of the original shape. //! The method is an overload for (Edge,Edge) and (Face,Face) corresponding //! methods and checks only these types of shapes. //! For faces the method checks if normal directions are opposite. //! For edges the method checks if tangent vectors are opposite. //! //! In case the directions do not coincide, it returns TRUE, meaning //! that split shape has to be reversed to match the direction of the //! original shape. //! //! If requested ( is not null), the method returns the status of the operation: //! - 0 - no error; //! - Error from (Edge,Edge) or (Face,Face) corresponding method //! - 100 - bad types. //! In case of any error the method always returns FALSE. //! //! @param[in] theSplit Split shape //! @param[in] theShape Original shape //! @param[in] theContext cached geometrical tools //! @param[out] theError Error Status of the operation Standard_EXPORT static bool IsSplitToReverse(const TopoDS_Shape& theSplit, const TopoDS_Shape& theShape, const occ::handle& theContext, int* theError = nullptr); //! Add-on for the *IsSplitToReverse()* to check for its errors //! and in case of any add the *BOPAlgo_AlertUnableToOrientTheShape* //! warning to the report. Standard_EXPORT static bool IsSplitToReverseWithWarn( const TopoDS_Shape& theSplit, const TopoDS_Shape& theShape, const occ::handle& theContext, const occ::handle& theReport = nullptr); //! Checks if the normal direction of the split face is opposite to //! the normal direction of the original face. //! The normal directions for both faces are taken in the same point - //! point inside the split face is projected onto the original face. //! Returns TRUE if the normals do not coincide, meaning the necessity //! to revert the orientation of the split face to match the direction //! of the original face. //! //! If requested ( is not null), the method returns the status of the operation: //! - 0 - no error; //! - 1 - unable to find the point inside split face; //! - 2 - unable to compute the normal for the split face; //! - 3 - unable to project the point inside the split face on the original face; //! - 4 - unable to compute the normal for the original face. //! In case of any error the method always returns FALSE. //! //! @param[in] theSplit Split face //! @param[in] theShape Original face //! @param[in] theContext cached geometrical tools //! @param[out] theError Error Status of the operation Standard_EXPORT static bool IsSplitToReverse(const TopoDS_Face& theSplit, const TopoDS_Face& theShape, const occ::handle& theContext, int* theError = nullptr); //! Checks if the tangent vector of the split edge is opposite to //! the tangent vector of the original edge. //! The tangent vectors for both edges are computed in the same point - //! point inside the split edge is projected onto the original edge. //! Returns TRUE if the tangent vectors do not coincide, meaning the necessity //! to revert the orientation of the split edge to match the direction //! of the original edge. //! //! If requested ( is not null), the method returns the status of the operation: //! - 0 - no error; //! - 1 - degenerated edges are given; //! - 2 - unable to compute the tangent vector for the split edge; //! - 3 - unable to project the point inside the split edge on the original edge; //! - 4 - unable to compute the tangent vector for the original edge; //! In case of any error the method always returns FALSE. //! //! @param[in] theSplit Split edge //! @param[in] theShape Original edge //! @param[in] theContext cached geometrical tools //! @param[out] theError Error Status of the operation Standard_EXPORT static bool IsSplitToReverse(const TopoDS_Edge& theSplit, const TopoDS_Edge& theShape, const occ::handle& theContext, int* theError = nullptr); //! Checks if the normals direction of the given faces computed near //! the shared edge coincide. //! Returns the status of operation: //! * 0 - in case of error (shared edge not found or directions are not collinear) //! * 1 - normal directions coincide; //! * -1 - normal directions are opposite. Standard_EXPORT static int Sense(const TopoDS_Face& theF1, const TopoDS_Face& theF2, const occ::handle& theContext); public: //! @name Making connexity blocks //! For the list of faces theLS build block //! theLSCB in terms of connexity by edges //! theMapAvoid - set of edges to avoid for //! the treatment Standard_EXPORT static void MakeConnexityBlock( NCollection_List& theLS, NCollection_IndexedMap& theMapAvoid, NCollection_List& theLSCB, const occ::handle& theAllocator); //! For the compound builds the blocks (compounds) of //! elements of type connected through the shapes //! of the type . //! The blocks are stored into the list . Standard_EXPORT static void MakeConnexityBlocks(const TopoDS_Shape& theS, const TopAbs_ShapeEnum theConnectionType, const TopAbs_ShapeEnum theElementType, NCollection_List& theLCB); //! For the compound builds the blocks (compounds) of //! elements of type connected through the shapes //! of the type . //! The blocks are stored into the list of lists . //! Returns also the connection map , filled during operation. Standard_EXPORT static void MakeConnexityBlocks( const TopoDS_Shape& theS, const TopAbs_ShapeEnum theConnectionType, const TopAbs_ShapeEnum theElementType, NCollection_List>& theLCB, NCollection_IndexedDataMap, TopTools_ShapeMapHasher>& theConnectionMap); //! Makes connexity blocks of elements of the given type with the given type of the //! connecting elements. The blocks are checked on regularity (multi-connectivity) //! and stored to the list of blocks . Standard_EXPORT static void MakeConnexityBlocks( const NCollection_List& theLS, const TopAbs_ShapeEnum theConnectionType, const TopAbs_ShapeEnum theElementType, NCollection_List& theLCB); public: //! @name Orienting elements in container //! Correctly orients edges on the wire Standard_EXPORT static void OrientEdgesOnWire(TopoDS_Shape& theWire); //! Correctly orients faces on the shell Standard_EXPORT static void OrientFacesOnShell(TopoDS_Shape& theShell); public: //! @name Methods for shape validation (correction) //! Provides valid values of tolerances for the shape //! is max value of the tolerance that can be //! accepted for correction. If real value of the tolerance //! will be greater than , the correction does not //! perform. Standard_EXPORT static void CorrectTolerances( const TopoDS_Shape& theS, const NCollection_IndexedMap& theMapToAvoid, const double theTolMax = 0.0001, const bool theRunParallel = false); //! Provides valid values of tolerances for the shape //! in terms of BRepCheck_InvalidCurveOnSurface. Standard_EXPORT static void CorrectCurveOnSurface( const TopoDS_Shape& theS, const NCollection_IndexedMap& theMapToAvoid, const double theTolMax = 0.0001, const bool theRunParallel = false); //! Provides valid values of tolerances for the shape //! in terms of BRepCheck_InvalidPointOnCurve. Standard_EXPORT static void CorrectPointOnCurve( const TopoDS_Shape& theS, const NCollection_IndexedMap& theMapToAvoid, const double theTolMax = 0.0001, const bool theRunParallel = false); //! Corrects tolerance values of the sub-shapes of the shape if needed. Standard_EXPORT static void CorrectShapeTolerances( const TopoDS_Shape& theS, const NCollection_IndexedMap& theMapToAvoid, const bool theRunParallel = false); public: //! Checking if the faces are coinciding //! Checks if the given faces are same-domain, i.e. coincide. Standard_EXPORT static bool AreFacesSameDomain(const TopoDS_Face& theF1, const TopoDS_Face& theF2, const occ::handle& theContext, const double theFuzz = Precision::Confusion()); public: //! @name Looking for the edge in the face //! Returns True if the face theFace contains //! the edge theEdge but with opposite orientation. //! If the method returns True theEdgeOff is the //! edge founded Standard_EXPORT static bool GetEdgeOff(const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, TopoDS_Edge& theEdgeOff); //! For the face theFace gets the edge theEdgeOnF //! that is the same as theEdge //! Returns True if such edge exists //! Returns False if there is no such edge Standard_EXPORT static bool GetEdgeOnFace(const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, TopoDS_Edge& theEdgeOnF); public: //! @name Correction of the edges range //! Correct shrunk range taking into account 3D-curve //! resolution and corresponding tolerance values of , Standard_EXPORT static void CorrectRange(const TopoDS_Edge& aE1, const TopoDS_Edge& aE2, const IntTools_Range& aSR, IntTools_Range& aNewSR); //! Correct shrunk range taking into account 3D-curve //! resolution and corresponding tolerance values of , Standard_EXPORT static void CorrectRange(const TopoDS_Edge& aE, const TopoDS_Face& aF, const IntTools_Range& aSR, IntTools_Range& aNewSR); public: //! @name Checking edge on micro status //! Checks if it is possible to compute shrunk range for the edge //! Flag defines whether to take into account //! the possibility to split the edge or not. Standard_EXPORT static bool IsMicroEdge(const TopoDS_Edge& theEdge, const occ::handle& theContext, const bool theCheckSplittable = true); public: //! @name Solid classification //! Returns true if the solid is inverted Standard_EXPORT static bool IsInvertedSolid(const TopoDS_Solid& theSolid); public: //! @name Edge/Face Deviation computation //! Computes the necessary value of the tolerance for the edge Standard_EXPORT static bool ComputeTolerance(const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, double& theMaxDist, double& theMaxPar); public: //! @name Other methods //! Makes empty container of requested type Standard_EXPORT static void MakeContainer(const TopAbs_ShapeEnum theType, TopoDS_Shape& theShape); //! Compute a 3D-point on the edge at parameter Standard_EXPORT static void PointOnEdge(const TopoDS_Edge& aEdge, const double aPrm, gp_Pnt& aP); //! Returns TRUE if PaveBlock lays on the face , i.e //! the is IN or ON in 2D of Standard_EXPORT static bool IsBlockInOnFace(const IntTools_Range& aShR, const TopoDS_Face& aF, const TopoDS_Edge& aE, const occ::handle& aContext); //! Returns the min and max dimensions of the shape . Standard_EXPORT static void Dimensions(const TopoDS_Shape& theS, int& theDMin, int& theDMax); //! Returns dimension of the shape . //! If the shape contains elements of different dimension, -1 is returned. Standard_EXPORT static int Dimension(const TopoDS_Shape& theS); //! Collects in the output list recursively all non-compound sub-shapes of the first level //! of the given shape theS. The optional map theMap is used to avoid the duplicates in the //! output list, so it will also contain all non-compound sub-shapes. Standard_EXPORT static void TreatCompound( const TopoDS_Shape& theS, NCollection_List& theList, NCollection_Map* theMap = nullptr); //! Returns true if the shell is open Standard_EXPORT static bool IsOpenShell(const TopoDS_Shell& theShell); }; #endif // _BOPTools_AlgoTools_HeaderFile