Salome HOME
Task 3.5 Build/Vertex on a whole Sketch (issue #3079)
authorazv <azv@opencascade.com>
Fri, 22 Nov 2019 07:47:22 +0000 (10:47 +0300)
committerazv <azv@opencascade.com>
Fri, 22 Nov 2019 07:47:22 +0000 (10:47 +0300)
src/BuildPlugin/BuildPlugin_Validators.cpp
src/BuildPlugin/BuildPlugin_Vertex.cpp
src/BuildPlugin/BuildPlugin_Vertex.h
src/BuildPlugin/CMakeLists.txt
src/BuildPlugin/Test/TestVertex.py
src/BuildPlugin/Test/TestVertex_WholeSketch_1.py [new file with mode: 0644]
src/BuildPlugin/Test/TestVertex_WholeSketch_2.py [new file with mode: 0644]
src/GeomAPI/GeomAPI_Vertex.cpp
src/GeomAPI/GeomAPI_Vertex.h

index 6b44423f877549b50f43992147414e87f3b68c6e..99ba50ccb427f5359e93b1bdb99ff3f18b01b544 100644 (file)
@@ -39,6 +39,8 @@
 #include <GeomValidators_FeatureKind.h>
 #include <GeomValidators_ShapeType.h>
 
+#include <SketchPlugin_Sketch.h>
+
 #include <Events_InfoMessage.h>
 
 //=================================================================================================
@@ -519,30 +521,33 @@ bool BuildPlugin_ValidatorBaseForVertex::isValid(const AttributePtr& theAttribut
 
     // Vertex?
     bool isVertex = false;
-    GeomShapePtr aShapeInList = aSelectionAttr->value();
-    if (aShapeInList.get()) {
-      isVertex = (aShapeInList->shapeType() == GeomAPI_Shape::VERTEX);
-    }
+    GeomShapePtr aShape = aSelectionAttr->value();
+    ResultPtr aContext = aSelectionAttr->context();
+    if (!aShape.get() && aContext.get())
+      aShape = aContext->shape();
+    if (aShape.get())
+      isVertex = (aShape->shapeType() == GeomAPI_Shape::VERTEX);
 
     if (!isVertex) {
       // Sketch?
       FeaturePtr aFeature = aSelectionAttr->contextFeature();
       if (!aFeature.get()) {
-        ResultPtr aContext = aSelectionAttr->context();
-        if (aContext.get()) {
+        GeomShapePtr aValue = aSelectionAttr->value();
+        // whole sketch is allowed only
+        if (aContext.get() && !aValue.get()) {
           aFeature = ModelAPI_Feature::feature(aContext);
         }
       }
 
-      if (aFeature.get()) {
-        std::string aFeatureKind = aFeature->getKind();
-        if (aFeatureKind != "Sketch" &&
-            aFeatureKind != "Point" &&
-            aFeatureKind != "Vertex") {
-          theError = "Error: %1 shape is not allowed for selection.";
-          theError.arg(aFeatureKind);
-          return false;
-        }
+      if (!aFeature.get()) {
+        theError = "Error: Incorrect selection.";
+        return false;
+      }
+
+      if (aFeature->getKind() != SketchPlugin_Sketch::ID()) {
+        theError = "Error: %1 shape is not allowed for selection.";
+        theError.arg(aFeature->getKind());
+        return false;
       }
     }
   }
index f2b20617707526352cd56918ff822cdeef705b20..caed091a2666136d012d500bbc9f9c6f2f383415 100644 (file)
@@ -26,7 +26,9 @@
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_Session.h>
 
+#include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_Copy.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
 #include <GeomAlgoAPI_Tools.h>
 #include <GeomAlgoAPI_Partition.h>
 #include <GeomAlgoAPI_ShapeTools.h>
@@ -47,177 +49,88 @@ void BuildPlugin_Vertex::initAttributes()
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), INTERSECT_ID());
 }
 
