Salome HOME
0f85ae3e443842129b491d6e11ee39ea6ccaa76e
[modules/shaper.git] / src / BuildPlugin / BuildPlugin_Edge.cpp
1 // Copyright (C) 2014-2019  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "BuildPlugin_Edge.h"
21
22 #include <ModelAPI_AttributeSelectionList.h>
23 #include <ModelAPI_AttributeString.h>
24 #include <ModelAPI_ResultBody.h>
25 #include <ModelAPI_Session.h>
26 #include <ModelAPI_Validator.h>
27
28 #include <GeomAlgoAPI_Copy.h>
29 #include <GeomAlgoAPI_EdgeBuilder.h>
30 #include <GeomAlgoAPI_Tools.h>
31
32 #include <GeomAPI_Edge.h>
33 #include <GeomAPI_ShapeExplorer.h>
34 #include <GeomAPI_Vertex.h>
35
36 static bool getShape(const AttributeSelectionPtr theAttribute,
37                      GeomShapePtr& theShape,
38                      std::string& theError)
39 {
40   theShape = theAttribute->value();
41   if (!theShape.get()) {
42     ResultPtr aContext = theAttribute->context();
43     if (!aContext.get()) {
44       theError = "Error: Attribute has empty context.";
45       return false;
46     }
47     theShape = aContext->shape();
48   }
49   return true;
50 }
51
52 //=================================================================================================
53 BuildPlugin_Edge::BuildPlugin_Edge()
54 {
55 }
56
57 //=================================================================================================
58 void BuildPlugin_Edge::initAttributes()
59 {
60   data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
61
62   data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
63   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHOD());
64
65   data()->addAttribute(FIRST_POINT(), ModelAPI_AttributeSelection::typeId());
66   data()->addAttribute(SECOND_POINT(), ModelAPI_AttributeSelection::typeId());
67 }
68
69 //=================================================================================================
70 void BuildPlugin_Edge::execute()
71 {
72   AttributeStringPtr aCreationMethod = string(CREATION_METHOD());
73   if (aCreationMethod && aCreationMethod->isInitialized() &&
74       aCreationMethod->value() == CREATION_BY_POINTS())
75     edgeByPoints();
76   else
77     edgesBySegments();
78 }
79
80 //=================================================================================================
81 void BuildPlugin_Edge::edgesBySegments()
82 {
83   string(CREATION_METHOD())->setValue(CREATION_BY_SEGMENTS());
84
85   // Get base objects list.
86   AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
87   if(!aSelectionList.get()) {
88     setError("Error: Could not get selection list.");
89     return;
90   }
91   if(aSelectionList->size() == 0) {
92     setError("Error: Empty selection list.");
93     return;
94   }
95
96   // Collect base shapes.
97   ListOfShape aListOfShapes;
98   std::string aError;
99   int aResultIndex = 0;
100   for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
101     AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
102     GeomShapePtr aShape;
103     if (!getShape(aSelection, aShape, aError)) {
104       setError(aError);
105       return;
106     }
107     if(!aShape.get()) {
108       setError("Error: Empty shape selected.");
109       return;
110     }
111
112     if(aShape->shapeType() != GeomAPI_Shape::EDGE) {
113       setError("Error: Selected shape has wrong type. Only edges acceptable.");
114       return;
115     }
116
117     // Copy shape.
118     GeomMakeShapePtr aCopyAlgo(new GeomAlgoAPI_Copy(aShape));
119
120     std::string anError;
121     if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCopyAlgo, getKind(), anError)) {
122       setError(anError);
123       return;
124     }
125
126     // Store result.
127     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
128
129     ListOfShape aBaseShapes;
130     aBaseShapes.push_back(aShape);
131     aResultBody->storeModified(aBaseShapes, aCopyAlgo->shape(), aCopyAlgo);
132     aResultBody->loadModifiedShapes(aCopyAlgo, aShape, GeomAPI_Shape::VERTEX);
133
134     setResult(aResultBody, aResultIndex);
135     ++aResultIndex;
136   }
137
138   removeResults(aResultIndex);
139 }
140
141 void BuildPlugin_Edge::edgeByPoints()
142 {
143   // Get base points.
144   AttributeSelectionPtr aFirstPointAttr = selection(FIRST_POINT());
145   AttributeSelectionPtr aSecondPointAttr = selection(SECOND_POINT());
146   if (!aFirstPointAttr.get() || !aSecondPointAttr.get()) {
147     setError("Error: Not enough points selected.");
148     return;
149   }
150
151   std::string aError;
152   GeomShapePtr aFirstShape, aSecondShape;
153   if (!getShape(aFirstPointAttr, aFirstShape, aError) ||
154       !getShape(aSecondPointAttr, aSecondShape, aError)) {
155     setError(aError);
156     return;
157   }
158   if (!aFirstShape.get() || !aSecondShape.get()) {
159     setError("Error: Empty shape selected.");
160     return;
161   }
162
163   if (!aFirstShape->isVertex() || !aSecondShape->isVertex()) {
164     setError("Error: Selected shape has wrong type. Only vertices acceptable.");
165     return;
166   }
167
168   int aResultIndex = 0;
169
170   GeomEdgePtr anEdge = GeomAlgoAPI_EdgeBuilder::line(aFirstShape->vertex()->point(),
171                                                      aSecondShape->vertex()->point());
172   if (!anEdge.get()) {
173     setError("Error: Algorithm failed.");
174     return;
175   }
176
177   // Store result.
178   ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
179   aResultBody->store(anEdge);
180   // History of vertices
181   GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX);
182   GeomShapePtr aStartVertex = anExp.current();
183   anExp.next();
184   GeomShapePtr anEndVertex = anExp.current();
185   aResultBody->modified(aFirstShape, aStartVertex);
186   aResultBody->modified(aSecondShape, anEndVertex);
187
188   setResult(aResultBody, aResultIndex++);
189   removeResults(aResultIndex);
190 }