1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-16 10:08:36 +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

@ -1501,3 +1501,4 @@ The following obsolete features have been removed:
- *IntTools_IndexedDataMapOfTransientAddress* is removed as unused; - *IntTools_IndexedDataMapOfTransientAddress* is removed as unused;
* The container *BiTgte_DataMapOfShapeBox* is replaced with *TopTools_DataMapOfShapeBox*; * The container *BiTgte_DataMapOfShapeBox* is replaced with *TopTools_DataMapOfShapeBox*;
* The class *BOPTools* has been removed as duplicate of the class *TopExp*; * The class *BOPTools* has been removed as duplicate of the class *TopExp*;
* The method *BOPAlgo_Builder::Splits()* has been removed as excessive. The method *BOPAlgo_Builder::Images()* can be used instead.

View File

@ -995,38 +995,17 @@ void BOPAlgo_BOP::BuildSolid()
} }
// //
TopTools_IndexedDataMapOfShapeListOfShape aMEF; TopTools_IndexedDataMapOfShapeListOfShape aMEF;
// Split faces will be added in the end // Fill the list of faces to build the result solids
// to avoid errors in BuilderSolid algorithm TopTools_ListOfShape aSFS;
TopTools_ListOfShape aLF, aLFx;
aNb = aMFS.Extent(); aNb = aMFS.Extent();
for (i = 1; i <= aNb; ++i) { for (i = 1; i <= aNb; ++i) {
const TopTools_ListOfShape& aLSx = aMFS(i); const TopTools_ListOfShape& aLSx = aMFS(i);
if (aLSx.Extent() == 1) { if (aLSx.Extent() == 1) {
const TopoDS_Shape& aFx = aMFS.FindKey(i); const TopoDS_Shape& aFx = aMFS.FindKey(i);
TopExp::MapShapesAndAncestors(aFx, TopAbs_EDGE, TopAbs_FACE, aMEF); TopExp::MapShapesAndAncestors(aFx, TopAbs_EDGE, TopAbs_FACE, aMEF);
if (IsBoundSplits(aFx, aMEF)){
aLFx.Append(aFx);
continue;
}
aLF.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); aSFS.Append(aFx);
} }
//
// Split faces
aItLS.Initialize(aLFx);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aFx = aItLS.Value();
aSFS.Append(aFx);
} }
//
// Internal faces // Internal faces
aNb = aMFI.Extent(); aNb = aMFI.Extent();
for (i = 1; i <= aNb; ++i) { for (i = 1; i <= aNb; ++i) {
@ -1158,54 +1137,6 @@ void BOPAlgo_BOP::BuildSolid()
myShape = aResult; 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 //function : TypeToExplore
//purpose : //purpose :
//======================================================================= //=======================================================================

View File

@ -102,8 +102,6 @@ protected:
Standard_EXPORT void BuildSolid(); Standard_EXPORT void BuildSolid();
Standard_EXPORT Standard_Boolean IsBoundSplits (const TopoDS_Shape& theS, TopTools_IndexedDataMapOfShapeListOfShape& theMEF);
//! Treatment of the cases with empty shapes.<br> //! Treatment of the cases with empty shapes.<br>
//! It returns TRUE if there is nothing to do, i.e. //! It returns TRUE if there is nothing to do, i.e.
//! all shapes in one of the groups are empty shapes. //! all shapes in one of the groups are empty shapes.

View File

@ -49,10 +49,10 @@ BOPAlgo_Builder::BOPAlgo_Builder()
myEntryPoint(0), myEntryPoint(0),
myImages(100, myAllocator), myImages(100, myAllocator),
myShapesSD(100, myAllocator), myShapesSD(100, myAllocator),
mySplits(100, myAllocator),
myOrigins(100, myAllocator), myOrigins(100, myAllocator),
myNonDestructive(Standard_False), myNonDestructive(Standard_False),
myGlue(BOPAlgo_GlueOff) myGlue(BOPAlgo_GlueOff),
myCheckInverted(Standard_True)
{ {
} }
//======================================================================= //=======================================================================
@ -70,10 +70,10 @@ BOPAlgo_Builder::BOPAlgo_Builder
myEntryPoint(0), myEntryPoint(0),
myImages(100, myAllocator), myImages(100, myAllocator),
myShapesSD(100, myAllocator), myShapesSD(100, myAllocator),
mySplits(100, myAllocator),
myOrigins(100, myAllocator), myOrigins(100, myAllocator),
myNonDestructive(Standard_False), myNonDestructive(Standard_False),
myGlue(BOPAlgo_GlueOff) myGlue(BOPAlgo_GlueOff),
myCheckInverted(Standard_True)
{ {
} }
//======================================================================= //=======================================================================
@ -100,7 +100,6 @@ void BOPAlgo_Builder::Clear()
myMapFence.Clear(); myMapFence.Clear();
myImages.Clear(); myImages.Clear();
myShapesSD.Clear(); myShapesSD.Clear();
mySplits.Clear();
myOrigins.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 // function: CheckData
// purpose: // purpose:
//======================================================================= //=======================================================================

View File

@ -53,6 +53,10 @@ class BOPAlgo_PaveFiller;
//! shapes during the operation (by default it is off);<br> //! shapes during the operation (by default it is off);<br>
//! - *Gluing options* - allows to speed up the calculation of the intersections //! - *Gluing options* - allows to speed up the calculation of the intersections
//! on the special cases, in which some sub-shapes are coinciding.<br> //! 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: //! The algorithm returns the following Error statuses:
//! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation; //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;
@ -66,28 +70,108 @@ public:
DEFINE_STANDARD_ALLOC DEFINE_STANDARD_ALLOC
//! Empty constructor.
Standard_EXPORT BOPAlgo_Builder(); Standard_EXPORT BOPAlgo_Builder();
Standard_EXPORT virtual ~BOPAlgo_Builder(); Standard_EXPORT virtual ~BOPAlgo_Builder();
Standard_EXPORT BOPAlgo_Builder(const Handle(NCollection_BaseAllocator)& theAllocator); Standard_EXPORT BOPAlgo_Builder(const Handle(NCollection_BaseAllocator)& theAllocator);
//! Clears the content of the algorithm.
Standard_EXPORT virtual void Clear() Standard_OVERRIDE; Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
Standard_EXPORT BOPAlgo_PPaveFiller PPaveFiller(); //! Returns the PaveFiller, algorithm for sub-shapes intersection.
BOPAlgo_PPaveFiller PPaveFiller()
{
return myPaveFiller;
}
Standard_EXPORT BOPDS_PDS PDS(); //! 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); 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); Standard_EXPORT virtual void SetArguments (const TopTools_ListOfShape& theLS);
Standard_EXPORT const TopTools_ListOfShape& Arguments() const; //! Returns the list of arguments.
const TopTools_ListOfShape& Arguments() const
{
return myArguments;
}
public: //! @name Options
//! 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.
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_Boolean NonDestructive() const
{
return myNonDestructive;
}
//! Sets the glue option for the algorithm
void SetGlue(const BOPAlgo_GlueEnum theGlue)
{
myGlue = theGlue;
}
//! Returns the glue option of the algorithm
BOPAlgo_GlueEnum Glue() const
{
return myGlue;
}
//! 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;
}
public: //! @name Performing the operation
//! Performs the operation.
//! The intersection will be performed also.
Standard_EXPORT virtual void Perform() Standard_OVERRIDE; 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); Standard_EXPORT virtual void PerformWithFiller (const BOPAlgo_PaveFiller& theFiller);
public: //! @name History methods
//! Returns the list of shapes generated from the //! Returns the list of shapes generated from the
//! shape theS. //! shape theS.
Standard_EXPORT virtual const TopTools_ListOfShape& Generated (const TopoDS_Shape& theS) Standard_OVERRIDE; Standard_EXPORT virtual const TopTools_ListOfShape& Generated (const TopoDS_Shape& theS) Standard_OVERRIDE;
@ -99,106 +183,169 @@ Standard_EXPORT virtual ~BOPAlgo_Builder();
//! Returns true if the shape theS has been deleted. //! Returns true if the shape theS has been deleted.
Standard_EXPORT virtual Standard_Boolean IsDeleted (const TopoDS_Shape& theS) Standard_OVERRIDE; 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; public: //! @name Images/Origins
//! Returns myOrigins. //! Returns the map of images.
Standard_EXPORT const TopTools_DataMapOfShapeListOfShape& Origins() const; const TopTools_DataMapOfShapeListOfShape& Images() const
{
return myImages;
}
//! Returns myShapesSD. //! Returns the map of origins.
Standard_EXPORT const TopTools_DataMapOfShapeShape& ShapesSD() const; const TopTools_DataMapOfShapeListOfShape& Origins() const
{
return myOrigins;
}
//! Returns mySplits. //! Returns the map of Same Domain (SD) shapes - coinciding shapes
Standard_EXPORT const TopTools_DataMapOfShapeListOfShape& Splits() const; //! from different arguments.
const TopTools_DataMapOfShapeShape& ShapesSD() const
{
return myShapesSD;
}
//! Sets the flag that defines the mode of treatment. protected: //! @name Methods for building the result
//! 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);
//! 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;
//! Sets the glue option for the algorithm
Standard_EXPORT void SetGlue(const BOPAlgo_GlueEnum theGlue);
//! Returns the glue option of the algorithm
Standard_EXPORT BOPAlgo_GlueEnum Glue() const;
protected:
//! Prepare information for history support
Standard_EXPORT virtual void PrepareHistory() Standard_OVERRIDE;
//! 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); 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); Standard_EXPORT virtual void PerformInternal1 (const BOPAlgo_PaveFiller& thePF);
Standard_EXPORT virtual void CheckData() Standard_OVERRIDE; //! Prepare information for history support.
Standard_EXPORT virtual void PrepareHistory() Standard_OVERRIDE;
//! Checks if the intersection algorithm has Errors/Warnings
Standard_EXPORT void CheckFiller();
Standard_EXPORT virtual void Prepare();
Standard_EXPORT void FillImagesVertices();
Standard_EXPORT void FillImagesEdges();
//! 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); 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.
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();
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 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 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(); 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(); 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 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 FillImagesSolids();
Standard_EXPORT void BuildDraftSolid (const TopoDS_Shape& theSolid, TopoDS_Shape& theDraftSolid, TopTools_ListOfShape& theLIF); //! 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);
Standard_EXPORT virtual void FillIn3DParts (TopTools_DataMapOfShapeListOfShape& theInParts, TopTools_DataMapOfShapeShape& theDraftSolids, const Handle(NCollection_BaseAllocator)& theAllocator); //! Finds faces located inside each solid.
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 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(); 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(); Standard_EXPORT virtual void PostTreat();
TopTools_ListOfShape myArguments; protected: //! @name Fields
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;
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 #endif // _BOPAlgo_Builder_HeaderFile