-//=================================================================================================
-bool BuildPlugin_Vertex::buildVertices(GeomShapePtr theShape,
-                                       bool isIntersect,
-                                       int& theResultIndex)
+void BuildPlugin_Vertex::buildVertices(const ListOfShape& theShapes, bool isIntersect)
 {
-  if (!theShape.get()) {
-    setError("Error: Empty shape selected.");
-    return false;
-  }
-
-  if (theShape->shapeType() == GeomAPI_Shape::VERTEX) {
-    // Copy shape.
-    std::shared_ptr<GeomAlgoAPI_Copy> aCopyAlgo(new GeomAlgoAPI_Copy(theShape));
+  GeomShapePtr aResult;
+  std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo;
+  if (isIntersect) {
+    aPartitionAlgo.reset(new GeomAlgoAPI_Partition(theShapes, ListOfShape()));
 
     std::string anError;
-    if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCopyAlgo, getKind(), anError)) {
+    if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPartitionAlgo, getKind(), anError)) {
       setError(anError);
-      return false;
+      return;
     }
 
-    // Store result.
-    ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
-    aResultBody->storeModified(theShape, aCopyAlgo->shape());
-    setResult(aResultBody, theResultIndex);
-    ++theResultIndex;
-  } else {
-    // Sketch
-    GeomAPI_DataMapOfShapeShape alreadyProcessed;
-
-    // 1. Explode on Vertices
-    for (GeomAPI_ShapeExplorer anExp (theShape, GeomAPI_Shape::VERTEX);
-         anExp.more(); anExp.next()) {
-      GeomShapePtr aSubShape = anExp.current();
+    aResult = aPartitionAlgo->shape();
+  }
+  else
+    aResult = GeomAlgoAPI_CompoundBuilder::compound(theShapes);
 
-      if (alreadyProcessed.bind(aSubShape, aSubShape)) {
-        // Store result.
-        ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
-        aResultBody->storeModified(theShape, aSubShape);
-        setResult(aResultBody, theResultIndex);
-        ++theResultIndex;
-      }
-    }
+  int aResultIndex = 0;
 
-    // 2. If need intersection points, perform Partition
-    if (isIntersect) {
-      // Partition
-      ListOfShape anObjList, aTools;
-      anObjList.push_back(theShape);
-      std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo (
-          new GeomAlgoAPI_Partition(anObjList, aTools));
+  // Explode on vertices
+  std::set<GeomVertexPtr, GeomAPI_Vertex::GeometricComparator> aProcessed;
+  for (GeomAPI_ShapeExplorer anExp(aResult, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
+    GeomVertexPtr aVertex(new GeomAPI_Vertex(anExp.current()));
+    if (aProcessed.find(aVertex) != aProcessed.end())
+      continue; // vertex is already processed
+    aProcessed.insert(aVertex);
 
-      std::string anError;
-      if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPartitionAlgo, getKind(), anError)) {
-        setError(anError);
-        return false;
-      }
-      GeomShapePtr aSplittedSketch = aPartitionAlgo->shape();
+    std::shared_ptr<GeomAlgoAPI_Copy> aCopy(new GeomAlgoAPI_Copy(aVertex));
+    aVertex.reset(new GeomAPI_Vertex(aCopy->shape()));
 
-      // Explode on Vertices, skip vertices of initial sketch
-      for (GeomAPI_ShapeExplorer anExp (aSplittedSketch, GeomAPI_Shape::VERTEX);
-           anExp.more(); anExp.next()) {
-        GeomShapePtr aSubShape = anExp.current();
+    std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList);
+    if (aPartitionAlgo)
+      aMakeShapeList->appendAlgo(aPartitionAlgo);
+    aMakeShapeList->appendAlgo(aCopy);
 
-        //if (!theShape->isSubShape(aSubShape)) { // skip vertices of initial sketch
-        if (alreadyProcessed.bind(aSubShape, aSubShape)) {
-          // Store result.
-          ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
-          aResultBody->storeGenerated(anObjList, aSubShape, aPartitionAlgo);
-          setResult(aResultBody, theResultIndex);
-          ++theResultIndex;
-        }
-      }
-    }
+    // Store result.
+    ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+    aResultBody->storeModified(theShapes, aVertex, aMakeShapeList);
+    setResult(aResultBody, aResultIndex);
+    ++aResultIndex;
   }
 
