diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md
index 24dfcf10fb..1909ee2191 100644
--- a/dox/dev_guides/upgrade/upgrade.md
+++ b/dox/dev_guides/upgrade/upgrade.md
@@ -1501,3 +1501,4 @@ The following obsolete features have been removed:
- *IntTools_IndexedDataMapOfTransientAddress* is removed as unused;
* The container *BiTgte_DataMapOfShapeBox* is replaced with *TopTools_DataMapOfShapeBox*;
* The class *BOPTools* has been removed as duplicate of the class *TopExp*;
+* The method *BOPAlgo_Builder::Splits()* has been removed as excessive. The method *BOPAlgo_Builder::Images()* can be used instead.
\ No newline at end of file
diff --git a/src/BOPAlgo/BOPAlgo_BOP.cxx b/src/BOPAlgo/BOPAlgo_BOP.cxx
index 0207408dc8..c1e8804295 100644
--- a/src/BOPAlgo/BOPAlgo_BOP.cxx
+++ b/src/BOPAlgo/BOPAlgo_BOP.cxx
@@ -995,38 +995,17 @@ void BOPAlgo_BOP::BuildSolid()
}
//
TopTools_IndexedDataMapOfShapeListOfShape aMEF;
- // Split faces will be added in the end
- // to avoid errors in BuilderSolid algorithm
- TopTools_ListOfShape aLF, aLFx;
+ // Fill the list of faces to build the result solids
+ TopTools_ListOfShape aSFS;
aNb = aMFS.Extent();
for (i = 1; i <= aNb; ++i) {
const TopTools_ListOfShape& aLSx = aMFS(i);
if (aLSx.Extent() == 1) {
const TopoDS_Shape& aFx = aMFS.FindKey(i);
TopExp::MapShapesAndAncestors(aFx, TopAbs_EDGE, TopAbs_FACE, aMEF);
- if (IsBoundSplits(aFx, aMEF)){
- aLFx.Append(aFx);
- continue;
- }
- aLF.Append(aFx);
+ aSFS.Append(aFx);
}
}
- //
- // Faces to build result solids
- TopTools_ListOfShape aSFS;
- aItLS.Initialize(aLF);
- for(; aItLS.More(); aItLS.Next()) {
- const TopoDS_Shape& aFx = aItLS.Value();
- aSFS.Append(aFx);
- }
- //
- // Split faces
- aItLS.Initialize(aLFx);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Shape& aFx = aItLS.Value();
- aSFS.Append(aFx);
- }
- //
// Internal faces
aNb = aMFI.Extent();
for (i = 1; i <= aNb; ++i) {
@@ -1158,54 +1137,6 @@ void BOPAlgo_BOP::BuildSolid()
myShape = aResult;
}
//=======================================================================
-//function : IsBoundSplits
-//purpose :
-//=======================================================================
-Standard_Boolean BOPAlgo_BOP::IsBoundSplits
- (const TopoDS_Shape& aS,
- TopTools_IndexedDataMapOfShapeListOfShape& aMEF)
-{
- Standard_Boolean bRet = Standard_False;
- if (mySplits.IsBound(aS) || myOrigins.IsBound(aS)) {
- return !bRet;
- }
-
- TopTools_ListIteratorOfListOfShape aIt;
- Standard_Integer aNbLS;
- TopAbs_Orientation anOr;
- //
- //check face aF may be connected to face from mySplits
- TopExp_Explorer aExp(aS, TopAbs_EDGE);
- for (; aExp.More(); aExp.Next()) {
- const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
- //
- anOr = aE.Orientation();
- if (anOr==TopAbs_INTERNAL) {
- continue;
- }
- //
- if (BRep_Tool::Degenerated(aE)) {
- continue;
- }
- //
- const TopTools_ListOfShape& aLS=aMEF.FindFromKey(aE);
- aNbLS = aLS.Extent();
- if (!aNbLS) {
- continue;
- }
- //
- aIt.Initialize(aLS);
- for (; aIt.More(); aIt.Next()) {
- const TopoDS_Shape& aSx = aIt.Value();
- if (mySplits.IsBound(aSx) || myOrigins.IsBound(aS)) {
- return !bRet;
- }
- }
- }
- //
- return bRet;
-}
-//=======================================================================
//function : TypeToExplore
//purpose :
//=======================================================================
diff --git a/src/BOPAlgo/BOPAlgo_BOP.hxx b/src/BOPAlgo/BOPAlgo_BOP.hxx
index bab184bfec..8f18135c09 100644
--- a/src/BOPAlgo/BOPAlgo_BOP.hxx
+++ b/src/BOPAlgo/BOPAlgo_BOP.hxx
@@ -102,8 +102,6 @@ protected:
Standard_EXPORT void BuildSolid();
- Standard_EXPORT Standard_Boolean IsBoundSplits (const TopoDS_Shape& theS, TopTools_IndexedDataMapOfShapeListOfShape& theMEF);
-
//! Treatment of the cases with empty shapes.
//! It returns TRUE if there is nothing to do, i.e.
//! all shapes in one of the groups are empty shapes.
diff --git a/src/BOPAlgo/BOPAlgo_Builder.cxx b/src/BOPAlgo/BOPAlgo_Builder.cxx
index f0fa58cc79..da6483598d 100644
--- a/src/BOPAlgo/BOPAlgo_Builder.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder.cxx
@@ -49,10 +49,10 @@ BOPAlgo_Builder::BOPAlgo_Builder()
myEntryPoint(0),
myImages(100, myAllocator),
myShapesSD(100, myAllocator),
- mySplits(100, myAllocator),
myOrigins(100, myAllocator),
myNonDestructive(Standard_False),
- myGlue(BOPAlgo_GlueOff)
+ myGlue(BOPAlgo_GlueOff),
+ myCheckInverted(Standard_True)
{
}
//=======================================================================
@@ -70,10 +70,10 @@ BOPAlgo_Builder::BOPAlgo_Builder
myEntryPoint(0),
myImages(100, myAllocator),
myShapesSD(100, myAllocator),
- mySplits(100, myAllocator),
myOrigins(100, myAllocator),
myNonDestructive(Standard_False),
- myGlue(BOPAlgo_GlueOff)
+ myGlue(BOPAlgo_GlueOff),
+ myCheckInverted(Standard_True)
{
}
//=======================================================================
@@ -100,7 +100,6 @@ void BOPAlgo_Builder::Clear()
myMapFence.Clear();
myImages.Clear();
myShapesSD.Clear();
- mySplits.Clear();
myOrigins.Clear();
}
//=======================================================================
@@ -130,95 +129,6 @@ void BOPAlgo_Builder::SetArguments(const TopTools_ListOfShape& theShapes)
}
}
//=======================================================================
-//function : Arguments
-//purpose :
-//=======================================================================
-const TopTools_ListOfShape& BOPAlgo_Builder::Arguments()const
-{
- return myArguments;
-}
-//=======================================================================
-//function : Images
-//purpose :
-//=======================================================================
-const TopTools_DataMapOfShapeListOfShape& BOPAlgo_Builder::Images()const
-{
- return myImages;
-}
-//=======================================================================
-//function : Origins
-//purpose :
-//=======================================================================
-const TopTools_DataMapOfShapeListOfShape& BOPAlgo_Builder::Origins()const
-{
- return myOrigins;
-}
-
-//=======================================================================
-//function : ShapesSd
-//purpose :
-//=======================================================================
-const TopTools_DataMapOfShapeShape& BOPAlgo_Builder::ShapesSD()const
-{
- return myShapesSD;
-}
-//=======================================================================
-//function : Splits
-//purpose :
-//=======================================================================
-const TopTools_DataMapOfShapeListOfShape& BOPAlgo_Builder::Splits()const
-{
- return mySplits;
-}
-//=======================================================================
-//function : PPaveFiller
-//purpose :
-//=======================================================================
-BOPAlgo_PPaveFiller BOPAlgo_Builder::PPaveFiller()
-{
- return myPaveFiller;
-}
-//=======================================================================
-//function : PDS
-//purpose :
-//=======================================================================
-BOPDS_PDS BOPAlgo_Builder::PDS()
-{
- return myDS;
-}
-//=======================================================================
-//function : SetNonDestructive
-//purpose :
-//=======================================================================
-void BOPAlgo_Builder::SetNonDestructive(const Standard_Boolean theFlag)
-{
- myNonDestructive = theFlag;
-}
-//=======================================================================
-//function : NonDestructive
-//purpose :
-//=======================================================================
-Standard_Boolean BOPAlgo_Builder::NonDestructive() const
-{
- return myNonDestructive;
-}
-//=======================================================================
-//function : SetGlue
-//purpose :
-//=======================================================================
-void BOPAlgo_Builder::SetGlue(const BOPAlgo_GlueEnum theGlue)
-{
- myGlue=theGlue;
-}
-//=======================================================================
-//function : Glue
-//purpose :
-//=======================================================================
-BOPAlgo_GlueEnum BOPAlgo_Builder::Glue() const
-{
- return myGlue;
-}
-//=======================================================================
// function: CheckData
// purpose:
//=======================================================================
diff --git a/src/BOPAlgo/BOPAlgo_Builder.hxx b/src/BOPAlgo/BOPAlgo_Builder.hxx
index 62e8f679a5..3ccbad05a7 100644
--- a/src/BOPAlgo/BOPAlgo_Builder.hxx
+++ b/src/BOPAlgo/BOPAlgo_Builder.hxx
@@ -53,6 +53,10 @@ class BOPAlgo_PaveFiller;
//! shapes during the operation (by default it is off);
//! - *Gluing options* - allows to speed up the calculation of the intersections
//! on the special cases, in which some sub-shapes are coinciding.
+//! - *Disabling the check for inverted solids* - Disables/Enables the check of the input solids
+//! for inverted status (holes in the space). The default value is TRUE,
+//! i.e. the check is performed. Setting this flag to FALSE for inverted solids,
+//! most likely will lead to incorrect results.
//!
//! The algorithm returns the following Error statuses:
//! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;
@@ -66,139 +70,282 @@ public:
DEFINE_STANDARD_ALLOC
-
+ //! Empty constructor.
Standard_EXPORT BOPAlgo_Builder();
-Standard_EXPORT virtual ~BOPAlgo_Builder();
-
- Standard_EXPORT BOPAlgo_Builder(const Handle(NCollection_BaseAllocator)& theAllocator);
-
- Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
-
- Standard_EXPORT BOPAlgo_PPaveFiller PPaveFiller();
-
- Standard_EXPORT BOPDS_PDS PDS();
-
- Standard_EXPORT virtual void AddArgument (const TopoDS_Shape& theShape);
-
- Standard_EXPORT virtual void SetArguments (const TopTools_ListOfShape& theLS);
-
- Standard_EXPORT const TopTools_ListOfShape& Arguments() const;
+ Standard_EXPORT virtual ~BOPAlgo_Builder();
+
+ Standard_EXPORT BOPAlgo_Builder(const Handle(NCollection_BaseAllocator)& theAllocator);
+
+ //! Clears the content of the algorithm.
+ Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+
+ //! Returns the PaveFiller, algorithm for sub-shapes intersection.
+ BOPAlgo_PPaveFiller PPaveFiller()
+ {
+ return myPaveFiller;
+ }
+
+ //! Returns the Data Structure, holder of intersection information.
+ BOPDS_PDS PDS()
+ {
+ return myDS;
+ }
+
+ //! Returns the Context, tool for cashing heavy algorithms.
+ Handle(IntTools_Context) Context() const
+ {
+ return myContext;
+ }
+
+
+public: //! @name Arguments
+
+ //! Adds the argument to the operation.
+ Standard_EXPORT virtual void AddArgument (const TopoDS_Shape& theShape);
+
+ //! Sets the list of arguments for the operation.
+ Standard_EXPORT virtual void SetArguments (const TopTools_ListOfShape& theLS);
+
+ //! Returns the list of arguments.
+ const TopTools_ListOfShape& Arguments() const
+ {
+ return myArguments;
+ }
+
+public: //! @name Options
- Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
-
- Standard_EXPORT virtual void PerformWithFiller (const BOPAlgo_PaveFiller& theFiller);
-
- //! Returns the list of shapes generated from the
- //! shape theS.
- Standard_EXPORT virtual const TopTools_ListOfShape& Generated (const TopoDS_Shape& theS) Standard_OVERRIDE;
-
- //! Returns the list of shapes modified from the shape
- //! theS.
- Standard_EXPORT virtual const TopTools_ListOfShape& Modified (const TopoDS_Shape& theS) Standard_OVERRIDE;
-
- //! Returns true if the shape theS has been deleted.
- Standard_EXPORT virtual Standard_Boolean IsDeleted (const TopoDS_Shape& theS) Standard_OVERRIDE;
-
- Standard_EXPORT const TopTools_DataMapOfShapeListOfShape& Images() const;
-
- Standard_EXPORT Standard_Boolean IsInterferred (const TopoDS_Shape& theS) const;
-
- //! Returns myOrigins.
- Standard_EXPORT const TopTools_DataMapOfShapeListOfShape& Origins() const;
-
- //! Returns myShapesSD.
- Standard_EXPORT const TopTools_DataMapOfShapeShape& ShapesSD() const;
-
- //! Returns mySplits.
- Standard_EXPORT const TopTools_DataMapOfShapeListOfShape& Splits() const;
-
-
//! 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.
//! This flag is taken into account if internal PaveFiller is used only.
//! In the case of calling PerformWithFiller the corresponding flag of that PaveFiller
//! is in force.
- Standard_EXPORT void SetNonDestructive(const Standard_Boolean theFlag);
+ void SetNonDestructive(const Standard_Boolean theFlag)
+ {
+ myNonDestructive = 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 Standard_Boolean NonDestructive() const;
+ Standard_Boolean NonDestructive() const
+ {
+ return myNonDestructive;
+ }
//! Sets the glue option for the algorithm
- Standard_EXPORT void SetGlue(const BOPAlgo_GlueEnum theGlue);
-
+ void SetGlue(const BOPAlgo_GlueEnum theGlue)
+ {
+ myGlue = theGlue;
+ }
+
//! Returns the glue option of the algorithm
- Standard_EXPORT BOPAlgo_GlueEnum Glue() const;
+ BOPAlgo_GlueEnum Glue() const
+ {
+ return myGlue;
+ }
-protected:
+ //! Enables/Disables the check of the input solids for inverted status
+ void SetCheckInverted(const Standard_Boolean theCheck)
+ {
+ myCheckInverted = theCheck;
+ }
- //! Prepare information for history support
- Standard_EXPORT virtual void PrepareHistory() Standard_OVERRIDE;
-
+ //! Returns the flag defining whether the check for input solids on inverted status
+ //! should be performed or not.
+ Standard_Boolean CheckInverted() const
+ {
+ return myCheckInverted;
+ }
+
+
+public: //! @name Performing the operation
+
+ //! Performs the operation.
+ //! The intersection will be performed also.
+ Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
+
+ //! Performs the operation with the prepared filler.
+ //! The intersection will not be performed in this case.
+ Standard_EXPORT virtual void PerformWithFiller (const BOPAlgo_PaveFiller& theFiller);
+
+
+public: //! @name History methods
+
+ //! Returns the list of shapes generated from the
+ //! shape theS.
+ Standard_EXPORT virtual const TopTools_ListOfShape& Generated (const TopoDS_Shape& theS) Standard_OVERRIDE;
+
+ //! Returns the list of shapes modified from the shape
+ //! theS.
+ Standard_EXPORT virtual const TopTools_ListOfShape& Modified (const TopoDS_Shape& theS) Standard_OVERRIDE;
+
+ //! Returns true if the shape theS has been deleted.
+ Standard_EXPORT virtual Standard_Boolean IsDeleted (const TopoDS_Shape& theS) Standard_OVERRIDE;
+
+
+public: //! @name Images/Origins
+
+ //! Returns the map of images.
+ const TopTools_DataMapOfShapeListOfShape& Images() const
+ {
+ return myImages;
+ }
+
+ //! Returns the map of origins.
+ const TopTools_DataMapOfShapeListOfShape& Origins() const
+ {
+ return myOrigins;
+ }
+
+ //! Returns the map of Same Domain (SD) shapes - coinciding shapes
+ //! from different arguments.
+ const TopTools_DataMapOfShapeShape& ShapesSD() const
+ {
+ return myShapesSD;
+ }
+
+
+protected: //! @name Methods for building the result
+
+ //! Performs the building of the result.
+ //! The method calls the PerfromInternal1() method surrounded by a try-catch block.
Standard_EXPORT virtual void PerformInternal (const BOPAlgo_PaveFiller& thePF);
-
+
+ //! Performs the building of the result.
+ //! To build the result of any other operation
+ //! it will be necessary to override this method.
Standard_EXPORT virtual void PerformInternal1 (const BOPAlgo_PaveFiller& thePF);
-
+
+ //! Prepare information for history support.
+ Standard_EXPORT virtual void PrepareHistory() Standard_OVERRIDE;
+
+ //! Builds the result of operation.
+ //! The method is called for each of the arguments type and
+ //! adds into the result the splits of the arguments of that type.
+ Standard_EXPORT virtual void BuildResult (const TopAbs_ShapeEnum theType);
+
+
+protected: //! @name Checking input arguments
+
+ //! Checks the input data.
Standard_EXPORT virtual void CheckData() Standard_OVERRIDE;
- //! Checks if the intersection algorithm has Errors/Warnings
+ //! Checks if the intersection algorithm has Errors/Warnings.
Standard_EXPORT void CheckFiller();
-
+
+ //! Prepares the result shape by making it empty compound.
Standard_EXPORT virtual void Prepare();
-
+
+
+protected: //! @name Fill Images of VERTICES
+
+ //! Fills the images of vertices.
Standard_EXPORT void FillImagesVertices();
-
+
+
+protected: //! @name Fill Images of EDGES
+
+ //! Fills the images of edges.
Standard_EXPORT void FillImagesEdges();
-
- Standard_EXPORT virtual void BuildResult (const TopAbs_ShapeEnum theType);
-
+
+
+protected: //! @name Fill Images of CONTAINERS
+
+ //! Fills the images of containers (WIRES/SHELLS/COMPSOLID).
Standard_EXPORT void FillImagesContainers (const TopAbs_ShapeEnum theType);
-
- Standard_EXPORT void FillImagesCompounds();
-
+
+ //! Builds the image of the given container using the splits
+ //! of its sub-shapes.
Standard_EXPORT void FillImagesContainer (const TopoDS_Shape& theS, const TopAbs_ShapeEnum theType);
-
- Standard_EXPORT void FillImagesCompound (const TopoDS_Shape& theS, TopTools_MapOfShape& theMF);
-
+
+
+protected: //! @name Fill Images of FACES
+
+ //! Fills the images of faces.
+ //! The method consists of three steps:
+ //! 1. Build the splits of faces;
+ //! 2. Find SD faces;
+ //! 3. Add internal vertices (if any) to faces.
Standard_EXPORT void FillImagesFaces();
-
+
+ //! Builds the splits of faces using the information from the
+ //! intersection stage stored in Data Structure.
Standard_EXPORT virtual void BuildSplitFaces();
-
+
+ //! Looks for the same domain faces among the splits of the faces.
+ //! Updates the map of images with SD faces.
Standard_EXPORT void FillSameDomainFaces();
-
- Standard_EXPORT void FillImagesFaces1();
-
+
+ //! Classifies the alone vertices on faces relatively its splits
+ //! and adds them as INTERNAL into the splits.
+ Standard_EXPORT void FillInternalVertices();
+
+
+protected: //! @name Fill Images of SOLIDS
+
+ //! Fills the images of solids.
+ //! The method consists of four steps:
+ //! 1. Build the draft solid - just rebuild the solid using the splits of faces;
+ //! 2. Find faces from other arguments located inside the solids;
+ //! 3. Build splits of solid using the inside faces;
+ //! 4. Fill internal shapes for the splits (Wires and vertices).
Standard_EXPORT void FillImagesSolids();
-
- Standard_EXPORT void BuildDraftSolid (const TopoDS_Shape& theSolid, TopoDS_Shape& theDraftSolid, TopTools_ListOfShape& theLIF);
-
- Standard_EXPORT virtual void FillIn3DParts (TopTools_DataMapOfShapeListOfShape& theInParts, TopTools_DataMapOfShapeShape& theDraftSolids, const Handle(NCollection_BaseAllocator)& theAllocator);
-
- Standard_EXPORT void BuildSplitSolids (TopTools_DataMapOfShapeListOfShape& theInParts, TopTools_DataMapOfShapeShape& theDraftSolids, const Handle(NCollection_BaseAllocator)& theAllocator);
-
+
+ //! Builds the draft solid by rebuilding the shells of the solid
+ //! with the splits of faces.
+ Standard_EXPORT void BuildDraftSolid (const TopoDS_Shape& theSolid,
+ TopoDS_Shape& theDraftSolid,
+ TopTools_ListOfShape& theLIF);
+
+ //! Finds faces located inside each solid.
+ Standard_EXPORT virtual void FillIn3DParts (TopTools_DataMapOfShapeListOfShape& theInParts,
+ TopTools_DataMapOfShapeShape& theDraftSolids,
+ const Handle(NCollection_BaseAllocator)& theAllocator);
+
+ //! Builds the splits of the solids using their draft versions
+ //! and faces located inside.
+ Standard_EXPORT void BuildSplitSolids (TopTools_DataMapOfShapeListOfShape& theInParts,
+ TopTools_DataMapOfShapeShape& theDraftSolids,
+ const Handle(NCollection_BaseAllocator)& theAllocator);
+
+ //! Classifies the vertices and edges from the arguments relatively
+ //! splits of solids and makes them INTERNAL for solids.
Standard_EXPORT void FillInternalShapes();
-
+
+
+protected: //! @name Fill Images of COMPOUNDS
+
+ //! Fills the images of compounds.
+ Standard_EXPORT void FillImagesCompounds();
+
+ //! Builds the image of the given compound.
+ Standard_EXPORT void FillImagesCompound (const TopoDS_Shape& theS,
+ TopTools_MapOfShape& theMF);
+
+protected: //! @name Post treatment
+
+ //! Post treatment of the result of the operation.
+ //! The method checks validity of the sub-shapes of the result
+ //! and updates the tolerances to make them valid.
Standard_EXPORT virtual void PostTreat();
- TopTools_ListOfShape myArguments;
- TopTools_MapOfShape myMapFence;
- BOPAlgo_PPaveFiller myPaveFiller;
- BOPDS_PDS myDS;
- Handle(IntTools_Context) myContext;
- Standard_Integer myEntryPoint;
- TopTools_DataMapOfShapeListOfShape myImages;
- TopTools_DataMapOfShapeShape myShapesSD;
- TopTools_DataMapOfShapeListOfShape mySplits;
- TopTools_DataMapOfShapeListOfShape myOrigins;
- Standard_Boolean myNonDestructive;
- BOPAlgo_GlueEnum myGlue;
+protected: //! @name Fields
-private:
+ TopTools_ListOfShape myArguments; //!< Arguments of the operation
+ TopTools_MapOfShape myMapFence; //!< Fence map providing the uniqueness of the shapes in the list of arguments
+ BOPAlgo_PPaveFiller myPaveFiller; //!< Pave Filler - algorithm for sub-shapes intersection
+ BOPDS_PDS myDS; //!< Data Structure - holder of intersection information
+ Handle(IntTools_Context) myContext; //!< Context - tool for cashing heavy algorithms such as Projectors and Classifiers
+ Standard_Integer myEntryPoint; //!< EntryPoint - controls the deletion of the PaveFiller, which could live longer than the Builder
+ TopTools_DataMapOfShapeListOfShape myImages; //!< Images - map of Images of the sub-shapes of arguments
+ TopTools_DataMapOfShapeShape myShapesSD; //!< ShapesSD - map of SD Shapes
+ TopTools_DataMapOfShapeListOfShape myOrigins; //!< Origins - map of Origins, back map of Images
+ Standard_Boolean myNonDestructive; //!< Safe processing option allows avoiding modification of the input shapes
+ BOPAlgo_GlueEnum myGlue; //!< Gluing option allows speeding up the intersection of the input shapes
+ Standard_Boolean myCheckInverted; //!< Check inverted option allows disabling the check of input solids on inverted status
};
-
#endif // _BOPAlgo_Builder_HeaderFile
diff --git a/src/BOPAlgo/BOPAlgo_Builder_1.cxx b/src/BOPAlgo/BOPAlgo_Builder_1.cxx
index 15eb1893dd..69fc0f84cb 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_1.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_1.cxx
@@ -40,28 +40,22 @@
//=======================================================================
void BOPAlgo_Builder::FillImagesVertices()
{
- Standard_Integer nV, nVSD;
- TColStd_DataMapIteratorOfDataMapOfIntegerInteger aIt;
- //
- const TColStd_DataMapOfIntegerInteger& aMSDV=myDS->ShapesSD();
- aIt.Initialize(aMSDV);
- for (; aIt.More(); aIt.Next()) {
- nV=aIt.Key();
- nVSD=aIt.Value();
- const TopoDS_Shape& aV=myDS->Shape(nV);
- const TopoDS_Shape& aVSD=myDS->Shape(nVSD);
- //
- TopTools_ListOfShape aLVSD(myAllocator);
- //
- aLVSD.Append(aVSD);
- myImages.Bind(aV, aLVSD);
- //
+ TColStd_DataMapIteratorOfDataMapOfIntegerInteger aIt(myDS->ShapesSD());
+ for (; aIt.More(); aIt.Next())
+ {
+ Standard_Integer nV = aIt.Key();
+ Standard_Integer nVSD = aIt.Value();
+
+ const TopoDS_Shape& aV = myDS->Shape(nV);
+ const TopoDS_Shape& aVSD = myDS->Shape(nVSD);
+ // Add to Images map
+ myImages.Bound(aV, TopTools_ListOfShape(myAllocator))->Append(aVSD);
+ // Add to SD map
myShapesSD.Bind(aV, aVSD);
- //
+ // Add to Origins map
TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aVSD);
- if (!pLOr) {
+ if (!pLOr)
pLOr = myOrigins.Bound(aVSD, TopTools_ListOfShape());
- }
pLOr->Append(aV);
}
}
@@ -115,26 +109,6 @@ void BOPAlgo_Builder::FillImagesVertices()
}
}
//=======================================================================
-// function: IsInterferred
-// purpose:
-//=======================================================================
- Standard_Boolean BOPAlgo_Builder::IsInterferred(const TopoDS_Shape& theS)const
-{
- Standard_Boolean bInterferred;
- TopoDS_Iterator aIt;
- //
- bInterferred=Standard_False;
- aIt.Initialize(theS);
- for (; aIt.More(); aIt.Next()) {
- const TopoDS_Shape& aSx=aIt.Value();
- if (myImages.IsBound(aSx)) {
- bInterferred=!bInterferred;
- break;
- }
- }
- return bInterferred;
-}
-//=======================================================================
//function : BuildResult
//purpose :
//=======================================================================
@@ -211,45 +185,57 @@ void BOPAlgo_Builder::FillImagesVertices()
void BOPAlgo_Builder::FillImagesContainer(const TopoDS_Shape& theS,
const TopAbs_ShapeEnum theType)
{
- Standard_Boolean bInterferred, bToReverse;
- TopoDS_Iterator aIt;
- BRep_Builder aBB;
- TopTools_ListIteratorOfListOfShape aItIm;
- //
- bInterferred=IsInterferred(theS);
- if (!bInterferred){
+ // Check if any of the sub-shapes of the container have been modified
+ TopoDS_Iterator aIt(theS);
+ for (; aIt.More(); aIt.Next())
+ {
+ const TopoDS_Shape& aSS = aIt.Value();
+ const TopTools_ListOfShape* pLFIm = myImages.Seek(aSS);
+ if (pLFIm && ((pLFIm->Extent() != 1) || !pLFIm->First().IsSame(aSS)))
+ break;
+ }
+
+ if (!aIt.More())
+ {
+ // Non of the sub-shapes have been modified.
+ // No need to create the new container.
return;
}
- //
+
+ BRep_Builder aBB;
+ // Make the new container of the splits of its sub-shapes
TopoDS_Shape aCIm;
BOPTools_AlgoTools::MakeContainer(theType, aCIm);
- //
+
aIt.Initialize(theS);
- for (; aIt.More(); aIt.Next()) {
- const TopoDS_Shape& aSx=aIt.Value();
- if (myImages.IsBound(aSx)) {
- const TopTools_ListOfShape& aLFIm=myImages.Find(aSx);
- aItIm.Initialize(aLFIm);
- for (; aItIm.More(); aItIm.Next()) {
- TopoDS_Shape aSxIm=aItIm.Value();
- //
- bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSxIm, aSx, myContext);
- if (bToReverse) {
- aSxIm.Reverse();
- }
- aBB.Add(aCIm, aSxIm);
- }
+ for (; aIt.More(); aIt.Next())
+ {
+ const TopoDS_Shape& aSS = aIt.Value();
+ const TopTools_ListOfShape* pLSSIm = myImages.Seek(aSS);
+
+ if (!pLSSIm)
+ {
+ // No splits, add the sub-shape itself
+ aBB.Add(aCIm, aSS);
+ continue;
}
- else {
- aBB.Add(aCIm, aSx);
+
+ // Add the splits
+ TopTools_ListIteratorOfListOfShape aItIm(*pLSSIm);
+ for (; aItIm.More(); aItIm.Next())
+ {
+ TopoDS_Shape aSSIm = aItIm.Value();
+ if (!aSSIm.IsEqual(aSS) &&
+ BOPTools_AlgoTools::IsSplitToReverse(aSSIm, aSS, myContext))
+ {
+ aSSIm.Reverse();
+ }
+ aBB.Add(aCIm, aSSIm);
}
}
- //
+
aCIm.Closed(BRep_Tool::IsClosed(aCIm));
- //
- TopTools_ListOfShape aLSIm(myAllocator);
- aLSIm.Append(aCIm);
- myImages.Bind(theS, aLSIm);
+ myImages.Bound(theS, TopTools_ListOfShape(myAllocator))->Append(aCIm);
}
//=======================================================================
//function : FillImagesCompound
diff --git a/src/BOPAlgo/BOPAlgo_Builder_2.cxx b/src/BOPAlgo/BOPAlgo_Builder_2.cxx
index 37510efdec..b4bb60ed74 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_2.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_2.cxx
@@ -154,7 +154,7 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
BOPAlgo_VFI() :
BOPAlgo_Algo(),
- myFlag(-1) {
+ myIsInternal(Standard_False) {
}
//
virtual ~BOPAlgo_VFI(){
@@ -176,8 +176,8 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
return myF;
}
//
- Standard_Integer Flag()const {
- return myFlag;
+ Standard_Boolean IsInternal()const {
+ return myIsInternal;
}
//
void SetContext(const Handle(IntTools_Context)& aContext) {
@@ -192,11 +192,13 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
Standard_Real aT1, aT2, dummy;
//
BOPAlgo_Algo::UserBreak();
- myFlag = myContext->ComputeVF(myV, myF, aT1, aT2, dummy, myFuzzyValue);
+ Standard_Integer iFlag =
+ myContext->ComputeVF(myV, myF, aT1, aT2, dummy, myFuzzyValue);
+ myIsInternal = (iFlag == 0);
}
//
protected:
- Standard_Integer myFlag;
+ Standard_Boolean myIsInternal;
TopoDS_Vertex myV;
TopoDS_Face myF;
Handle(IntTools_Context) myContext;
@@ -223,7 +225,7 @@ void BOPAlgo_Builder::FillImagesFaces()
{
BuildSplitFaces();
FillSameDomainFaces();
- FillImagesFaces1();
+ FillInternalVertices();
}
//=======================================================================
//function : BuildSplitFaces
@@ -290,6 +292,20 @@ void BOPAlgo_Builder::BuildSplitFaces()
if (!aNbPBIn && !aNbPBSc)
{
+ if (!aNbAV)
+ {
+ // Check if any wires of the face have been modified.
+ // If not, there is no need to create the new face.
+ TopoDS_Iterator aItW(aF);
+ for (; aItW.More(); aItW.Next())
+ {
+ if (myImages.IsBound(aItW.Value()))
+ break;
+ }
+ if (!aItW.More())
+ continue;
+ }
+
// No internal parts for the face, so just build the draft face
// and keep it to pass directly into result.
// If the original face has any internal edges, the draft face
@@ -454,7 +470,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
anOriF = aF.Orientation();
const TopTools_ListOfShape& aLFR = aFacesIm(k);
//
- TopTools_ListOfShape* pLFIm = mySplits.Bound(aF, TopTools_ListOfShape());
+ TopTools_ListOfShape* pLFIm = myImages.Bound(aF, TopTools_ListOfShape());
aIt.Initialize(aLFR);
for (; aIt.More(); aIt.Next()) {
TopoDS_Shape& aFR=aIt.ChangeValue();
@@ -564,7 +580,7 @@ void BOPAlgo_Builder::FillSameDomainFaces()
}
}
- const TopTools_ListOfShape* pLFSp = mySplits.Seek(aF);
+ const TopTools_ListOfShape* pLFSp = myImages.Seek(aF);
if (pLFSp)
{
TopTools_ListIteratorOfListOfShape aItLF(*pLFSp);
@@ -649,18 +665,83 @@ void BOPAlgo_Builder::FillSameDomainFaces()
for (; aItB.More(); aItB.Next())
{
const TopTools_ListOfShape& aLSD = aItB.Value();
- // First face will be SD face for all faces in the group
- const TopoDS_Shape& aFSD1 = aLSD.First();
+ // If the group contains some original faces, the one with minimal
+ // index in the DS will be chosen as the SD for the whole group.
+ // If there are no original faces in the group, the first face from
+ // the group will be used as the SD face.
+ // Such SD face will be representative of the whole group in the result.
+ TopoDS_Face* pFSD = NULL;
+ Standard_Integer nFMin = ::IntegerLast();
TopTools_ListIteratorOfListOfShape aItLF(aLSD);
for (; aItLF.More(); aItLF.Next())
{
- const TopoDS_Shape& aFSD = aItLF.Value();
- myShapesSD.Bind(aFSD, aFSD1);
- // If the face has no splits but have an SD face, it is considered as being split
- if (myDS->Index(aFSD) >= 0)
- mySplits.Bound(aFSD, TopTools_ListOfShape())->Append(aFSD);
+ const TopoDS_Shape& aF = aItLF.Value();
+ // Check the index of the face in DS
+ const Standard_Integer nF = myDS->Index(aF);
+ if (nF >= 0)
+ {
+ // The fact that the face is found in the DS, means that
+ // the face has not been change, and thus it is original one.
+ //
+ // Such face does not have any splits, but have an SD face.
+ // Consider it being split.
+ myImages.Bound(aF, TopTools_ListOfShape())->Append(aF);
+
+ // For the SD face chose the one with minimal index
+ if (nF < nFMin)
+ {
+ nFMin = nF;
+ pFSD = (TopoDS_Face*)&aF;
+ }
+ }
+ }
+
+ if (!pFSD)
+ {
+ // No original faces in the group, take the first one
+ pFSD = (TopoDS_Face*)&aLSD.First();
+ }
+
+ // Save all SD connections
+ aItLF.Initialize(aLSD);
+ for (; aItLF.More(); aItLF.Next())
+ {
+ const TopoDS_Shape& aF = aItLF.Value();
+ myShapesSD.Bind(aF, *pFSD);
}
}
+
+ // Update the map of images with SD faces and
+ // fill the map of origins.
+ Standard_Integer aNbS = myDS->NbSourceShapes();
+ for (Standard_Integer i = 0; i < aNbS; ++i)
+ {
+ const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
+ if (aSI.ShapeType() != TopAbs_FACE)
+ continue;
+
+ const TopoDS_Shape& aF = aSI.Shape();
+ TopTools_ListOfShape* pLFIm = myImages.ChangeSeek(aF);
+ if (!pLFIm)
+ continue;
+
+ TopTools_ListIteratorOfListOfShape aItLFIm(*pLFIm);
+ for (; aItLFIm.More(); aItLFIm.Next())
+ {
+ TopoDS_Shape& aFIm = aItLFIm.ChangeValue();
+ const TopoDS_Shape* pFSD = myShapesSD.Seek(aFIm);
+ if (pFSD)
+ // Update image with SD face
+ aFIm = *pFSD;
+
+ // Fill the map of origins
+ TopTools_ListOfShape* pLFOr = myOrigins.ChangeSeek(aFIm);
+ if (!pLFOr)
+ pLFOr = myOrigins.Bound(aFIm, TopTools_ListOfShape());
+ pLFOr->Append(aF);
+ }
+ }
+
aMBlocks.Clear();
aDMSLS.Clear();
}
@@ -668,103 +749,63 @@ void BOPAlgo_Builder::FillSameDomainFaces()
// function: FillImagesFaces1
// purpose:
//=======================================================================
-void BOPAlgo_Builder::FillImagesFaces1()
+void BOPAlgo_Builder::FillInternalVertices()
{
- Standard_Integer i, aNbS, iSense, nVx, aNbVFI, iFlag;
- TopoDS_Face aFSD;
- TopoDS_Vertex aVx;
- BRep_Builder aBB;
- TColStd_ListOfInteger aLIAV;
- TopTools_ListOfShape aLFIm;
- TColStd_ListIteratorOfListOfInteger aItV;
- TopTools_ListIteratorOfListOfShape aItLS, aItF;
+ // Vector of pairs of Vertex/Face for classification of the vertices
+ // relatively faces, and adding them as internal into the faces
BOPAlgo_VectorOfVFI aVVFI;
- //
- aNbS=myDS->NbSourceShapes();
- for (i=0; iShapeInfo(i);
- if (aSI.ShapeType()!=TopAbs_FACE) {
+
+ Standard_Integer aNbS = myDS->NbSourceShapes();
+ for (Standard_Integer i = 0; i < aNbS; ++i)
+ {
+ const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
+ if (aSI.ShapeType() != TopAbs_FACE)
continue;
- }
- //
- const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
- //
- if (!mySplits.IsBound(aF)) {
+
+ const TopoDS_Shape& aF = aSI.Shape();
+ const TopTools_ListOfShape* pLFIm = myImages.Seek(aF);
+ if (!pLFIm)
continue;
- }
- //
- // 1.
- aLIAV.Clear();
+
+ // Find vertices to add as internal into the splits
+ TColStd_ListOfInteger aLIAV;
myDS->AloneVertices(i, aLIAV);
- aLFIm.Clear();
- //
- const TopTools_ListOfShape& aLSp=mySplits.Find(aF);
- aItLS.Initialize(aLSp);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
- if (!myShapesSD.IsBound(aFSp)) {
- aLFIm.Append(aFSp);
- }
- else {
- aFSD=(*(TopoDS_Face*)(&myShapesSD.Find(aFSp)));
- iSense=BOPTools_AlgoTools::Sense(aFSp, aFSD, myContext);
- if (iSense<0) {
- aFSD.Reverse();
- }
- aLFIm.Append(aFSD);
- }
- }
- //
- //FillInternalVertices(aLFIm, aLIAV);
- //
- myImages.Bind(aF, aLFIm);
- //
- // 2. fill myOrigins
- aItLS.Initialize(aLFIm);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
- //
- TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aFSp);
- if (!pLOr) {
- pLOr = myOrigins.Bound(aFSp, TopTools_ListOfShape());
- }
- pLOr->Append(aF);
- }
- //
- // 3.
- aItV.Initialize(aLIAV);
- for (; aItV.More(); aItV.Next()) {
- nVx=aItV.Value();
- aVx=(*(TopoDS_Vertex*)(&myDS->Shape(nVx)));
- aVx.Orientation(TopAbs_INTERNAL);
- //
- aItF.Initialize(aLFIm);
- for (; aItF.More(); aItF.Next()) {
- TopoDS_Face& aFy=(*(TopoDS_Face*)(&aItF.Value()));
- //
- BOPAlgo_VFI& aVFI=aVVFI.Appended();
- aVFI.SetVertex(aVx);
- aVFI.SetFace(aFy);
+
+ // Add vertices and faces for classification
+ TColStd_ListIteratorOfListOfInteger aItLV(aLIAV);
+ for (; aItLV.More(); aItLV.Next())
+ {
+ TopoDS_Vertex aV = TopoDS::Vertex(myDS->Shape(aItLV.Value()));
+ aV.Orientation(TopAbs_INTERNAL);
+
+ TopTools_ListIteratorOfListOfShape aItLFIm(*pLFIm);
+ for (; aItLFIm.More(); aItLFIm.Next())
+ {
+ const TopoDS_Face& aFIm = TopoDS::Face(aItLFIm.Value());
+ // Make the pair
+ BOPAlgo_VFI& aVFI = aVVFI.Appended();
+ aVFI.SetVertex(aV);
+ aVFI.SetFace(aFIm);
aVFI.SetFuzzyValue(myFuzzyValue);
aVFI.SetProgressIndicator(myProgressIndicator);
}
}
- }// for (i=0; i
#include
#include
+#include
#include
#include
#include
@@ -414,12 +415,11 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
return;
}
//
- Standard_Boolean bCB, bV1, bV2;
- Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
+ Standard_Integer i, nE, nV1, nV2, nSp, aNbVBSE, k;
Standard_Real aT1, aT2;
BOPDS_ListIteratorOfListOfPaveBlock aItPB;
Handle(BOPDS_PaveBlock) aPB;
- BOPDS_MapOfPaveBlock aMPB(100);
+ BOPDS_MapOfCommonBlock aMCB(100);
TopoDS_Vertex aV1, aV2;
TopoDS_Edge aE;
BOPAlgo_VectorOfSplitEdge aVBSE;
@@ -429,77 +429,96 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
//
aNbPBP=aPBP.Length();
//
- for (i=0; iIndices(nV1, nV2);
- bV1=myDS->IsNewShape(nV1);
- bV2=myDS->IsNewShape(nV2);
- bCB=myDS->IsCommonBlock(aPB);
- //
- if (!(bV1 || bV2)) { // no new vertices here
- if (!myNonDestructive || !bCB) {
- if (bCB) {
- if (!aPB->HasEdge()) {
- const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
- nE = aCB->PaveBlock1()->OriginalEdge();
- aCB->SetEdge(nE);
- // Compute tolerance of the common block and update the edge
- Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext);
- myDS->UpdateEdgeTolerance(nE, aTol);
- }
- }
- else {
- nE = aPB->OriginalEdge();
- aPB->SetEdge(nE);
- }
- continue;
- }
- }
- }
+ for (i = 0; i < aNbPBP; ++i)
+ {
+ BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
//
aItPB.Initialize(aLPB);
for (; aItPB.More(); aItPB.Next()) {
- aPB=aItPB.Value();
- nE=aPB->OriginalEdge();
- const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
- if (aSIE.HasFlag()){
+ aPB = aItPB.Value();
+ nE = aPB->OriginalEdge();
+ const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
+ if (aSIE.HasFlag())
+ {
+ // Skip degenerated edges
continue;
}
- //
- const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
- bCB=!aCB.IsNull();
- if (bCB) {
- aPB=aCB->PaveBlock1();
- }
- //
- if (aMPB.Add(aPB)) {
- nE=aPB->OriginalEdge();
- aPB->Indices(nV1, nV2);
- aPB->Range(aT1, aT2);
- //
- aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
- aE.Orientation(TopAbs_FORWARD);
- //
- aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
- aV1.Orientation(TopAbs_FORWARD);
- //
- aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
- aV2.Orientation(TopAbs_REVERSED);
- //
- BOPAlgo_SplitEdge& aBSE=aVBSE.Appended();
- //
- aBSE.SetData(aE, aV1, aT1, aV2, aT2);
- aBSE.SetPaveBlock(aPB);
- if (bCB) {
- aBSE.SetCommonBlock(aCB);
+
+ const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
+ Standard_Boolean bCB = !aCB.IsNull();
+ if (bCB && !aMCB.Add(aCB))
+ continue;
+
+ aPB->Indices(nV1, nV2);
+ // Check if it is necessary to make the split of the edge
+ {
+ Standard_Boolean bV1 = myDS->IsNewShape(nV1);
+ Standard_Boolean bV2 = myDS->IsNewShape(nV2);
+
+ Standard_Boolean bToSplit = Standard_True;
+ if (!bV1 && !bV2) // no new vertices here
+ {
+ if (!myNonDestructive || !bCB)
+ {
+ if (bCB)
+ {
+ // Find the edge with these vertices
+ BOPDS_ListIteratorOfListOfPaveBlock it(aCB->PaveBlocks());
+ for (; it.More(); it.Next())
+ {
+ nE = it.Value()->OriginalEdge();
+ if (myDS->PaveBlocks(nE).Extent() == 1)
+ break;
+ }
+ if (it.More())
+ {
+ // The pave block is found
+ bToSplit = Standard_False;
+ aCB->SetRealPaveBlock(it.Value());
+ aCB->SetEdge(nE);
+ // Compute tolerance of the common block and update the edge
+ Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext);
+ myDS->UpdateEdgeTolerance(nE, aTol);
+ }
+ }
+ else if (aLPB.Extent() == 1)
+ {
+ bToSplit = Standard_False;
+ aPB->SetEdge(nE);
+ }
+ if (!bToSplit)
+ continue;
+ }
}
- aBSE.SetDS(myDS);
- aBSE.SetProgressIndicator(myProgressIndicator);
}
+
+ // Split the edge
+ if (bCB)
+ {
+ aPB = aCB->PaveBlock1();
+ nE = aPB->OriginalEdge();
+ aPB->Indices(nV1, nV2);
+ }
+ aPB->Range(aT1, aT2);
+ //
+ aE = (*(TopoDS_Edge *)(&myDS->Shape(nE)));
+ aE.Orientation(TopAbs_FORWARD);
+ //
+ aV1 = (*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
+ aV1.Orientation(TopAbs_FORWARD);
+ //
+ aV2 = (*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
+ aV2.Orientation(TopAbs_REVERSED);
+ //
+ BOPAlgo_SplitEdge& aBSE = aVBSE.Appended();
+ //
+ aBSE.SetData(aE, aV1, aT1, aV2, aT2);
+ aBSE.SetPaveBlock(aPB);
+ if (bCB) {
+ aBSE.SetCommonBlock(aCB);
+ }
+ aBSE.SetDS(myDS);
+ aBSE.SetProgressIndicator(myProgressIndicator);
} // for (; aItPB.More(); aItPB.Next()) {
} // for (i=0; i
//!
+//! Additionally to the options defined in the base class, the algorithm has
+//! the following options:
+//! - *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 of the intersections
+//! on the special cases, in which some sub-shapes are coinciding.
+//! - *Disabling the check for inverted solids* - Disables/Enables the check of the input solids
+//! for inverted status (holes in the space). The default value is TRUE,
+//! i.e. the check is performed. Setting this flag to FALSE for inverted solids,
+//! most likely will lead to incorrect results.
+//!
//! It returns the following Error statuses:
//! - 0 - in case of success;
//! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;
@@ -72,6 +82,19 @@ Standard_EXPORT virtual ~BRepAlgoAPI_BuilderAlgo();
//! Returns the glue option of the algorithm
Standard_EXPORT BOPAlgo_GlueEnum Glue() const;
+ //! Enables/Disables the check of the input solids for inverted status
+ void SetCheckInverted(const Standard_Boolean theCheck)
+ {
+ myCheckInverted = theCheck;
+ }
+
+ //! Returns the flag defining whether the check for input solids on inverted status
+ //! should be performed or not.
+ Standard_Boolean CheckInverted() const
+ {
+ return myCheckInverted;
+ }
+
//! Sets the arguments
Standard_EXPORT void SetArguments (const TopTools_ListOfShape& theLS);
@@ -130,20 +153,10 @@ protected:
Standard_Boolean myNonDestructive;
TopTools_ListOfShape myArguments;
BOPAlgo_GlueEnum myGlue;
-
+ Standard_Boolean myCheckInverted;
private:
-
-
-
-
};
-
-
-
-
-
-
#endif // _BRepAlgoAPI_BuilderAlgo_HeaderFile
diff --git a/src/BRepFeat/BRepFeat_Builder.cxx b/src/BRepFeat/BRepFeat_Builder.cxx
index fae5e26533..480d2334bd 100644
--- a/src/BRepFeat/BRepFeat_Builder.cxx
+++ b/src/BRepFeat/BRepFeat_Builder.cxx
@@ -503,9 +503,7 @@
}
}
//
- mySplits.Bind(aF, aLFIm);
if (aLFIm.Extent() == 0) {
- mySplits.UnBind(aF);
myImages.UnBind(aF);
}
}
diff --git a/src/BRepOffset/BRepOffset_MakeOffset_1.cxx b/src/BRepOffset/BRepOffset_MakeOffset_1.cxx
index 6b3feb8bd7..47ff3c4e76 100644
--- a/src/BRepOffset/BRepOffset_MakeOffset_1.cxx
+++ b/src/BRepOffset/BRepOffset_MakeOffset_1.cxx
@@ -5632,14 +5632,8 @@ void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImage
GetBoundsToUpdate(aLF, theOEImages, theOEOrigins, aMEB,
aLABounds, aLAValid, aBounds, theAsDes);
//
- // intersect valid splits with bounds and update both
+ // Intersect valid splits with bounds and update both
BOPAlgo_Builder aGF;
- // The order is important here, because we need to keep the
- // unmodified edges from the Bounds in the resulting maps.
- // In case of total coincidence of the edges with the same vertices
- // the edges in the common block will not be split and no new
- // edges will be created and the first pave block
- // will be used as a real pave block.
aGF.AddArgument(aBounds);
aGF.AddArgument(aSplits);
aGF.Perform();
@@ -5667,18 +5661,56 @@ void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImage
}
}
//
+ // Rebuild the map of edges to avoid, using the intersection results
+ TopTools_IndexedMapOfShape aMEAvoid;
+ // GF's data structure
+ const BOPDS_PDS& pDS = aGF.PDS();
+
aNbE = theEdgesToAvoid.Extent();
- for (i = 1; i <= aNbE; ++i) {
+ for (i = 1; i <= aNbE; ++i)
+ {
const TopoDS_Shape& aE = theEdgesToAvoid(i);
const TopTools_ListOfShape& aLEIm = aGF.Modified(aE);
- TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
- for (; aItLEIm.More(); aItLEIm.Next()) {
- const TopoDS_Shape& aEIm = aItLEIm.Value();
- if (!aNewEdges.Contains(aEIm)) {
- theEdgesToAvoid.Add(aEIm);
+
+ // Only untouched and fully coinciding edges should be kept in the avoid map
+ Standard_Boolean bKeep = aLEIm.IsEmpty();
+ if (aLEIm.Extent() == 1 && aE.IsSame(aLEIm.First()))
+ {
+ const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(pDS->Index(aE));
+ if (aLPB.Extent() == 1)
+ {
+ const Handle(BOPDS_PaveBlock)& aPB = aLPB.First();
+ const Handle(BOPDS_CommonBlock)& aCB = pDS->CommonBlock(aPB);
+ if (!aCB.IsNull())
+ {
+ const BOPDS_ListOfPaveBlock& aLPBCB = aCB->PaveBlocks();
+ BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBCB);
+ for (; aItLPB.More(); aItLPB.Next())
+ {
+ if (pDS->PaveBlocks(aItLPB.Value()->OriginalEdge()).Extent() > 1)
+ break;
+ }
+ bKeep = !aItLPB.More();
+ }
}
}
+
+ if (bKeep)
+ {
+ // keep the original edge
+ aMEAvoid.Add(aE);
+ continue;
+ }
+
+ TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
+ for (; aItLEIm.More(); aItLEIm.Next())
+ {
+ const TopoDS_Shape& aEIm = aItLEIm.Value();
+ if (!aNewEdges.Contains(aEIm))
+ aMEAvoid.Add(aEIm);
+ }
}
+ theEdgesToAvoid = aMEAvoid;
}
//=======================================================================
diff --git a/tests/blend/complex/G9 b/tests/blend/complex/G9
index ff4881becc..340187c593 100644
--- a/tests/blend/complex/G9
+++ b/tests/blend/complex/G9
@@ -8,6 +8,6 @@ pcylinder c2 5 20
ttranslate c2 4.9 0 10
bfuse f c1b c2
explode f E
-blend result f 4.9 f_5
+blend result f 4.9 f_4
checkprops result -s 2104.35
diff --git a/tests/blend/complex/H2 b/tests/blend/complex/H2
deleted file mode 100644
index cc8343d537..0000000000
--- a/tests/blend/complex/H2
+++ /dev/null
@@ -1,16 +0,0 @@
-# ====================================
-## Grid : CFI900
-## Test : N1
-## Comment : from USA60109
-## ====================================
-
-pcylinder c1 10 20
-pcylinder c2 5 20
-ttranslate c2 5 0 20
-bfuse f c1 c2
-explode f E
-blend result f 1 f_1
-explode result sh
-renamevar result_1 result
-
-checkprops result -s 2485.86
diff --git a/tests/blend/simple/Q4 b/tests/blend/simple/Q4
index e47e8603c6..cb6ec86dda 100644
--- a/tests/blend/simple/Q4
+++ b/tests/blend/simple/Q4
@@ -5,6 +5,6 @@ pcylinder c 1 10
ttranslate c 2.5 2.5 2.5
bfuse s c b
explode s E
-blend result s 1 s_3
+blend result s 1 s_2
checkprops result -s 192.343
diff --git a/tests/blend/simple/Z1 b/tests/blend/simple/Z1
index 1afc065575..ec3e6b9920 100644
--- a/tests/blend/simple/Z1
+++ b/tests/blend/simple/Z1
@@ -7,8 +7,8 @@ ttranslate c2 5 0 20
bfuse f c1 c2
-explode f E
+explode c1 e
-blend result f 1 f_1
+blend result f 1 c1_3
checkprops result -s 2485.86
diff --git a/tests/bugs/modalg_7/bug24632_1 b/tests/bugs/modalg_7/bug24632_1
index 759dd7f69e..312017ca39 100644
--- a/tests/bugs/modalg_7/bug24632_1
+++ b/tests/bugs/modalg_7/bug24632_1
@@ -26,7 +26,7 @@ bop beam_1 cut_2
bopcut result
checkshape result
-checknbshapes result -solid 2 -shell 2 -face 32 -wire 39
+checknbshapes result -solid 2 -shell 2 -face 33 -wire 40 -t
checkprops result -v 5.40325e+7
checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug24632_2 b/tests/bugs/modalg_7/bug24632_2
index 255d18acca..601a4e60dd 100644
--- a/tests/bugs/modalg_7/bug24632_2
+++ b/tests/bugs/modalg_7/bug24632_2
@@ -42,7 +42,7 @@ bop beam_2 cut_2
bopcut result
checkshape result
-checknbshapes result -solid 4 -shell 4 -face 64 -wire 73
+checknbshapes result -solid 4 -shell 4 -face 64 -wire 73 -t
checkprops result -v 1.61677e+8
checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug27711 b/tests/bugs/modalg_7/bug27711
index 8105c11ba3..6ec342352a 100644
--- a/tests/bugs/modalg_7/bug27711
+++ b/tests/bugs/modalg_7/bug27711
@@ -11,20 +11,15 @@ puts ""
smallview
-box a -1.5 -1.5 0 3 3 3
-box b -3 -3 -3 6 6 3
-bfuse result a b
-set bug_info [string trim [checkshape result]]
-if {$bug_info != "This shape seems to be valid"} {
- puts "ERROR: Problem of test case functionality. Should be additionally investigated."
-}
+restore [locate_data_file bug27711.brep] s
+
clear
-display result
+display s
fit
xwd $imagedir/${casename}_step_0.png
-explode result e
-blend result result 0.5 result_12 0.5 result_11
+explode s e
+blend result s 0.5 s_12 0.5 s_11
set bug_info [string trim [checkshape result]]
if {$bug_info != "This shape seems to be valid"} {
puts "ERROR: Problem of test case functionality. Should be additionally investigated."
diff --git a/tests/bugs/modalg_7/bug29333_1 b/tests/bugs/modalg_7/bug29333_1
new file mode 100644
index 0000000000..fa77f316f9
--- /dev/null
+++ b/tests/bugs/modalg_7/bug29333_1
@@ -0,0 +1,65 @@
+puts "========"
+puts "OCC29333"
+puts "========"
+puts ""
+#################################################
+# Boolean Operations - Prevent modification of the input shapes in case their sub-shapes have not been modified
+#################################################
+
+# create two touching faces
+plane p 0 0 0 0 0 1
+mkface f1 p -10 10 -10 10
+
+copy f1 f2
+ttranslate f2 20 0 0
+
+# fuse these faces
+bfuse s f1 f2
+
+# split one of these faces
+explode s f
+
+line l 0 0 0 1 0 0
+mkedge e l
+bclearobjects
+bcleartools
+baddobjects s_1
+baddtools e
+bfillds
+bsplit s1_sp
+
+
+# fuse again
+bclearobjects
+bcleartools
+baddobjects s1_sp
+baddtools s_2
+bfillds
+bbuild result
+
+checkshape result
+checkprops result -s 800
+checknbshapes result -vertex 8 -edge 10 -wire 3 -face 3
+
+
+# check that non of the shapes from s1_sp is modified
+compound result s1_sp c
+checknbshapes c -vertex 8 -edge 10 -wire 3 -face 3
+
+
+# fuse with different order
+bclearobjects
+bcleartools
+baddobjects s_2
+baddtools s1_sp
+bfillds
+bbuild result
+
+checkshape result
+checkprops result -s 800
+checknbshapes result -vertex 8 -edge 10 -wire 3 -face 3
+
+
+# check that non of the shapes from s1_sp is modified
+compound result s1_sp c
+checknbshapes c -vertex 8 -edge 10 -wire 3 -face 3
diff --git a/tests/bugs/modalg_7/bug29333_2 b/tests/bugs/modalg_7/bug29333_2
new file mode 100644
index 0000000000..ccb0760745
--- /dev/null
+++ b/tests/bugs/modalg_7/bug29333_2
@@ -0,0 +1,62 @@
+puts "========"
+puts "OCC29333"
+puts "========"
+puts ""
+#################################################
+# Boolean Operations - Prevent modification of the input shapes in case their sub-shapes have not been modified
+#################################################
+
+# create two touching boxes
+box b1 10 10 10
+box b2 10 0 0 10 10 10
+
+# make them share the common face
+mkvolume s b1 b2
+
+# split one of these solids
+explode s so
+
+plane p 0 0 5 0 0 1
+mkface f p
+bclearobjects
+bcleartools
+baddobjects s_1
+baddtools f
+bfillds
+bsplit s1_sp
+
+
+# fuse again
+bclearobjects
+bcleartools
+baddobjects s1_sp
+baddtools s_2
+bfillds
+bbuild result
+
+checkshape result
+checkprops result -s 1400 -v 2000
+checknbshapes result -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
+
+
+# check that non of the shapes from s1_sp is modified
+compound result s1_sp c
+checknbshapes c -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
+
+
+# fuse with different order
+bclearobjects
+bcleartools
+baddobjects s_2
+baddtools s1_sp
+bfillds
+bbuild result
+
+checkshape result
+checkprops result -s 1400 -v 2000
+checknbshapes result -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
+
+
+# check that non of the shapes from s1_sp is modified
+compound result s1_sp c
+checknbshapes c -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
diff --git a/tests/caf/named_shape/F8 b/tests/caf/named_shape/F8
index 36389003db..4147563580 100755
--- a/tests/caf/named_shape/F8
+++ b/tests/caf/named_shape/F8
@@ -9,7 +9,7 @@
# 1. Create 3 boxes $B1, $B2, $B3
# 2. $FS1 = Fuse ($B1, $B2)
# 3. $FS2 = Fuse ($B1, $B3)
-# 4. Make selections of the face 'fuse2_23'
+# 4. Make selections of the face 'fuse2_19'
# 5. Modify B2
# 6. Recompute
# ===============================================
@@ -37,12 +37,12 @@ GetShape $doc $FS2:2 fuse2
explode fuse2 f
-#4. select fuse2_23 (using SelectShape)
-set Sel1 0:2:23
-SelectShape $doc $Sel1 fuse2_23 fuse2
-GetShape $doc $Sel1 f23before
-#f23before is face
-set info1 [whatis f23before]
+#4. select fuse2_19 (using SelectShape)
+set Sel1 0:2:19
+SelectShape $doc $Sel1 fuse2_19 fuse2
+GetShape $doc $Sel1 f19before
+#f19before is face
+set info1 [whatis f19before]
#5. Modify
@@ -53,40 +53,40 @@ ComputeFun $doc $B2:1
ComputeFun $doc $FS1
ComputeFun $doc $FS2
SolveSelection $doc $Sel1
-GetShape $doc $Sel1 f23after
-#f23after is face
-set info2 [whatis f23after]
+GetShape $doc $Sel1 f19after
+#f19after is face
+set info2 [whatis f19after]
if { [regexp "shape" $info1] != 1 } {
- puts "Error : There is not word shape in f23after"
+ puts "Error : There is not word shape in f19after"
}
if { [regexp "FACE" $info1] != 1 } {
- puts "Error : There is not word FACE in f23after"
+ puts "Error : There is not word FACE in f19after"
}
if { [regexp "REVERSED" $info1] != 1 } {
- puts "Error : There is not word REVERSED in f23after"
+ puts "Error : There is not word REVERSED in f19after"
}
if { [regexp "Modified" $info1] != 1 } {
- puts "Error : There is not word Modified in f23after"
+ puts "Error : There is not word Modified in f19after"
}
if { [regexp "Orientable" $info1] != 1 } {
- puts "Error : There is not word Orientable in f23after"
+ puts "Error : There is not word Orientable in f19after"
}
if { [regexp "shape" $info2] != 1 } {
- puts "Error : There is not word shape in f23before"
+ puts "Error : There is not word shape in f19before"
}
if { [regexp "FACE" $info2] != 1 } {
- puts "Error : There is not word FACE in f23before"
+ puts "Error : There is not word FACE in f19before"
}
if { [regexp "REVERSED" $info2] != 1 } {
- puts "Error : There is not word REVERSED in f23before"
+ puts "Error : There is not word REVERSED in f19before"
}
if { [regexp "Modified" $info2] != 1 } {
- puts "Error : There is not word Modified in f23before"
+ puts "Error : There is not word Modified in f19before"
}
if { [regexp "Orientable" $info2] != 1 } {
- puts "Error : There is not word Orientable in f23before"
+ puts "Error : There is not word Orientable in f19before"
}
diff --git a/tests/caf/named_shape/F9 b/tests/caf/named_shape/F9
index c3612a5515..4489ec0916 100755
--- a/tests/caf/named_shape/F9
+++ b/tests/caf/named_shape/F9
@@ -9,7 +9,7 @@
# 1. Create 3 boxes $B1, $B2, $B3
# 2. $FS1 = Fuse ($B1, $B2)
# 3. $FS2 = Fuse ($B1, $B3)
-# 4. Make selections of the face 'fuse2_23'
+# 4. Make selections of the face 'fuse2_19'
# 5. Modify B2
# 6. Recompute
# ===============================================
@@ -38,11 +38,11 @@ explode fuse2 f
-#4. Select fuse2_23 using Attach
-set Sel2 [AttachShape $doc fuse2_23 $B1]
-GetShape $doc $Sel2:1:2 nf23before
-#nf23before is face
-set info1 [whatis nf23before]
+#4. Select fuse2_19 using Attach
+set Sel2 [AttachShape $doc fuse2_19 $B1]
+GetShape $doc $Sel2:1:2 nf19before
+#nf19before is face
+set info1 [whatis nf19before]
#5. Modify
@@ -56,38 +56,38 @@ ComputeFun $doc $B3:1
ComputeFun $doc $FS1
ComputeFun $doc $FS2
ComputeFun $doc $Sel2:1
-GetShape $doc $Sel2:1:2 nf23after
-#nf23after is face
-set info2 [whatis nf23after]
+GetShape $doc $Sel2:1:2 nf19after
+#nf19after is face
+set info2 [whatis nf19after]
if { [regexp "shape" $info1] != 1 } {
- puts "Error : There is not word shape in nf23after"
+ puts "Error : There is not word shape in nf19after"
}
if { [regexp "FACE" $info1] != 1 } {
- puts "Error : There is not word FACE in nf23after"
+ puts "Error : There is not word FACE in nf19after"
}
if { [regexp "REVERSED" $info1] != 1 } {
- puts "Error : There is not word REVERSED in nf23after"
+ puts "Error : There is not word REVERSED in nf19after"
}
if { [regexp "Modified" $info1] != 1 } {
- puts "Error : There is not word Modified in nf23after"
+ puts "Error : There is not word Modified in nf19after"
}
if { [regexp "Orientable" $info1] != 1 } {
- puts "Error : There is not word Orientable in nf23after"
+ puts "Error : There is not word Orientable in nf19after"
}
if { [regexp "shape" $info2] != 1 } {
- puts "Error : There is not word shape in nf23before"
+ puts "Error : There is not word shape in nf19before"
}
if { [regexp "FACE" $info2] != 1 } {
- puts "Error : There is not word FACE in nf23before"
+ puts "Error : There is not word FACE in nf19before"
}
if { [regexp "REVERSED" $info2] != 1 } {
- puts "Error : There is not word REVERSED in nf23before"
+ puts "Error : There is not word REVERSED in nf19before"
}
if { [regexp "Modified" $info2] != 1 } {
- puts "Error : There is not word Modified in nf23before"
+ puts "Error : There is not word Modified in nf19before"
}
if { [regexp "Orientable" $info2] != 1 } {
- puts "Error : There is not word Orientable in nf23before"
+ puts "Error : There is not word Orientable in nf19before"
}
\ No newline at end of file
diff --git a/tests/perf/modalg/bug29237_1 b/tests/perf/modalg/bug29237_1
index 37ff7bfaf4..548e87b24c 100644
--- a/tests/perf/modalg/bug29237_1
+++ b/tests/perf/modalg/bug29237_1
@@ -37,10 +37,10 @@ dchrono cpu stop counter OCC29237
# check the result of CUT
checkshape rcut
-checknbshapes rcut -vertex 640 -edge 1760 -wire 842 -face 842 -shell 1 -solid 1
+checknbshapes rcut -vertex 1200 -edge 2040 -wire 842 -face 842 -shell 1 -solid 1 -t -m "CUT"
checkprops rcut -s 3.4136e+006 -v 2.9712e+007
# check the result of COMMON
checkshape rcommon
-checknbshapes rcommon -vertex 616 -edge 1484 -wire 882 -face 882 -shell 147 -solid 147
+checknbshapes rcommon -vertex 1176 -edge 1764 -wire 882 -face 882 -shell 147 -solid 147 -t -m "COMMON"
checkprops rcommon -s 2.13392e+006 -v 1.6448e+007
diff --git a/tests/perf/modalg/bug29237_3 b/tests/perf/modalg/bug29237_3
index 1f38f4fe2a..dc46481621 100644
--- a/tests/perf/modalg/bug29237_3
+++ b/tests/perf/modalg/bug29237_3
@@ -37,10 +37,10 @@ dchrono cpu stop counter OCC29237
# check the result of CUT
checkshape rcut
-checknbshapes rcut -vertex 1294 -edge 3074 -wire 1842 -face 1842 -shell 301 -solid 301
+checknbshapes rcut -vertex 2488 -edge 3732 -wire 1846 -face 1846 -shell 301 -solid 301 -t -m "CUT"
checkprops rcut -s 2.59678e+006 -v 1.5346e+007
# check the result of COMMON
checkshape rcommon
-checknbshapes rcommon -vertex 0 -edge 0 -wire 0 -face 0 -shell 0 -solid 0
+checknbshapes rcommon -vertex 0 -edge 0 -wire 0 -face 0 -shell 0 -solid 0 -t -m "COMMON"
checkprops rcommon -s empty -v empty