View File

@ -40,28 +40,22 @@
//======================================================================= //=======================================================================
void BOPAlgo_Builder::FillImagesVertices() void BOPAlgo_Builder::FillImagesVertices()
{ {
Standard_Integer nV, nVSD; TColStd_DataMapIteratorOfDataMapOfIntegerInteger aIt(myDS->ShapesSD());
TColStd_DataMapIteratorOfDataMapOfIntegerInteger aIt; for (; aIt.More(); aIt.Next())
// {
const TColStd_DataMapOfIntegerInteger& aMSDV=myDS->ShapesSD(); Standard_Integer nV = aIt.Key();
aIt.Initialize(aMSDV); Standard_Integer nVSD = aIt.Value();
for (; aIt.More(); aIt.Next()) {
nV=aIt.Key();
nVSD=aIt.Value();
const TopoDS_Shape& aV = myDS->Shape(nV); const TopoDS_Shape& aV = myDS->Shape(nV);
const TopoDS_Shape& aVSD = myDS->Shape(nVSD); const TopoDS_Shape& aVSD = myDS->Shape(nVSD);
// // Add to Images map
TopTools_ListOfShape aLVSD(myAllocator); myImages.Bound(aV, TopTools_ListOfShape(myAllocator))->Append(aVSD);
// // Add to SD map
aLVSD.Append(aVSD);
myImages.Bind(aV, aLVSD);
//
myShapesSD.Bind(aV, aVSD); myShapesSD.Bind(aV, aVSD);
// // Add to Origins map
TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aVSD); TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aVSD);
if (!pLOr) { if (!pLOr)
pLOr = myOrigins.Bound(aVSD, TopTools_ListOfShape()); pLOr = myOrigins.Bound(aVSD, TopTools_ListOfShape());
}
pLOr->Append(aV); 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 //function : BuildResult
//purpose : //purpose :
//======================================================================= //=======================================================================
@ -211,45 +185,57 @@ void BOPAlgo_Builder::FillImagesVertices()
void BOPAlgo_Builder::FillImagesContainer(const TopoDS_Shape& theS, void BOPAlgo_Builder::FillImagesContainer(const TopoDS_Shape& theS,
const TopAbs_ShapeEnum theType) const TopAbs_ShapeEnum theType)
{ {
Standard_Boolean bInterferred, bToReverse; // Check if any of the sub-shapes of the container have been modified
TopoDS_Iterator aIt; TopoDS_Iterator aIt(theS);
BRep_Builder aBB; for (; aIt.More(); aIt.Next())
TopTools_ListIteratorOfListOfShape aItIm; {
// const TopoDS_Shape& aSS = aIt.Value();
bInterferred=IsInterferred(theS); const TopTools_ListOfShape* pLFIm = myImages.Seek(aSS);
if (!bInterferred){ 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; return;
} }
//
BRep_Builder aBB;
// Make the new container of the splits of its sub-shapes
TopoDS_Shape aCIm; TopoDS_Shape aCIm;
BOPTools_AlgoTools::MakeContainer(theType, aCIm); BOPTools_AlgoTools::MakeContainer(theType, aCIm);
//
aIt.Initialize(theS); aIt.Initialize(theS);
for (; aIt.More(); aIt.Next()) { for (; aIt.More(); aIt.Next())
const TopoDS_Shape& aSx=aIt.Value(); {
if (myImages.IsBound(aSx)) { const TopoDS_Shape& aSS = aIt.Value();
const TopTools_ListOfShape& aLFIm=myImages.Find(aSx); const TopTools_ListOfShape* pLSSIm = myImages.Seek(aSS);
aItIm.Initialize(aLFIm);
for (; aItIm.More(); aItIm.Next()) { if (!pLSSIm)
TopoDS_Shape aSxIm=aItIm.Value(); {
// // No splits, add the sub-shape itself
bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSxIm, aSx, myContext); aBB.Add(aCIm, aSS);
if (bToReverse) { continue;
aSxIm.Reverse();
} }
aBB.Add(aCIm, aSxIm);
// 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);
} }
} }
else {
aBB.Add(aCIm, aSx);
}
}
//
aCIm.Closed(BRep_Tool::IsClosed(aCIm)); aCIm.Closed(BRep_Tool::IsClosed(aCIm));
// myImages.Bound(theS, TopTools_ListOfShape(myAllocator))->Append(aCIm);
TopTools_ListOfShape aLSIm(myAllocator);
aLSIm.Append(aCIm);
myImages.Bind(theS, aLSIm);
} }
//======================================================================= //=======================================================================
//function : FillImagesCompound //function : FillImagesCompound

