Salome HOME
Issue #1369: Added "Create Shell" feature.
authordbv <dbv@opencascade.com>
Tue, 26 Apr 2016 13:52:00 +0000 (16:52 +0300)
committerdbv <dbv@opencascade.com>
Tue, 26 Apr 2016 13:52:20 +0000 (16:52 +0300)
15 files changed:
src/BuildPlugin/BuildPlugin_Plugin.cpp
src/BuildPlugin/BuildPlugin_Shell.cpp [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_Shell.h [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_Wire.cpp
src/BuildPlugin/CMakeLists.txt
src/BuildPlugin/icons/feature_shell.png [new file with mode: 0644]
src/BuildPlugin/plugin-Build.xml
src/BuildPlugin/shell_widget.xml [new file with mode: 0644]
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/GeomAlgoAPI/CMakeLists.txt
src/GeomAlgoAPI/GeomAlgoAPI.i
src/GeomAlgoAPI/GeomAlgoAPI_Sewing.cpp [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_Sewing.h [new file with mode: 0644]
src/GeomAlgoAPI/GeomAlgoAPI_swig.h

index f11e4ba6ecc6c035687089412acb7c57651ed0e3..d834be91f67edda124b4ebed1526762b8f42dd76 100644 (file)
@@ -13,6 +13,7 @@
 #include <BuildPlugin_Edge.h>
 #include <BuildPlugin_Wire.h>
 #include <BuildPlugin_Face.h>
+#include <BuildPlugin_Shell.h>
 #include <BuildPlugin_Validators.h>
 
 // the only created instance of this plugin
@@ -46,6 +47,8 @@ FeaturePtr BuildPlugin_Plugin::createFeature(std::string theFeatureID)
     return FeaturePtr(new BuildPlugin_Wire());
   } else if(theFeatureID == BuildPlugin_Face::ID()) {
     return FeaturePtr(new BuildPlugin_Face());
+  } else if(theFeatureID == BuildPlugin_Shell::ID()) {
+    return FeaturePtr(new BuildPlugin_Shell());
   }
 
   // Feature of such kind is not found.
diff --git a/src/BuildPlugin/BuildPlugin_Shell.cpp b/src/BuildPlugin/BuildPlugin_Shell.cpp
new file mode 100644 (file)
index 0000000..bb934a2
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        BuildPlugin_Shell.cpp
+// Created:     14 April 2016
+// Author:      Dmitry Bobylev
+
+#include "BuildPlugin_Shell.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <GeomAlgoAPI_Sewing.h>
+#include <GeomAPI_ShapeExplorer.h>
+
+//=================================================================================================
+BuildPlugin_Shell::BuildPlugin_Shell()
+{
+}
+
+//=================================================================================================
+void BuildPlugin_Shell::initAttributes()
+{
+  data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
+}
+
+//=================================================================================================
+void BuildPlugin_Shell::execute()
+{
+  // Get base objects list.
+  AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
+
+  // Collect base shapes.
+  ListOfShape aShapes;
+  for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+    AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+    GeomShapePtr aShape = aSelection->value();
+    if(!aShape.get()) {
+      aShape = aSelection->context()->shape();
+    }
+    aShapes.push_back(aShape);
+  }
+
+  // Sew faces.
+  GeomAlgoAPI_Sewing aSewingAlgo(aShapes);
+
+  // Check that algo is done.
+  if(!aSewingAlgo.isDone()) {
+    setError("Error: " + getKind() + " algorithm failed.");
+    return;
+  }
+
+  // Check if shape is not null.
+  if(!aSewingAlgo.shape().get() || aSewingAlgo.shape()->isNull()) {
+    setError("Error: Resulting shape is null.");
+    return;
+  }
+
+  // Check that resulting shape is valid.
+  if(!aSewingAlgo.isValid()) {
+    setError("Error: Resulting shape is not valid.");
+    return;
+  }
+
+  // Store result.
+  GeomShapePtr aResult = aSewingAlgo.shape();
+  std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfShapes = aSewingAlgo.mapOfSubShapes();
+
+  int anIndex = 0;
+  for(GeomAPI_ShapeExplorer anExp(aResult, GeomAPI_Shape::SHELL); anExp.more(); anExp.next()) {
+    GeomShapePtr aShell = anExp.current();
+    ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
+    aResultBody->store(aShell);
+    for(ListOfShape::const_iterator anIt = aShapes.cbegin(); anIt != aShapes.cend(); ++anIt) {
+      for(GeomAPI_ShapeExplorer aFaceExp(*anIt, GeomAPI_Shape::FACE); aFaceExp.more(); aFaceExp.next()) {
+        GeomShapePtr aFace = aFaceExp.current();
+        ListOfShape aHistory;
+        aSewingAlgo.modified(aFace, aHistory);
+        for(ListOfShape::const_iterator aHistoryIt = aHistory.cbegin();
+            aHistoryIt != aHistory.cend();
+            ++aHistoryIt) {
+          if(aShell->isSubShape(*aHistoryIt)) {
+            aResultBody->loadAndOrientModifiedShapes(&aSewingAlgo, aFace, GeomAPI_Shape::EDGE,
+                                                     1, "Modified", *aMapOfShapes.get());
+          }
+        }
+      }
+    }
+    setResult(aResultBody, anIndex);
+    ++anIndex;
+  }
+
+  removeResults(anIndex);
+}
diff --git a/src/BuildPlugin/BuildPlugin_Shell.h b/src/BuildPlugin/BuildPlugin_Shell.h
new file mode 100644 (file)
index 0000000..be63415
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        BuildPlugin_Shell.h
+// Created:     14 April 2016
+// Author:      Dmitry Bobylev
+
+#ifndef BuildPlugin_Shell_H_
+#define BuildPlugin_Shell_H_
+
+#include "BuildPlugin.h"
+
+#include <ModelAPI_Feature.h>
+
+/// \class BuildPlugin_Shell
+/// \ingroup Plugins
+/// \brief Feature for creation of shell from faces and shells.
+class BuildPlugin_Shell: public ModelAPI_Feature
+{
+public:
+  /// Use plugin manager for features creation
+  BuildPlugin_Shell();
+
+  /// Feature kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_ID("Shell");
+    return MY_ID;
+  }
+
+  /// Attribute name of base objects.
+  inline static const std::string& BASE_OBJECTS_ID()
+  {
+    static const std::string MY_BASE_OBJECTS_ID("base_objects");
+    return MY_BASE_OBJECTS_ID;
+  }
+
+  /// \return the kind of a feature.
+  BUILDPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = BuildPlugin_Shell::ID();
+    return MY_KIND;
+  }
+
+  /// Request for initialization of data model of the feature: adding all attributes.
+  BUILDPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Creates a new part document if needed.
+  BUILDPLUGIN_EXPORT virtual void execute();
+};
+
+#endif
index 439b082b015e7d9bfad04a19aef9dc9cc8f125fd..523c81a03c970ec00c8bc6c30667c8d321aacd7d 100644 (file)
@@ -148,13 +148,6 @@ bool BuildPlugin_Wire::addContour()
     AttributeSelectionPtr aSelection = *aListIt;
     std::shared_ptr<GeomAPI_Edge> anEdgeInList(new GeomAPI_Edge(aSelection->value()));
 
