// 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 _BOPAlgo_PaveFiller_HeaderFile #define _BOPAlgo_PaveFiller_HeaderFile #include "Standard.hxx" #include "Standard_DefineAlloc.hxx" #include "Standard_Handle.hxx" #include "BOPAlgo_Algo.hxx" #include "BOPAlgo_GlueEnum.hxx" #include "BOPAlgo_SectionAttribute.hxx" #include "NCollection_DataMap.hxx" #include "BOPDS_PaveBlock.hxx" #include "NCollection_IndexedDataMap.hxx" #include "Standard_Integer.hxx" #include "NCollection_List.hxx" #include "BOPDS_CoupleOfPaveBlocks.hxx" #include "TopTools_ShapeMapHasher.hxx" #include "NCollection_IndexedMap.hxx" #include "NCollection_Map.hxx" #include "BOPDS_Pair.hxx" #include "BOPDS_PDS.hxx" #include "BOPDS_PIterator.hxx" #include "NCollection_DynamicArray.hxx" #include "BOPDS_Curve.hxx" #include "BOPTools_BoxTree.hxx" #include "IntSurf_PntOn2S.hxx" #include "IntTools_ShrunkRange.hxx" #include "NCollection_BaseAllocator.hxx" #include "Standard_Real.hxx" #include "TopAbs_ShapeEnum.hxx" #include "TopoDS_Shape.hxx" #include class IntTools_Context; class BOPDS_PaveBlock; class gp_Pnt; class BOPDS_Curve; class TopoDS_Vertex; class TopoDS_Edge; class TopoDS_Face; //! //! The class represents the Intersection phase of the //! Boolean Operations algorithm. //! It performs the pairwise intersection of the sub-shapes of //! the arguments in the following order: //! 1. Vertex/Vertex; //! 2. Vertex/Edge; //! 3. Edge/Edge; //! 4. Vertex/Face; //! 5. Edge/Face; //! 6. Face/Face. //! //! The results of intersection are stored into the Data Structure //! of the algorithm. //! //! Additionally to the options provided by the parent class, //! the algorithm has the following options: //! - *Section attributes* - allows to customize the intersection of the faces //! (avoid approximation or building 2d curves); //! - *Safe processing mode* - allows to avoid modification of the input //! shapes during the operation (by default it is off); //! - *Gluing options* - allows to speed up the calculation on the special //! cases, in which some sub-shapes are coincide. //! //! The algorithm returns the following Warning statuses: //! - *BOPAlgo_AlertSelfInterferingShape* - in case some of the argument shapes are self-interfering //! shapes; //! - *BOPAlgo_AlertTooSmallEdge* - in case some edges of the input shapes have no valid range; //! - *BOPAlgo_AlertNotSplittableEdge* - in case some edges of the input shapes has such a small //! valid range so it cannot be split; //! - *BOPAlgo_AlertBadPositioning* - in case the positioning of the input shapes leads to creation //! of small edges; //! - *BOPAlgo_AlertIntersectionOfPairOfShapesFailed* - in case intersection of some of the //! sub-shapes has failed; //! - *BOPAlgo_AlertAcquiredSelfIntersection* - in case some sub-shapes of the argument become //! connected //! through other shapes; //! - *BOPAlgo_AlertBuildingPCurveFailed* - in case building 2D curve for some of the edges //! on the faces has failed. //! //! The algorithm returns the following Error alerts: //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to //! perform the operation; //! - *BOPAlgo_AlertIntersectionFailed* - in case some unexpected error occurred; //! - *BOPAlgo_AlertNullInputShapes* - in case some of the arguments are null shapes. //! class BOPAlgo_PaveFiller : public BOPAlgo_Algo { public: DEFINE_STANDARD_ALLOC Standard_EXPORT BOPAlgo_PaveFiller(); Standard_EXPORT ~BOPAlgo_PaveFiller() override; Standard_EXPORT BOPAlgo_PaveFiller(const occ::handle& theAllocator); Standard_EXPORT const BOPDS_DS& DS(); Standard_EXPORT BOPDS_PDS PDS(); Standard_EXPORT const BOPDS_PIterator& Iterator(); //! Sets the arguments for operation void SetArguments(const NCollection_List& theLS) { myArguments = theLS; } //! Sets the arguments for operation (move semantics) void SetArguments(NCollection_List&& theLS) { myArguments = std::move(theLS); } //! Adds the argument for operation void AddArgument(const TopoDS_Shape& theShape) { myArguments.Append(theShape); } //! Returns the list of arguments const NCollection_List& Arguments() const { return myArguments; } Standard_EXPORT const occ::handle& Context(); Standard_EXPORT void SetSectionAttribute(const BOPAlgo_SectionAttribute& theSecAttr); //! Sets the flag that defines the mode of treatment. //! In non-destructive mode the argument shapes are not modified. Instead //! a copy of a sub-shape is created in the result if it is needed to be updated. Standard_EXPORT void SetNonDestructive(const bool theFlag); //! Returns the flag that defines the mode of treatment. //! In non-destructive mode the argument shapes are not modified. Instead //! a copy of a sub-shape is created in the result if it is needed to be updated. Standard_EXPORT bool NonDestructive() const; Standard_EXPORT void Perform( const Message_ProgressRange& theRange = Message_ProgressRange()) override; //! Sets the glue option for the algorithm Standard_EXPORT void SetGlue(const BOPAlgo_GlueEnum theGlue); //! Returns the glue option of the algorithm Standard_EXPORT BOPAlgo_GlueEnum Glue() const; //! Sets the flag to avoid building of p-curves of edges on faces void SetAvoidBuildPCurve(const bool theValue) { myAvoidBuildPCurve = theValue; } //! Returns the flag to avoid building of p-curves of edges on faces bool IsAvoidBuildPCurve() const { return myAvoidBuildPCurve; } protected: typedef NCollection_DataMap, Bnd_Box> BOPAlgo_DataMapOfPaveBlockBndBox; typedef NCollection_DataMap, NCollection_List> BOPAlgo_DataMapOfPaveBlockListOfInteger; typedef NCollection_DataMap>> BOPAlgo_DataMapOfIntegerMapOfPaveBlock; //! Sets non-destructive mode automatically if an argument //! contains a locked sub-shape (see TopoDS_Shape::Locked()). Standard_EXPORT void SetNonDestructive(); Standard_EXPORT void SetIsPrimary(const bool theFlag); Standard_EXPORT bool IsPrimary() const; Standard_EXPORT virtual void PerformInternal(const Message_ProgressRange& theRange); Standard_EXPORT void Clear() override; Standard_EXPORT virtual void Init(const Message_ProgressRange& theRange); Standard_EXPORT void Prepare(const Message_ProgressRange& theRange); Standard_EXPORT virtual void PerformVV(const Message_ProgressRange& theRange); Standard_EXPORT virtual void PerformVE(const Message_ProgressRange& theRange); //! Performs the intersection of the vertices with edges. Standard_EXPORT void IntersectVE( const NCollection_IndexedDataMap, NCollection_List>& theVEPairs, const Message_ProgressRange& theRange, const bool bAddInterfs = true); //! Splits the Pave Blocks of the given edges with the extra paves. //! The method also builds the shrunk data for the new pave blocks and //! in case there is no valid range on the pave block, the vertices of //! this pave block will be united making SD vertex. //! Parameter defines whether this interference will be added //! into common table of interferences or not. //! If some of the Pave Blocks are forming the Common Blocks, the splits //! of the Pave Blocks will also form a Common Block. Standard_EXPORT void SplitPaveBlocks(const NCollection_Map& theMEdges, const bool theAddInterfs); Standard_EXPORT virtual void PerformVF(const Message_ProgressRange& theRange); Standard_EXPORT virtual void PerformEE(const Message_ProgressRange& theRange); Standard_EXPORT virtual void PerformEF(const Message_ProgressRange& theRange); Standard_EXPORT virtual void PerformFF(const Message_ProgressRange& theRange); Standard_EXPORT void TreatVerticesEE(); Standard_EXPORT void MakeSDVerticesFF( const NCollection_DataMap>& aDMVLV, NCollection_DataMap& theDMNewSD); Standard_EXPORT void MakeSplitEdges(const Message_ProgressRange& theRange); Standard_EXPORT void MakeBlocks(const Message_ProgressRange& theRange); Standard_EXPORT void MakePCurves(const Message_ProgressRange& theRange); Standard_EXPORT int MakeSDVertices(const NCollection_List& theVertIndices, const bool theAddInterfs = true); Standard_EXPORT void ProcessDE(const Message_ProgressRange& theRange); Standard_EXPORT void FillShrunkData(occ::handle& thePB); Standard_EXPORT void FillShrunkData(const TopAbs_ShapeEnum theType1, const TopAbs_ShapeEnum theType2); //! Analyzes the results of computation of the valid range for the //! pave block and in case of error adds the warning status, otherwise //! saves the valid range in the pave block. Standard_EXPORT void AnalyzeShrunkData(const occ::handle& thePB, const IntTools_ShrunkRange& theSR); //! Performs intersection of new vertices, obtained in E/E and E/F intersections Standard_EXPORT void PerformNewVertices( NCollection_IndexedDataMap& theMVCPB, const occ::handle& theAllocator, const Message_ProgressRange& theRange, const bool theIsEEIntersection = true); Standard_EXPORT bool CheckFacePaves(const TopoDS_Vertex& theVnew, const NCollection_Map& theMIF); Standard_EXPORT static bool CheckFacePaves(const int theN, const NCollection_Map& theMIFOn, const NCollection_Map& theMIFIn); Standard_EXPORT bool IsExistingVertex(const gp_Pnt& theP, const double theTol, const NCollection_Map& theMVOn) const; //! Checks and puts paves from on the curve . //! At that, common (from theMVCommon) and not common vertices //! are processed differently. Standard_EXPORT void PutPavesOnCurve(const NCollection_Map& theMVOnIn, const NCollection_Map& theMVCommon, BOPDS_Curve& theNC, const NCollection_Map& theMI, const NCollection_Map& theMVEF, NCollection_DataMap& theMVTol, NCollection_DataMap>& theDMVLV); Standard_EXPORT void FilterPavesOnCurves(const NCollection_DynamicArray& theVNC, NCollection_DataMap& theMVTol); //! Depending on the parameter aType it checks whether //! the vertex nV was created in EE or EF intersections. //! If so, it increases aTolVExt from tolerance value of vertex to //! the max distance from vertex nV to the ends of the range of common part. //! Possible values of aType: //! 1 - checks only EE; //! 2 - checks only EF; //! other - checks both types of intersections. Standard_EXPORT bool ExtendedTolerance(const int nV, const NCollection_Map& aMI, double& aTolVExt, const int aType = 0); Standard_EXPORT void PutBoundPaveOnCurve(const TopoDS_Face& theF1, const TopoDS_Face& theF2, BOPDS_Curve& theNC, NCollection_List& theLBV); //! Checks if the given pave block (created on section curve) //! coincides with any of the pave blocks of the faces //! created the section curve. Standard_EXPORT bool IsExistingPaveBlock( const occ::handle& thePB, const BOPDS_Curve& theNC, const double theTolR3D, const NCollection_IndexedMap>& theMPB, BOPTools_BoxTree& thePBTree, const NCollection_Map>& theMPBCommon, occ::handle& thePBOut, double& theTolNew); //! Checks if the given pave block (created on section curve) //! coincides with any of the edges shared between the faces //! created the section curve. Standard_EXPORT bool IsExistingPaveBlock(const occ::handle& thePB, const BOPDS_Curve& theNC, const NCollection_List& theLSE, int& theNEOut, double& theTolNew); //! Treatment of section edges. Standard_EXPORT void PostTreatFF( NCollection_IndexedDataMap& theMSCPB, NCollection_DataMap, NCollection_List>>& theDMExEdges, NCollection_DataMap& theDMNewSD, const NCollection_IndexedMap>& theMicroPB, const NCollection_IndexedMap& theVertsOnRejectedPB, const occ::handle& theAllocator, const Message_ProgressRange& theRange); Standard_EXPORT void FindPaveBlocks(const int theV, const int theF, NCollection_List>& theLPB); Standard_EXPORT void FillPaves(const int theV, const int theE, const int theF, const NCollection_List>& theLPB, const occ::handle& thePB); Standard_EXPORT void MakeSplitEdge(const int theV, const int theF); Standard_EXPORT void GetEFPnts(const int nF1, const int nF2, NCollection_List& aListOfPnts); //! Checks and puts paves created in EF intersections on the curve . Standard_EXPORT void PutEFPavesOnCurve(const NCollection_DynamicArray& theVC, const int theIndex, const NCollection_Map& theMI, const NCollection_Map& theMVEF, NCollection_DataMap& theMVTol, NCollection_DataMap>& aDMVLV); //! Puts stick paves on the curve Standard_EXPORT void PutStickPavesOnCurve( const TopoDS_Face& aF1, const TopoDS_Face& aF2, const NCollection_Map& theMI, const NCollection_DynamicArray& theVC, const int theIndex, const NCollection_Map& theMVStick, NCollection_DataMap& theMVTol, NCollection_DataMap>& aDMVLV); //! Collects indices of vertices created in all intersections between //! two faces ( and ) to the map . //! Also, it collects indices of EF vertices to the map //! and indices of all subshapes of these two faces to the map. Standard_EXPORT void GetStickVertices(const int nF1, const int nF2, NCollection_Map& theMVStick, NCollection_Map& theMVEF, NCollection_Map& theMI); //! Collects index nF and indices of all subshapes of the shape with index //! to the map . Standard_EXPORT void GetFullShapeMap(const int nF, NCollection_Map& theMI); //! Removes indices of vertices that are already on the //! curve from the map . //! It is used in PutEFPavesOnCurve and PutStickPavesOnCurve methods. Standard_EXPORT void RemoveUsedVertices(const NCollection_DynamicArray& theVC, NCollection_Map& theMV); //! Puts the pave nV on the curve theNC. //! Parameter aType defines whether to check the pave with //! extended tolerance: //! 0 - do not perform the check; //! other - perform the check (aType goes to ExtendedTolerance). Standard_EXPORT void PutPaveOnCurve(const int nV, const double theTolR3D, const BOPDS_Curve& theNC, const NCollection_Map& theMI, NCollection_DataMap& theMVTol, NCollection_DataMap>& aDMVLV, const int aType = 0); //! Adds the existing edges for intersection with section edges //! by checking the possible intersection with the faces comparing //! pre-saved E-F distances with new tolerances. Standard_EXPORT void ProcessExistingPaveBlocks( const int theInt, const int theCur, const int nF1, const int nF2, const TopoDS_Edge& theES, const NCollection_IndexedMap>& theMPBOnIn, BOPTools_BoxTree& thePBTree, NCollection_IndexedDataMap& theMSCPB, NCollection_DataMap& theMVI, NCollection_List>& theLPBC, BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap, NCollection_Map>& theMPB); //! Adds the existing edges from the map which interfere //! with the vertices from map to the post treatment of section edges. Standard_EXPORT void ProcessExistingPaveBlocks( const int theInt, const int nF1, const int nF2, const NCollection_IndexedMap>& theMPBOnIn, BOPTools_BoxTree& thePBTree, const NCollection_DataMap>& theDMBV, NCollection_IndexedDataMap& theMSCPB, NCollection_DataMap& theMVI, BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap, NCollection_Map>& theMPB); //! Replaces existing pave block with new pave blocks . //! The list contains images of which were created in //! the post treatment of section edges. //! Tries to project the new edges on the faces contained in the . Standard_EXPORT void UpdateExistingPaveBlocks( const occ::handle& thePB, NCollection_List>& theLPB, const BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap); //! Treatment of vertices that were created in EE intersections. Standard_EXPORT void TreatNewVertices( const NCollection_IndexedDataMap& theMVCPB, NCollection_IndexedDataMap, TopTools_ShapeMapHasher>& theImages); //! Put paves on the curve in case when //! is closed 3D-curve Standard_EXPORT void PutClosingPaveOnCurve(BOPDS_Curve& aNC); //! Keeps data for post treatment Standard_EXPORT void PreparePostTreatFF( const int aInt, const int aCur, const occ::handle& aPB, NCollection_IndexedDataMap& aMSCPB, NCollection_DataMap& aMVI, NCollection_List>& aLPB); //! Updates the information about faces Standard_EXPORT void UpdateFaceInfo( NCollection_DataMap, NCollection_List>>& theDME, const NCollection_DataMap& theDMV, const BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap); //! Updates tolerance of vertex with index //! to make it interfere with edge. //! Returns TRUE if intersection happened. Standard_EXPORT bool ForceInterfVE(const int nV, occ::handle& aPB, NCollection_Map& theMEdges); //! Updates tolerance of vertex with index //! to make it interfere with face with index Standard_EXPORT bool ForceInterfVF(const int nV, const int nF); //! Checks if there are any common or intersecting sub shapes //! between two planar faces. Standard_EXPORT bool CheckPlanes(const int nF1, const int nF2) const; //! Creates new edge from the edge nE with vertices nV1 and nV2 //! and returns the index of that new edge in the DS. Standard_EXPORT int SplitEdge(const int nE, const int nV1, const double aT1, const int nV2, const double aT2); //! Updates pave blocks which have the paves with indices contained //! in the map . Standard_EXPORT void UpdatePaveBlocks(const NCollection_DataMap& aDMNewSD); //! Updates tolerance vertex nV due to V/E interference. //! It always creates new vertex if nV is from arguments. //! @return DS index of updated vertex. Standard_EXPORT int UpdateVertex(const int nV, const double aTolNew); Standard_EXPORT void UpdatePaveBlocksWithSDVertices(); Standard_EXPORT void UpdateCommonBlocksWithSDVertices(); Standard_EXPORT void UpdateBlocksWithSharedVertices(); Standard_EXPORT void UpdateInterfsWithSDVertices(); Standard_EXPORT bool EstimatePaveOnCurve(const int nV, const BOPDS_Curve& theNC, const double theTolR3D); Standard_EXPORT void UpdateEdgeTolerance(const int nE, const double aTolNew); Standard_EXPORT void RemovePaveBlocks(const NCollection_Map& theEdges); Standard_EXPORT void CorrectToleranceOfSE(); //! Reduce the intersection range using the common ranges of //! Edge/Edge interferences to avoid creation of close //! intersection vertices Standard_EXPORT void ReduceIntersectionRange(const int theV1, const int theV2, const int theE, const int theF, double& theTS1, double& theTS2); //! Gets the bounding box for the given Pave Block. //! If Pave Block has shrunk data it will be used to get the box, //! and the Shrunk Range (, ). //! Otherwise the box will be computed using BndLib_Add3dCurve method, //! and the Shrunk Range will be equal to the PB's range. //! To avoid re-computation of the bounding box for the same Pave Block //! it will be saved in the map . //! Returns FALSE in case the PB's range is less than the //! Precision::PConfusion(), otherwise returns TRUE. Standard_EXPORT bool GetPBBox(const TopoDS_Edge& theE, const occ::handle& thePB, BOPAlgo_DataMapOfPaveBlockBndBox& thePBBox, double& theFirst, double& theLast, double& theSFirst, double& theSLast, Bnd_Box& theBox); //! Treatment of the possible common zones, not detected by the //! Face/Face intersection algorithm, by intersection of each section edge //! with all faces not participated in creation of that section edge. //! If the intersection says that the section edge is lying on the face //! it will be added into FaceInfo structure of the face as IN edge //! and will be used for splitting. Standard_EXPORT void PutSEInOtherFaces(const Message_ProgressRange& theRange); //! Analyzes the results of interferences of sub-shapes of the shapes //! looking for self-interfering entities by the following rules: //! 1. The Faces of the same shape considered interfering in case they: //! - Interfere with the other shapes in the same place (in the same vertex) or; //! - Included in the same common block. //! 2. The Faces of the same shape considered interfering in case they //! share the IN or SECTION edges. //! In case self-interference is found the warning is added. Standard_EXPORT void CheckSelfInterference(); //! Adds the warning about failed intersection of pair of sub-shapes Standard_EXPORT void AddIntersectionFailedWarning(const TopoDS_Shape& theS1, const TopoDS_Shape& theS2); //! Repeat intersection of sub-shapes with increased vertices. Standard_EXPORT void RepeatIntersection(const Message_ProgressRange& theRange); //! Updates vertices of CommonBlocks with real tolerance of CB. Standard_EXPORT void UpdateVerticesOfCB(); //! The method looks for the additional common blocks among pairs of edges //! with the same bounding vertices. Standard_EXPORT void ForceInterfEE(const Message_ProgressRange& theRange); //! The method looks for the additional edge/face common blocks //! among pairs of edge/face having the same vertices. Standard_EXPORT void ForceInterfEF(const Message_ProgressRange& theRange); //! Performs intersection of given pave blocks //! with all faces from arguments. Standard_EXPORT void ForceInterfEF( const NCollection_IndexedMap>& theMPB, const Message_ProgressRange& theRange, const bool theAddInterf); //! When all section edges are created and no increase of the tolerance //! of vertices put on the section edges is expected, make sure that //! the created sections have valid range. //! If any of the section edges do not have valid range, remove them //! from Face/Face intersection info and from the input map. //! Put such edges into map for further unification of their //! vertices in the PostTreatFF method. //! //! All these section edges have already been checked to have valid range. //! Current check is necessary for the edges whose vertices have also //! been put on other section edges with greater tolerance, which has caused //! increase of the tolerance value of the vertices. Standard_EXPORT void RemoveMicroSectionEdges( NCollection_IndexedDataMap& theMSCPB, NCollection_IndexedMap>& theMicroPB); //! Check all edges on the micro status and remove the positive ones Standard_EXPORT void RemoveMicroEdges(); //! Auxiliary structure to hold the edge distance to the face struct EdgeRangeDistance { double First; double Last; double Distance; EdgeRangeDistance(const double theFirst = 0.0, const double theLast = 0.0, const double theDistance = RealLast()) : First(theFirst), Last(theLast), Distance(theDistance) { } }; protected: //! Analyzing Progress steps //! Filling steps for constant operations Standard_EXPORT void fillPIConstants(const double theWhole, BOPAlgo_PISteps& theSteps) const override; //! Filling steps for all other operations Standard_EXPORT void fillPISteps(BOPAlgo_PISteps& theSteps) const override; protected: //! Fields NCollection_List myArguments; BOPDS_PDS myDS; BOPDS_PIterator myIterator; occ::handle myContext; BOPAlgo_SectionAttribute mySectionAttribute; bool myNonDestructive; bool myIsPrimary; bool myAvoidBuildPCurve; BOPAlgo_GlueEnum myGlue; // clang-format off BOPAlgo_DataMapOfIntegerMapOfPaveBlock myFPBDone; //!< Fence map of intersected faces and pave blocks NCollection_Map myIncreasedSS; //!< Sub-shapes with increased tolerance during the operation NCollection_Map myVertsToAvoidExtension; //!< Vertices located close to E/E or E/F intersection points //! which has already been extended to cover the real intersection //! points, and should not be extended any longer to be put //! on a section curve. NCollection_DataMap > myDistances; //!< Map to store minimal distances between shapes //! which have no real intersections // clang-format on }; #endif // _BOPAlgo_PaveFiller_HeaderFile