]> 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)
committeremv <emv@opencascade.com>
Fri, 13 Apr 2018 08:00:35 +0000 (11:00 +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 9199f96304ef8cf73807fa3c8424c19b4e4ec6fd..8e13457e24b3b06e578c87163be5e9218357c886 100644 (file)
@@ -1464,3 +1464,13 @@ The following obsolete features have been removed:
 @subsection upgrade_730_BOPAlgo_Section Changes in BOPAlgo_Section
 
 The public method *BuildSection()* in the class *BOPAlgo_Section* has became protected. The methods *Perform()* or *PerformWithFiller()* should be called for construction of the result of SECTION operation.
+
+@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 b39a610a2c3663916a16ed725a97ef60ac200701..72c842f7df9e121e46ee52fae8a164e399985e7e 100644 (file)
@@ -87,4 +87,7 @@ Warning: Unable to remove the feature
 Error: No faces have been found for removal
 
 .BOPAlgo_AlertRemoveFeaturesFailed
-Error: The Feature Removal algorithm has failed
\ No newline at end of file
+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 8889480015e430e92710fd064378a4b8f10c9e5f..13933957a3dd1b0f65544197e4835d8d97a0be42 100644 (file)
@@ -1058,16 +1058,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 BOPCol_ListOfShape& aLSR = aSB.Areas();
+    const BOPCol_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 c56c6b9647333bf3544f7d3d020f75d4248059fa..2d59eac59513858712c75572f9854fbba99d6cde 100644 (file)
@@ -106,22 +106,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  : 
 //=======================================================================
@@ -677,8 +661,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.
   BOPCol_IndexedMapOfShape aMFUnUsed;
+
   for (i = 1; i <= aNbF; ++i)
   {
     const TopoDS_Shape& aF = aMFs(i);
@@ -688,24 +674,21 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
 
   if (aMFUnUsed.Extent())
   {
-    TopoDS_Solid aSolid;
-    aBB.MakeSolid(aSolid);
-    //
     BOPCol_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 3bb4f440bb8133a2d3ad53b913afe4f2294f4343..bb583f2cacb33d3345adf8686d54e96d7e982ed6 100644 (file)
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
 
-#include <TopoDS_Solid.hxx>
 #include <BOPAlgo_BuilderArea.hxx>
 #include <BOPCol_BaseAllocator.hxx>
 #include <BOPCol_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 BOPCol_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 BOPCol_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 e03cf01778209c9e997ee3a8caf13f2e7e8ed145..05014c68b35d85a025029033585c54008f8f0ebe 100644 (file)
@@ -333,10 +333,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 BOPCol_NCVector<BOPAlgo_BuilderSolid> BOPAlgo_VectorOfBuilderSolid;
+typedef BOPCol_NCVector<BOPAlgo_SplitSolid> BOPAlgo_VectorOfBuilderSolid;
 // Functors to split solids
-typedef BOPCol_Functor<BOPAlgo_BuilderSolid,
+typedef BOPCol_Functor<BOPAlgo_SplitSolid,
                        BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidFunctor;
 //
 typedef BOPCol_Cnt<BOPAlgo_BuilderSolidFunctor,
@@ -432,7 +450,7 @@ void BOPAlgo_Builder::BuildSplitSolids
     }
     //
     // 1.3 Build new solids
-    BOPAlgo_BuilderSolid& aBS=aVBS.Append1();
+    BOPAlgo_SplitSolid& aBS=aVBS.Append1();
     aBS.SetSolid(aSolid);
     aBS.SetShapes(aSFS);
     aBS.SetRunParallel(myRunParallel);
@@ -449,8 +467,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 e36405224df4185e70def49d24548b5e71877e07..4eae759a7c7d846f5dc67e8fd5f40ee47d563931 100644 (file)
@@ -887,6 +887,8 @@ Standard_Boolean BOPAlgo_CellsBuilder::RemoveInternals(const BOPCol_ListOfShape&
         continue;
       }
       //
+      myReport->Merge(aBS.GetReport());
+      //
       TopoDS_Solid& aSNew = *(TopoDS_Solid*)&aBS.Areas().First();
       //
       // put all internal parts into new solid
index 1266136d071528ad57e0685237b81a07629f1fd9..7a99fb1747bf7897daea8ba16ceb4148edd4ae9a 100644 (file)
@@ -256,7 +256,6 @@ void BOPAlgo_MakerVolume::BuildSolids(BOPCol_ListOfShape& theLSR)
   //
   BOPAlgo_BuilderSolid aBS;
   //
-  aBS.SetSolid(mySBox);
   aBS.SetShapes(myFaces);
   aBS.SetRunParallel(myRunParallel);
   aBS.SetAvoidInternalShapes(myAvoidInternalShapes);
@@ -267,6 +266,8 @@ void BOPAlgo_MakerVolume::BuildSolids(BOPCol_ListOfShape& theLSR)
     return;
   }
   //
+  myReport->Merge(aBS.GetReport());
+  //
   theLSR = aBS.Areas();
 }
 
index b3fde89676df784fd395bb179bf0cc5513fc845e..38de815795fb5d9cd240a74c09dd4797dab60424 100644 (file)
@@ -1505,8 +1505,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