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:
@@ -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 :
|
||||
//=======================================================================
|
||||
|
@@ -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.
|
||||
|
@@ -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:
|
||||
//=======================================================================
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
@@ -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) {
|
||||
//
|
||||
|
Reference in New Issue
Block a user