]> OCCT Git - occt-copy.git/commitdiff
0029580: Regression: invalid result of BOP Fuse
authoremv <emv@opencascade.com>
Thu, 15 Mar 2018 14:02:46 +0000 (17:02 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 20 Mar 2018 12:18:16 +0000 (15:18 +0300)
Boolean Operation - avoid creation of INTERNAL solid from unclassified faces in Solid Builder algorithm.
Instead warn the user that some of the faces have been unclassified and not used for solids creation.

Adjustment of the test cases.
Test cases for the issue.

18 files changed:
dox/dev_guides/upgrade/upgrade.md
src/BOPAlgo/BOPAlgo.msg
src/BOPAlgo/BOPAlgo_Alerts.hxx
src/BOPAlgo/BOPAlgo_BOP.cxx
src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx
src/BOPAlgo/BOPAlgo_BuilderSolid.cxx
src/BOPAlgo/BOPAlgo_BuilderSolid.hxx
src/BOPAlgo/BOPAlgo_Builder_3.cxx
src/BOPAlgo/BOPAlgo_CellsBuilder.cxx
src/BOPAlgo/BOPAlgo_MakerVolume.cxx
src/BOPAlgo/BOPAlgo_Tools.cxx
tests/boolean/bcut_complex/F2
tests/bugs/modalg_6/bug26789_1
tests/bugs/modalg_7/bug25983 [deleted file]
tests/bugs/modalg_7/bug25983_1 [new file with mode: 0644]
tests/bugs/modalg_7/bug25983_2 [new file with mode: 0644]
tests/bugs/modalg_7/bug29580_1 [new file with mode: 0644]
tests/bugs/modalg_7/bug29580_2 [new file with mode: 0644]

index 450b7443d669e8a84d9c4eb91679c5980b3e16a1..6742c1e57a61e68b56856e73ad7e0f4788c5aec9 100644 (file)
@@ -1552,3 +1552,11 @@ Since new version, the method BRepAdaptor_CompCurve::IsPeriodic() will always re
 
 Interfaces of the following methods have been changed: IntPatch_WLineTool::ComputePurgedWLine(...), IntPatch_PrmPrmIntersection::Perform(...), IntPatch_Intersection::Perform(...), IntPatch_Intersection::ParamParamPerfom(...), IntPatch_Intersection::GeomGeomPerfom(...). Please see documentation about corresponding methods.
 
+@subsection upgrade_730_BuilderSolid Boolean Operations - Solid Builder algorithm
+
+Previously, the unclassified faces of *BOPAlgo_BuilderSolid* algorithm (the faces which have not been used for solids creation and located outside of all created solids) have been used to form an additional solid (not closed one) with INTERNAL orientation.
+Since new version, these unclassified faces are no longer added into resulting solids. Instead, the @ref occt_algorithms_ers "warning" containing these faces appears.
+
+The following public methods of the *BOPAlgo_BuilderSolid* class have been removed as excessive:
+* void SetSolid(const TopoDS_Solid& theSolid);
+* const TopoDS_Solid& Solid() const;
index e6c22a306c0e0433834fbe4532b71b6089feccbb..72c842f7df9e121e46ee52fae8a164e399985e7e 100644 (file)
@@ -88,3 +88,6 @@ Error: No faces have been found for removal
 
 .BOPAlgo_AlertRemoveFeaturesFailed
 Error: The Feature Removal algorithm has failed
+
+.BOPAlgo_AlertSolidBuilderUnusedFaces
+Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation
index 806184d0fd7eb33444e35e760303d8987c2240e8..7a4f927f7658bcb991739d8bb52cc4b9860b2615 100644 (file)
@@ -100,4 +100,8 @@ DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToRemoveTheFeature)
 //! The Feature Removal algorithm has failed
 DEFINE_SIMPLE_ALERT(BOPAlgo_AlertRemoveFeaturesFailed)
 
+//! Some of the faces passed to the Solid Builder algorithm have not been classified
+//! and not used for solids creation
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertSolidBuilderUnusedFaces)
+
 #endif // _BOPAlgo_Alerts_HeaderFile