-  return true;
+  removeResults(aResultIndex);
 }
 
-//=================================================================================================
-bool BuildPlugin_Vertex::buildVertices(FeaturePtr theFeature,
-                                       bool isIntersect,
-                                       int& theResultIndex)
+static void collectEdgesAndVertices(AttributeSelectionPtr theSelection, ListOfShape& thePrimitives)
 {
-  if (theFeature->getKind() != "Sketch") return false;
-
-  // Sub-features
-  CompositeFeaturePtr aComposite =
-    std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
-  if (!aComposite) return false;
-  int nbSubs = aComposite->numberOfSubs();
-  if (nbSubs < 1) return false;
-
-  // The whole sketch shape
-  ResultPtr aContext = theFeature->firstResult();
-  GeomShapePtr theShape = aContext->shape();
-
-  GeomAPI_DataMapOfShapeShape alreadyProcessed;
-
-  // 1. Explode on Vertices
-  for (GeomAPI_ShapeExplorer anExp (theShape, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
-    GeomShapePtr aSubShape = anExp.current();
-
-    if (alreadyProcessed.bind(aSubShape, aSubShape)) {
-      // Store result.
-      ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
-      aResultBody->storeModified(theShape, aSubShape);
-      setResult(aResultBody, theResultIndex);
-      ++theResultIndex;
-    }
-  }
-
-  // 2. If need intersection points, perform Partition
-  if (isIntersect) {
-    // Partition
-    ListOfShape anObjList, aTools;
-    anObjList.push_back(theShape);
-    std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo (
-        new GeomAlgoAPI_Partition(anObjList, aTools));
-
-    std::string anError;
-    if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPartitionAlgo, getKind(), anError)) {
-      setError(anError);
-      return false;
-    }
-    GeomShapePtr aSplittedSketch = aPartitionAlgo->shape();
-
-    // Explode on Vertices, skip vertices of initial sketch
-    for (GeomAPI_ShapeExplorer anExp (aSplittedSketch, GeomAPI_Shape::VERTEX);
-         anExp.more(); anExp.next()) {
-      GeomShapePtr aSubShape = anExp.current();
-
-      //if (!theShape->isSubShape(aSubShape)) { // skip vertices of initial sketch
-      if (alreadyProcessed.bind(aSubShape, aSubShape)) {
-        // Store result.
-        ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
-        aResultBody->storeGenerated(anObjList, aSubShape, aPartitionAlgo);
-        setResult(aResultBody, theResultIndex);
-        ++theResultIndex;
+  FeaturePtr aFeature = theSelection->contextFeature();
+  ResultPtr aContext = theSelection->context();
+  GeomShapePtr aShape = theSelection->value();
+  if (aShape)
+    thePrimitives.push_back(aShape);
+  else {
+    if (aContext && !aFeature)
+      aFeature = ModelAPI_Feature::feature(aContext);
+    if (!aFeature)
+      return;
+
+    // process results of the feature
+    const std::list<ResultPtr>& aResults = aFeature->results();
+    std::list<ResultPtr>::const_iterator anIt = aResults.begin();
+    for (; anIt != aResults.end(); ++anIt)
+      thePrimitives.push_back((*anIt)->shape());
+
+    CompositeFeaturePtr aComposite =
+        std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
+    if (!aComposite)
+      return;
+
+    // add construction points (centers of circles, etc.)
+    for (int i = 0, nbSubs = aComposite->numberOfSubs(); i < nbSubs; ++i) {
+      FeaturePtr aSubFeature = aComposite->subFeature(i);
+      const std::list<ResultPtr>& aSubResults = aSubFeature->results();
+      // find all points
+      for (anIt = aSubResults.begin(); anIt != aSubResults.cend(); ++anIt) {
+        GeomShapePtr aSubResShape = (*anIt)->shape();
+        if (aSubResShape->isVertex())
+          thePrimitives.push_back(aSubResShape);
       }
     }
   }
-
-  // 3. Add construction points (centers of circles, etc.)
-  for (int i = 0; i < nbSubs; i++) {
-    FeaturePtr aSubFeature = aComposite->subFeature(i);
-    const std::list<ResultPtr>& aSubResults = aSubFeature->results();
-    std::list<ResultPtr>::const_iterator anItRes = aSubResults.cbegin();
-    // Iterate on all sub-results
-    for (; anItRes != aSubResults.cend(); anItRes++) {
-      ResultPtr aRes = *anItRes;
-      if (aRes.get()) {
-        // Sub-result i
-        GeomShapePtr aSubResShape = aRes->shape();
-
-        for (GeomAPI_ShapeExplorer anExp (aSubResShape, GeomAPI_Shape::VERTEX);
-             anExp.more(); anExp.next()) {
-          GeomShapePtr aSubShape = anExp.current();
-
-          if (alreadyProcessed.bind(aSubShape, aSubShape)) {
-            // Store result.
-            ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
-            aResultBody->storeModified(theShape, aSubShape);
-            setResult(aResultBody, theResultIndex);
-            ++theResultIndex;
-          }
-        }
-      }
-    }
-  }
-
-  return true;
 }
 
 void BuildPlugin_Vertex::execute()
@@ -239,51 +152,12 @@ void BuildPlugin_Vertex::execute()
     isIntersect = boolean(INTERSECT_ID())->value();
   }
 
-  // Iterate arguments and build results
-  int aResultIndex = 0;
+  // Iterate arguments and collect shapes
+  ListOfShape aShapes;
   for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
     AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
-    GeomShapePtr aShape = aSelection->value();
-    if (aShape.get()) {
-      // A shape selected
-      if (!buildVertices(aShape, isIntersect, aResultIndex)) return;
-    } else {
-      ResultPtr aContext = aSelection->context();
-      if (aContext.get()) { // Result selected
-        FeaturePtr aFeature = ModelAPI_Feature::feature(aContext);
-        if (aFeature.get()) {
-          if (aFeature->getKind() == "Sketch") {
-            // Special processing for sketch to build center vertices etc.
-            if (!buildVertices(aFeature, isIntersect, aResultIndex)) return;
-          } else {
-            aShape = aContext->shape();
-            if (!buildVertices(aShape, isIntersect, aResultIndex)) return;
-          }
-        }
-      } else {
-        FeaturePtr aFeature = aSelection->contextFeature();
-        if (aFeature.get()) { // Feature selected
-          if (aFeature->getKind() == "Sketch") {
-            // Special processing for sketch to build center vertices etc.
-            if (!buildVertices(aFeature, isIntersect, aResultIndex)) return;
-          } else {
-            const std::list<ResultPtr>& anArgResults = aFeature->results();
-            std::list<ResultPtr>::const_iterator anItRes = anArgResults.cbegin();
-            // Iterate on all its results
-            for (; anItRes != anArgResults.cend(); anItRes++) {
-              ResultPtr aRes = *anItRes;
-              if (aRes.get()) {
-                // Result i
-                aShape = aRes->shape();
-                if (!buildVertices(aShape, isIntersect, aResultIndex)) return;
-              }
-            }
-          }
-        }
-      }
-    }
+    collectEdgesAndVertices(aSelection, aShapes);
   }
 
