Salome HOME
Updated copyright comment
[modules/shaper.git] / src / BuildPlugin / BuildPlugin_Vertex.cpp
index 82f3521ed81ac72dd66859b97c9a7e5a19e83bef..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
 #include "BuildPlugin_Vertex.h"
 
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_CompositeFeature.h>
 #include <ModelAPI_ResultBody.h>
+#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>
+
+#include <GeomAPI_ShapeExplorer.h>
 
 //=================================================================================================
 BuildPlugin_Vertex::BuildPlugin_Vertex()
@@ -34,62 +44,120 @@ BuildPlugin_Vertex::BuildPlugin_Vertex()
 void BuildPlugin_Vertex::initAttributes()
 {
   data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
+
+  data()->addAttribute(INTERSECT_ID(), ModelAPI_AttributeBoolean::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), INTERSECT_ID());
 }
 
-//=================================================================================================
-void BuildPlugin_Vertex::execute()
+void BuildPlugin_Vertex::buildVertices(const ListOfShape& theShapes, bool isIntersect)
 {
-  // Get base objects list.
-  AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
-  if(!aSelectionList.get()) {
-    setError("Error: Could not get selection list.");
-    return;
-  }
-  if(aSelectionList->size() == 0) {
-    setError("Error: Empty selection list.");
-    return;
-  }
+  GeomShapePtr aResult;
+  std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo;
+  if (isIntersect) {
+    aPartitionAlgo.reset(new GeomAlgoAPI_Partition(theShapes, ListOfShape()));
 
-  // Collect base shapes.
-  ListOfShape aListOfShapes;
-  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();
-    }
-    if(!aShape.get()) {
-      setError("Error: Empty shape selected.");
+    std::string anError;
+    if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPartitionAlgo, getKind(), anError)) {
+      setError(anError);
       return;
     }
 
-    if(aShape->shapeType() != GeomAPI_Shape::VERTEX) {
-      setError("Error: Selected shape has wrong type. Only vertices acceptable.");
-      return;
-    }
+    aResult = aPartitionAlgo->shape();
+  }
+  else
+    aResult = GeomAlgoAPI_CompoundBuilder::compound(theShapes);
 
-    // Copy shape.
-    std::shared_ptr<GeomAlgoAPI_Copy> aCopyAlgo(new GeomAlgoAPI_Copy(aShape));
+  int aResultIndex = 0;
 
-    std::string anError;
-    if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCopyAlgo, getKind(), anError)) {
-      setError(anError);
-      return;
-    }
+  // 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::shared_ptr<GeomAlgoAPI_Copy> aCopy(new GeomAlgoAPI_Copy(aVertex));
+    aVertex.reset(new GeomAPI_Vertex(aCopy->shape()));
+
+    std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList);
+    if (aPartitionAlgo)
+      aMakeShapeList->appendAlgo(aPartitionAlgo);
+    aMakeShapeList->appendAlgo(aCopy);
 
     // Store result.
     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-    aResultBody->storeModified(aShape, aCopyAlgo->shape());
+    aResultBody->storeModified(theShapes, aVertex, aMakeShapeList);
     setResult(aResultBody, aResultIndex);
     ++aResultIndex;
   }
 
   removeResults(aResultIndex);
 }
+
+static void collectEdgesAndVertices(AttributeSelectionPtr theSelection, ListOfShape& thePrimitives)
+{
+  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);
+      }
+    }
+  }
+}
+
+void BuildPlugin_Vertex::execute()
+{
+  // Get base objects list.
+  AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
+  if (!aSelectionList.get()) {
+    setError("Error: Could not get selection list.");
+    return;
+  }
+  if (aSelectionList->size() == 0) {
+    setError("Error: Empty selection list.");
+    return;
+  }
+
+  // Get "Compute intersections" flag value
+  bool isIntersect = false;
+  if (boolean(INTERSECT_ID()).get() && boolean(INTERSECT_ID())->isInitialized()) {
+    isIntersect = boolean(INTERSECT_ID())->value();
+  }
+
+  // Iterate arguments and collect shapes
+  ListOfShape aShapes;
+  for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+    AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+    collectEdgesAndVertices(aSelection, aShapes);
+  }
+
+  buildVertices(aShapes, isIntersect);
+}