index 17343295fd47fdd7541a4392d234d42db74ac6e1..3d1271c59541ff0df189a9f269781893d23f517c 100644 (file)
@@ -1019,16 +1019,19 @@ void BOPAlgo_BOP::BuildSolid()
   BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC);
   if (aSFS.Extent()) {
     // Build solids from set of faces
-    BOPAlgo_BuilderSolid aSB;
-    aSB.SetContext(myContext);
-    aSB.SetShapes(aSFS);
-    aSB.Perform();
-    if (aSB.HasErrors()) {
+    BOPAlgo_BuilderSolid aBS;
+    aBS.SetContext(myContext);
+    aBS.SetShapes(aSFS);
+    aBS.Perform();
+    if (aBS.HasErrors()) {
       AddError (new BOPAlgo_AlertSolidBuilderFailed); // SolidBuilder failed
       return;
     }
+
+    myReport->Merge(aBS.GetReport());
+
     // new solids
-    const TopTools_ListOfShape& aLSR = aSB.Areas();
+    const TopTools_ListOfShape& aLSR = aBS.Areas();
     //
     // add new solids to result
     aItLS.Initialize(aLSR);
index 6d3ff3882aee66dba518b830287d3859afc5fff0..6cd2187474dd154d0b42e3bf9d05eef4cf283504 100644 (file)
@@ -90,4 +90,7 @@ static const char BOPAlgo_BOPAlgo_msg[] =
   "Error: No faces have been found for removal\n"
   "\n"
   ".BOPAlgo_AlertRemoveFeaturesFailed\n"
-  "Error: The Feature Removal algorithm has failed\n";
+  "Error: The Feature Removal algorithm has failed\n"
+  "\n"
+  ".BOPAlgo_AlertSolidBuilderUnusedFaces\n"
+  "Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n";
index d9e62412678d397a81047872a81d4893cad60ce7..bcff591cd79a1b3801235c2e510983cf24455d1b 100644 (file)
@@ -103,22 +103,6 @@ BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
 {
 }
 //=======================================================================
-//function : SetSolid 
-//purpose  : 
-//=======================================================================
-void BOPAlgo_BuilderSolid::SetSolid(const TopoDS_Solid& aS)
-{
-  mySolid=aS;
-}
-//=======================================================================
-//function : Solid 
-//purpose  : 
-//=======================================================================
-const TopoDS_Solid& BOPAlgo_BuilderSolid::Solid()const
-{
-  return mySolid;
-}
-//=======================================================================
 //function : Perform
 //purpose  : 
 //=======================================================================
@@ -674,8 +658,10 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
     }
   }
 
-  // Make solid from the unused faces (if any)
+  // Find all unclassified faces and warn the user about them.
+  // Do not put such faces into result as they will form not closed solid.
   TopTools_IndexedMapOfShape aMFUnUsed;
+
   for (i = 1; i <= aNbF; ++i)
   {
     const TopoDS_Shape& aF = aMFs(i);
@@ -685,24 +671,21 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
 
   if (aMFUnUsed.Extent())
   {
-    TopoDS_Solid aSolid;
-    aBB.MakeSolid(aSolid);
-    //
     TopTools_ListOfShape aLSI;
     MakeInternalShells(aMFUnUsed, aLSI);
-    //
-    aItLS.Initialize(aLSI);
-    for (; aItLS.More(); aItLS.Next())
-    {
-      const TopoDS_Shape& aSI = aItLS.Value();
-      aBB.Add (aSolid, aSI);
 
-      Bnd_Box aBox;
-      BRepBndLib::Add(aSolid, aBox);
-      myBoxes.Bind(aSolid, aBox);
+    TopoDS_Shape aWShape;
+    if (aLSI.Extent() == 1)
+      aWShape = aLSI.First();
+    else
+    {
+      aBB.MakeCompound(TopoDS::Compound(aWShape));
+      aItLS.Initialize(aLSI);
+      for (; aItLS.More(); aItLS.Next())
+        aBB.Add(aWShape, aItLS.Value());
     }
-    myAreas.Append(aSolid);
-  }
+
+    AddWarning(new BOPAlgo_AlertSolidBuilderUnusedFaces(aWShape));  }
 }
 //=======================================================================
 //function : MakeInternalShells
index b665e3ecf0856a21dbd50cd8f774cce887dbd238..756d1861e816c78488d9956bba000728ffe6428d 100644 (file)
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
 
-#include <TopoDS_Solid.hxx>
 #include <BOPAlgo_BuilderArea.hxx>
 #include <NCollection_BaseAllocator.hxx>
 #include <TopTools_DataMapOfShapeBox.hxx>
