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