Salome HOME
Merge branch 'master' into cgt/devCEA
[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 <FeaturesPlugin_Tools.h>
23
24 //=================================================================================================
25 FeaturesPlugin_Translation::FeaturesPlugin_Translation()
26 {
27 }
28
29 //=================================================================================================
30 void FeaturesPlugin_Translation::initAttributes()
31 {
32   data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
33
34   AttributeSelectionListPtr aSelection =
35     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
36     FeaturesPlugin_Translation::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
37
38   data()->addAttribute(FeaturesPlugin_Translation::AXIS_OBJECT_ID(),
39                        ModelAPI_AttributeSelection::typeId());
40   data()->addAttribute(FeaturesPlugin_Translation::DISTANCE_ID(),
41                        ModelAPI_AttributeDouble::typeId());
42
43   data()->addAttribute(FeaturesPlugin_Translation::DX_ID(),
44                        ModelAPI_AttributeDouble::typeId());
45   data()->addAttribute(FeaturesPlugin_Translation::DY_ID(),
46                        ModelAPI_AttributeDouble::typeId());
47   data()->addAttribute(FeaturesPlugin_Translation::DZ_ID(),
48                        ModelAPI_AttributeDouble::typeId());
49 }
50
51 //=================================================================================================
52 void FeaturesPlugin_Translation::execute()
53 {
54   AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Translation::CREATION_METHOD());
55   std::string aMethodType = aMethodTypeAttr->value();
56
57   if (aMethodType == CREATION_METHOD_BY_DISTANCE()) {
58     performTranslationByAxisAndDistance();
59   }
60
61   if (aMethodType == CREATION_METHOD_BY_DIMENSIONS()) {
62     performTranslationByDimensions();
63   }
64 }
65
66 //=================================================================================================
67 void FeaturesPlugin_Translation::performTranslationByAxisAndDistance()
68 {
69   // Getting objects.
70   ListOfShape anObjects;
71   std::list<ResultPtr> aContextes;
72   AttributeSelectionListPtr anObjectsSelList =
73     selectionList(FeaturesPlugin_Translation::OBJECTS_LIST_ID());
74   if (anObjectsSelList->size() == 0) {
75     return;
76   }
77   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
78     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
79       anObjectsSelList->value(anObjectsIndex);
80     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
81     if(!anObject.get()) { // may be for not-activated parts
82       eraseResults();
83       return;
84     }
85     anObjects.push_back(anObject);
86     aContextes.push_back(anObjectAttr->context());
87   }
88
89   //Getting axis.
90   std::shared_ptr<GeomAPI_Ax1> anAxis;
91   std::shared_ptr<GeomAPI_Edge> anEdge;
92   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
93     selection(FeaturesPlugin_Translation::AXIS_OBJECT_ID());
94   if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
95     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
96   } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
97              anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
98     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
99   }
100   if(anEdge) {
101     anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
102                                                           anEdge->line()->direction()));
103   }
104
105   // Getting distance.
106   double aDistance = real(FeaturesPlugin_Translation::DISTANCE_ID())->value();
107
108   // Moving each object.
109   int aResultIndex = 0;
110   std::list<ResultPtr>::iterator aContext = aContextes.begin();
111   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
112         anObjectsIt++, aContext++) {
113     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
114     bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
115
116     // Setting result.
117     if (isPart) {
118       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
119       aTrsf->setTranslation(anAxis, aDistance);
120       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
121       ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
122       aResultPart->setTrsf(*aContext, aTrsf);
123       setResult(aResultPart, aResultIndex);
124     } else {
125       GeomAlgoAPI_Translation aTranslationAlgo(aBaseShape, anAxis, aDistance);
126
127       if (!aTranslationAlgo.check()) {
128         setError(aTranslationAlgo.getError());
129         return;
130       }
131
132       aTranslationAlgo.build();
133
134       // Checking that the algorithm worked properly.
135       if(!aTranslationAlgo.isDone()) {
136         static const std::string aFeatureError = "Error: Translation algorithm failed.";
137         setError(aFeatureError);
138         break;
139       }
140       if(aTranslationAlgo.shape()->isNull()) {
141         static const std::string aShapeError = "Error: Resulting shape is Null.";
142         setError(aShapeError);
143         break;
144       }
145       if(!aTranslationAlgo.isValid()) {
146         std::string aFeatureError = "Error: Resulting shape is not valid.";
147         setError(aFeatureError);
148         break;
149       }
150
151       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
152       loadNamingDS(aTranslationAlgo, aResultBody, aBaseShape);
153       setResult(aResultBody, aResultIndex);
154     }
155     aResultIndex++;
156   }
157
158   // Remove the rest results if there were produced in the previous pass.
159   removeResults(aResultIndex);
160 }
161
162 //=================================================================================================
163 void FeaturesPlugin_Translation::performTranslationByDimensions()
164 {
165   // Getting objects.
166   ListOfShape anObjects;
167   std::list<ResultPtr> aContextes;
168   AttributeSelectionListPtr anObjectsSelList =
169     selectionList(FeaturesPlugin_Translation::OBJECTS_LIST_ID());
170   if (anObjectsSelList->size() == 0) {
171     return;
172   }
173   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
174     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
175       anObjectsSelList->value(anObjectsIndex);
176     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
177     if(!anObject.get()) { // may be for not-activated parts
178       eraseResults();
179       return;
180     }
181     anObjects.push_back(anObject);
182     aContextes.push_back(anObjectAttr->context());
183   }
184
185   // Getting dimensions in X, in Y and in Z
186   double aDX = real(FeaturesPlugin_Translation::DX_ID())->value();
187   double aDY = real(FeaturesPlugin_Translation::DY_ID())->value();
188   double aDZ = real(FeaturesPlugin_Translation::DZ_ID())->value();
189
190   // Moving each object.
191   int aResultIndex = 0;
192   std::list<ResultPtr>::iterator aContext = aContextes.begin();
193   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
194         anObjectsIt++, aContext++) {
195     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
196     bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
197
198     // Setting result.
199     if (isPart) {
200       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
201       aTrsf->setTranslation(aDX, aDY, aDZ);
202       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
203       ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
204       aResultPart->setTrsf(*aContext, aTrsf);
205       setResult(aResultPart, aResultIndex);
206     } else {
207       GeomAlgoAPI_Translation aTranslationAlgo(aBaseShape, aDX, aDY, aDZ);
208
209       if (!aTranslationAlgo.check()) {
210         setError(aTranslationAlgo.getError());
211         return;
212       }
213
214       aTranslationAlgo.build();
215
216       // Checking that the algorithm worked properly.
217       if(!aTranslationAlgo.isDone()) {
218         static const std::string aFeatureError = "Error: Translation algorithm failed.";
219         setError(aFeatureError);
220         break;
221       }
222       if(aTranslationAlgo.shape()->isNull()) {
223         static const std::string aShapeError = "Error: Resulting shape is Null.";
224         setError(aShapeError);
225         break;
226       }
227       if(!aTranslationAlgo.isValid()) {
228         std::string aFeatureError = "Error: Resulting shape is not valid.";
229         setError(aFeatureError);
230         break;
231       }
232
233       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
234       loadNamingDS(aTranslationAlgo, aResultBody, aBaseShape);
235       setResult(aResultBody, aResultIndex);
236     }
237     aResultIndex++;
238   }
239
240   // Remove the rest results if there were produced in the previous pass.
241   removeResults(aResultIndex);
242 }
243
244 //=================================================================================================
245 void FeaturesPlugin_Translation::loadNamingDS(GeomAlgoAPI_Translation& theTranslationAlgo,
246                                               std::shared_ptr<ModelAPI_ResultBody> theResultBody,
247                                               std::shared_ptr<GeomAPI_Shape> theBaseShape)
248 {
249   // Store result.
250   theResultBody->storeModified(theBaseShape, theTranslationAlgo.shape());
251
252   int aTranslatedTag = 1;
253   std::string aTranslatedName = "Translated";
254   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theTranslationAlgo.mapOfSubShapes();
255
256   FeaturesPlugin_Tools::storeModifiedShapes(theTranslationAlgo, theResultBody,
257                                             theBaseShape, aTranslatedTag, aTranslatedName,
258                                             *aSubShapes.get());
259 }