-  // Remove extra results from previous execution
-  removeResults(aResultIndex);
+  buildVertices(aShapes, isIntersect);
 }
index d6dfa9c7814e880a940f2dd39030fe45f74ca721..980dd82017a2a91cd7c411bbf4e66209d46cf1eb 100644 (file)
@@ -68,14 +68,8 @@ public:
   /// Creates a new part document if needed.
   BUILDPLUGIN_EXPORT virtual void execute();
 
- protected:
-  bool buildVertices(GeomShapePtr theShape,
-                     bool isIntersect,
-                     int& theResultIndex);
-
-  bool buildVertices(FeaturePtr theFeature,
-                     bool isIntersect,
-                     int& theResultIndex);
+protected:
+  void buildVertices(const ListOfShape& theShapes, bool isIntersect);
 };
 
 #endif
index 1d1bf847c3e963a26d1c39f3f9229e4d569aa4c6..121f992cfd039770159556bede62f16c9766522f 100644 (file)
@@ -25,7 +25,9 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
                     ${PROJECT_SOURCE_DIR}/src/ModelAPI
                     ${PROJECT_SOURCE_DIR}/src/GeomAPI
                     ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI
+                    ${PROJECT_SOURCE_DIR}/src/GeomDataAPI
                     ${PROJECT_SOURCE_DIR}/src/GeomValidators
