]> SALOME platform Git repositories - modules/shaper.git/blob - src/FeaturesPlugin/FeaturesPlugin_MultiTranslation.cpp
Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_MultiTranslation.cpp
1 // Copyright (C) 2014-201x CEA/DEN, EDF R&D
2
3 // File:        FeaturesPlugin_MultiTranslation.cpp
4 // Created:     30 Jan 2017
5 // Author:      Clarisse Genrault (CEA)
6
7 #include <FeaturesPlugin_MultiTranslation.h>
8
9 #include <GeomAlgoAPI_CompoundBuilder.h>
10
11 #include <GeomAPI_Ax1.h>
12 #include <GeomAPI_Edge.h>
13 #include <GeomAPI_Lin.h>
14
15 #include <ModelAPI_AttributeDouble.h>
16 #include <ModelAPI_AttributeInteger.h>
17 #include <ModelAPI_AttributeSelectionList.h>
18 #include <ModelAPI_AttributeString.h>
19 #include <ModelAPI_ResultBody.h>
20
21 #include <math.h>
22
23 //=================================================================================================
24 FeaturesPlugin_MultiTranslation::FeaturesPlugin_MultiTranslation()
25 {
26 }
27
28 //=================================================================================================
29 void FeaturesPlugin_MultiTranslation::initAttributes()
30 {
31   AttributeSelectionListPtr aSelection =
32     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
33     FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID(),
34     ModelAPI_AttributeSelectionList::typeId()));
35
36   data()->addAttribute(FeaturesPlugin_MultiTranslation::AXIS_FIRST_DIR_ID(),
37                        ModelAPI_AttributeSelection::typeId());
38   data()->addAttribute(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID(),
39                        ModelAPI_AttributeDouble::typeId());
40   data()->addAttribute(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID(),
41                        ModelAPI_AttributeInteger::typeId());
42
43   data()->addAttribute(FeaturesPlugin_MultiTranslation::USE_SECOND_DIR_ID(),
44                        ModelAPI_AttributeString::typeId());
45   data()->addAttribute(FeaturesPlugin_MultiTranslation::AXIS_SECOND_DIR_ID(),
46                        ModelAPI_AttributeSelection::typeId());
47   data()->addAttribute(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID(),
48                        ModelAPI_AttributeDouble::typeId());
49   data()->addAttribute(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID(),
50                        ModelAPI_AttributeInteger::typeId());
51 }
52
53 //=================================================================================================
54 void FeaturesPlugin_MultiTranslation::execute()
55 {
56   std::string useSecondDir = string(FeaturesPlugin_MultiTranslation::USE_SECOND_DIR_ID())->value();
57   if(!useSecondDir.empty()) {
58     performTwoDirection();
59   } else {
60     performOneDirection();
61   }
62 }
63
64 //=================================================================================================
65 void FeaturesPlugin_MultiTranslation::performOneDirection()
66 {
67   // Getting objects.
68   ListOfShape anObjects;
69   std::list<ResultPtr> aContextes;
70   AttributeSelectionListPtr anObjectsSelList =
71     selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
72   if (anObjectsSelList->size() == 0) {
73     return;
74   }
75   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
76     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
77       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 =
91     selection(FeaturesPlugin_MultiTranslation::AXIS_FIRST_DIR_ID());
92   if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
93     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
94   } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
95              anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
96     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
97   }
98   if(anEdge) {
99     anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
100                                                           anEdge->line()->direction()));
101   }
102
103   // Getting step.
104   double aStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
105
106   // Getting number of copies.
107   int nbCopies =
108     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
109
110   // Moving each object.
111   int aResultIndex = 0;
112   std::list<ResultPtr>::iterator aContext = aContextes.begin();
113   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
114         anObjectsIt++, aContext++) {
115     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
116
117     ListOfShape aListOfShape;
118     std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
119
120     for (int i=0; i<nbCopies; i++) {
121       std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
122         new GeomAlgoAPI_Translation(aBaseShape, anAxis, i*aStep));
123
124       if (!aTranslationAlgo->check()) {
125         setError(aTranslationAlgo->getError());
126         break;
127       }
128
129       aTranslationAlgo->build();
130
131       // Checking that the algorithm worked properly.
132       if (!aTranslationAlgo->isDone()) {
133         static const std::string aFeatureError = "Error : Multitranslation algorithm failed.";
134         setError(aFeatureError);
135         break;
136       }
137       if (aTranslationAlgo->shape()->isNull()) {
138         static const std::string aShapeError = "Error : Resulting shape is null.";
139         setError(aShapeError);
140         break;
141       }
142       if (!aTranslationAlgo->isValid()) {
143         static const std::string aFeatureError = "Error : Resulting shape in not valid.";
144         setError(aFeatureError);
145         break;
146       }
147       aListOfShape.push_back(aTranslationAlgo->shape());
148       aListOfTranslationAlgo.push_back(aTranslationAlgo);
149     }
150     std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
151     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
152     aResultBody->storeModified(aBaseShape, aCompound);
153     loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
154
155     setResult(aResultBody, aResultIndex);
156     aResultIndex++;
157   }
158
159   // Remove the rest results if there were produced in the previous pass.
160   removeResults(aResultIndex);
161 }
162
163 //=================================================================================================
164 void FeaturesPlugin_MultiTranslation::performTwoDirection()
165 {
166   // Getting objects.
167   ListOfShape anObjects;
168   std::list<ResultPtr> aContextes;
169   AttributeSelectionListPtr anObjectsSelList =
170     selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
171   if (anObjectsSelList->size() == 0) {
172     return;
173   }
174   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
175     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
176       anObjectsSelList->value(anObjectsIndex);
177     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
178     if(!anObject.get()) { // may be for not-activated parts
179       eraseResults();
180       return;
181     }
182     anObjects.push_back(anObject);
183     aContextes.push_back(anObjectAttr->context());
184   }
185
186   //Getting axis.
187   std::shared_ptr<GeomAPI_Ax1> aFirstAxis;
188   std::shared_ptr<GeomAPI_Edge> anEdge;
189   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
190     selection(FeaturesPlugin_MultiTranslation::AXIS_FIRST_DIR_ID());
191   if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
192     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
193   } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
194              anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
195     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
196   }
197   if(anEdge) {
198     aFirstAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
199                                                               anEdge->line()->direction()));
200   }
201   std::shared_ptr<GeomAPI_Ax1> aSecondAxis;
202   anObjRef = selection(FeaturesPlugin_MultiTranslation::AXIS_SECOND_DIR_ID());
203   if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
204     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
205   } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
206              anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
207     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
208   }
209   if(anEdge) {
210     aSecondAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
211                                                                anEdge->line()->direction()));
212   }
213
214   // Getting step.
215   double aFirstStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
216   double aSecondStep = real(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID())->value();
217
218   // Getting number of copies.
219   int aFirstNbCopies =
220     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
221   int aSecondNbCopies =
222     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID())->value();
223
224   // Coord aFirstAxis
225   double x1 = aFirstAxis->dir()->x();
226   double y1 = aFirstAxis->dir()->y();
227   double z1 = aFirstAxis->dir()->z();
228   double norm1 = sqrt(x1*x1 + y1*y1 + z1*z1);
229
230   // Coord aSecondAxis
231   double x2 = aSecondAxis->dir()->x();
232   double y2 = aSecondAxis->dir()->y();
233   double z2 = aSecondAxis->dir()->z();
234   double norm2 = sqrt(x2*x2 + y2*y2 + z2*z2);
235
236   // Moving each object.
237   int aResultIndex = 0;
238   std::list<ResultPtr>::iterator aContext = aContextes.begin();
239   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
240         anObjectsIt++, aContext++) {
241     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
242
243     ListOfShape aListOfShape;
244     std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
245
246     for (int j=0; j<aSecondNbCopies; j++) {
247       for (int i=0; i<aFirstNbCopies; i++) {
248         double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
249         double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
250         double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
251         std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
252           new GeomAlgoAPI_Translation(aBaseShape, dx, dy, dz));
253
254         if (!aTranslationAlgo->check()) {
255           setError(aTranslationAlgo->getError());
256           break;
257         }
258
259         aTranslationAlgo->build();
260
261         // Checking that the algorithm worked properly.
262         if (!aTranslationAlgo->isDone()) {
263           static const std::string aFeatureError = "Error : Multitranslation algorithm failed.";
264           setError(aFeatureError);
265           break;
266         }
267         if (aTranslationAlgo->shape()->isNull()) {
268           static const std::string aShapeError = "Error : Resulting shape is null.";
269           setError(aShapeError);
270           break;
271         }
272         if (!aTranslationAlgo->isValid()) {
273           static const std::string aFeatureError = "Error : Resulting shape in not valid.";
274           setError(aFeatureError);
275           break;
276         }
277         aListOfShape.push_back(aTranslationAlgo->shape());
278         aListOfTranslationAlgo.push_back(aTranslationAlgo);
279       }
280     }
281     std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
282     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
283     aResultBody->storeModified(aBaseShape, aCompound);
284     loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
285     setResult(aResultBody, aResultIndex);
286     aResultIndex++;
287   }
288
289   // Remove the rest results if there were produced in the previous pass.
290   removeResults(aResultIndex);
291 }
292
293 //=================================================================================================
294 void FeaturesPlugin_MultiTranslation::loadNamingDS(
295     std::list<std::shared_ptr<GeomAlgoAPI_Translation> > theListOfTranslationAlgo,
296     std::shared_ptr<ModelAPI_ResultBody> theResultBody,
297     std::shared_ptr<GeomAPI_Shape> theBaseShape)
298 {
299   int aTag = 1;
300   int anIndex = 1;
301   std::string aTranslatedName;
302
303   for (std::list<std::shared_ptr<GeomAlgoAPI_Translation> >::const_iterator anIt =
304     theListOfTranslationAlgo.begin(); anIt != theListOfTranslationAlgo.cend(); ++anIt) {
305     std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = (*anIt)->mapOfSubShapes();
306
307     // naming of faces
308     aTranslatedName = "Translated_Face_" + std::to_string((long long) anIndex);
309     theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::FACE,
310                                                aTag++, aTranslatedName, *aSubShapes.get(),
311                                                false, true);
312
313     // naming of edges
314     aTranslatedName = "Translated_Edge_" + std::to_string((long long) anIndex);
315     theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::EDGE,
316                                                aTag++, aTranslatedName, *aSubShapes.get(),
317                                                false, true);
318
319     // naming of vertex
320     aTranslatedName = "Translated_Vertex_" + std::to_string((long long) anIndex);
321     theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::VERTEX,
322                                                aTag++, aTranslatedName, *aSubShapes.get(),
323                                                false, true);
324
325     ++anIndex;
326   }
327 }