View File

@ -154,7 +154,7 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
BOPAlgo_VFI() : BOPAlgo_VFI() :
BOPAlgo_Algo(), BOPAlgo_Algo(),
myFlag(-1) { myIsInternal(Standard_False) {
} }
// //
virtual ~BOPAlgo_VFI(){ virtual ~BOPAlgo_VFI(){
@ -176,8 +176,8 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
return myF; return myF;
} }
// //
Standard_Integer Flag()const { Standard_Boolean IsInternal()const {
return myFlag; return myIsInternal;
} }
// //
void SetContext(const Handle(IntTools_Context)& aContext) { void SetContext(const Handle(IntTools_Context)& aContext) {
@ -192,11 +192,13 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
Standard_Real aT1, aT2, dummy; Standard_Real aT1, aT2, dummy;
// //
BOPAlgo_Algo::UserBreak(); 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: protected:
Standard_Integer myFlag; Standard_Boolean myIsInternal;
TopoDS_Vertex myV; TopoDS_Vertex myV;
TopoDS_Face myF; TopoDS_Face myF;
Handle(IntTools_Context) myContext; Handle(IntTools_Context) myContext;
@ -223,7 +225,7 @@ void BOPAlgo_Builder::FillImagesFaces()
{ {
BuildSplitFaces(); BuildSplitFaces();
FillSameDomainFaces(); FillSameDomainFaces();
FillImagesFaces1(); FillInternalVertices();
} }
//======================================================================= //=======================================================================
//function : BuildSplitFaces //function : BuildSplitFaces
@ -290,6 +292,20 @@ void BOPAlgo_Builder::BuildSplitFaces()
if (!aNbPBIn && !aNbPBSc) 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 // No internal parts for the face, so just build the draft face
// and keep it to pass directly into result. // and keep it to pass directly into result.
// If the original face has any internal edges, the draft face // If the original face has any internal edges, the draft face
@ -454,7 +470,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
anOriF = aF.Orientation(); anOriF = aF.Orientation();
const TopTools_ListOfShape& aLFR = aFacesIm(k); 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); aIt.Initialize(aLFR);
for (; aIt.More(); aIt.Next()) { for (; aIt.More(); aIt.Next()) {
TopoDS_Shape& aFR=aIt.ChangeValue(); 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) if (pLFSp)
{ {
TopTools_ListIteratorOfListOfShape aItLF(*pLFSp); TopTools_ListIteratorOfListOfShape aItLF(*pLFSp);
@ -649,18 +665,83 @@ void BOPAlgo_Builder::FillSameDomainFaces()
for (; aItB.More(); aItB.Next()) for (; aItB.More(); aItB.Next())
{ {
const TopTools_ListOfShape& aLSD = aItB.Value(); const TopTools_ListOfShape& aLSD = aItB.Value();
// First face will be SD face for all faces in the group // If the group contains some original faces, the one with minimal
const TopoDS_Shape& aFSD1 = aLSD.First(); // 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); TopTools_ListIteratorOfListOfShape aItLF(aLSD);
for (; aItLF.More(); aItLF.Next()) for (; aItLF.More(); aItLF.Next())
{ {
const TopoDS_Shape& aFSD = aItLF.Value(); const TopoDS_Shape& aF = aItLF.Value();
myShapesSD.Bind(aFSD, aFSD1); // Check the index of the face in DS
// If the face has no splits but have an SD face, it is considered as being split const Standard_Integer nF = myDS->Index(aF);
if (myDS->Index(aFSD) >= 0) if (nF >= 0)
mySplits.Bound(aFSD, TopTools_ListOfShape())->Append(aFSD); {
// 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(); aMBlocks.Clear();
aDMSLS.Clear(); aDMSLS.Clear();
} }
@ -668,103 +749,63 @@ void BOPAlgo_Builder::FillSameDomainFaces()
// function: FillImagesFaces1 // function: FillImagesFaces1
// purpose: // purpose:
//======================================================================= //=======================================================================
void BOPAlgo_Builder::FillImagesFaces1() void BOPAlgo_Builder::FillInternalVertices()
{ {
Standard_Integer i, aNbS, iSense, nVx, aNbVFI, iFlag; // Vector of pairs of Vertex/Face for classification of the vertices
TopoDS_Face aFSD; // relatively faces, and adding them as internal into the faces
TopoDS_Vertex aVx;
BRep_Builder aBB;
TColStd_ListOfInteger aLIAV;
TopTools_ListOfShape aLFIm;
TColStd_ListIteratorOfListOfInteger aItV;
TopTools_ListIteratorOfListOfShape aItLS, aItF;
BOPAlgo_VectorOfVFI aVVFI; BOPAlgo_VectorOfVFI aVVFI;
//
aNbS=myDS->NbSourceShapes(); Standard_Integer aNbS = myDS->NbSourceShapes();
for (i=0; i<aNbS; ++i) { for (Standard_Integer i = 0; i < aNbS; ++i)
{
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
if (aSI.ShapeType()!=TopAbs_FACE) { if (aSI.ShapeType() != TopAbs_FACE)
continue; continue;
}
// const TopoDS_Shape& aF = aSI.Shape();
const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape())); const TopTools_ListOfShape* pLFIm = myImages.Seek(aF);
// if (!pLFIm)
if (!mySplits.IsBound(aF)) {
continue; continue;
}
// // Find vertices to add as internal into the splits
// 1. TColStd_ListOfInteger aLIAV;
aLIAV.Clear();
myDS->AloneVertices(i, aLIAV); myDS->AloneVertices(i, aLIAV);
aLFIm.Clear();
// // Add vertices and faces for classification
const TopTools_ListOfShape& aLSp=mySplits.Find(aF); TColStd_ListIteratorOfListOfInteger aItLV(aLIAV);
aItLS.Initialize(aLSp); for (; aItLV.More(); aItLV.Next())
for (; aItLS.More(); aItLS.Next()) { {
const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value())); TopoDS_Vertex aV = TopoDS::Vertex(myDS->Shape(aItLV.Value()));
if (!myShapesSD.IsBound(aFSp)) { aV.Orientation(TopAbs_INTERNAL);
aLFIm.Append(aFSp);
} TopTools_ListIteratorOfListOfShape aItLFIm(*pLFIm);
else { for (; aItLFIm.More(); aItLFIm.Next())
aFSD=(*(TopoDS_Face*)(&myShapesSD.Find(aFSp))); {
iSense=BOPTools_AlgoTools::Sense(aFSp, aFSD, myContext); const TopoDS_Face& aFIm = TopoDS::Face(aItLFIm.Value());
if (iSense<0) { // Make the pair
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(); BOPAlgo_VFI& aVFI = aVVFI.Appended();
aVFI.SetVertex(aVx); aVFI.SetVertex(aV);
aVFI.SetFace(aFy); aVFI.SetFace(aFIm);
aVFI.SetFuzzyValue(myFuzzyValue); aVFI.SetFuzzyValue(myFuzzyValue);
aVFI.SetProgressIndicator(myProgressIndicator); aVFI.SetProgressIndicator(myProgressIndicator);
} }
} }
}// for (i=0; i<aNbS; ++i) { }
//
// 4. // Perform classification
aNbVFI=aVVFI.Length();
//================================================================ //================================================================
BOPAlgo_VFICnt::Perform(myRunParallel, aVVFI, myContext); BOPAlgo_VFICnt::Perform(myRunParallel, aVVFI, myContext);
//================================================================ //================================================================
//
for (i=0; i < aNbVFI; ++i) { Standard_Integer aNbVFI = aVVFI.Length();
for (Standard_Integer i = 0; i < aNbVFI; ++i)
{
BOPAlgo_VFI& aVFI = aVVFI(i); BOPAlgo_VFI& aVFI = aVVFI(i);
// if (aVFI.IsInternal())
iFlag=aVFI.Flag(); {
if (!iFlag) { TopoDS_Vertex& aV = aVFI.Vertex();
TopoDS_Vertex& aVertex=aVFI.Vertex(); TopoDS_Face& aF = aVFI.Face();
TopoDS_Face& aFy=aVFI.Face(); BRep_Builder().Add(aF, aV);
aBB.Add(aFy, aVertex);
} }
} }
} }

View File

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

View File

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

View File

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

View File

@ -26,6 +26,7 @@
#include <BOPDS_Interf.hxx> #include <BOPDS_Interf.hxx>
#include <BOPDS_Iterator.hxx> #include <BOPDS_Iterator.hxx>
#include <BOPDS_ListOfPaveBlock.hxx> #include <BOPDS_ListOfPaveBlock.hxx>
#include <BOPDS_MapOfCommonBlock.hxx>
#include <BOPDS_MapOfPair.hxx> #include <BOPDS_MapOfPair.hxx>
#include <BOPDS_MapOfPaveBlock.hxx> #include <BOPDS_MapOfPaveBlock.hxx>
#include <BOPDS_Pave.hxx> #include <BOPDS_Pave.hxx>
@ -414,12 +415,11 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
return; return;
} }
// //
Standard_Boolean bCB, bV1, bV2; Standard_Integer i, nE, nV1, nV2, nSp, aNbVBSE, k;
Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
Standard_Real aT1, aT2; Standard_Real aT1, aT2;
BOPDS_ListIteratorOfListOfPaveBlock aItPB; BOPDS_ListIteratorOfListOfPaveBlock aItPB;
Handle(BOPDS_PaveBlock) aPB; Handle(BOPDS_PaveBlock) aPB;
BOPDS_MapOfPaveBlock aMPB(100); BOPDS_MapOfCommonBlock aMCB(100);
TopoDS_Vertex aV1, aV2; TopoDS_Vertex aV1, aV2;
TopoDS_Edge aE; TopoDS_Edge aE;
BOPAlgo_VectorOfSplitEdge aVBSE; BOPAlgo_VectorOfSplitEdge aVBSE;
@ -429,56 +429,76 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
// //
aNbPBP=aPBP.Length(); aNbPBP=aPBP.Length();
// //
for (i=0; i<aNbPBP; ++i) { for (i = 0; i < aNbPBP; ++i)
{
BOPDS_ListOfPaveBlock& aLPB = aPBP(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;
}
}
}
//
aItPB.Initialize(aLPB); aItPB.Initialize(aLPB);
for (; aItPB.More(); aItPB.Next()) { for (; aItPB.More(); aItPB.Next()) {
aPB = aItPB.Value(); aPB = aItPB.Value();
nE = aPB->OriginalEdge(); nE = aPB->OriginalEdge();
const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE); const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
if (aSIE.HasFlag()){ if (aSIE.HasFlag())
{
// Skip degenerated edges
continue; continue;
} }
//
const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB); const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
bCB=!aCB.IsNull(); Standard_Boolean bCB = !aCB.IsNull();
if (bCB) { if (bCB && !aMCB.Add(aCB))
aPB=aCB->PaveBlock1(); 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())
if (aMPB.Add(aPB)) { {
// 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;
}
}
}
// Split the edge
if (bCB)
{
aPB = aCB->PaveBlock1();
nE = aPB->OriginalEdge(); nE = aPB->OriginalEdge();
aPB->Indices(nV1, nV2); aPB->Indices(nV1, nV2);
}
aPB->Range(aT1, aT2); aPB->Range(aT1, aT2);
// //
aE = (*(TopoDS_Edge *)(&myDS->Shape(nE))); aE = (*(TopoDS_Edge *)(&myDS->Shape(nE)));
@ -499,7 +519,6 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
} }
aBSE.SetDS(myDS); aBSE.SetDS(myDS);
aBSE.SetProgressIndicator(myProgressIndicator); aBSE.SetProgressIndicator(myProgressIndicator);
}
} // for (; aItPB.More(); aItPB.Next()) { } // for (; aItPB.More(); aItPB.Next()) {
} // for (i=0; i<aNbPBP; ++i) { } // for (i=0; i<aNbPBP; ++i) {
// //