-    ListOfShape::const_iterator anEdgesIt = anAddedEdges.cbegin();
-    for(; anEdgesIt != anAddedEdges.cend(); ++anEdgesIt) {
-      if(anEdgeInList->isEqual(*anEdgesIt)) {
-        break;
-      }
-    }
-
     ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSelection->context());
     std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges = std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aConstruction->shape());
 
@@ -179,7 +172,7 @@ bool BuildPlugin_Wire::addContour()
     if(aFoundFace.get()) {
       for(GeomAPI_ShapeExplorer anExp(aFoundFace, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
         std::shared_ptr<GeomAPI_Edge> anEdgeOnFace(new GeomAPI_Edge(anExp.current()));
-        anEdgesIt = anAddedEdges.cbegin();
+        ListOfShape::const_iterator anEdgesIt = anAddedEdges.cbegin();
         for(; anEdgesIt != anAddedEdges.cend(); ++anEdgesIt) {
           if(anEdgeOnFace->isEqual(*anEdgesIt)) {
             break;
index a2ada0459e3b27680d19a8025560635461efed2f..0a7cda8f9ce71e5c656ee8d3bc85564a6b4f84ad 100644 (file)
@@ -18,6 +18,7 @@ SET(PROJECT_HEADERS
     BuildPlugin_Edge.h
     BuildPlugin_Wire.h
     BuildPlugin_Face.h
+    BuildPlugin_Shell.h
     BuildPlugin_Validators.h
 )
 
@@ -27,6 +28,7 @@ SET(PROJECT_SOURCES
     BuildPlugin_Edge.cpp
     BuildPlugin_Wire.cpp
     BuildPlugin_Face.cpp
+    BuildPlugin_Shell.cpp
     BuildPlugin_Validators.cpp
 )
 
@@ -36,6 +38,7 @@ SET(XML_RESOURCES
     edge_widget.xml
     wire_widget.xml
     face_widget.xml
+    shell_widget.xml
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/BuildPlugin/icons/feature_shell.png b/src/BuildPlugin/icons/feature_shell.png
new file mode 100644 (file)
index 0000000..5144ea8
Binary files /dev/null and b/src/BuildPlugin/icons/feature_shell.png differ
index cfa04ecf0581114acc1e6d3649ba6e6fde6d8ea2..362eb118f65b4abb7751616895db16cfff69087c 100644 (file)
@@ -9,12 +9,15 @@
       <feature id="Edge" title="Edge" tooltip ="Create an edge from sketch edges and edge objects" icon="icons/Build/feature_edge.png">
         <source path="edge_widget.xml"/>
       </feature>
-      <feature id="Wire" title="Wire" tooltip ="Create a wire from sketch edges and wires objects" icon="icons/Build/feature_wire.png">
+      <feature id="Wire" title="Wire" tooltip ="Create a wire from sketch edges, edges and wires objects" icon="icons/Build/feature_wire.png">
         <source path="wire_widget.xml"/>
       </feature>
-      <feature id="Face" title="Face" tooltip ="Create a face from sketch edges and wires objects" icon="icons/Build/feature_face.png">
+      <feature id="Face" title="Face" tooltip ="Create a face from sketch edges, edges and wires objects" icon="icons/Build/feature_face.png">
         <source path="face_widget.xml"/>
       </feature>
+      <feature id="Shell" title="Shell" tooltip ="Create a shell from faces or shells objects" icon="icons/Build/feature_shell.png">
+        <source path="shell_widget.xml"/>
+      </feature>
     </group>
    </workbench>
 </plugin>
diff --git a/src/BuildPlugin/shell_widget.xml b/src/BuildPlugin/shell_widget.xml
new file mode 100644 (file)
index 0000000..fc4bca3
--- /dev/null
@@ -0,0 +1,11 @@
+<!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+<source>
+  <multi_selector id="base_objects"
+                  label="Faces and shells:"
+                  tooltip="Select faces or shells objects."
+                  type_choice="objects">
+    <validator id="GeomValidators_ShapeType" parameters="face,shell"/>
+  </multi_selector>
+  <!--<validator id="BuildPlugin_ValidatorBaseForShell" parameters="base_objects"/>-->
+</source>
index cba5be5ce00993d69a696c3513bb447cfd6a2a63..1c97ef8b42ec78f4211e03035d2212d0595e0ace 100644 (file)
@@ -21,6 +21,7 @@
 #include <Geom_Plane.hxx>
 #include <Geom_RectangularTrimmedSurface.hxx>
 #include <Geom_TrimmedCurve.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <TopoDS_Shape.hxx>
@@ -250,6 +251,26 @@ std::string GeomAPI_Shape::shapeTypeStr() const
   return aShapeTypeStr;
 }
 
+bool GeomAPI_Shape::isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape) const
+{
+  if(!theShape.get()) {
+    return false;
+  }
+
+  const TopoDS_Shape& aShapeToSearch = theShape->impl<TopoDS_Shape>();
+  if(aShapeToSearch.IsNull()) {
+    return false;
+  }
+
+  for(TopExp_Explorer anExp(*MY_SHAPE, aShapeToSearch.ShapeType()); anExp.More(); anExp.Next()) {
+    if(aShapeToSearch.IsEqual(anExp.Current())) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 bool GeomAPI_Shape::computeSize(double& theXmin, double& theYmin, double& theZmin,
                                 double& theXmax, double& theYmax, double& theZmax) const
 {
index 7adf4da806700ea5f439f8963d727e2b44bfd770..1ed86db9c1059bf83a3acc89f098d11bc9382961 100644 (file)
@@ -78,6 +78,11 @@ public:
   GEOMAPI_EXPORT
   virtual std::string shapeTypeStr() const;
 
+  /// \return true if passed shape is a sub-shape of this shape.
+  /// \param theShape shape to search.
+  GEOMAPI_EXPORT virtual bool isSubShape(const std::shared_ptr<GeomAPI_Shape> theShape) const;
+
+
   /// Computes boundary dimensions of the shape
   /// Returns False if it is not possible
   GEOMAPI_EXPORT 
index 84105385f42764f97c25112a439e55a01f27ecaf..e765913a8bb46a71c9617c52f3501e09690287af 100644 (file)
@@ -37,6 +37,7 @@ SET(PROJECT_HEADERS
     GeomAlgoAPI_Intersection.h
     GeomAlgoAPI_Pipe.h
     GeomAlgoAPI_WireBuilder.h
+    GeomAlgoAPI_Sewing.h
 )
 
 SET(PROJECT_SOURCES
@@ -70,6 +71,7 @@ SET(PROJECT_SOURCES
     GeomAlgoAPI_Intersection.cpp
     GeomAlgoAPI_Pipe.cpp
     GeomAlgoAPI_WireBuilder.cpp
+    GeomAlgoAPI_Sewing.cpp
 )
 
 SET(PROJECT_LIBRARIES
index 8c9279226a17c8deafb28e56f7947354b3b5c756..e4efaa2ba357688ebfd5c3e9dc4086aba5c0213f 100644 (file)
@@ -43,6 +43,7 @@
 %include "GeomAlgoAPI_Intersection.h"
 %include "GeomAlgoAPI_Pipe.h"
 %include "GeomAlgoAPI_WireBuilder.h"
+%include "GeomAlgoAPI_Sewing.h"
 
 %typemap(out) std::list< std::shared_ptr< GeomAPI_Shape > >::value_type & {
   $result = SWIG_NewPointerObj(SWIG_as_voidptr(new std::shared_ptr<GeomAPI_Shape>(*$1)), $descriptor(std::shared_ptr<GeomAPI_Shape> *), SWIG_POINTER_OWN | 0 );
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.cpp
new file mode 100644 (file)
index 0000000..4539b08
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Sewing.cpp
+// Created:     25 April 2016
+// Author:      Dmitry Bobylev
+
+
+#include "GeomAlgoAPI_Sewing.h"
+
+#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_MakeShell.hxx>
+#include <BRepBuilderAPI_Sewing.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+
+//==================================================================================================
+GeomAlgoAPI_Sewing::GeomAlgoAPI_Sewing(const ListOfShape& theShapes)
+{
+  build(theShapes);
+}
+
+void GeomAlgoAPI_Sewing::build(const ListOfShape& theShapes)
+{
+  if(theShapes.empty()) {
+    return;
+  }
+
+  BRepBuilderAPI_Sewing* aSewingBuilder = new BRepBuilderAPI_Sewing();
+  this->setImpl(aSewingBuilder);
+
+  for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
+    const TopoDS_Shape& aShape = (*anIt)->impl<TopoDS_Shape>();
+    aSewingBuilder->Add(aShape);
+  }
+
+  aSewingBuilder->Perform();
+
+  TopoDS_Shape aResult = aSewingBuilder->SewedShape();
+  BRep_Builder aBuilder;
+  TopoDS_Compound aResultCompound;
+  aBuilder.MakeCompound(aResultCompound);
+  for(TopoDS_Iterator anIt(aResult); anIt.More(); anIt.Next()) {
+    const TopoDS_Shape aSubShape = anIt.Value();
+    if(aSubShape.ShapeType() == TopAbs_SHELL) {
+      aBuilder.Add(aResultCompound, aSubShape);
+    } else if (aSubShape.ShapeType() == TopAbs_FACE) {
+      TopoDS_Shell aShell;
+      aBuilder.MakeShell(aShell);
+      aBuilder.Add(aShell, aSubShape);
+      aBuilder.Add(aResultCompound, aShell);
+    }
+  }
+  TopoDS_Iterator anIt(aResultCompound);
+  if(anIt.More()) {
+    aResult = aResultCompound;
+  }
+
+  std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+  aShape->setImpl(new TopoDS_Shape(aResult));
+  this->setShape(aShape);
+  this->setDone(true);
+}
+
+//==================================================================================================
+void GeomAlgoAPI_Sewing::modified(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                  ListOfShape& theHistory)
+{
+  static int anIndex = 0;
+  if(!theShape.get()) {
+    return;
+  }
+
+  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+  const BRepBuilderAPI_Sewing& aSewingBuilder = this->impl<BRepBuilderAPI_Sewing>();
+
+  TopoDS_Shape aModifiedShape = aSewingBuilder.Modified(aShape);
+  if(aModifiedShape.IsEqual(aShape)) {
+    aModifiedShape = aSewingBuilder.ModifiedSubShape(aShape);
+  }
+
+  for(TopExp_Explorer anExp(aModifiedShape, aShape.ShapeType()); anExp.More(); anExp.Next()) {
+    GeomShapePtr aGeomShape(new GeomAPI_Shape());
+    aGeomShape->setImpl(new TopoDS_Shape(anExp.Current()));
+    theHistory.push_back(aGeomShape);
+  }
+}
diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.h b/src/GeomAlgoAPI/GeomAlgoAPI_Sewing.h
new file mode 100644 (file)
index 0000000..aa11b86
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAlgoAPI_Sewing.h
+// Created:     25 April 2016
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAlgoAPI_Sewing_H_
+#define GeomAlgoAPI_Sewing_H_
+
+#include "GeomAlgoAPI.h"
+#include "GeomAlgoAPI_MakeShape.h"
+
+#include <GeomAPI_Shape.h>
+
+/// \class GeomAlgoAPI_Sewing
+/// \ingroup DataAlgo
+/// \brief Allows creation of connected topology (shells) from a set of separate topological elements (faces).
+class GeomAlgoAPI_Sewing : public GeomAlgoAPI_MakeShape
+{
+public:
+  /// Constructor.
+  GEOMALGOAPI_EXPORT GeomAlgoAPI_Sewing(const ListOfShape& theShapes);
+
+  /// \return the list of shapes modified from the shape \a theShape.
+  /// \param[in] theShape base shape.
+  /// \param[out] theHistory modified shapes.
+  GEOMALGOAPI_EXPORT virtual void modified(const std::shared_ptr<GeomAPI_Shape> theShape,
+                                           ListOfShape& theHistory);
+
+private:
+  /// Builds resulting shape.
+  void build(const ListOfShape& theShapes);
+};
+
+#endif
index 92327a03d72f79b36a2d4fe80af438695423d230..3cf49122dbd9ab254e62aa0a7e1aa8c8bb825d8c 100644 (file)
@@ -37,7 +37,8 @@
   #include "GeomAlgoAPI_Intersection.h"
   #include "GeomAlgoAPI_Pipe.h"
   #include "GeomAlgoAPI_WireBuilder.h"
-
+  #include "GeomAlgoAPI_Sewing.h"
+  
   #include <memory>
   #include <string>
   #include <list>