Salome HOME
Updated copyright comment
[modules/shaper.git] / src / BuildPlugin / BuildPlugin_Vertex.cpp
index cd14766ed902b40105e2d42c9db29d47c36a09ae..4632aa3ef33f72d5bc09604bcd3c2c90f235d22a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2024  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -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,171 +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()
@@ -233,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);
 }