1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0029333: Boolean Operations - Prevent modification of the input shapes in case their sub-shapes have not been modified

Prevent modification of the input shapes in destructive mode in case their sub-shapes have not been modified:
1. Prevent edge splitting for the pave blocks with old vertices if it is possible to use the existing edge (*BOPAlgo_PaveFiller::MakeSplitEdges*);
2. Prevent creation of the new containers (WIRES/SHELLS/COMPSOLIDS) if non of its parts have been modified (*BOPAlgo_Builder::FillImagesContainer*);
3. Prevent creation of the new face if non of its wires have been modified (*BOPAlgo_Builder::FillImagesFaces*);
4. If possible, use the original face to be the representative for the group of SD faces (*BOPAlgo_Builder::FillSameDomainFaces*).

Cosmetic changes:
1. Documentation of the *BOPAlgo_Builder* class.
2. Making simple methods of the *BOPAlgo_Builder* class inline.
3. Getting rid of the *BOPAlgo_Builder::mySplits* field as it is excessive. *BOPAlgo_Builder::myImages* can be used instead.
3. Moving the Check Inverted option from *BOPAlgo_Options* to *BOPAlgo_Builder*.

Test cases for the issue.
Adjustment of the test case to their current behavior.
Test case *blend/complex/H2* has been deleted as duplicate of the test case *blend/simple/Z1*.
This commit is contained in:
emv
2017-11-17 16:27:36 +03:00
committed by bugmaster
parent 1155d05a06
commit 81a55a6996
31 changed files with 817 additions and 649 deletions

View File

@@ -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 :
//=======================================================================

View File

@@ -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.<br>
//! It returns TRUE if there is nothing to do, i.e.
//! all shapes in one of the groups are empty shapes.

View File

@@ -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:
//=======================================================================

View File

@@ -53,6 +53,10 @@ class BOPAlgo_PaveFiller;
//! shapes during the operation (by default it is off);<br>
//! - *Gluing options* - allows to speed up the calculation of the intersections
//! on the special cases, in which some sub-shapes are coinciding.<br>
//! - *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

View File

@@ -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

View File

@@ -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; i<aNbS; ++i) {
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(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<aNbS; ++i) {
//
// 4.
aNbVFI=aVVFI.Length();
}
// Perform classification
//================================================================
BOPAlgo_VFICnt::Perform(myRunParallel, aVVFI, myContext);
//================================================================
//
for (i=0; i < aNbVFI; ++i) {
BOPAlgo_VFI& aVFI=aVVFI(i);
//
iFlag=aVFI.Flag();
if (!iFlag) {
TopoDS_Vertex& aVertex=aVFI.Vertex();
TopoDS_Face& aFy=aVFI.Face();
aBB.Add(aFy, aVertex);
Standard_Integer aNbVFI = aVVFI.Length();
for (Standard_Integer i = 0; i < aNbVFI; ++i)
{
BOPAlgo_VFI& aVFI = aVVFI(i);
if (aVFI.IsInternal())
{
TopoDS_Vertex& aV = aVFI.Vertex();
TopoDS_Face& aF = aVFI.Face();
BRep_Builder().Add(aF, aV);
}
}
}

View File

@@ -250,7 +250,7 @@ void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
TopAbs_Orientation aOrF, aOrSh, aOrSd;
TopoDS_Iterator aIt1, aIt2;
TopoDS_Shell aShD;
TopoDS_Shape aFSDx, aFx;
TopoDS_Shape aFx;
BRep_Builder aBB;
TopTools_ListIteratorOfListOfShape aItS;
//
@@ -281,21 +281,20 @@ void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
aFx=aItS.Value();
//
if (myShapesSD.IsBound(aFx)) {
aFSDx=myShapesSD.Find(aFx);
//
if (aOrF==TopAbs_INTERNAL) {
aFSDx.Orientation(aOrF);
theLIF.Append(aFSDx);
aFx.Orientation(aOrF);
theLIF.Append(aFx);
}
else {
bToReverse=BOPTools_AlgoTools::IsSplitToReverse
(aFSDx, aF, myContext);
(aFx, aF, myContext);
if (bToReverse) {
aFSDx.Reverse();
aFx.Reverse();
}
//
iFlag=1;
aBB.Add(aShD, aFSDx);
aBB.Add(aShD, aFx);
}
}//if (myShapesSD.IsBound(aFx)) {
else {

View File

@@ -50,8 +50,7 @@ BOPAlgo_Options::BOPAlgo_Options()
myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
myReport(new Message_Report),
myRunParallel(myGlobalRunParallel),
myFuzzyValue(Precision::Confusion()),
myCheckInverted(Standard_True)
myFuzzyValue(Precision::Confusion())
{
BOPAlgo_LoadMessages();
}
@@ -66,8 +65,7 @@ BOPAlgo_Options::BOPAlgo_Options
myAllocator(theAllocator),
myReport(new Message_Report),
myRunParallel(myGlobalRunParallel),
myFuzzyValue(Precision::Confusion()),
myCheckInverted(Standard_True)
myFuzzyValue(Precision::Confusion())
{
BOPAlgo_LoadMessages();
}

View File

@@ -32,10 +32,6 @@ class Message_ProgressIndicator;
//! touching or coinciding cases;
//! - *Progress indicator* - provides interface to track the progress of
//! operation and stop the operation by user's break.
//! - *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.
//!
class BOPAlgo_Options
{
@@ -160,22 +156,6 @@ public:
//! Set the Progress Indicator object.
Standard_EXPORT void SetProgressIndicator(const Handle(Message_ProgressIndicator)& theObj);
public:
//!@name Check input solids for inverted status
//! 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;
}
protected:
//! Breaks the execution if the break signal
@@ -189,7 +169,6 @@ protected:
Standard_Boolean myRunParallel;
Standard_Real myFuzzyValue;
Handle(Message_ProgressIndicator) myProgressIndicator;
Standard_Boolean myCheckInverted;
};

View File

@@ -26,6 +26,7 @@
#include <BOPDS_Interf.hxx>
#include <BOPDS_Iterator.hxx>
#include <BOPDS_ListOfPaveBlock.hxx>
#include <BOPDS_MapOfCommonBlock.hxx>
#include <BOPDS_MapOfPair.hxx>
#include <BOPDS_MapOfPaveBlock.hxx>
#include <BOPDS_Pave.hxx>
@@ -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; i<aNbPBP; ++i) {
BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
//
aNbPB=aLPB.Extent();
if (aNbPB==1) {
aPB=aLPB.First();
aPB->Indices(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<aNbPBP; ++i) {
//