]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Task 3.10. BuildEdge from two points
authorazv <azv@opencascade.com>
Fri, 17 May 2019 06:57:42 +0000 (09:57 +0300)
committervsv <vsv@opencascade.com>
Mon, 3 Jun 2019 10:32:07 +0000 (13:32 +0300)
src/BuildAPI/BuildAPI_Edge.cpp
src/BuildAPI/BuildAPI_Edge.h
src/BuildPlugin/BuildPlugin_Edge.cpp
src/BuildPlugin/BuildPlugin_Edge.h
src/BuildPlugin/CMakeLists.txt
src/BuildPlugin/Test/TestEdge_ByPoints.py [new file with mode: 0644]
src/BuildPlugin/edge_widget.xml
src/BuildPlugin/icons/edge_by_points_32x32.png [new file with mode: 0644]
src/BuildPlugin/icons/edge_by_segments_32x32.png [new file with mode: 0644]

index cd8052f300cdc27a8cc61ebd00c04399940eb743..3371f01eaf109912c91fd67a226bd60af4a7191d 100644 (file)
@@ -35,10 +35,26 @@ BuildAPI_Edge::BuildAPI_Edge(const std::shared_ptr<ModelAPI_Feature>& theFeature
 : ModelHighAPI_Interface(theFeature)
 {
   if(initialize()) {
+    fillAttribute(BuildPlugin_Edge::CREATION_BY_SEGMENTS(), mycreationMethod);
     setBase(theBaseObjects);
   }
 }
 
+//==================================================================================================
+BuildAPI_Edge::BuildAPI_Edge(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                             const ModelHighAPI_Selection& theFirstPoint,
+                             const ModelHighAPI_Selection& theSecondPoint)
+: ModelHighAPI_Interface(theFeature)
+{
+  if(initialize()) {
+    fillAttribute(BuildPlugin_Edge::CREATION_BY_POINTS(), mycreationMethod);
+    fillAttribute(theFirstPoint, myfirstPoint);
+    fillAttribute(theSecondPoint, mysecondPoint);
+
+    execute();
+  }
+}
+
 //==================================================================================================
 BuildAPI_Edge::~BuildAPI_Edge()
 {
@@ -59,8 +75,17 @@ void BuildAPI_Edge::dump(ModelHighAPI_Dumper& theDumper) const
   FeaturePtr aBase = feature();
   std::string aPartName = theDumper.name(aBase->document());
 
-  theDumper << aBase << " = model.addEdge(" << aPartName << ", "
-            << aBase->selectionList(BuildPlugin_Edge::BASE_OBJECTS_ID()) << ")" << std::endl;
+  theDumper << aBase << " = model.addEdge(" << aPartName << ", ";
+
+  AttributeStringPtr aCreationMethod = aBase->string(BuildPlugin_Edge::CREATION_METHOD());
+  if (aCreationMethod && aCreationMethod->isInitialized() &&
+      aCreationMethod->value() == BuildPlugin_Edge::CREATION_BY_POINTS()) {
+    theDumper << aBase->selection(BuildPlugin_Edge::FIRST_POINT()) << ", "
+              << aBase->selection(BuildPlugin_Edge::SECOND_POINT());
+  }
+  else
+    theDumper << aBase->selectionList(BuildPlugin_Edge::BASE_OBJECTS_ID());
+  theDumper << ")" << std::endl;
 }
 
 //==================================================================================================
@@ -70,3 +95,11 @@ EdgePtr addEdge(const std::shared_ptr<ModelAPI_Document>& thePart,
   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(BuildAPI_Edge::ID());
   return EdgePtr(new BuildAPI_Edge(aFeature, theBaseObjects));
 }
+
+EdgePtr addEdge(const std::shared_ptr<ModelAPI_Document>& thePart,
+                const ModelHighAPI_Selection& theFirstPoint,
+                const ModelHighAPI_Selection& theSecondPoint)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(BuildAPI_Edge::ID());
+  return EdgePtr(new BuildAPI_Edge(aFeature, theFirstPoint, theSecondPoint));
+}
index d5c016399627118841046e3aa8833ce227acd36b..11a7fa90210d6a424a649fa964899287c22a325e 100644 (file)
@@ -44,13 +44,25 @@ public:
   explicit BuildAPI_Edge(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                          const std::list<ModelHighAPI_Selection>& theBaseObjects);
 
