Salome HOME
Revert "Issue #2593: CEA 2018-2 Geometrical Naming"
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Translation.cpp
1 // Copyright (C) 2014-2017  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
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include <FeaturesPlugin_Translation.h>
22
23 #include <ModelAPI_AttributeDouble.h>
24 #include <ModelAPI_AttributeSelectionList.h>
25 #include <ModelAPI_AttributeString.h>
26 #include <ModelAPI_BodyBuilder.h>
27 #include <ModelAPI_ResultBody.h>
28 #include <ModelAPI_ResultPart.h>
29 #include <ModelAPI_Session.h>
30
31 #include <GeomAPI_Edge.h>
32 #include <GeomAPI_Lin.h>
33 #include <GeomAPI_Trsf.h>
34
35 #include <GeomAlgoAPI_PointBuilder.h>
36
37 #include <FeaturesPlugin_Tools.h>
38
39 //=================================================================================================
40 FeaturesPlugin_Translation::FeaturesPlugin_Translation()
41 {
42 }
43
44 //=================================================================================================
45 void FeaturesPlugin_Translation::initAttributes()
46 {
47   data()->addAttribute(FeaturesPlugin_Translation::CREATION_METHOD(),
48                        ModelAPI_AttributeString::typeId());
49
50   AttributeSelectionListPtr aSelection =
51     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
52     FeaturesPlugin_Translation::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
53
54   data()->addAttribute(FeaturesPlugin_Translation::AXIS_OBJECT_ID(),
55                        ModelAPI_AttributeSelection::typeId());
56   data()->addAttribute(FeaturesPlugin_Translation::DISTANCE_ID(),
57                        ModelAPI_AttributeDouble::typeId());
58
59   data()->addAttribute(FeaturesPlugin_Translation::DX_ID(),
60                        ModelAPI_AttributeDouble::typeId());
61   data()->addAttribute(FeaturesPlugin_Translation::DY_ID(),
62                        ModelAPI_AttributeDouble::typeId());
63   data()->addAttribute(FeaturesPlugin_Translation::DZ_ID(),
64                        ModelAPI_AttributeDouble::typeId());
65
66   data()->addAttribute(FeaturesPlugin_Translation::START_POINT_ID(),
67                        ModelAPI_AttributeSelection::typeId());
68   data()->addAttribute(FeaturesPlugin_Translation::END_POINT_ID(),
69                        ModelAPI_AttributeSelection::typeId());
70 }
71
72 //=================================================================================================
73 void FeaturesPlugin_Translation::execute()
74 {
75   AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Translation::CREATION_METHOD());
76   std::string aMethodType = aMethodTypeAttr->value();
77
78   if (aMethodType == CREATION_METHOD_BY_DISTANCE()) {
79     performTranslationByAxisAndDistance();
80   }
81
82   if (aMethodType == CREATION_METHOD_BY_DIMENSIONS()) {
83     performTranslationByDimensions();
84   }
85
86   if (aMethodType == CREATION_METHOD_BY_TWO_POINTS()) {
87     performTranslationByTwoPoints();
88   }
89 }
90
91 //=================================================================================================
92 void FeaturesPlugin_Translation::performTranslationByAxisAndDistance()
93 {
94   // Getting objects.
95   ListOfShape anObjects;
96   std::list<ResultPtr> aContextes;
97   AttributeSelectionListPtr anObjectsSelList =
98     selectionList(FeaturesPlugin_Translation::OBJECTS_LIST_ID());
99   if (anObjectsSelList->size() == 0) {
100     return;
101   }
102   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
103     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
104       anObjectsSelList->value(anObjectsIndex);
105     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
106     if(!anObject.get()) { // may be for not-activated parts
107       eraseResults();
108       return;
109     }
110     anObjects.push_back(anObject);
111     aContextes.push_back(anObjectAttr->context());
112   }
113
114   //Getting axis.
115   std::shared_ptr<GeomAPI_Ax1> anAxis;
116   std::shared_ptr<GeomAPI_Edge> anEdge;
117   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
118     selection(FeaturesPlugin_Translation::AXIS_OBJECT_ID());
119   if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
120     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
121   } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
122              anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
123     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
124   }
125   if(anEdge) {
126     anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
127                                                           anEdge->line()->direction()));
128   }
129
130   // Getting distance.
131   double aDistance = real(FeaturesPlugin_Translation::DISTANCE_ID())->value();
132
133   // Moving each object.
134   int aResultIndex = 0;
135   std::list<ResultPtr>::iterator aContext = aContextes.begin();
136   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
137         anObjectsIt++, aContext++) {
138     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
139     bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
140
141     // Setting result.
142     if (isPart) {
143       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
144       aTrsf->setTranslation(anAxis, aDistance);
145       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
146       ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
147       aResultPart->setTrsf(*aContext, aTrsf);
148       setResult(aResultPart, aResultIndex);
149     } else {
150       GeomAlgoAPI_Translation aTranslationAlgo(aBaseShape, anAxis, aDistance);
151
152       if (!aTranslationAlgo.check()) {
153         setError(aTranslationAlgo.getError());
154         return;
155       }
156
157       aTranslationAlgo.build();
158
159       // Checking that the algorithm worked properly.
160       if(!aTranslationAlgo.isDone()) {
161         static const std::string aFeatureError = "Error: Translation algorithm failed.";
162         setError(aFeatureError);
163         break;
164       }
165       if(aTranslationAlgo.shape()->isNull()) {
166         static const std::string aShapeError = "Error: Resulting shape is Null.";
167         setError(aShapeError);
168         break;
169       }
170       if(!aTranslationAlgo.isValid()) {
171         std::string aFeatureError = "Error: Resulting shape is not valid.";
172         setError(aFeatureError);
173         break;
174       }
175
176       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
177       loadNamingDS(aTranslationAlgo, aResultBody, aBaseShape);
178       setResult(aResultBody, aResultIndex);
179     }
180     aResultIndex++;
181   }
182
183   // Remove the rest results if there were produced in the previous pass.
184   removeResults(aResultIndex);
185 }
186
187 //=================================================================================================
188 void FeaturesPlugin_Translation::performTranslationByDimensions()
189 {
190   // Getting objects.
191   ListOfShape anObjects;
192   std::list<ResultPtr> aContextes;
193   AttributeSelectionListPtr anObjectsSelList =
194     selectionList(FeaturesPlugin_Translation::OBJECTS_LIST_ID());
195   if (anObjectsSelList->size() == 0) {
196     return;
197   }
198   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
199     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
200       anObjectsSelList->value(anObjectsIndex);
201     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
202     if(!anObject.get()) { // may be for not-activated parts
203       eraseResults();
204       return;
205     }
206     anObjects.push_back(anObject);
207     aContextes.push_back(anObjectAttr->context());
208   }
209
210   // Getting dimensions in X, in Y and in Z
211   double aDX = real(FeaturesPlugin_Translation::DX_ID())->value();
212   double aDY = real(FeaturesPlugin_Translation::DY_ID())->value();
213   double aDZ = real(FeaturesPlugin_Translation::DZ_ID())->value();
214
215   // Moving each object.
216   int aResultIndex = 0;
217   std::list<ResultPtr>::iterator aContext = aContextes.begin();
218   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
219         anObjectsIt++, aContext++) {
220     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
221     bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
222
223     // Setting result.
224     if (isPart) {
225       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
226       aTrsf->setTranslation(aDX, aDY, aDZ);
227       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
228       ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
229       aResultPart->setTrsf(*aContext, aTrsf);
230       setResult(aResultPart, aResultIndex);
231     } else {
232       GeomAlgoAPI_Translation aTranslationAlgo(aBaseShape, aDX, aDY, aDZ);
233
234       if (!aTranslationAlgo.check()) {
235         setError(aTranslationAlgo.getError());
236         return;
237       }
238
239       aTranslationAlgo.build();
240
241       // Checking that the algorithm worked properly.
242       if(!aTranslationAlgo.isDone()) {
243         static const std::string aFeatureError = "Error: Translation algorithm failed.";
244         setError(aFeatureError);
245         break;
246       }
247       if(aTranslationAlgo.shape()->isNull()) {
248         static const std::string aShapeError = "Error: Resulting shape is Null.";
249         setError(aShapeError);
250         break;
251       }
252       if(!aTranslationAlgo.isValid()) {
253         std::string aFeatureError = "Error: Resulting shape is not valid.";
254         setError(aFeatureError);
255         break;
256       }
257
258       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
259       loadNamingDS(aTranslationAlgo, aResultBody, aBaseShape);
260       setResult(aResultBody, aResultIndex);
261     }
262     aResultIndex++;
263   }
264
265   // Remove the rest results if there were produced in the previous pass.
266   removeResults(aResultIndex);
267 }
268
269 //=================================================================================================
270 void FeaturesPlugin_Translation::performTranslationByTwoPoints()
271 {
272   // Getting objects.
273   ListOfShape anObjects;
274   std::list<ResultPtr> aContextes;
275   AttributeSelectionListPtr anObjectsSelList =
276     selectionList(FeaturesPlugin_Translation::OBJECTS_LIST_ID());
277   if (anObjectsSelList->size() == 0) {
278     return;
279   }
280   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
281     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
282       anObjectsSelList->value(anObjectsIndex);
283     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
284     if(!anObject.get()) { // may be for not-activated parts
285       eraseResults();
286       return;
287     }
288     anObjects.push_back(anObject);
289     aContextes.push_back(anObjectAttr->context());
290   }
291
292   // Getting the start point and the end point
293   AttributeSelectionPtr aRef1 = data()->selection(FeaturesPlugin_Translation::START_POINT_ID());
294   AttributeSelectionPtr aRef2 = data()->selection(FeaturesPlugin_Translation::END_POINT_ID());
295   std::shared_ptr<GeomAPI_Pnt> aFirstPoint;
296   std::shared_ptr<GeomAPI_Pnt> aSecondPoint;
297   if ((aRef1.get() != NULL) && (aRef2.get() != NULL)) {
298     GeomShapePtr aShape1 = aRef1->value();
299     if (!aShape1.get()) //If we can't get the points directly, try getting them from the context
300       aShape1 = aRef1->context()->shape();
301     GeomShapePtr aShape2 = aRef2->value();
302     if (!aShape2.get())
303       aShape2 = aRef2->context()->shape();
304     if (aShape1 && aShape2) {
305       aFirstPoint = GeomAlgoAPI_PointBuilder::point(aShape1);
306       aSecondPoint = GeomAlgoAPI_PointBuilder::point(aShape2);
307     }
308   }
309
310   // Moving each object.
311   int aResultIndex = 0;
312   std::list<ResultPtr>::iterator aContext = aContextes.begin();
313   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
314         anObjectsIt++, aContext++) {
315     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
316     bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
317
318     // Setting result.
319     if (isPart) {
320       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
321       aTrsf->setTranslation(aFirstPoint, aSecondPoint);
322       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
323       ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
324       aResultPart->setTrsf(*aContext, aTrsf);
325       setResult(aResultPart, aResultIndex);
326     } else {
327       GeomAlgoAPI_Translation aTranslationAlgo(aBaseShape, aFirstPoint, aSecondPoint);
328
329       if (!aTranslationAlgo.check()) {
330         setError(aTranslationAlgo.getError());
331         return;
332       }
333
334       aTranslationAlgo.build();
335
336       // Checking that the algorithm worked properly.
337       if(!aTranslationAlgo.isDone()) {
338         static const std::string aFeatureError = "Error: Translation algorithm failed.";
339         setError(aFeatureError);
340         break;
341       }
342       if(aTranslationAlgo.shape()->isNull()) {
343         static const std::string aShapeError = "Error: Resulting shape is Null.";
344         setError(aShapeError);
345         break;
346       }
347       if(!aTranslationAlgo.isValid()) {
348         std::string aFeatureError = "Error: Resulting shape is not valid.";
349         setError(aFeatureError);
350         break;
351       }
352
353       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
354       loadNamingDS(aTranslationAlgo, aResultBody, aBaseShape);
355       setResult(aResultBody, aResultIndex);
356     }
357     aResultIndex++;
358   }
359
360   // Remove the rest results if there were produced in the previous pass.
361   removeResults(aResultIndex);
362 }
363
364 //=================================================================================================
365 void FeaturesPlugin_Translation::loadNamingDS(GeomAlgoAPI_Translation& theTranslationAlgo,
366                                               std::shared_ptr<ModelAPI_ResultBody> theResultBody,
367                                               std::shared_ptr<GeomAPI_Shape> theBaseShape)
368 {
369   // Store result.
370   theResultBody->storeModified(theBaseShape, theTranslationAlgo.shape());
371
372   std::string aTranslatedName = "Translated";
373   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theTranslationAlgo.mapOfSubShapes();
374
375   FeaturesPlugin_Tools::storeModifiedShapes(theTranslationAlgo, theResultBody,
376                                             theBaseShape, 1, 2, 3, aTranslatedName,
377                                             *aSubShapes.get());
378 }