1 // Copyright (C) 2014-2019 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "BuildPlugin_Vertex.h"
22 #include <ModelAPI_AttributeSelectionList.h>
23 #include <ModelAPI_AttributeBoolean.h>
24 #include <ModelAPI_CompositeFeature.h>
25 #include <ModelAPI_ResultBody.h>
26 #include <ModelAPI_Validator.h>
27 #include <ModelAPI_Session.h>
29 #include <GeomAlgoAPI_Copy.h>
30 #include <GeomAlgoAPI_Tools.h>
31 #include <GeomAlgoAPI_Partition.h>
32 #include <GeomAlgoAPI_ShapeTools.h>
34 #include <GeomAPI_ShapeExplorer.h>
36 //=================================================================================================
37 BuildPlugin_Vertex::BuildPlugin_Vertex()
41 //=================================================================================================
42 void BuildPlugin_Vertex::initAttributes()
44 data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
46 data()->addAttribute(INTERSECT_ID(), ModelAPI_AttributeBoolean::typeId());
47 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), INTERSECT_ID());
50 //=================================================================================================
51 bool BuildPlugin_Vertex::buildVertices(GeomShapePtr theShape,
55 if (!theShape.get()) {
56 setError("Error: Empty shape selected.");
60 if (theShape->shapeType() == GeomAPI_Shape::VERTEX) {
62 std::shared_ptr<GeomAlgoAPI_Copy> aCopyAlgo(new GeomAlgoAPI_Copy(theShape));
65 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCopyAlgo, getKind(), anError)) {
71 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
72 aResultBody->storeModified(theShape, aCopyAlgo->shape());
73 setResult(aResultBody, theResultIndex);
77 GeomAPI_DataMapOfShapeShape alreadyProcessed;
79 // 1. Explode on Vertices
80 for (GeomAPI_ShapeExplorer anExp (theShape, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
81 GeomShapePtr aSubShape = anExp.current();
83 if (alreadyProcessed.bind(aSubShape, aSubShape)) {
85 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
86 aResultBody->storeModified(theShape, aSubShape);
87 setResult(aResultBody, theResultIndex);
92 // 2. If need intersection points, perform Partition
95 ListOfShape anObjList, aTools;
96 anObjList.push_back(theShape);
97 std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo (new GeomAlgoAPI_Partition(anObjList, aTools));
100 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPartitionAlgo, getKind(), anError)) {
104 GeomShapePtr aSplittedSketch = aPartitionAlgo->shape();
106 // Explode on Vertices, skip vertices of initial sketch
107 for (GeomAPI_ShapeExplorer anExp (aSplittedSketch, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
108 GeomShapePtr aSubShape = anExp.current();
110 //if (!theShape->isSubShape(aSubShape)) { // skip vertices of initial sketch
111 if (alreadyProcessed.bind(aSubShape, aSubShape)) {
113 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
114 aResultBody->storeGenerated(anObjList, aSubShape, aPartitionAlgo);
115 setResult(aResultBody, theResultIndex);
125 //=================================================================================================
126 bool BuildPlugin_Vertex::buildVertices(FeaturePtr theFeature,
130 if (theFeature->getKind() != "Sketch") return false;
133 CompositeFeaturePtr aComposite =
134 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
135 if (!aComposite) return false;
136 int nbSubs = aComposite->numberOfSubs();
137 if (nbSubs < 1) return false;
139 // The whole sketch shape
140 ResultPtr aContext = theFeature->firstResult();
141 GeomShapePtr theShape = aContext->shape();
143 GeomAPI_DataMapOfShapeShape alreadyProcessed;
145 // 1. Explode on Vertices
146 for (GeomAPI_ShapeExplorer anExp (theShape, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
147 GeomShapePtr aSubShape = anExp.current();
149 if (alreadyProcessed.bind(aSubShape, aSubShape)) {
151 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
152 aResultBody->storeModified(theShape, aSubShape);
153 setResult(aResultBody, theResultIndex);
158 // 2. If need intersection points, perform Partition
161 ListOfShape anObjList, aTools;
162 anObjList.push_back(theShape);
163 std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo (new GeomAlgoAPI_Partition(anObjList, aTools));
166 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPartitionAlgo, getKind(), anError)) {
170 GeomShapePtr aSplittedSketch = aPartitionAlgo->shape();
172 // Explode on Vertices, skip vertices of initial sketch
173 for (GeomAPI_ShapeExplorer anExp (aSplittedSketch, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
174 GeomShapePtr aSubShape = anExp.current();
176 //if (!theShape->isSubShape(aSubShape)) { // skip vertices of initial sketch
177 if (alreadyProcessed.bind(aSubShape, aSubShape)) {
179 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
180 aResultBody->storeGenerated(anObjList, aSubShape, aPartitionAlgo);
181 setResult(aResultBody, theResultIndex);
187 // 3. Add construction points (centers of circles, etc.)
188 for (int i = 0; i < nbSubs; i++) {
189 FeaturePtr aSubFeature = aComposite->subFeature(i);
190 const std::list<ResultPtr>& aSubResults = aSubFeature->results();
191 std::list<ResultPtr>::const_iterator anItRes = aSubResults.cbegin();
192 // Iterate on all sub-results
193 for (; anItRes != aSubResults.cend(); anItRes++) {
194 ResultPtr aRes = *anItRes;
197 GeomShapePtr aSubResShape = aRes->shape();
199 for (GeomAPI_ShapeExplorer anExp (aSubResShape, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
200 GeomShapePtr aSubShape = anExp.current();
202 if (alreadyProcessed.bind(aSubShape, aSubShape)) {
204 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
205 aResultBody->storeModified(theShape, aSubShape);
206 setResult(aResultBody, theResultIndex);
217 void BuildPlugin_Vertex::execute()
219 // Get base objects list.
220 AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
221 if (!aSelectionList.get()) {
222 setError("Error: Could not get selection list.");
225 if (aSelectionList->size() == 0) {
226 setError("Error: Empty selection list.");
230 // Get "Compute intersections" flag value
231 bool isIntersect = false;
232 if (boolean(INTERSECT_ID()).get() && boolean(INTERSECT_ID())->isInitialized()) {
233 isIntersect = boolean(INTERSECT_ID())->value();
236 // Iterate arguments and build results
237 int aResultIndex = 0;
238 for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
239 AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
240 GeomShapePtr aShape = aSelection->value();
243 if (!buildVertices(aShape, isIntersect, aResultIndex)) return;
245 ResultPtr aContext = aSelection->context();
246 if (aContext.get()) { // Result selected
247 FeaturePtr aFeature = ModelAPI_Feature::feature(aContext);
248 if (aFeature.get()) {
249 if (aFeature->getKind() == "Sketch") {
250 // Special processing for sketch to build center vertices etc.
251 if (!buildVertices(aFeature, isIntersect, aResultIndex)) return;
253 aShape = aContext->shape();
254 if (!buildVertices(aShape, isIntersect, aResultIndex)) return;
258 FeaturePtr aFeature = aSelection->contextFeature();
259 if (aFeature.get()) { // Feature selected
260 if (aFeature->getKind() == "Sketch") {
261 // Special processing for sketch to build center vertices etc.
262 if (!buildVertices(aFeature, isIntersect, aResultIndex)) return;
264 const std::list<ResultPtr>& anArgResults = aFeature->results();
265 std::list<ResultPtr>::const_iterator anItRes = anArgResults.cbegin();
266 // Iterate on all its results
267 for (; anItRes != anArgResults.cend(); anItRes++) {
268 ResultPtr aRes = *anItRes;
271 aShape = aRes->shape();
272 if (!buildVertices(aShape, isIntersect, aResultIndex)) return;
281 // Remove extra results from previous execution
282 removeResults(aResultIndex);