+  /// Constructor by points.
+  BUILDAPI_EXPORT
+  explicit BuildAPI_Edge(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                         const ModelHighAPI_Selection& theFirstPoint,
+                         const ModelHighAPI_Selection& theSecondPoint);
+
   /// Destructor.
   BUILDAPI_EXPORT
   virtual ~BuildAPI_Edge();
 
-  INTERFACE_1(BuildPlugin_Edge::ID(),
+  INTERFACE_4(BuildPlugin_Edge::ID(),
               baseObjects, BuildPlugin_Edge::BASE_OBJECTS_ID(),
-              ModelAPI_AttributeSelectionList, /** Base objects */)
+              ModelAPI_AttributeSelectionList, /** Base objects */,
+              creationMethod, BuildPlugin_Edge::CREATION_METHOD(),
+              ModelAPI_AttributeString, /** Creation method */,
+              firstPoint, BuildPlugin_Edge::FIRST_POINT(),
+              ModelAPI_AttributeSelection, /** First point */,
+              secondPoint, BuildPlugin_Edge::SECOND_POINT(),
+              ModelAPI_AttributeSelection, /** Second point */)
 
   /// Modify base attribute of the feature.
   BUILDAPI_EXPORT
@@ -69,5 +81,11 @@ typedef std::shared_ptr<BuildAPI_Edge> EdgePtr;
 BUILDAPI_EXPORT
 EdgePtr addEdge(const std::shared_ptr<ModelAPI_Document>& thePart,
                 const std::list<ModelHighAPI_Selection>& theBaseObjects);
+/// \ingroup CPPHighAPI
+/// \brief Create Edge feature.
+BUILDAPI_EXPORT
+EdgePtr addEdge(const std::shared_ptr<ModelAPI_Document>& thePart,
+                const ModelHighAPI_Selection& theFirstPoint,
+                const ModelHighAPI_Selection& theSecondPoint);
 
 #endif // BuildAPI_Edge_H_
index c7928d083dcad5eb5bb818763d8baaf65148a8f2..0f85ae3e443842129b491d6e11ee39ea6ccaa76e 100644 (file)
 #include "BuildPlugin_Edge.h"
 
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_ResultBody.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
 
 #include <GeomAlgoAPI_Copy.h>