-class TopoDS_Solid;
 
 
-//! The algorithm to build solids from set of faces
+//! Solid Builder is the algorithm for building solids from set of faces.
+//! The given faces should be non-intersecting, i.e. all coinciding parts
+//! of the faces should be shared among them.
+//!
+//! The algorithm performs the following steps to build the solids:
+//! 1. Find:
+//!    - faces orientated INTERNAL;
+//!    - alone faces given twice with different orientation;
+//! 2. Build all possible closed shells from the rest of the faces
+//!    (*BOPAlgo_ShellSplitter* is used for that);
+//! 3. Classify the obtained shells on the Holes and Growths;
+//! 4. Build solids from the Growth shells, put Hole shells into closest Growth solids;
+//! 5. Classify all unused faces relatively created solids and put them as internal
+//!    shells into the closest solids;
+//! 6. Find all unclassified faces, i.e. faces outside of all created solids,
+//!    make internal shells from them and put these shells into a warning.
+//!
+//! It is possible to avoid all internal shells in the resulting solids.
+//! For that it is necessary to use the method SetAvoidInternalShapes(true)
+//! of the base class. In this case the steps 5 and 6 will not be performed at all.
+//!
+//! The algorithm may return the following warnings:
+//! - *BOPAlgo_AlertShellSplitterFailed* in case the ShellSplitter algorithm has failed;
+//! - *BOPAlgo_AlertSolidBuilderUnusedFaces* in case there are some faces outside of
+//!   created solids left.
+//!
+//! Example of usage of the algorithm:
+//! ~~~~
+//! const TopTools_ListOfShape& aFaces = ...;     // Faces to build the solids
+//! Standard_Boolean isAvoidInternals = ...;      // Flag which defines whether to create the internal shells or not
+//! BOPAlgo_BuilderSolid aBS;                     // Solid Builder tool
+//! aBS.SetShapes(aFaces);                        // Set the faces
+//! aBS.SetAvoidInternalShapes(isAvoidInternals); // Set the AvoidInternalShapesFlag
+//! aBS.Perform();                                // Perform the operation
+//! if (!aBS.IsDone())                            // Check for the errors
+//! {
+//!   // error treatment
+//!   Standard_SStream aSStream;
+//!   aBS.DumpErrors(aSStream);
+//!   return;
+//! }
+//! if (aBS.HasWarnings())                        // Check for the warnings
+//! {
+//!   // warnings treatment
+//!   Standard_SStream aSStream;
+//!   aBS.DumpWarnings(aSStream);
+//! }
+//!
+//! const TopTools_ListOfShape& aSolids = aBS.Areas(); // Obtaining the result solids
+//! ~~~~
+//!
 class BOPAlgo_BuilderSolid  : public BOPAlgo_BuilderArea
 {
 public:
 
   DEFINE_STANDARD_ALLOC
 
-  
+public: //! @name Constructors
+
+  //! Empty constructor
   Standard_EXPORT BOPAlgo_BuilderSolid();
-Standard_EXPORT virtual ~BOPAlgo_BuilderSolid();
-  
+  Standard_EXPORT virtual ~BOPAlgo_BuilderSolid();
+
+  //! Constructor with allocator
   Standard_EXPORT BOPAlgo_BuilderSolid(const Handle(NCollection_BaseAllocator)& theAllocator);
-  
-  //! Sets the source solid <theSolid>
-  Standard_EXPORT void SetSolid (const TopoDS_Solid& theSolid);
-  
-  //! Returns the source solid
-  Standard_EXPORT const TopoDS_Solid& Solid() const;
-  
-  //! Performs the algorithm
+
+public: //! @name Performing the operation
+
+  //! Performs the construction of the solids from the given faces
   Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
 
-  //! Returns the map of solid/box pairs
+public: //! @name Getting the bounding boxes of the created solids
+
+  //! For classification purposes the algorithm builds the bounding boxes
+  //! for all created solids. This method returns the data map of solid - box pairs.
   const TopTools_DataMapOfShapeBox& GetBoxesMap() const
   {
     return myBoxes;
   }
 
-protected:
-  
-  //! Collect the faces that
-  //! a) are internal
-  //! b) are the same and have different orientation
+protected: //! @name Protected methods performing the operation
+
+  //! Collect the faces:
+  //! - with INTERNAL orientation;
+  //! - that are alone but given twice with different orientation.
+  //! These faces will be put into the map *myShapesToAvoid* and will be
+  //! avoided in shells construction, but will be classified later on.
   Standard_EXPORT virtual void PerformShapesToAvoid() Standard_OVERRIDE;
-  
-  //! Build draft shells
-  //! a)myLoops - draft shells that consist of
-  //! boundary faces
-  //! b)myLoopsInternal - draft shells that contains
-  //! inner faces
-  Standard_EXPORT virtual void PerformLoops() Standard_OVERRIDE;
-  
-  //! Build draft solids that contains boundary faces
-  Standard_EXPORT virtual void PerformAreas() Standard_OVERRIDE;
-  
-  //! Build finalized solids with internal shells
-  Standard_EXPORT virtual void PerformInternalShapes() Standard_OVERRIDE;
 
+  //! Build all possible closed shells from the given faces.
+  //! The method fills the following maps:
+  //! - myLoops - Created closed shells;
+  //! - myLoopsInternal - The shells created from unused faces.
+  Standard_EXPORT virtual void PerformLoops() Standard_OVERRIDE;
 
-  TopoDS_Solid mySolid;
+  //! Classifies the created shells on the Holes and Growths.
+  //! Creates the solids from the Growths shells.
+  //! Puts the Hole shells into the closest Growths solids.
+  Standard_EXPORT virtual void PerformAreas() Standard_OVERRIDE;
 
+  //! Classifies the unused faces relatively the created solids.
+  //! Puts the classified faces into the closest solids as internal shells.
+  //! Warns the user about unclassified faces if any.
+  Standard_EXPORT virtual void PerformInternalShapes() Standard_OVERRIDE;
 
 private:
 
index f3f9c7d2667cf53ca253df4a11d46d55ae6b3a68..f7763d37cb58d935ef1212a93d2e2a6c9acbfce2 100644 (file)
@@ -329,10 +329,28 @@ void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
 }
 
 //=======================================================================