+                    ${PROJECT_SOURCE_DIR}/src/SketchPlugin
 )
 
 SET(PROJECT_HEADERS
@@ -108,6 +110,8 @@ INSTALL(DIRECTORY icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Build
 
 ADD_UNIT_TESTS(TestVertex.py
                TestVertex_ErrorMsg.py
+               TestVertex_WholeSketch_1.py
+               TestVertex_WholeSketch_2.py
                TestEdge.py
                TestEdge_ByPoints.py
                TestEdge_ErrorMsg.py
index e2b9369902f8236ba6d9322a1eb392bdf62f8985..8f086716cd0e9262ea860eb6f0363f8bd8eed06a 100644 (file)
@@ -75,33 +75,34 @@ aSession.finishOperation()
 # Test results
 assert (len(aVertexFeature.results()) == aNumOfPoints)
 
-# Check Vertex feature failed on incorrect input
+# Check Vertex feature correct on a whole sketch
 aSession.startOperation()
 aVertexFeature2 = aPart.addFeature("Vertex")
 aBaseObjectsList = aVertexFeature2.selectionList("base_objects")
 aBaseObjectsList.append(aSketchResult, None)
 aSession.finishOperation()
-assert (len(aVertexFeature2.results()) == 10)
+assert (len(aVertexFeature2.results()) == aNumOfPoints)
 
+# Check Vertex feature failed on incorrect input
 aSession.startOperation()
 aLine = aSketchFeature.addFeature("SketchLine")
 geomDataAPI_Point2D(aLine.attribute("StartPoint")).setValue(0, 0)
 geomDataAPI_Point2D(aLine.attribute("EndPoint")).setValue(100, 100)
 aSession.finishOperation()
 aSession.startOperation()
-aBaseObjectsList.clear()
+aPart.setCurrentFeature(aVertexFeature2, False)
+aSession.finishOperation()
+aSession.startOperation()
+aVertexFeature3 = aPart.addFeature("Vertex")
+aBaseObjectsList = aVertexFeature3.selectionList("base_objects")
 aBaseObjectsList.append(aSketchResult, aLine.lastResult().shape())
 aSession.finishOperation()
-assert (len(aVertexFeature2.results()) == 0)
-
-# Check Vertex feature failed on incorrect input
-# TODO
+assert (len(aVertexFeature3.results()) == 0)
 
 # remove failed feature
-#aSession.startOperation()
-#aPart.removeFeature(aVertexFeature2)
-#aPart.setCurrentFeature(aVertexFeature, True)
-#aSession.finishOperation()
+aSession.startOperation()
+aPart.removeFeature(aVertexFeature3)
+aSession.finishOperation()
 
 from salome.shaper import model
 assert(model.checkPythonDump())
diff --git a/src/BuildPlugin/Test/TestVertex_WholeSketch_1.py b/src/BuildPlugin/Test/TestVertex_WholeSketch_1.py
new file mode 100644 (file)
index 0000000..1bc8fde
--- /dev/null
@@ -0,0 +1,43 @@
+# Copyright (C) 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
+from GeomAPI import *
+
+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(0, -20, 45, -15)
+SketchLine_2 = Sketch_1.addLine(45, -15, 10, 15)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(10, 15, 25, -40)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchArc_1 = Sketch_2.addArc(-5, 10, -5, -10, 15, 10, False)
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_1"), model.selection("COMPOUND", "Sketch_2")], False)
+model.end()
+
+model.testNbResults(Vertex_1, 7)
+model.testNbSubShapes(Vertex_1, GeomAPI_Shape.VERTEX, [1, 1, 1, 1, 1, 1, 1])
+
+assert(model.checkPythonDump())
diff --git a/src/BuildPlugin/Test/TestVertex_WholeSketch_2.py b/src/BuildPlugin/Test/TestVertex_WholeSketch_2.py
new file mode 100644 (file)
index 0000000..b79a7d9
--- /dev/null
@@ -0,0 +1,43 @@
+# Copyright (C) 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
+from GeomAPI import *
+
+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(0, -20, 45, -15)
+SketchLine_2 = Sketch_1.addLine(45, -15, 10, 15)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(10, 15, 25, -40)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchArc_1 = Sketch_2.addArc(-5, 10, -5, -10, 15, 10, False)
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_1"), model.selection("COMPOUND", "Sketch_2")], True)
+model.end()
+
+model.testNbResults(Vertex_1, 9)
+model.testNbSubShapes(Vertex_1, GeomAPI_Shape.VERTEX, [1, 1, 1, 1, 1, 1, 1, 1, 1])
+
+assert(model.checkPythonDump())
index 683413c63e9a2aa92cdc35af97daa64a06464f29..5025a6aaa75846722e73d765f7f7d2f8f6ea9f6c 100644 (file)
@@ -75,3 +75,23 @@ bool GeomAPI_Vertex::isEqual(const std::shared_ptr<GeomAPI_Shape> theVert) const
 
   return aPoint1.IsEqual(aPoint2, Precision::Confusion()) == Standard_True;
 }
+
+
+
+bool GeomAPI_Vertex::GeometricComparator::operator()(const GeomVertexPtr& theVertex1,
+                                                     const GeomVertexPtr& theVertex2) const
+{
+  const TopoDS_Vertex& aVertex1 = theVertex1->impl<TopoDS_Vertex>();
+  const TopoDS_Vertex& aVertex2 = theVertex2->impl<TopoDS_Vertex>();
+
+  gp_Pnt aPnt1 = BRep_Tool::Pnt(aVertex1);
+  gp_Pnt aPnt2 = BRep_Tool::Pnt(aVertex2);
+
+  bool isLess = aPnt1.X() + myTolerance < aPnt2.X();
+  if (!isLess && aPnt1.X() <= aPnt2.X() + myTolerance) {
+    isLess = aPnt1.Y() + myTolerance < aPnt2.Y();
+    if (!isLess && aPnt1.Y() <= aPnt2.Y() + myTolerance)
+      isLess = aPnt1.Z() + myTolerance < aPnt2.Z();
+  }
+  return isLess;
+}
index 13668b6af2c4c1034c719c06d6ba5b1b99ad28d3..5c564f842fb7f5ffefa6f49184571d6d93e21072 100644 (file)
@@ -49,6 +49,24 @@ public:
   /// Returns true if the current edge is geometrically equal to the given edge.
   GEOMAPI_EXPORT
   virtual bool isEqual(const std::shared_ptr<GeomAPI_Shape> theVert) const;
+
+public:
+  /// \brief Compare vertices geometrically
+  class GeometricComparator
+  {
+  public:
+    GEOMAPI_EXPORT
+    GeometricComparator(const double theTolerance = 1.e-7) : myTolerance(theTolerance)
+    {}
+
+    /// Return \c true if the first vertex is less than the second
+    GEOMAPI_EXPORT
+    bool operator ()(const std::shared_ptr<GeomAPI_Vertex>& theVertex1,
+                     const std::shared_ptr<GeomAPI_Vertex>& theVertex2) const;
+  private:
+    double myTolerance;
+  };
+
 };
 
 //! Pointer on the object