Salome HOME
Add a new method for translation feature : translation by DX, DY, DZ vector.
[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 = selectionList(FeaturesPlugin_Translation::OBJECTS_LIST_ID());
73   if (anObjectsSelList->size() == 0) {
74     return;
75   }
76   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
77     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr = anObjectsSelList->value(anObjectsIndex);
78     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
79     if(!anObject.get()) { // may be for not-activated parts
80       eraseResults();
81       return;
82     }
83     anObjects.push_back(anObject);
84     aContextes.push_back(anObjectAttr->context());
85   }
86   
87   //Getting axis.
88   std::shared_ptr<GeomAPI_Ax1> anAxis;
89   std::shared_ptr<GeomAPI_Edge> anEdge;
90   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(FeaturesPlugin_Translation::AXIS_OBJECT_ID());
91   if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
92     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
93   } else if (anObjRef && !anObjRef->value() && anObjRef->context() && 
94              anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
95     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
96   }
97   if(anEdge) {
98     anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(), anEdge->line()->direction()));
99   }
100
101   // Getting distance.
102   double aDistance = real(FeaturesPlugin_Translation::DISTANCE_ID())->value();
103   
104   // Moving each object.
105   int aResultIndex = 0;
106   std::list<ResultPtr>::iterator aContext = aContextes.begin();
107   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
108         anObjectsIt++, aContext++) {
109     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
110     bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
111
112     // Setting result.
113     if (isPart) {
114       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
115       aTrsf->setTranslation(anAxis, aDistance);
116       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
117       ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
118       aResultPart->setTrsf(*aContext, aTrsf);
119       setResult(aResultPart, aResultIndex);
120     } else {
121       GeomAlgoAPI_Translation aTranslationAlgo(aBaseShape, anAxis, aDistance);
122       
123       if (!aTranslationAlgo.check()) {
124         setError(aTranslationAlgo.getError());
125         return;
126       }
127       
128       aTranslationAlgo.build();
129
130       // Checking that the algorithm worked properly.
131       if(!aTranslationAlgo.isDone()) {
132         static const std::string aFeatureError = "Error: Translation algorithm failed.";
133         setError(aFeatureError);
134         break;
135       }
136       if(aTranslationAlgo.shape()->isNull()) {
137         static const std::string aShapeError = "Error: Resulting shape is Null.";
138         setError(aShapeError);
139         break;
140       }
141       if(!aTranslationAlgo.isValid()) {
142         std::string aFeatureError = "Error: Resulting shape is not valid.";
143         setError(aFeatureError);
144         break;
145       }
146
147       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
148       loadNamingDS(aTranslationAlgo, aResultBody, aBaseShape);
149       setResult(aResultBody, aResultIndex);
150     }
151     aResultIndex++;
152   }
153
154   // Remove the rest results if there were produced in the previous pass.
155   removeResults(aResultIndex);
156 }
157
158 //=================================================================================================
159 void FeaturesPlugin_Translation::performTranslationByDimensions()
160 {
161   // Getting objects.
162   ListOfShape anObjects;
163   std::list<ResultPtr> aContextes;
164   AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Translation::OBJECTS_LIST_ID());
165   if (anObjectsSelList->size() == 0) {
166     return;
167   }
168   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
169     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr = anObjectsSelList->value(anObjectsIndex);
170     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
171     if(!anObject.get()) { // may be for not-activated parts
172       eraseResults();
173       return;
174     }
175     anObjects.push_back(anObject);
176     aContextes.push_back(anObjectAttr->context());
177   }
178   
179   // Getting dimensions in X, in Y and in Z
180   double aDX = real(FeaturesPlugin_Translation::DX_ID())->value();
181   double aDY = real(FeaturesPlugin_Translation::DY_ID())->value();
182   double aDZ = real(FeaturesPlugin_Translation::DZ_ID())->value();
183   
184   // Moving each object.
185   int aResultIndex = 0;
186   std::list<ResultPtr>::iterator aContext = aContextes.begin();
187   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
188         anObjectsIt++, aContext++) {
189     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
190     bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
191
192     // Setting result.
193     if (isPart) {
194       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
195       aTrsf->setTranslation(aDX, aDY, aDZ);
196       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
197       ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
198       aResultPart->setTrsf(*aContext, aTrsf);
199       setResult(aResultPart, aResultIndex);
200     } else {
201       GeomAlgoAPI_Translation aTranslationAlgo(aBaseShape, aDX, aDY, aDZ);
202       
203       if (!aTranslationAlgo.check()) {
204         setError(aTranslationAlgo.getError());
205         return;
206       }
207       
208       aTranslationAlgo.build();
209
210       // Checking that the algorithm worked properly.
211       if(!aTranslationAlgo.isDone()) {
212         static const std::string aFeatureError = "Error: Translation algorithm failed.";
213         setError(aFeatureError);
214         break;
215       }
216       if(aTranslationAlgo.shape()->isNull()) {
217         static const std::string aShapeError = "Error: Resulting shape is Null.";
218         setError(aShapeError);
219         break;
220       }
221       if(!aTranslationAlgo.isValid()) {
222         std::string aFeatureError = "Error: Resulting shape is not valid.";
223         setError(aFeatureError);
224         break;
225       }
226
227       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
228       loadNamingDS(aTranslationAlgo, aResultBody, aBaseShape);
229       setResult(aResultBody, aResultIndex);
230     }
231     aResultIndex++;
232   }
233
234   // Remove the rest results if there were produced in the previous pass.
235   removeResults(aResultIndex);
236 }
237
238 //=================================================================================================
239 void FeaturesPlugin_Translation::loadNamingDS(GeomAlgoAPI_Translation& theTranslationAlgo,
240                                               std::shared_ptr<ModelAPI_ResultBody> theResultBody,
241                                               std::shared_ptr<GeomAPI_Shape> theBaseShape)
242 {
243   // Store result.
244   theResultBody->storeModified(theBaseShape, theTranslationAlgo.shape());
245
246   int aTranslatedTag = 1;
247   std::string aTranslatedName = "Translated";
248   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theTranslationAlgo.mapOfSubShapes();
249
250   FeaturesPlugin_Tools::storeModifiedShapes(theTranslationAlgo, theResultBody, theBaseShape, aTranslatedTag, aTranslatedName, *aSubShapes.get());
251 }