+
+//=======================================================================
+//class : BOPAlgo_SplitSolid
+//purpose  : Auxiliary class to extend the BOPAlgo_BuilderSolid with the solid to split
+//=======================================================================
+class BOPAlgo_SplitSolid : public BOPAlgo_BuilderSolid
+{
+public:
+  //! Sets the solid
+  void SetSolid(const TopoDS_Solid& theSolid) { mySolid = theSolid; }
+
+  //! Returns the solid
+  const TopoDS_Solid& Solid() const { return mySolid; }
+
+private:
+  TopoDS_Solid mySolid; //!< Solid to split
+};
+
 // Vector of Solid Builders
-typedef NCollection_Vector<BOPAlgo_BuilderSolid> BOPAlgo_VectorOfBuilderSolid;
+typedef NCollection_Vector<BOPAlgo_SplitSolid> BOPAlgo_VectorOfBuilderSolid;
 // Functors to split solids
-typedef BOPTools_Functor<BOPAlgo_BuilderSolid,
+typedef BOPTools_Functor<BOPAlgo_SplitSolid,
                        BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidFunctor;
 //
 typedef BOPTools_Cnt<BOPAlgo_BuilderSolidFunctor,
@@ -428,7 +446,7 @@ void BOPAlgo_Builder::BuildSplitSolids
     }
     //
     // 1.3 Build new solids
-    BOPAlgo_BuilderSolid& aBS=aVBS.Appended();
+    BOPAlgo_SplitSolid& aBS=aVBS.Appended();
     aBS.SetSolid(aSolid);
     aBS.SetShapes(aSFS);
     aBS.SetRunParallel(myRunParallel);
@@ -445,8 +463,9 @@ void BOPAlgo_Builder::BuildSplitSolids
   //
   for (k = 0; k < aNbBS; ++k)
   {
-    BOPAlgo_BuilderSolid& aBS = aVBS(k);
+    BOPAlgo_SplitSolid& aBS = aVBS(k);
     aSolidsIm.Add(aBS.Solid(), aBS.Areas());
+    myReport->Merge(aBS.GetReport());
   }
   //
   // Add new solids to images map
index f9c33b684e1a842b033cc91d0d9e05e46a4a1a8e..7b1c928d3e19e27e26a553b5042177257d3237d6 100644 (file)
@@ -922,6 +922,8 @@ Standard_Boolean BOPAlgo_CellsBuilder::RemoveInternals(const TopTools_ListOfShap
         continue;
       }
       //
+      myReport->Merge(aBS.GetReport());
+      //
       TopoDS_Solid& aSNew = *(TopoDS_Solid*)&aBS.Areas().First();
       //
       // put all internal parts into new solid
