]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Combine solids in compounds after extrusion/revolution to compsolids
authordbv <dbv@opencascade.com>
Wed, 19 Aug 2015 13:55:43 +0000 (16:55 +0300)
committerdbv <dbv@opencascade.com>
Wed, 19 Aug 2015 13:56:42 +0000 (16:56 +0300)
src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp
src/FeaturesPlugin/FeaturesPlugin_Revolution.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h

index 029fd2bdbe5ab33516a589326800d3e78fa3ba56..09e3e3c14af4497b24338043ca264381b9711c04 100644 (file)
@@ -21,6 +21,7 @@
 #include <ModelAPI_AttributeString.h>
 #include <ModelAPI_AttributeReference.h>
 
+#include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_Prism.h>
 #include <GeomAlgoAPI_ShapeTools.h>
 
@@ -130,7 +131,8 @@ void FeaturesPlugin_Extrusion::execute()
   // Searching faces with common edges.
   ListOfShape aShells;
   ListOfShape aFreeFaces;
-  GeomAlgoAPI_ShapeTools::combineFacesToShells(aFacesList, aShells, aFreeFaces);
+  std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
+  GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
   if(aShells.empty()) {
     aShells = aFreeFaces;
   } else {
index 4bbbca96f27dbb35718f5ad725723f1a395311ac..52b00ffc1400fed5daded1ef1031e172995f6f09 100644 (file)
@@ -15,6 +15,7 @@
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_ResultBody.h>
 
+#include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_ShapeTools.h>
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Lin.h>
@@ -140,7 +141,8 @@ void FeaturesPlugin_Revolution::execute()
   // Searching faces with common edges.
   ListOfShape aShells;
   ListOfShape aFreeFaces;
-  GeomAlgoAPI_ShapeTools::combineFacesToShells(aFacesList, aShells, aFreeFaces);
+  std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
+  GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
   if(aShells.empty()) {
     aShells = aFreeFaces;
   } else {
index b77b08dad05d081d2c0130e3b9b422e7f39e4bbf..f4c7218af17e8a8ce3609fad5f581fd651b1cf8b 100644 (file)
@@ -264,9 +264,26 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr<GeomAPI_Shape>& theBasis,
   if(aResult.ShapeType() == TopAbs_COMPOUND) {
     aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
   }
-
-  myShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape);
-  myShape->setImpl(new TopoDS_Shape(aResult));
+  if(aResult.ShapeType() == TopAbs_COMPOUND) {
+    std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
+    aCompound->setImpl(new TopoDS_Shape(aResult));
+    ListOfShape aCompSolids, aFreeSolids;
+    GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
+    if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
+      aResult = aCompSolids.front()->impl<TopoDS_Shape>();
+    } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
+      TopoDS_Compound aResultComp;
+      TopoDS_Builder aBuilder;
+      aBuilder.MakeCompound(aResultComp);
+      for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
+        aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
+      }
+      for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
+        aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
+      }
+      aResult = aResultComp;
+    }
+  }
 
   // Fill data map to keep correct orientation of sub-shapes.
   myMap = std::shared_ptr<GeomAPI_DataMapOfShapeShape>(new GeomAPI_DataMapOfShapeShape);
@@ -275,7 +292,8 @@ void GeomAlgoAPI_Prism::build(const std::shared_ptr<GeomAPI_Shape>& theBasis,
     aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
     myMap->bind(aCurrentShape, aCurrentShape);
   }
-
+  myShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape);
+  myShape->setImpl(new TopoDS_Shape(aResult));
   myMkShape = std::shared_ptr<GeomAlgoAPI_MakeShapeList>(new GeomAlgoAPI_MakeShapeList(aListOfMakeShape));
   myDone = true;
 }
index b6e10dbe9b763373c51d1ab3ec003759e07f6939..4b29cf0c7a5c4b43418f3d362fa4ac4c56e02135 100644 (file)
@@ -158,14 +158,21 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBasi
   GeomLib_IsPlanarSurface isBasisPlanar(BRep_Tool::Surface(aBasisFace));
   gp_Pln aBasisPln = isBasisPlanar.Plan();
   Geom_Plane aBasisPlane(aBasisPln);