+#include <GeomAlgoAPI_EdgeBuilder.h>
 #include <GeomAlgoAPI_Tools.h>
 
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_Vertex.h>
+
+static bool getShape(const AttributeSelectionPtr theAttribute,
+                     GeomShapePtr& theShape,
+                     std::string& theError)
+{
+  theShape = theAttribute->value();
+  if (!theShape.get()) {
+    ResultPtr aContext = theAttribute->context();
+    if (!aContext.get()) {
+      theError = "Error: Attribute has empty context.";
+      return false;
+    }
+    theShape = aContext->shape();
+  }
+  return true;
+}
+
 //=================================================================================================
 BuildPlugin_Edge::BuildPlugin_Edge()
 {
@@ -34,11 +58,30 @@ BuildPlugin_Edge::BuildPlugin_Edge()
 void BuildPlugin_Edge::initAttributes()
 {
   data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
+
+  data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHOD());
+
+  data()->addAttribute(FIRST_POINT(), ModelAPI_AttributeSelection::typeId());
+  data()->addAttribute(SECOND_POINT(), ModelAPI_AttributeSelection::typeId());
 }
 
 //=================================================================================================
 void BuildPlugin_Edge::execute()
 {
+  AttributeStringPtr aCreationMethod = string(CREATION_METHOD());
+  if (aCreationMethod && aCreationMethod->isInitialized() &&
+      aCreationMethod->value() == CREATION_BY_POINTS())
+    edgeByPoints();
+  else
+    edgesBySegments();
+}
+
+//=================================================================================================
+void BuildPlugin_Edge::edgesBySegments()
+{
+  string(CREATION_METHOD())->setValue(CREATION_BY_SEGMENTS());
+
   // Get base objects list.
   AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
   if(!aSelectionList.get()) {
@@ -52,18 +95,14 @@ void BuildPlugin_Edge::execute()
 
   // Collect base shapes.
   ListOfShape aListOfShapes;
+  std::string aError;
   int aResultIndex = 0;
   for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
     AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
-    GeomShapePtr aShape = aSelection->value();
-    if(!aShape.get()) {
-      ResultPtr aContext = aSelection->context();
-      if(!aContext.get()) {
-        setError("Error: Attribute has empty context.");
-        return;
-      }
-
-      aShape = aContext->shape();
+    GeomShapePtr aShape;
+    if (!getShape(aSelection, aShape, aError)) {
+      setError(aError);
+      return;
     }
     if(!aShape.get()) {
       setError("Error: Empty shape selected.");
@@ -98,3 +137,54 @@ void BuildPlugin_Edge::execute()
 
   removeResults(aResultIndex);
 }
+
+void BuildPlugin_Edge::edgeByPoints()
+{
+  // Get base points.
+  AttributeSelectionPtr aFirstPointAttr = selection(FIRST_POINT());
+  AttributeSelectionPtr aSecondPointAttr = selection(SECOND_POINT());
+  if (!aFirstPointAttr.get() || !aSecondPointAttr.get()) {
+    setError("Error: Not enough points selected.");
+    return;
+  }
+
+  std::string aError;
+  GeomShapePtr aFirstShape, aSecondShape;
+  if (!getShape(aFirstPointAttr, aFirstShape, aError) ||
+      !getShape(aSecondPointAttr, aSecondShape, aError)) {
+    setError(aError);
+    return;
+  }
+  if (!aFirstShape.get() || !aSecondShape.get()) {
+    setError("Error: Empty shape selected.");
+    return;
+  }
+
+  if (!aFirstShape->isVertex() || !aSecondShape->isVertex()) {
+    setError("Error: Selected shape has wrong type. Only vertices acceptable.");
+    return;
+  }
+
+  int aResultIndex = 0;
+
+  GeomEdgePtr anEdge = GeomAlgoAPI_EdgeBuilder::line(aFirstShape->vertex()->point(),
+                                                     aSecondShape->vertex()->point());
+  if (!anEdge.get()) {
+    setError("Error: Algorithm failed.");
+    return;
+  }
+
+  // Store result.
+  ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+  aResultBody->store(anEdge);
+  // History of vertices
+  GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX);
+  GeomShapePtr aStartVertex = anExp.current();
+  anExp.next();
+  GeomShapePtr anEndVertex = anExp.current();
+  aResultBody->modified(aFirstShape, aStartVertex);
+  aResultBody->modified(aSecondShape, anEndVertex);
+
+  setResult(aResultBody, aResultIndex++);
+  removeResults(aResultIndex);
+}
index e1f7594dcfa9c55cd939212196984054d51a9c4a..27f1665ba0eb3f0da9ff5510a13cfc5f3725b20f 100644 (file)
@@ -54,11 +54,52 @@ public:
     return MY_KIND;
   }
 
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD()
+  {
+    static const std::string MY_CREATION_METHOD_ID("creation_method");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Value for creation method.
+  inline static const std::string& CREATION_BY_SEGMENTS()
+  {
+    static const std::string MY_CREATION_METHOD_ID("by_segments");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Value for creation method.
+  inline static const std::string& CREATION_BY_POINTS()
+  {
+    static const std::string MY_CREATION_METHOD_ID("by_points");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name for the first point.
+  inline static const std::string& FIRST_POINT()
+  {
+    static const std::string MY_FIRST_POINT_ID("first_point");
+    return MY_FIRST_POINT_ID;
+  }
+
+  /// Attribute name for the second point.
+  inline static const std::string& SECOND_POINT()
+  {
+    static const std::string MY_SECOND_POINT_ID("second_point");
+    return MY_SECOND_POINT_ID;
+  }
+
   /// 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();
+
+private:
+  /// Build edges by the set of segments
+  void edgesBySegments();
+  /// Build edge by two points.
+  void edgeByPoints();
 };
 
 #endif
index f22f6598bbc9d5a385958abcfa4c4ca2c253a770..25bc5a01310fe54987e856066887768cbaffd885 100644 (file)
@@ -108,6 +108,7 @@ INSTALL(DIRECTORY icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Build
 ADD_UNIT_TESTS(TestVertex.py
                TestVertex_ErrorMsg.py
                TestEdge.py
+               TestEdge_ByPoints.py
                TestEdge_ErrorMsg.py
                TestWire.py
                TestWire_ErrorMsg.py
diff --git a/src/BuildPlugin/Test/TestEdge_ByPoints.py b/src/BuildPlugin/Test/TestEdge_ByPoints.py
new file mode 100644 (file)
index 0000000..f5185f1
--- /dev/null
@@ -0,0 +1,51 @@
+# Copyright (C) 2014-2019  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
+#
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(30, -30, -20, -30)
+SketchLine_2 = Sketch_1.addLine(-20, -30, -20, 35)
+SketchLine_3 = Sketch_1.addLine(-20, 35, 30, 35)
+SketchLine_4 = Sketch_1.addLine(30, 35, 30, -30)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+Edge_1 = model.addEdge(Part_1_doc, model.selection("VERTEX", "Sketch_1/SketchLine_2_StartVertex"), model.selection("VERTEX", "Sketch_1/SketchLine_4_StartVertex"))
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Edge_2 = model.addEdge(Part_1_doc, model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_2][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_1][Extrusion_1_1/To_Face]"), model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]"))
+Edge_3_objects = [model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_1][Extrusion_1_1/To_Face]"), model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_1]"), model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/From_Face]")]
+Edge_3 = model.addEdge(Part_1_doc, Edge_3_objects)
+model.end()
+
+assert(Edge_1.feature().error() == "")
+assert(Edge_2.feature().error() == "")
+assert(Edge_3.feature().error() == "")
+
+assert(model.checkPythonDump())
index 3aa7d16c2538581dbd7aa993406f34983609caa4..be088557818ee0d083ec375f0d348ab196f459a9 100644 (file)
@@ -1,9 +1,32 @@
 <source>
-  <multi_selector id="base_objects"
-                  label="Edges:"
-                  tooltip="Select edges on sketch or edges objects."
-                  type_choice="edges"
-                  concealment="true">
-    <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="edge"/>
-  </multi_selector>
+  <toolbox id="creation_method">
+    <box id="by_segments" title="By segments" icon="icons/Build/edge_by_segments_32x32.png">
+      <multi_selector id="base_objects"
+                      label="Edges:"
+                      tooltip="Select edges on sketch or edges objects."
+                      type_choice="edges"
+                      concealment="true">
+        <validator id="BuildPlugin_ValidatorBaseForBuild" parameters="edge"/>
+      </multi_selector>
+    </box>
+    <box id="by_points" title="By two points" icon="icons/Build/edge_by_points_32x32.png">
+      <shape_selector id="first_point"
+                      label="First point"
+                      icon="icons/Construction/point.png"
+                      tooltip="Select a first point"
+                      shape_types="vertex">
+        <validator id="GeomValidators_ConstructionComposite"/>
+        <validator id="GeomValidators_ShapeType" parameters="vertex"/>
+      </shape_selector>
+      <shape_selector id="second_point"
+                      label="Second point"
+                      icon="icons/Construction/point.png"
+                      tooltip="Select a second point"
+                      shape_types="vertex">
+        <validator id="GeomValidators_ConstructionComposite"/>
+        <validator id="GeomValidators_ShapeType" parameters="vertex"/>
+        <validator id="GeomValidators_DifferentShapes"/>
+      </shape_selector>
+    </box>
+  </toolbox>
 </source>
diff --git a/src/BuildPlugin/icons/edge_by_points_32x32.png b/src/BuildPlugin/icons/edge_by_points_32x32.png
new file mode 100644 (file)
index 0000000..469f9d8
Binary files /dev/null and b/src/BuildPlugin/icons/edge_by_points_32x32.png differ
diff --git a/src/BuildPlugin/icons/edge_by_segments_32x32.png b/src/BuildPlugin/icons/edge_by_segments_32x32.png
new file mode 100644 (file)
index 0000000..abdccd7
Binary files /dev/null and b/src/BuildPlugin/icons/edge_by_segments_32x32.png differ