index 27748d76ff27905b1f5224f6baca347bd1605aa3..21c20486bb043de30e5cd54f8f73ec975ccb74b8 100644 (file)
@@ -254,7 +254,6 @@ void BOPAlgo_MakerVolume::BuildSolids(TopTools_ListOfShape& theLSR)
   //
   BOPAlgo_BuilderSolid aBS;
   //
-  aBS.SetSolid(mySBox);
   aBS.SetShapes(myFaces);
   aBS.SetRunParallel(myRunParallel);
   aBS.SetAvoidInternalShapes(myAvoidInternalShapes);
@@ -265,6 +264,8 @@ void BOPAlgo_MakerVolume::BuildSolids(TopTools_ListOfShape& theLSR)
     return;
   }
   //
+  myReport->Merge(aBS.GetReport());
+  //
   theLSR = aBS.Areas();
 }
 
index 1e6184990f4909b0066ed922dcb41df221f8051e..ac65629892e3d69c8a9e2f81afcd0219cc25eb16 100644 (file)
@@ -1491,8 +1491,8 @@ void BOPAlgo_FillIn3DParts::MakeConnexityBlock(const TopoDS_Face& theFStart,
       myItW.Initialize(aW);
       for (; myItW.More(); myItW.Next())
       {
-        const TopoDS_Shape& aE = myItW.Value();
-        if (theMEAvoid.Contains(aE))
+        const TopoDS_Edge& aE = TopoDS::Edge(myItW.Value());
+        if (theMEAvoid.Contains(aE) || BRep_Tool::Degenerated(aE))
         {
           if (theFaceToClassify.IsNull())
             theFaceToClassify = TopoDS::Face(aF);
index 5ca5836f25077d52707f8130e1a742a17a0f644c..7aa2f6f0b780f5fc5df3a370472358a2b4acfcb9 100644 (file)
@@ -1,12 +1,10 @@
 # Original bug : buc60127
 # Date : 18mar98
 
-puts "TODO #22911 ALL: Faulty shapes in variables faulty_1 to faulty_"
-puts "TODO #22911 ALL: Error : The area of result shape is"
+puts "TODO #22911 ALL: Error : The command is not valid. The area is 0."
 
 restore [locate_data_file buc60127-part.rle] part
 restore [locate_data_file buc60127-tool.rle] tool
 
 bcut result part tool
 checkprops result -s 0
-checkview -display result -2d -s -otherwise { part tool } -path ${imagedir}/${test_image}.png
index c5dddec066248f77357a3516cc4011d914f81b04..c1bb6f2b380d1ac7672741d3f7ff9cd281082dfe 100644 (file)
@@ -1,8 +1,6 @@
 puts "TODO 0026789 ALL: Error : The area of result shape is"
 puts "TODO 0026789 ALL: Error : The volume of result shape is"
-puts "TODO 0026789 ALL: Error :  is WRONG because number of SOLID entities in shape"
-puts "TODO 0026789 ALL: Error :  is WRONG because number of SHELL entities in shape"
-puts "TODO 0026789 ALL: Faulty shapes in variables faulty_"
+puts "TODO 0026789 ALL: Error :  is WRONG because number of"
 
 puts "========"
 puts "OCC26789"
diff --git a/tests/bugs/modalg_7/bug25983 b/tests/bugs/modalg_7/bug25983
deleted file mode 100644 (file)
index 9eb515c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-puts "TODO OCC25983 ALL: Faulty shapes in variables faulty_1 to faulty_"
-
-puts "========"
-puts "OCC25983"
-puts "========"
-puts ""
-##########################################
-# Fusion of sweep and its mirror invalid
-##########################################
-
-restore [locate_data_file bug25983_deform-fusion1-tcl-BSpline.brep] BSpline
-wire Knurling-0-spine BSpline
-mksweep Knurling-0-spine
-setsweep -FR
-polyline DWire 0 0 0 1 -0.9999999999999998 0 1.0000000000000002 0.9999999999999998 0 0 0 0
-trotate DWire 0 0 0 1 0 0 134.99999999999693
-ttranslate DWire 9 0 0
-addsweep DWire 
-buildsweep Knurling -C -S
-copy Knurling Clone
-tmirror Clone 0 0 0 1 0 0
-bfuse result Knurling Clone
-
-checkshape result
diff --git a/tests/bugs/modalg_7/bug25983_1 b/tests/bugs/modalg_7/bug25983_1
new file mode 100644 (file)
index 0000000..9d5204f
--- /dev/null
@@ -0,0 +1,30 @@
+puts "TODO OCC25983 ALL: Error :  is WRONG because number of"
+puts "TODO OCC25983 ALL: Error : The area of result shape is"
+puts "TODO OCC25983 ALL: Error : The volume of result shape is"
+
+puts "========"
+puts "OCC25983"
+puts "========"
+puts ""
+##########################################
+# Fusion of sweep and its mirror invalid
+##########################################
+
+restore [locate_data_file bug25983_deform-fusion1-tcl-BSpline.brep] BSpline
+wire Knurling-0-spine BSpline
+mksweep Knurling-0-spine
+setsweep -FR
+polyline DWire 0 0 0 1 -0.9999999999999998 0 1.0000000000000002 0.9999999999999998 0 0 0 0
+trotate DWire 0 0 0 1 0 0 134.99999999999693
+ttranslate DWire 9 0 0
+addsweep DWire 
+buildsweep Knurling -C -S
+copy Knurling Clone
+tmirror Clone 0 0 0 1 0 0
+bfuse result Knurling Clone
+
+checkshape result
+checknbshapes result -wire 24 -face 24 -shell 1 -solid 1
+checkprops result -s 262.476 -v 54.0383
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug25983_2 b/tests/bugs/modalg_7/bug25983_2
new file mode 100644 (file)
index 0000000..23fad79
--- /dev/null
@@ -0,0 +1,28 @@
+puts "========"
+puts "OCC25983"
+puts "========"
+puts ""
+##########################################
+# Fusion of sweep and its mirror invalid
+##########################################
+
+restore [locate_data_file bug25983_deform-fusion1-tcl-BSpline.brep] BSpline
+wire Knurling-0-spine BSpline
+mksweep Knurling-0-spine
+setsweep -FR
+polyline DWire 0 0 0 1 -0.9999999999999998 0 1.0000000000000002 0.9999999999999998 0 0 0 0
+trotate DWire 0 0 0 1 0 0 134.99999999999693
+ttranslate DWire 9 0 0
+addsweep DWire 
+buildsweep Knurling -C -S
+copy Knurling Clone
+tmirror Clone 0 0 0 1 0 0
+
+bfuzzyvalue 1.e-3
+bfuse result Knurling Clone
+
+checkshape result
+checknbshapes result -wire 24 -face 24 -shell 1 -solid 1
+checkprops result -s 262.476 -v 54.0383
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug29580_1 b/tests/bugs/modalg_7/bug29580_1
new file mode 100644 (file)
index 0000000..5592ec7
--- /dev/null
@@ -0,0 +1,18 @@
+puts "========"
+puts "OCC29580"
+puts "========"
+puts ""
+#################################################
+# Regression: invalid result of BOP Fuse
+#################################################
+
+restore [locate_data_file bug29580_Cylinder.brep] b1
+restore [locate_data_file bug29580_Solid.brep] b2
+
+bfuse result b1 b2
+
+checkshape result
+checknbshapes result -wire 14 -face 13 -shell 1 -solid 1
+checkprops result -s 865.851 -v 1622.19
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug29580_2 b/tests/bugs/modalg_7/bug29580_2
new file mode 100644 (file)
index 0000000..2b60f9a
--- /dev/null
@@ -0,0 +1,37 @@
+puts "========"
+puts "OCC29580"
+puts "========"
+puts ""
+#################################################
+# Regression: invalid result of BOP Fuse
+#################################################
+
+
+circle c1 0 -5 0 1 0 0 10 
+circle c2 0 5 0 1 0 0 10
+mkedge e1 c1 
+mkedge e2 c2 
+wire w1 e1 
+wire w2 e2 
+mkplane f1 w1 
+mkplane f2 w2 
+bcut f12 f1 f2 
+revol b1 f12 0 0 0 0 0 1 180
+ttranslate b1 0 31.358955689999998 0 
+
+plane pln 0 0 0 0 0 1 1.1102230246251565e-016 -1 0 
+psphere b2 pln 8.6602540399999999 180 
+ttranslate b2  0 31.358955689999998 0
+
+bclearobjects
+bcleartools
+baddobjects b1
+baddtools b2
+bfillds
+bbuild result
+
+checkshape result
+checknbshapes result -vertex 4 -edge 14 -wire 10 -face 10 -shell 3 -solid 3 -t
+checkprops result -s 3879.55 -v 6295.15
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png