+  gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
+  if(aBasisPlane.Axis().Angle(anAxis) < Precision::Confusion()) {
+    return;
+  }
+  gp_Lin anAxisLin(anAxis);
 
   // Creating circle for pipe.
   gp_Pnt aBasisCentre = GeomAlgoAPI_ShapeTools::centreOfMass(theBasis)->impl<gp_Pnt>();
+  gp_Pnt aStartPnt = aBasisCentre;
   const TopoDS_Shape& aBasisShape = theBasis->impl<TopoDS_Shape>();
-  gp_Ax1 anAxis = theAxis->impl<gp_Ax1>();
-  gp_Lin anAxisLin(anAxis);
   Handle(Geom_Line) anAxisLine = new Geom_Line(anAxis);
-  GeomAPI_ProjectPointOnCurve aProjection(aBasisCentre, anAxisLine);
+  if(anAxisLin.Contains(aStartPnt, Precision::Confusion())) {
+    aStartPnt.Translate(anAxis.Direction() ^ aBasisPln.Axis().Direction());
+  }
+  GeomAPI_ProjectPointOnCurve aProjection(aStartPnt, anAxisLine);
   if(aProjection.NbPoints() != 1) {
     return;
   }
@@ -178,7 +185,7 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBasi
     // Rotating base face with the negative value of "from angle".
     gp_Trsf aBaseTrsf;
     aBaseTrsf.SetRotation(anAxis, -theFromAngle / 180.0 * M_PI);
-    gp_Pnt aFromPnt = aBasisCentre.Transformed(aBaseTrsf);
+    gp_Pnt aFromPnt = aStartPnt.Transformed(aBaseTrsf);
     aCircle = gp_Circ(gp_Ax2(aProjection.NearestPoint(), anAxis.Direction(), gp_Vec(aProjection.NearestPoint(), aFromPnt)),
                       aRadius);
     BRepBuilderAPI_Transform* aBaseTransform = new BRepBuilderAPI_Transform(aBasisShape,
@@ -446,6 +453,29 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBasi
   if(!anExp.More()) {
     return;
   }
+  if(aResult.ShapeType() == TopAbs_COMPOUND) {
+    aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
+  }
+  if(aResult.ShapeType() == TopAbs_COMPOUND) {
+    std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
+    aCompound->setImpl(new TopoDS_Shape(aResult));
+    ListOfShape aCompSolids, aFreeSolids;
+    GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
+    if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
+      aResult = aCompSolids.front()->impl<TopoDS_Shape>();
+    } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
+      TopoDS_Compound aResultComp;
+      TopoDS_Builder aBuilder;
+      aBuilder.MakeCompound(aResultComp);
+      for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
+        aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
+      }
+      for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
+        aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
+      }
+      aResult = aResultComp;
+    }
+  }
 
   // fill data map to keep correct orientation of sub-shapes
   myMap = std::shared_ptr<GeomAPI_DataMapOfShapeShape>(new GeomAPI_DataMapOfShapeShape());
@@ -458,7 +488,6 @@ void GeomAlgoAPI_Revolution::build(const std::shared_ptr<GeomAPI_Shape>& theBasi
   myShape->setImpl(new TopoDS_Shape(aResult));
   myMkShape = std::shared_ptr<GeomAlgoAPI_MakeShapeList>(new GeomAlgoAPI_MakeShapeList(aListOfMakeShape));
   myDone = true;
-  return;
 }
 
 //=================================================================================================
index 338581782d9204e445b1efcfc91ea6e744cc6d87..6955720e2f46bd3cfcc165f2a03fb673414020af 100644 (file)
@@ -50,31 +50,37 @@ std::shared_ptr<GeomAPI_Pnt> GeomAlgoAPI_ShapeTools::centreOfMass(std::shared_pt
 }
 
 //=================================================================================================
