Salome HOME
Fix for the issue #2753 : error when dump/load script
[modules/shaper.git] / src / BuildPlugin / BuildPlugin_Face.cpp
index 36ef2b3e8a73f3dfb9bf35c7ff3ebcf7454d69f3..c7992999ad4dbe04b768aabb5c37e6561cf547ad 100644 (file)
@@ -1,28 +1,36 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        BuildPlugin_Face.cpp
-// Created:     14 April 2016
-// Author:      Dmitry Bobylev
+// Copyright (C) 2014-2017  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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
 
 #include "BuildPlugin_Face.h"
 
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_ResultBody.h>
-#include <ModelAPI_ResultConstruction.h>
-
-#include <Events_Error.h>
 
-#include <GeomAPI_DataMapOfShapeShape.h>
+#include <GeomAPI_Edge.h>
 #include <GeomAPI_PlanarEdges.h>
 #include <GeomAPI_Pln.h>
 #include <GeomAPI_ShapeExplorer.h>
 
 #include <GeomAlgoAPI_ShapeTools.h>
 #include <GeomAlgoAPI_SketchBuilder.h>
-#include <GeomAlgoAPI_WireBuilder.h>
-
-#include <algorithm>
-#include <sstream>
+#include <GeomAlgoAPI_Copy.h>
 
 //=================================================================================================
 BuildPlugin_Face::BuildPlugin_Face()
@@ -51,53 +59,56 @@ void BuildPlugin_Face::execute()
 
   // Collect base shapes.
   ListOfShape anEdges;
+  ListOfShape anOriginalFaces;
+  std::list< std::shared_ptr<GeomAPI_Dir> > aListOfNormals;
   for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
     AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
     GeomShapePtr aShape = aSelection->value();
+    GeomShapePtr aContext = aSelection->context()->shape();
     if(!aShape.get()) {
-      aShape = aSelection->context()->shape();
+      aShape = aContext;
+    }
+    // keep selected faces "as is"
+    if (aShape->shapeType() == GeomAPI_Shape::FACE) {
+      anOriginalFaces.push_back(aShape);
+      continue;
     }
+
     for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
       GeomShapePtr anEdge = anExp.current();
       anEdges.push_back(anEdge);
     }
-  }
 
-  // Get plane.
-  std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
+    // check whether the context is a sketch, in this case store its normal for further needs
+    std::shared_ptr<GeomAPI_PlanarEdges> aSketch =
+        std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aContext);
+    if (aSketch)
+      aListOfNormals.push_back(aSketch->norm());
+  }
 
-  // Get faces.
+  // Build faces by edges.
   ListOfShape aFaces;
-  GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(), aPln->direction(), anEdges, aFaces);
+  if (!anEdges.empty())
+    buildFacesByEdges(anEdges, aListOfNormals, aFaces);
 
-  // Get wires from faces.
-  ListOfShape aWires;
-  for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
-    for(GeomAPI_ShapeExplorer anExp(*anIt, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
-      aWires.push_back(anExp.current());
-    }
-  }
-
-  // Make faces with holes.
-  aFaces.clear();
-  GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aPln->location(), aPln->direction(), aWires, aFaces);
+  // 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) {
     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 anEdgeInResult = anExp.current();
-      for(ListOfShape::const_iterator anIt = anEdges.cbegin(); anIt != anEdges.cend(); ++anIt) {
-        std::shared_ptr<GeomAPI_Edge> anEdgeInList(new GeomAPI_Edge(*anIt));
-        if(anEdgeInList->isEqual(anEdgeInResult)) {
-          aResultBody->modified(anEdgeInList, anEdgeInResult, "Edge");
-          break;
-        }
-      }
+      GeomShapePtr anEdge = anExp.current();
+      aResultBody->generated(anEdge, "Edge_" + std::to_string((long long)anEdgeIndex));
+      ++anEdgeIndex;
     }
 
     setResult(aResultBody, anIndex);
@@ -106,3 +117,36 @@ void BuildPlugin_Face::execute()
 
   removeResults(anIndex);
 }
+
+void BuildPlugin_Face::buildFacesByEdges(
+    const ListOfShape& theEdges,
+    const std::list< std::shared_ptr<GeomAPI_Dir> >& theNormals,
+    ListOfShape& theFaces) const
+{
+  // Get plane.
+  std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(theEdges);
+  std::shared_ptr<GeomAPI_Dir> aNormal = aPln->direction();
+  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) {
+    aNormal->reverse();
+    aPln = std::shared_ptr<GeomAPI_Pln>(new GeomAPI_Pln(aPln->location(), aNormal));
+  }
+
+  // Get faces.
+  GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
+                                         aPln->direction(), theEdges, theFaces);
+
+  // Get wires from faces.
+  ListOfShape aWires;
+  for(ListOfShape::const_iterator anIt = theFaces.cbegin(); anIt != theFaces.cend(); ++anIt)
+    aWires.push_back(GeomAlgoAPI_ShapeTools::getFaceOuterWire(*anIt));
+
+  // Make faces with holes.
+  theFaces.clear();
+  GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aPln->location(), aPln->direction(),
+                                             aWires, theFaces);
+}