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