-void GeomAlgoAPI_ShapeTools::combineFacesToShells(const ListOfShape& theFacesList,
-                                                  ListOfShape& theShells,
-                                                  ListOfShape& theFreeFaces)
+void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
+                                           const GeomAPI_Shape::ShapeType theType,
+                                           ListOfShape& theCombinedShapes,
+                                           ListOfShape& theFreeShapes)
 {
-  if(theFacesList.empty()) {
+  if(!theCompound.get()) {
     return;
   }
 
-  // Adding all faces to compoud.
-  std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(theFacesList);
-  if(!aFacesCompound.get()) {
+  if(theType != GeomAPI_Shape::SHELL && theType != GeomAPI_Shape::COMPSOLID) {
     return;
   }
 
-  // Map edges and faces.
-  const TopoDS_Shape& aFacesComp = aFacesCompound->impl<TopoDS_Shape>();
+  TopAbs_ShapeEnum aTS = TopAbs_EDGE;
+  TopAbs_ShapeEnum aTA = TopAbs_FACE;
+  if(theType == GeomAPI_Shape::COMPSOLID) {
+    aTS = TopAbs_FACE;
+    aTA = TopAbs_SOLID;
+  }
+
+  // Map subshapes and shapes.
+  const TopoDS_Shape& aShapesComp = theCompound->impl<TopoDS_Shape>();
   BOPCol_IndexedDataMapOfShapeListOfShape aMapEF;
-  BOPTools::MapShapesAndAncestors(aFacesComp, TopAbs_EDGE, TopAbs_FACE, aMapEF);
+  BOPTools::MapShapesAndAncestors(aShapesComp, aTS, aTA, aMapEF);
   if(aMapEF.IsEmpty()) {
     return;
   }
 
-  // Get all faces with common edges and free faces.
-  NCollection_Map<TopoDS_Shape> aFreeFaces;
-  NCollection_Vector<NCollection_Map<TopoDS_Shape>> aFacesWithCommonEdges;
+  // Get all shapes with common subshapes and free shapes.
+  NCollection_Map<TopoDS_Shape> aFreeShapes;
+  NCollection_Vector<NCollection_Map<TopoDS_Shape>> aShapesWithCommonSubshapes;
   for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapEF); anIter.More(); anIter.Next()) {
     const TopoDS_Shape& aShape = anIter.Key();
     BOPCol_ListOfShape& aListOfShape = anIter.ChangeValue();
@@ -82,14 +88,14 @@ void GeomAlgoAPI_ShapeTools::combineFacesToShells(const ListOfShape& theFacesLis
       continue;
     }
     else if(aListOfShape.Size() == 1) {
-      aFreeFaces.Add(aListOfShape.First());
+      aFreeShapes.Add(aListOfShape.First());
       aListOfShape.Clear();
     } else {
       NCollection_Map<TopoDS_Shape> aTempMap;
       aTempMap.Add(aListOfShape.First());
       aTempMap.Add(aListOfShape.Last());
-      aFreeFaces.Remove(aListOfShape.First());
-      aFreeFaces.Remove(aListOfShape.Last());
+      aFreeShapes.Remove(aListOfShape.First());
+      aFreeShapes.Remove(aListOfShape.Last());
       aListOfShape.Clear();
       for(NCollection_Map<TopoDS_Shape>::Iterator aTempIter(aTempMap); aTempIter.More(); aTempIter.Next()) {
         const TopoDS_Shape& aTempShape = aTempIter.Value();
@@ -102,41 +108,42 @@ void GeomAlgoAPI_ShapeTools::combineFacesToShells(const ListOfShape& theFacesLis
           } else if(aTempListOfShape.Size() > 1) {
             if(aTempListOfShape.First() == aTempShape) {
               aTempMap.Add(aTempListOfShape.Last());
-              aFreeFaces.Remove(aTempListOfShape.Last());
+              aFreeShapes.Remove(aTempListOfShape.Last());
               aTempListOfShape.Clear();
             } else if(aTempListOfShape.Last() == aTempShape) {
               aTempMap.Add(aTempListOfShape.First());
-              aFreeFaces.Remove(aTempListOfShape.First());
+              aFreeShapes.Remove(aTempListOfShape.First());
               aTempListOfShape.Clear();
             }
           }
         }
       }
-      aFacesWithCommonEdges.Append(aTempMap);
+      aShapesWithCommonSubshapes.Append(aTempMap);
     }
   }
 