View File

@ -116,6 +116,23 @@ void BOPDS_CommonBlock::AppendFaces(TColStd_ListOfInteger& aLF)
return myPaveBlocks.First(); return myPaveBlocks.First();
} }
//======================================================================= //=======================================================================
// function: SetRealPaveBlock
// purpose:
//=======================================================================
void BOPDS_CommonBlock::SetRealPaveBlock(const Handle(BOPDS_PaveBlock)& thePB)
{
BOPDS_ListIteratorOfListOfPaveBlock it(myPaveBlocks);
for (; it.More(); it.Next())
{
if (it.Value() == thePB)
{
myPaveBlocks.Prepend(thePB);
myPaveBlocks.Remove(it);
break;
}
}
}
//=======================================================================
// function: PaveBlockOnEdge // function: PaveBlockOnEdge
// purpose: // purpose:
//======================================================================= //=======================================================================

View File

@ -149,29 +149,21 @@ public:
Standard_EXPORT void Dump() const; Standard_EXPORT void Dump() const;
//! Moves the pave blocks in the list to make the given
//! pave block to be the first.
//! It will be representative for the whole group.
Standard_EXPORT void SetRealPaveBlock(const Handle(BOPDS_PaveBlock)& thePB);
DEFINE_STANDARD_RTTIEXT(BOPDS_CommonBlock,Standard_Transient) DEFINE_STANDARD_RTTIEXT(BOPDS_CommonBlock,Standard_Transient)
protected: protected:
BOPDS_ListOfPaveBlock myPaveBlocks; BOPDS_ListOfPaveBlock myPaveBlocks;
TColStd_ListOfInteger myFaces; TColStd_ListOfInteger myFaces;
private: private:
}; };
#endif // _BOPDS_CommonBlock_HeaderFile #endif // _BOPDS_CommonBlock_HeaderFile

