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);
81 anExp.more(); anExp.next()) {
82 GeomShapePtr aSubShape = anExp.current();
84 if (alreadyProcessed.bind(aSubShape, aSubShape)) {
86 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
87 aResultBody->storeModified(theShape, aSubShape);
88 setResult(aResultBody, theResultIndex);
93 // 2. If need intersection points, perform Partition
96 ListOfShape anObjList, aTools;
97 anObjList.push_back(theShape);
98 std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo (
99 new GeomAlgoAPI_Partition(anObjList, aTools));
102 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPartitionAlgo, getKind(), anError)) {
106 GeomShapePtr aSplittedSketch = aPartitionAlgo->shape();
108 // Explode on Vertices, skip vertices of initial sketch
109 for (GeomAPI_ShapeExplorer anExp (aSplittedSketch, GeomAPI_Shape::VERTEX);
110 anExp.more(); anExp.next()) {
111 GeomShapePtr aSubShape = anExp.current();
113 //if (!theShape->isSubShape(aSubShape)) { // skip vertices of initial sketch
114 if (alreadyProcessed.bind(aSubShape, aSubShape)) {
116 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
117 aResultBody->storeGenerated(anObjList, aSubShape, aPartitionAlgo);
118 setResult(aResultBody, theResultIndex);
128 //=================================================================================================
129 bool BuildPlugin_Vertex::buildVertices(FeaturePtr theFeature,
133 if (theFeature->getKind() != "Sketch") return false;
136 CompositeFeaturePtr aComposite =
137 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
138 if (!aComposite) return false;
139 int nbSubs = aComposite->numberOfSubs();
140 if (nbSubs < 1) return false;
142 // The whole sketch shape
143 ResultPtr aContext = theFeature->firstResult();
144 GeomShapePtr theShape = aContext->shape();
146 GeomAPI_DataMapOfShapeShape alreadyProcessed;
148 // 1. Explode on Vertices
149 for (GeomAPI_ShapeExplorer anExp (theShape, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) {
150 GeomShapePtr aSubShape = anExp.current();
152 if (alreadyProcessed.bind(aSubShape, aSubShape)) {
154 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
155 aResultBody->storeModified(theShape, aSubShape);
156 setResult(aResultBody, theResultIndex);
161 // 2. If need intersection points, perform Partition
164 ListOfShape anObjList, aTools;
165 anObjList.push_back(theShape);
166 std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo (
167 new GeomAlgoAPI_Partition(anObjList, aTools));
170 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPartitionAlgo, getKind(), anError)) {
174 GeomShapePtr aSplittedSketch = aPartitionAlgo->shape();
176 // Explode on Vertices, skip vertices of initial sketch
177 for (GeomAPI_ShapeExplorer anExp (aSplittedSketch, GeomAPI_Shape::VERTEX);
178 anExp.more(); anExp.next()) {
179 GeomShapePtr aSubShape = anExp.current();
181 //if (!theShape->isSubShape(aSubShape)) { // skip vertices of initial sketch
182 if (alreadyProcessed.bind(aSubShape, aSubShape)) {
184 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
185 aResultBody->storeGenerated(anObjList, aSubShape, aPartitionAlgo);
186 setResult(aResultBody, theResultIndex);
192 // 3. Add construction points (centers of circles, etc.)
193 for (int i = 0; i < nbSubs; i++) {
194 FeaturePtr aSubFeature = aComposite->subFeature(i);
195 const std::list<ResultPtr>& aSubResults = aSubFeature->results();
196 std::list<ResultPtr>::const_iterator anItRes = aSubResults.cbegin();
197 // Iterate on all sub-results
198 for (; anItRes != aSubResults.cend(); anItRes++) {
199 ResultPtr aRes = *anItRes;
202 GeomShapePtr aSubResShape = aRes->shape();
204 for (GeomAPI_ShapeExplorer anExp (aSubResShape, GeomAPI_Shape::VERTEX);
205 anExp.more(); anExp.next()) {
206 GeomShapePtr aSubShape = anExp.current();
208 if (alreadyProcessed.bind(aSubShape, aSubShape)) {
210 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
211 aResultBody->storeModified(theShape, aSubShape);
212 setResult(aResultBody, theResultIndex);
223 void BuildPlugin_Vertex::execute()
225 // Get base objects list.
226 AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
227 if (!aSelectionList.get()) {
228 setError("Error: Could not get selection list.");
231 if (aSelectionList->size() == 0) {
232 setError("Error: Empty selection list.");
236 // Get "Compute intersections" flag value
237 bool isIntersect = false;
238 if (boolean(INTERSECT_ID()).get() && boolean(INTERSECT_ID())->isInitialized()) {
239 isIntersect = boolean(INTERSECT_ID())->value();
242 // Iterate arguments and build results
243 int aResultIndex = 0;
244 for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
245 AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
246 GeomShapePtr aShape = aSelection->value();
249 if (!buildVertices(aShape, isIntersect, aResultIndex)) return;
251 ResultPtr aContext = aSelection->context();
252 if (aContext.get()) { // Result selected
253 FeaturePtr aFeature = ModelAPI_Feature::feature(aContext);
254 if (aFeature.get()) {
255 if (aFeature->getKind() == "Sketch") {
256 // Special processing for sketch to build center vertices etc.
257 if (!buildVertices(aFeature, isIntersect, aResultIndex)) return;
259 aShape = aContext->shape();
260 if (!buildVertices(aShape, isIntersect, aResultIndex)) return;
264 FeaturePtr aFeature = aSelection->contextFeature();
265 if (aFeature.get()) { // Feature selected
266 if (aFeature->getKind() == "Sketch") {
267 // Special processing for sketch to build center vertices etc.
268 if (!buildVertices(aFeature, isIntersect, aResultIndex)) return;
270 const std::list<ResultPtr>& anArgResults = aFeature->results();
271 std::list<ResultPtr>::const_iterator anItRes = anArgResults.cbegin();
272 // Iterate on all its results
273 for (; anItRes != anArgResults.cend(); anItRes++) {
274 ResultPtr aRes = *anItRes;
277 aShape = aRes->shape();
278 if (!buildVertices(aShape, isIntersect, aResultIndex)) return;
287 // Remove extra results from previous execution
288 removeResults(aResultIndex);