-  // Make shells from faces with common edges.
-  NCollection_Vector<TopoDS_Shape> aShells;
-  for(NCollection_Vector<NCollection_Map<TopoDS_Shape>>::Iterator anIter(aFacesWithCommonEdges); anIter.More(); anIter.Next()) {
+  // Combine shapes with common subshapes.
+  for(NCollection_Vector<NCollection_Map<TopoDS_Shape>>::Iterator anIter(aShapesWithCommonSubshapes); anIter.More(); anIter.Next()) {
     TopoDS_Shell aShell;
+    TopoDS_CompSolid aCSolid;
     TopoDS_Builder aBuilder;
-    aBuilder.MakeShell(aShell);
+    theType == GeomAPI_Shape::COMPSOLID ? aBuilder.MakeCompSolid(aCSolid) : aBuilder.MakeShell(aShell);
     const NCollection_Map<TopoDS_Shape>& aShapesMap = anIter.Value();
     for(NCollection_Map<TopoDS_Shape>::Iterator aShIter(aShapesMap); aShIter.More(); aShIter.Next()) {
-      const TopoDS_Shape& aFace = aShIter.Value();
-      aBuilder.Add(aShell, aFace);
+      const TopoDS_Shape& aShape = aShIter.Value();
+      theType == GeomAPI_Shape::COMPSOLID ? aBuilder.Add(aCSolid, aShape) : aBuilder.Add(aShell, aShape);
     }
-    std::shared_ptr<GeomAPI_Shape> aGeomShell(new GeomAPI_Shape);
-    aGeomShell->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShell));
-    theShells.push_back(aGeomShell);
+    std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
+    TopoDS_Shape* aSh = theType == GeomAPI_Shape::COMPSOLID ? new TopoDS_Shape(aCSolid) : new TopoDS_Shape(aShell);
+    aGeomShape->setImpl<TopoDS_Shape>(aSh);
+    theCombinedShapes.push_back(aGeomShape);
   }
 
-  // Adding free faces.
-  for(NCollection_Map<TopoDS_Shape>::Iterator aShIter(aFreeFaces); aShIter.More(); aShIter.Next()) {
-    const TopoDS_Shape& aFace = aShIter.Value();
-    std::shared_ptr<GeomAPI_Shape> aGeomFace(new GeomAPI_Shape);
-    aGeomFace->setImpl<TopoDS_Shape>(new TopoDS_Shape(aFace));
-    theFreeFaces.push_back(aGeomFace);
+  // Adding free shapes.
+  for(NCollection_Map<TopoDS_Shape>::Iterator aShIter(aFreeShapes); aShIter.More(); aShIter.Next()) {
+    const TopoDS_Shape& aShape = aShIter.Value();
+    std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
+    aGeomShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
+    theFreeShapes.push_back(aGeomShape);
   }
 }
index 9dce03c2da94675adf0ff580bd6a0c8ca7847802..009828dc78569ab1629343bb05667c3714d27c1c 100644 (file)
@@ -27,14 +27,16 @@ public:
   /// are expressed in the absolute Cartesian coordinate system. (This function works only for surfaces).
   static std::shared_ptr<GeomAPI_Pnt> centreOfMass(std::shared_ptr<GeomAPI_Shape> theShape);
 
-  /** \brief Combines faces with common edges to shells
-   *  \param[in] theFacesList list of faces to be combined.
+  /** \brief Combines faces with common edges to shells, or solids to compsolids.
+   *  \param[in] theCompound compound of shapes.
+   *  \param[in] theType type of combine.
    *  \param[out] theShells resulting shells.
    *  \param[out] theFreeFaces faces that does not have common edges.
    */
-  static void combineFacesToShells(const ListOfShape& theFacesList,
-                                   ListOfShape& theShells,
-                                   ListOfShape& theFreeFaces);
+  static void combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
+                            const GeomAPI_Shape::ShapeType theType,
+                            ListOfShape& theCombinedShapes,
+                            ListOfShape& theFreeShapes);
 };
 
 #endif