View File

@ -55,7 +55,6 @@ public:
using BOPAlgo_Options::ClearWarnings; using BOPAlgo_Options::ClearWarnings;
using BOPAlgo_Options::GetReport; using BOPAlgo_Options::GetReport;
using BOPAlgo_Options::SetProgressIndicator; using BOPAlgo_Options::SetProgressIndicator;
using BOPAlgo_Options::SetCheckInverted;
protected: protected:

View File

@ -29,7 +29,8 @@ BRepAlgoAPI_BuilderAlgo::BRepAlgoAPI_BuilderAlgo()
myDSFiller(NULL), myDSFiller(NULL),
myBuilder(NULL), myBuilder(NULL),
myNonDestructive(Standard_False), myNonDestructive(Standard_False),
myGlue(BOPAlgo_GlueOff) myGlue(BOPAlgo_GlueOff),
myCheckInverted(Standard_True)
{} {}
//======================================================================= //=======================================================================
// function: // function:
@ -42,7 +43,8 @@ BRepAlgoAPI_BuilderAlgo::BRepAlgoAPI_BuilderAlgo
myEntryType(0), myEntryType(0),
myBuilder(NULL), myBuilder(NULL),
myNonDestructive(Standard_False), myNonDestructive(Standard_False),
myGlue(BOPAlgo_GlueOff) myGlue(BOPAlgo_GlueOff),
myCheckInverted(Standard_True)
{ {
BOPAlgo_PaveFiller* pPF=(BOPAlgo_PaveFiller*)&aPF; BOPAlgo_PaveFiller* pPF=(BOPAlgo_PaveFiller*)&aPF;
myDSFiller=pPF; myDSFiller=pPF;

View File

@ -31,9 +31,19 @@ class BOPAlgo_PaveFiller;
class TopoDS_Shape; class TopoDS_Shape;
//! The class contains API level of the General Fuse algorithm.<br> //! The class contains API level of the General Fuse algorithm.<br>
//! //!
//! Additionally to the options defined in the base class, the algorithm has
//! the following options:<br>
//! - *Safe processing mode* - allows to avoid modification of the input
//! shapes during the operation (by default it is off);
//! - *Gluing options* - allows to speed up the calculation of the intersections
//! on the special cases, in which some sub-shapes are coinciding.
//! - *Disabling the check for inverted solids* - Disables/Enables the check of the input solids
//! for inverted status (holes in the space). The default value is TRUE,
//! i.e. the check is performed. Setting this flag to FALSE for inverted solids,
//! most likely will lead to incorrect results.
//!
//! It returns the following Error statuses:<br> //! It returns the following Error statuses:<br>
//! - 0 - in case of success;<br> //! - 0 - in case of success;<br>
//! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;<br> //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;<br>
@ -72,6 +82,19 @@ Standard_EXPORT virtual ~BRepAlgoAPI_BuilderAlgo();
//! Returns the glue option of the algorithm //! Returns the glue option of the algorithm
Standard_EXPORT BOPAlgo_GlueEnum Glue() const; Standard_EXPORT BOPAlgo_GlueEnum Glue() const;
//! Enables/Disables the check of the input solids for inverted status
void SetCheckInverted(const Standard_Boolean theCheck)
{
myCheckInverted = theCheck;
}
//! Returns the flag defining whether the check for input solids on inverted status
//! should be performed or not.
Standard_Boolean CheckInverted() const
{
return myCheckInverted;
}
//! Sets the arguments //! Sets the arguments
Standard_EXPORT void SetArguments (const TopTools_ListOfShape& theLS); Standard_EXPORT void SetArguments (const TopTools_ListOfShape& theLS);
@ -130,20 +153,10 @@ protected:
Standard_Boolean myNonDestructive; Standard_Boolean myNonDestructive;
TopTools_ListOfShape myArguments; TopTools_ListOfShape myArguments;
BOPAlgo_GlueEnum myGlue; BOPAlgo_GlueEnum myGlue;
Standard_Boolean myCheckInverted;
private: private:
}; };
#endif // _BRepAlgoAPI_BuilderAlgo_HeaderFile #endif // _BRepAlgoAPI_BuilderAlgo_HeaderFile

