Salome HOME
[bos #26800] EDF 24492 - Pb with defeaturing
[modules/shaper.git] / src / GeomAPI / GeomAPI_Shape.cpp
index 4ddbe474e83b8a396880f1cf503837213033f630..7168ccdb5ac04c8bfc87a3aec94ac45d3a7b6a2b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2020  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2021  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -55,6 +55,7 @@
 
 #include <BOPAlgo_CheckerSI.hxx>
 #include <BOPDS_DS.hxx>
+#include <BOPTools_AlgoTools.hxx>
 
 #include <sstream>
 #include <algorithm> // for std::transform
@@ -148,6 +149,32 @@ bool GeomAPI_Shape::isCompound() const
   return !aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND;
 }
 
+bool GeomAPI_Shape::isCollectionOfSolids() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+  if (aShape.IsNull())
+    return false;
+
+  if (aShape.ShapeType() == TopAbs_SOLID ||
+      aShape.ShapeType() == TopAbs_COMPSOLID)
+    return true;
+
+  if (aShape.ShapeType() != TopAbs_COMPOUND)
+    return false;
+
+  TopTools_ListOfShape aLS;
+  TopTools_MapOfShape aMFence;
+  BOPTools_AlgoTools::TreatCompound(aShape, aLS, &aMFence);
+  TopTools_ListOfShape::Iterator it(aLS);
+  for (; it.More(); it.Next()) {
+    const TopoDS_Shape& aSx = it.Value();
+    if (aSx.ShapeType() != TopAbs_SOLID &&
+        aSx.ShapeType() != TopAbs_COMPSOLID)
+      return false;
+  }
+  return true;
+}
+
 bool GeomAPI_Shape::isCompoundOfSolids() const
 {
   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
@@ -593,7 +620,19 @@ bool GeomAPI_Shape::computeSize(double& theXmin, double& theYmin, double& theZmi
   if (aShape.IsNull())
     return false;
   Bnd_Box aBndBox;
-  BRepBndLib::Add(aShape, aBndBox, false);
+  // Workaround: compute optimal bounding box for the compounds of edges/vertices, because sometimes
+  // the bounding box of sketch is calculated if the transformation is applied twice (issue #20167).
+  bool isShape1D = false;
+  if (aShape.ShapeType() == TopAbs_COMPOUND) {
+    isShape1D = true;
+    for (TopoDS_Iterator anIt(aShape); anIt.More() && isShape1D; anIt.Next())
+      if (anIt.Value().ShapeType() < TopAbs_WIRE)
+        isShape1D = false;
+  }
+  if (isShape1D)
+    BRepBndLib::AddOptimal(aShape, aBndBox, false, true);
+  else
+    BRepBndLib::Add(aShape, aBndBox, false);
   if (aBndBox.IsVoid())
     return false;
   aBndBox.Get(theXmin, theYmin, theZmin, theXmax, theYmax, theZmax);