Salome HOME
updated copyright message
[modules/shaper.git] / src / BuildPlugin / BuildPlugin_Face.cpp
index fb782101f4d6367061db8275806e8629b5531d22..ba39fe3be77c9a37a81f2ffa9fcf8282eb061aa5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 //
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include "BuildPlugin_Face.h"
 
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultConstruction.h>
 
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_PlanarEdges.h>
 #include <GeomAPI_Pln.h>
 #include <GeomAPI_ShapeExplorer.h>
 
+#include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_ShapeTools.h>
 #include <GeomAlgoAPI_SketchBuilder.h>
 #include <GeomAlgoAPI_Copy.h>
@@ -59,6 +60,10 @@ void BuildPlugin_Face::execute()
 
   // Collect base shapes.
   ListOfShape anEdges;
+  ListOfShape anOriginalFaces;
+  ListOfShape aContexts;
+  getOriginalShapesAndContexts(BASE_OBJECTS_ID(), anOriginalFaces, aContexts);
+  anOriginalFaces.clear();
   std::list< std::shared_ptr<GeomAPI_Dir> > aListOfNormals;
   for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
     AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
@@ -67,6 +72,22 @@ void BuildPlugin_Face::execute()
     if(!aShape.get()) {
       aShape = aContext;
     }
+    if (aShape->shapeType() == GeomAPI_Shape::FACE) {
+      // keep selected faces "as is"
+      anOriginalFaces.push_back(aShape);
+      continue;
+    }
+    else if (!aSelection->value() && aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
+      // collect faces from the sketch
+      ResultConstructionPtr aSketch =
+          std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSelection->context());
+      if (aSketch && aSketch->facesNum() > 0) {
+        for (int i = 0; i < aSketch->facesNum(); ++i)
+          anOriginalFaces.push_back(aSketch->face(i));
+        continue;
+      }
+    }
+
     for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
       GeomShapePtr anEdge = anExp.current();
       anEdges.push_back(anEdge);
@@ -79,12 +100,50 @@ void BuildPlugin_Face::execute()
       aListOfNormals.push_back(aSketch->norm());
   }
 
+  // Build faces by edges.
+  ListOfShape aFaces;
+  GeomMakeShapePtr aFaceBuilder;
+  if (!anEdges.empty())
+    buildFacesByEdges(anEdges, aListOfNormals, aFaces, aFaceBuilder);
+  int aNbFacesFromEdges = (int)aFaces.size();
+
+  // Add faces selected by user.
+  aFaces.insert(aFaces.end(), anOriginalFaces.begin(), anOriginalFaces.end());
+
+  // Store result.
+  int anIndex = 0;
+  for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
+    std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList);
+    if (anIndex < aNbFacesFromEdges)
+      aMakeShapeList->appendAlgo(aFaceBuilder);
+
+    GeomShapePtr aShape = *anIt;
+    GeomMakeShapePtr aCopy(new GeomAlgoAPI_Copy(aShape));
+    aMakeShapeList->appendAlgo(aCopy);
+
+    ListOfShape aBaseShapes;
+    if (anIndex < aNbFacesFromEdges)
+      aBaseShapes = anEdges;
+    else
+      aBaseShapes.push_back(aShape);
+    storeResult(aMakeShapeList, aBaseShapes, aContexts, aCopy->shape(), anIndex++);
+  }
+
+  removeResults(anIndex);
+}
+
+void BuildPlugin_Face::buildFacesByEdges(
+    const ListOfShape& theEdges,
+    const std::list< std::shared_ptr<GeomAPI_Dir> >& theNormals,
+    ListOfShape& theFaces,
+    std::shared_ptr<GeomAlgoAPI_MakeShape>& theBuilderAlgo) const
+{
   // Get plane.
-  std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
+  std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(theEdges);
   std::shared_ptr<GeomAPI_Dir> aNormal = aPln->direction();
-  bool isReverse = !aListOfNormals.empty();
-  std::list< std::shared_ptr<GeomAPI_Dir> >::const_iterator aNormIt = aListOfNormals.begin();
-  for (; aNormIt != aListOfNormals.end() && isReverse; ++aNormIt)
+  bool isReverse = !theNormals.empty();
+  std::list< std::shared_ptr<GeomAPI_Dir> >::const_iterator aNormIt = theNormals.begin();
+  for (; aNormIt != theNormals.end() && isReverse; ++aNormIt)
     if ((*aNormIt)->dot(aNormal) > 1.e-7)
       isReverse = false;
   if (isReverse) {
@@ -93,46 +152,18 @@ void BuildPlugin_Face::execute()
   }
 
   // Get faces.
-  ListOfShape aFaces;
-  GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
-                                         aPln->direction(), anEdges, aFaces);
+  std::shared_ptr<GeomAlgoAPI_SketchBuilder> aSketchBuilder(
+      new GeomAlgoAPI_SketchBuilder(aPln, theEdges));
+  theFaces = aSketchBuilder->faces();
+  theBuilderAlgo = aSketchBuilder;
 
   // Get wires from faces.
   ListOfShape aWires;
-  for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
+  for(ListOfShape::const_iterator anIt = theFaces.cbegin(); anIt != theFaces.cend(); ++anIt)
     aWires.push_back(GeomAlgoAPI_ShapeTools::getFaceOuterWire(*anIt));
-    //for(GeomAPI_ShapeExplorer anExp(*anIt, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
-    //  if(anExp.current()->orientation() == GeomAPI_Shape::REVERSED) {
-    //    continue;
-    //  }
-    //  aWires.push_back(anExp.current());
-    //}
-  }
 
   // Make faces with holes.
-  aFaces.clear();
-  GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aPln->location(), aPln->direction(), aWires, aFaces);
-
-  // Store result.
-  int anIndex = 0;
-  for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
-    ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
-    GeomShapePtr aShape = *anIt;
-    GeomAlgoAPI_Copy aCopy(aShape);
-    aShape = aCopy.shape();
-    aResultBody->store(aShape);
-
-    // Store edges.
-    int anEdgeIndex = 1;
-    for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
-      GeomShapePtr anEdge = anExp.current();
-      aResultBody->generated(anEdge, "Edge_" + std::to_string((long long)anEdgeIndex), anEdgeIndex);
-      ++anEdgeIndex;
-    }
-
-    setResult(aResultBody, anIndex);
-    ++anIndex;
-  }
-
-  removeResults(anIndex);
+  theFaces.clear();
+  GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aPln->location(), aPln->direction(),
+                                             aWires, theFaces);
 }