View File

@ -503,9 +503,7 @@
} }
} }
// //
mySplits.Bind(aF, aLFIm);
if (aLFIm.Extent() == 0) { if (aLFIm.Extent() == 0) {
mySplits.UnBind(aF);
myImages.UnBind(aF); myImages.UnBind(aF);
} }
} }

View File

@ -5632,14 +5632,8 @@ void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImage
GetBoundsToUpdate(aLF, theOEImages, theOEOrigins, aMEB, GetBoundsToUpdate(aLF, theOEImages, theOEOrigins, aMEB,
aLABounds, aLAValid, aBounds, theAsDes); aLABounds, aLAValid, aBounds, theAsDes);
// //
// intersect valid splits with bounds and update both // Intersect valid splits with bounds and update both
BOPAlgo_Builder aGF; BOPAlgo_Builder aGF;
// The order is important here, because we need to keep the
// unmodified edges from the Bounds in the resulting maps.
// In case of total coincidence of the edges with the same vertices
// the edges in the common block will not be split and no new
// edges will be created and the first pave block
// will be used as a real pave block.
aGF.AddArgument(aBounds); aGF.AddArgument(aBounds);
aGF.AddArgument(aSplits); aGF.AddArgument(aSplits);
aGF.Perform(); aGF.Perform();
@ -5667,18 +5661,56 @@ void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImage
} }
} }
// //
// Rebuild the map of edges to avoid, using the intersection results
TopTools_IndexedMapOfShape aMEAvoid;
// GF's data structure
const BOPDS_PDS& pDS = aGF.PDS();
aNbE = theEdgesToAvoid.Extent(); aNbE = theEdgesToAvoid.Extent();
for (i = 1; i <= aNbE; ++i) { for (i = 1; i <= aNbE; ++i)
{
const TopoDS_Shape& aE = theEdgesToAvoid(i); const TopoDS_Shape& aE = theEdgesToAvoid(i);
const TopTools_ListOfShape& aLEIm = aGF.Modified(aE); const TopTools_ListOfShape& aLEIm = aGF.Modified(aE);
// Only untouched and fully coinciding edges should be kept in the avoid map
Standard_Boolean bKeep = aLEIm.IsEmpty();
if (aLEIm.Extent() == 1 && aE.IsSame(aLEIm.First()))
{
const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(pDS->Index(aE));
if (aLPB.Extent() == 1)
{
const Handle(BOPDS_PaveBlock)& aPB = aLPB.First();
const Handle(BOPDS_CommonBlock)& aCB = pDS->CommonBlock(aPB);
if (!aCB.IsNull())
{
const BOPDS_ListOfPaveBlock& aLPBCB = aCB->PaveBlocks();
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBCB);
for (; aItLPB.More(); aItLPB.Next())
{
if (pDS->PaveBlocks(aItLPB.Value()->OriginalEdge()).Extent() > 1)
break;
}
bKeep = !aItLPB.More();
}
}
}
if (bKeep)
{
// keep the original edge
aMEAvoid.Add(aE);
continue;
}
TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
for (; aItLEIm.More(); aItLEIm.Next()) { for (; aItLEIm.More(); aItLEIm.Next())
{
const TopoDS_Shape& aEIm = aItLEIm.Value(); const TopoDS_Shape& aEIm = aItLEIm.Value();
if (!aNewEdges.Contains(aEIm)) { if (!aNewEdges.Contains(aEIm))
theEdgesToAvoid.Add(aEIm); aMEAvoid.Add(aEIm);
}
} }
} }
theEdgesToAvoid = aMEAvoid;
} }
//======================================================================= //=======================================================================

View File

@ -8,6 +8,6 @@ pcylinder c2 5 20
ttranslate c2 4.9 0 10 ttranslate c2 4.9 0 10
bfuse f c1b c2 bfuse f c1b c2
explode f E explode f E
blend result f 4.9 f_5 blend result f 4.9 f_4
checkprops result -s 2104.35 checkprops result -s 2104.35

View File

@ -1,16 +0,0 @@
# ====================================
## Grid : CFI900
## Test : N1
## Comment : from USA60109
## ====================================
pcylinder c1 10 20
pcylinder c2 5 20
ttranslate c2 5 0 20
bfuse f c1 c2
explode f E
blend result f 1 f_1
explode result sh
renamevar result_1 result
checkprops result -s 2485.86

View File

@ -5,6 +5,6 @@ pcylinder c 1 10
ttranslate c 2.5 2.5 2.5 ttranslate c 2.5 2.5 2.5
bfuse s c b bfuse s c b
explode s E explode s E
blend result s 1 s_3 blend result s 1 s_2
checkprops result -s 192.343 checkprops result -s 192.343

View File

@ -7,8 +7,8 @@ ttranslate c2 5 0 20
bfuse f c1 c2 bfuse f c1 c2
explode f E explode c1 e
blend result f 1 f_1 blend result f 1 c1_3
checkprops result -s 2485.86 checkprops result -s 2485.86

View File

@ -26,7 +26,7 @@ bop beam_1 cut_2
bopcut result bopcut result
checkshape result checkshape result
checknbshapes result -solid 2 -shell 2 -face 32 -wire 39 checknbshapes result -solid 2 -shell 2 -face 33 -wire 40 -t
checkprops result -v 5.40325e+7 checkprops result -v 5.40325e+7
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -42,7 +42,7 @@ bop beam_2 cut_2
bopcut result bopcut result
checkshape result checkshape result
checknbshapes result -solid 4 -shell 4 -face 64 -wire 73 checknbshapes result -solid 4 -shell 4 -face 64 -wire 73 -t
checkprops result -v 1.61677e+8 checkprops result -v 1.61677e+8
checkview -display result -2d -path ${imagedir}/${test_image}.png checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -11,20 +11,15 @@ puts ""
smallview smallview
box a -1.5 -1.5 0 3 3 3 restore [locate_data_file bug27711.brep] s
box b -3 -3 -3 6 6 3
bfuse result a b
set bug_info [string trim [checkshape result]]
if {$bug_info != "This shape seems to be valid"} {
puts "ERROR: Problem of test case functionality. Should be additionally investigated."
}
clear clear
display result display s
fit fit
xwd $imagedir/${casename}_step_0.png xwd $imagedir/${casename}_step_0.png
explode result e explode s e
blend result result 0.5 result_12 0.5 result_11 blend result s 0.5 s_12 0.5 s_11
set bug_info [string trim [checkshape result]] set bug_info [string trim [checkshape result]]
if {$bug_info != "This shape seems to be valid"} { if {$bug_info != "This shape seems to be valid"} {
puts "ERROR: Problem of test case functionality. Should be additionally investigated." puts "ERROR: Problem of test case functionality. Should be additionally investigated."

View File

@ -0,0 +1,65 @@
puts "========"
puts "OCC29333"
puts "========"
puts ""
#################################################
# Boolean Operations - Prevent modification of the input shapes in case their sub-shapes have not been modified
#################################################
# create two touching faces
plane p 0 0 0 0 0 1
mkface f1 p -10 10 -10 10
copy f1 f2
ttranslate f2 20 0 0
# fuse these faces
bfuse s f1 f2
# split one of these faces
explode s f
line l 0 0 0 1 0 0
mkedge e l
bclearobjects
bcleartools
baddobjects s_1
baddtools e
bfillds
bsplit s1_sp
# fuse again
bclearobjects
bcleartools
baddobjects s1_sp
baddtools s_2
bfillds
bbuild result
checkshape result
checkprops result -s 800
checknbshapes result -vertex 8 -edge 10 -wire 3 -face 3
# check that non of the shapes from s1_sp is modified
compound result s1_sp c
checknbshapes c -vertex 8 -edge 10 -wire 3 -face 3
# fuse with different order
bclearobjects
bcleartools
baddobjects s_2
baddtools s1_sp
bfillds
bbuild result
checkshape result
checkprops result -s 800
checknbshapes result -vertex 8 -edge 10 -wire 3 -face 3
# check that non of the shapes from s1_sp is modified
compound result s1_sp c
checknbshapes c -vertex 8 -edge 10 -wire 3 -face 3

View File

@ -0,0 +1,62 @@
puts "========"
puts "OCC29333"
puts "========"
puts ""
#################################################
# Boolean Operations - Prevent modification of the input shapes in case their sub-shapes have not been modified
#################################################
# create two touching boxes
box b1 10 10 10
box b2 10 0 0 10 10 10
# make them share the common face
mkvolume s b1 b2
# split one of these solids
explode s so
plane p 0 0 5 0 0 1
mkface f p
bclearobjects
bcleartools
baddobjects s_1
baddtools f
bfillds
bsplit s1_sp
# fuse again
bclearobjects
bcleartools
baddobjects s1_sp
baddtools s_2
bfillds
bbuild result
checkshape result
checkprops result -s 1400 -v 2000
checknbshapes result -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
# check that non of the shapes from s1_sp is modified
compound result s1_sp c
checknbshapes c -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
# fuse with different order
bclearobjects
bcleartools
baddobjects s_2
baddtools s1_sp
bfillds
bbuild result
checkshape result
checkprops result -s 1400 -v 2000
checknbshapes result -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
# check that non of the shapes from s1_sp is modified
compound result s1_sp c
checknbshapes c -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3

View File

@ -9,7 +9,7 @@
# 1. Create 3 boxes $B1, $B2, $B3 # 1. Create 3 boxes $B1, $B2, $B3
# 2. $FS1 = Fuse ($B1, $B2) # 2. $FS1 = Fuse ($B1, $B2)
# 3. $FS2 = Fuse ($B1, $B3) # 3. $FS2 = Fuse ($B1, $B3)
# 4. Make selections of the face 'fuse2_23' # 4. Make selections of the face 'fuse2_19'
# 5. Modify B2 # 5. Modify B2
# 6. Recompute # 6. Recompute
# =============================================== # ===============================================
@ -37,12 +37,12 @@ GetShape $doc $FS2:2 fuse2
explode fuse2 f explode fuse2 f
#4. select fuse2_23 (using SelectShape) #4. select fuse2_19 (using SelectShape)
set Sel1 0:2:23 set Sel1 0:2:19
SelectShape $doc $Sel1 fuse2_23 fuse2 SelectShape $doc $Sel1 fuse2_19 fuse2
GetShape $doc $Sel1 f23before GetShape $doc $Sel1 f19before
#f23before is face #f19before is face
set info1 [whatis f23before] set info1 [whatis f19before]
#5. Modify #5. Modify
@ -53,40 +53,40 @@ ComputeFun $doc $B2:1
ComputeFun $doc $FS1 ComputeFun $doc $FS1
ComputeFun $doc $FS2 ComputeFun $doc $FS2
SolveSelection $doc $Sel1 SolveSelection $doc $Sel1
GetShape $doc $Sel1 f23after GetShape $doc $Sel1 f19after
#f23after is face #f19after is face
set info2 [whatis f23after] set info2 [whatis f19after]
if { [regexp "shape" $info1] != 1 } { if { [regexp "shape" $info1] != 1 } {
puts "Error : There is not word shape in f23after" puts "Error : There is not word shape in f19after"
} }
if { [regexp "FACE" $info1] != 1 } { if { [regexp "FACE" $info1] != 1 } {
puts "Error : There is not word FACE in f23after" puts "Error : There is not word FACE in f19after"
} }
if { [regexp "REVERSED" $info1] != 1 } { if { [regexp "REVERSED" $info1] != 1 } {
puts "Error : There is not word REVERSED in f23after" puts "Error : There is not word REVERSED in f19after"
} }
if { [regexp "Modified" $info1] != 1 } { if { [regexp "Modified" $info1] != 1 } {
puts "Error : There is not word Modified in f23after" puts "Error : There is not word Modified in f19after"
} }
if { [regexp "Orientable" $info1] != 1 } { if { [regexp "Orientable" $info1] != 1 } {
puts "Error : There is not word Orientable in f23after" puts "Error : There is not word Orientable in f19after"
} }
if { [regexp "shape" $info2] != 1 } { if { [regexp "shape" $info2] != 1 } {
puts "Error : There is not word shape in f23before" puts "Error : There is not word shape in f19before"
} }
if { [regexp "FACE" $info2] != 1 } { if { [regexp "FACE" $info2] != 1 } {
puts "Error : There is not word FACE in f23before" puts "Error : There is not word FACE in f19before"
} }
if { [regexp "REVERSED" $info2] != 1 } { if { [regexp "REVERSED" $info2] != 1 } {
puts "Error : There is not word REVERSED in f23before" puts "Error : There is not word REVERSED in f19before"
} }
if { [regexp "Modified" $info2] != 1 } { if { [regexp "Modified" $info2] != 1 } {
puts "Error : There is not word Modified in f23before" puts "Error : There is not word Modified in f19before"
} }
if { [regexp "Orientable" $info2] != 1 } { if { [regexp "Orientable" $info2] != 1 } {
puts "Error : There is not word Orientable in f23before" puts "Error : There is not word Orientable in f19before"
} }

View File

@ -9,7 +9,7 @@
# 1. Create 3 boxes $B1, $B2, $B3 # 1. Create 3 boxes $B1, $B2, $B3
# 2. $FS1 = Fuse ($B1, $B2) # 2. $FS1 = Fuse ($B1, $B2)
# 3. $FS2 = Fuse ($B1, $B3) # 3. $FS2 = Fuse ($B1, $B3)
# 4. Make selections of the face 'fuse2_23' # 4. Make selections of the face 'fuse2_19'
# 5. Modify B2 # 5. Modify B2
# 6. Recompute # 6. Recompute
# =============================================== # ===============================================
@ -38,11 +38,11 @@ explode fuse2 f
#4. Select fuse2_23 using Attach #4. Select fuse2_19 using Attach
set Sel2 [AttachShape $doc fuse2_23 $B1] set Sel2 [AttachShape $doc fuse2_19 $B1]
GetShape $doc $Sel2:1:2 nf23before GetShape $doc $Sel2:1:2 nf19before
#nf23before is face #nf19before is face
set info1 [whatis nf23before] set info1 [whatis nf19before]
#5. Modify #5. Modify
@ -56,38 +56,38 @@ ComputeFun $doc $B3:1
ComputeFun $doc $FS1 ComputeFun $doc $FS1
ComputeFun $doc $FS2 ComputeFun $doc $FS2
ComputeFun $doc $Sel2:1 ComputeFun $doc $Sel2:1
GetShape $doc $Sel2:1:2 nf23after GetShape $doc $Sel2:1:2 nf19after
#nf23after is face #nf19after is face
set info2 [whatis nf23after] set info2 [whatis nf19after]
if { [regexp "shape" $info1] != 1 } { if { [regexp "shape" $info1] != 1 } {
puts "Error : There is not word shape in nf23after" puts "Error : There is not word shape in nf19after"
} }
if { [regexp "FACE" $info1] != 1 } { if { [regexp "FACE" $info1] != 1 } {
puts "Error : There is not word FACE in nf23after" puts "Error : There is not word FACE in nf19after"
} }
if { [regexp "REVERSED" $info1] != 1 } { if { [regexp "REVERSED" $info1] != 1 } {
puts "Error : There is not word REVERSED in nf23after" puts "Error : There is not word REVERSED in nf19after"
} }
if { [regexp "Modified" $info1] != 1 } { if { [regexp "Modified" $info1] != 1 } {
puts "Error : There is not word Modified in nf23after" puts "Error : There is not word Modified in nf19after"
} }
if { [regexp "Orientable" $info1] != 1 } { if { [regexp "Orientable" $info1] != 1 } {
puts "Error : There is not word Orientable in nf23after" puts "Error : There is not word Orientable in nf19after"
} }
if { [regexp "shape" $info2] != 1 } { if { [regexp "shape" $info2] != 1 } {
puts "Error : There is not word shape in nf23before" puts "Error : There is not word shape in nf19before"
} }
if { [regexp "FACE" $info2] != 1 } { if { [regexp "FACE" $info2] != 1 } {
puts "Error : There is not word FACE in nf23before" puts "Error : There is not word FACE in nf19before"
} }
if { [regexp "REVERSED" $info2] != 1 } { if { [regexp "REVERSED" $info2] != 1 } {
puts "Error : There is not word REVERSED in nf23before" puts "Error : There is not word REVERSED in nf19before"
} }
if { [regexp "Modified" $info2] != 1 } { if { [regexp "Modified" $info2] != 1 } {
puts "Error : There is not word Modified in nf23before" puts "Error : There is not word Modified in nf19before"
} }
if { [regexp "Orientable" $info2] != 1 } { if { [regexp "Orientable" $info2] != 1 } {
puts "Error : There is not word Orientable in nf23before" puts "Error : There is not word Orientable in nf19before"
} }

View File

@ -37,10 +37,10 @@ dchrono cpu stop counter OCC29237
# check the result of CUT # check the result of CUT
checkshape rcut checkshape rcut
checknbshapes rcut -vertex 640 -edge 1760 -wire 842 -face 842 -shell 1 -solid 1 checknbshapes rcut -vertex 1200 -edge 2040 -wire 842 -face 842 -shell 1 -solid 1 -t -m "CUT"
checkprops rcut -s 3.4136e+006 -v 2.9712e+007 checkprops rcut -s 3.4136e+006 -v 2.9712e+007
# check the result of COMMON # check the result of COMMON
checkshape rcommon checkshape rcommon
checknbshapes rcommon -vertex 616 -edge 1484 -wire 882 -face 882 -shell 147 -solid 147 checknbshapes rcommon -vertex 1176 -edge 1764 -wire 882 -face 882 -shell 147 -solid 147 -t -m "COMMON"
checkprops rcommon -s 2.13392e+006 -v 1.6448e+007 checkprops rcommon -s 2.13392e+006 -v 1.6448e+007

View File

@ -37,10 +37,10 @@ dchrono cpu stop counter OCC29237
# check the result of CUT # check the result of CUT
checkshape rcut checkshape rcut
checknbshapes rcut -vertex 1294 -edge 3074 -wire 1842 -face 1842 -shell 301 -solid 301 checknbshapes rcut -vertex 2488 -edge 3732 -wire 1846 -face 1846 -shell 301 -solid 301 -t -m "CUT"
checkprops rcut -s 2.59678e+006 -v 1.5346e+007 checkprops rcut -s 2.59678e+006 -v 1.5346e+007
# check the result of COMMON # check the result of COMMON
checkshape rcommon checkshape rcommon
checknbshapes rcommon -vertex 0 -edge 0 -wire 0 -face 0 -shell 0 -solid 0 checknbshapes rcommon -vertex 0 -edge 0 -wire 0 -face 0 -shell 0 -solid 0 -t -m "COMMON"
checkprops rcommon -s empty -v empty checkprops rcommon -s empty -v empty