]> SALOME platform Git repositories - modules/shaper.git/blob - src/FeaturesPlugin/FeaturesPlugin_MultiRotation.cpp
Salome HOME
[Code coverage FeaturesPlugin]: Improve coverage of Common, Smash, Measurement and...
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_MultiRotation.cpp
1 // Copyright (C) 2014-201x CEA/DEN, EDF R&D
2
3 // File:        FeaturesPlugin_MultiRotation.cpp
4 // Created:     30 Jan 2017
5 // Author:      Clarisse Genrault (CEA)
6
7 #include <FeaturesPlugin_MultiRotation.h>
8
9 #include <GeomAlgoAPI_CompoundBuilder.h>
10 #include <GeomAlgoAPI_ShapeTools.h>
11 #include <GeomAlgoAPI_Translation.h>
12
13 #include <GeomAPI_ShapeExplorer.h>
14
15 #include <GeomAPI_Ax1.h>
16 #include <GeomAPI_Edge.h>
17 #include <GeomAPI_Lin.h>
18 #include <GeomAPI_ShapeIterator.h>
19 #include <GeomAPI_Trsf.h>
20
21 #include <ModelAPI_AttributeDouble.h>
22 #include <ModelAPI_AttributeInteger.h>
23 #include <ModelAPI_AttributeSelectionList.h>
24 #include <ModelAPI_AttributeString.h>
25 #include <ModelAPI_ResultBody.h>
26 #include <ModelAPI_ResultPart.h>
27
28 #include <math.h>
29 #include <iostream>
30
31 //=================================================================================================
32 FeaturesPlugin_MultiRotation::FeaturesPlugin_MultiRotation()
33 {
34 }
35
36 //=================================================================================================
37 void FeaturesPlugin_MultiRotation::initAttributes()
38 {
39   AttributeSelectionListPtr aSelection =
40     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
41     FeaturesPlugin_MultiRotation::OBJECTS_LIST_ID(),
42     ModelAPI_AttributeSelectionList::typeId()));
43
44   data()->addAttribute(FeaturesPlugin_MultiRotation::AXIS_ANGULAR_ID(),
45                        ModelAPI_AttributeSelection::typeId());
46   data()->addAttribute(FeaturesPlugin_MultiRotation::USE_ANGULAR_STEP_ID(),
47                        ModelAPI_AttributeString::typeId());
48   data()->addAttribute(FeaturesPlugin_MultiRotation::STEP_ANGULAR_ID(),
49                        ModelAPI_AttributeDouble::typeId());
50   data()->addAttribute(FeaturesPlugin_MultiRotation::NB_COPIES_ANGULAR_ID(),
51                        ModelAPI_AttributeInteger::typeId());
52
53 #ifdef FEATURE_MULTIROTATION_TWO_DIRECTIONS
54   data()->addAttribute(FeaturesPlugin_MultiRotation::USE_RADIAL_DIR_ID(),
55                        ModelAPI_AttributeString::typeId());
56   data()->addAttribute(FeaturesPlugin_MultiRotation::STEP_RADIAL_ID(),
57                        ModelAPI_AttributeDouble::typeId());
58   data()->addAttribute(FeaturesPlugin_MultiRotation::NB_COPIES_RADIAL_ID(),
59                        ModelAPI_AttributeInteger::typeId());
60 #endif
61 }
62
63 //=================================================================================================
64 void FeaturesPlugin_MultiRotation::execute()
65 {
66 #ifdef FEATURE_MULTIROTATION_TWO_DIRECTIONS
67   std::string useRadialDir = string(FeaturesPlugin_MultiRotation::USE_RADIAL_DIR_ID())->value();
68   if (useRadialDir.empty()) {
69     performRotation1D();
70   } else {
71     performRotation2D();
72   }
73 #else
74   performRotation1D();
75 #endif
76 }
77
78 //=================================================================================================
79 void FeaturesPlugin_MultiRotation::performRotation1D()
80 {
81   // Getting objects.
82   ListOfShape anObjects;
83   std::list<ResultPtr> aContextes;
84   AttributeSelectionListPtr anObjectsSelList =
85     selectionList(FeaturesPlugin_MultiRotation::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       return;
95     }
96     anObjects.push_back(anObject);
97     aContextes.push_back(anObjectAttr->context());
98   }
99
100   //Getting axis.
101   static const std::string aSelectionError = "Error: The axis shape selection is bad.";
102   AttributeSelectionPtr anObjRef = selection(AXIS_ANGULAR_ID());
103   GeomShapePtr aShape = anObjRef->value();
104   if (!aShape.get()) {
105     if (anObjRef->context().get()) {
106       aShape = anObjRef->context()->shape();
107     }
108   }
109   if (!aShape.get()) {
110     setError(aSelectionError);
111     return;
112   }
113
114   GeomEdgePtr anEdge;
115   if (aShape->isEdge())
116   {
117     anEdge = aShape->edge();
118   }
119   else if (aShape->isCompound())
120   {
121     GeomAPI_ShapeIterator anIt(aShape);
122     anEdge = anIt.current()->edge();
123   }
124   else
125   {
126     setError(aSelectionError);
127     return;
128   }
129
130   if (!anEdge.get())
131   {
132     setError(aSelectionError);
133     return;
134   }
135
136   std::shared_ptr<GeomAPI_Ax1> anAxis(new GeomAPI_Ax1(anEdge->line()->location(),
137                                                       anEdge->line()->direction()));
138
139   // Getting number of copies.
140   int nbCopies =
141     integer(FeaturesPlugin_MultiRotation::NB_COPIES_ANGULAR_ID())->value();
142
143   if (nbCopies <=0) {
144     std::string aFeatureError = "Multirotation builder ";
145     aFeatureError+=":: the number of copies for the angular direction is null or negative.";
146     setError(aFeatureError);
147     return;
148   }
149
150   // Getting angle
151   double anAngle;
152   std::string useAngularStep =
153     string(FeaturesPlugin_MultiRotation::USE_ANGULAR_STEP_ID())->value();
154   if (!useAngularStep.empty()) {
155     anAngle = real(FeaturesPlugin_MultiRotation::STEP_ANGULAR_ID())->value();
156   } else {
157     anAngle = 360./nbCopies;
158   }
159
160   // Moving each object.
161   int aResultIndex = 0;
162   std::list<ResultPtr>::iterator aContext = aContextes.begin();
163   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
164         anObjectsIt++, aContext++) {
165     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
166     bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
167
168     // Setting result.
169     if (isPart) {
170       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
171       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
172       for (int i=0; i<nbCopies; i++) {
173         aTrsf->setRotation(anAxis, i*anAngle);
174         ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
175         aResultPart->setTrsf(*aContext, aTrsf);
176         setResult(aResultPart, aResultIndex);
177         aResultIndex++;
178       }
179     } else {
180       ListOfShape aListOfShape;
181       std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > aListOfRotationAlgo;
182
183       for (int i=0; i<nbCopies; i++) {
184         std::shared_ptr<GeomAlgoAPI_Rotation> aRotationnAlgo(
185           new GeomAlgoAPI_Rotation(aBaseShape, anAxis, i*anAngle));
186
187         if (!aRotationnAlgo->check()) {
188           setError(aRotationnAlgo->getError());
189           break;
190         }
191
192         aRotationnAlgo->build();
193
194         // Checking that the algorithm worked properly.
195         if (!aRotationnAlgo->isDone()) {
196           static const std::string aFeatureError = "Error : Multitranslation algorithm failed.";
197           setError(aFeatureError);
198           break;
199         }
200         if (aRotationnAlgo->shape()->isNull()) {
201           static const std::string aShapeError = "Error : Resulting shape is null.";
202           setError(aShapeError);
203           break;
204         }
205         if (!aRotationnAlgo->isValid()) {
206           static const std::string aFeatureError = "Error : Resulting shape in not valid.";
207           setError(aFeatureError);
208           break;
209         }
210         aListOfShape.push_back(aRotationnAlgo->shape());
211         aListOfRotationAlgo.push_back(aRotationnAlgo);
212       }
213       std::shared_ptr<GeomAPI_Shape> aCompound =
214         GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
215       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
216       aResultBody->storeModified(aBaseShape, aCompound);
217       loadNamingDS(aListOfRotationAlgo, aResultBody, aBaseShape);
218
219       setResult(aResultBody, aResultIndex);
220     }
221     aResultIndex++;
222   }
223
224   // Remove the rest results if there were produced in the previous pass.
225   removeResults(aResultIndex);
226 }
227
228 //=================================================================================================
229 #ifdef FEATURE_MULTIROTATION_TWO_DIRECTIONS
230 void FeaturesPlugin_MultiRotation::performRotation2D()
231 {
232   // Getting objects.
233   ListOfShape anObjects;
234   std::list<ResultPtr> aContextes;
235   AttributeSelectionListPtr anObjectsSelList =
236     selectionList(FeaturesPlugin_MultiRotation::OBJECTS_LIST_ID());
237   if (anObjectsSelList->size() == 0) {
238     return;
239   }
240   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
241     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
242       anObjectsSelList->value(anObjectsIndex);
243     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
244     if(!anObject.get()) { // may be for not-activated parts
245       return;
246     }
247     anObjects.push_back(anObject);
248     aContextes.push_back(anObjectAttr->context());
249   }
250
251   //Getting axis.
252   std::shared_ptr<GeomAPI_Ax1> anAxis;
253   std::shared_ptr<GeomAPI_Edge> anEdge;
254   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
255     selection(FeaturesPlugin_MultiRotation::AXIS_ANGULAR_ID());
256   if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
257     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
258   } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
259              anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
260     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
261   }
262   if(anEdge) {
263     anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
264                                                           anEdge->line()->direction()));
265   }
266
267   // Getting number of copies int he angular direction.
268   int nbAngular =
269     integer(FeaturesPlugin_MultiRotation::NB_COPIES_ANGULAR_ID())->value();
270
271   if (nbAngular <=0) {
272     std::string aFeatureError = "Multirotation builder ";
273     aFeatureError+=":: the number of copies for the angular direction is null or negative.";
274     setError(aFeatureError);
275     return;
276   }
277
278   // Getting number of copies int he radial direction.
279   int nbRadial =
280     integer(FeaturesPlugin_MultiRotation::NB_COPIES_RADIAL_ID())->value();
281
282   if (nbRadial <=0) {
283     std::string aFeatureError = "Multirotation builder ";
284     aFeatureError+=":: the number of copies for the radial direction is null or negative.";
285     setError(aFeatureError);
286     return;
287   }
288
289   // Getting angle
290   double anAngle;
291   std::string useAngularStep =
292     string(FeaturesPlugin_MultiRotation::USE_ANGULAR_STEP_ID())->value();
293   if (!useAngularStep.empty()) {
294     anAngle = real(FeaturesPlugin_MultiRotation::STEP_ANGULAR_ID())->value();
295   } else {
296     anAngle = 360./nbAngular;
297   }
298
299   // Getting step
300   double aStep = real(FeaturesPlugin_MultiRotation::STEP_RADIAL_ID())->value();
301
302   // Moving each object.
303   int aResultIndex = 0;
304   std::list<ResultPtr>::iterator aContext = aContextes.begin();
305   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
306         anObjectsIt++, aContext++) {
307     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
308     bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
309
310     std::shared_ptr<GeomAPI_Dir> aDir =
311       GeomAlgoAPI_ShapeTools::buildDirFromAxisAndShape(aBaseShape, anAxis);
312     double x = aDir->x();
313     double y = aDir->y();
314     double z = aDir->z();
315     double norm = sqrt(x*x+y*y+z*z);
316
317     // Setting result.
318     if (isPart) {
319       /*ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
320       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
321       for (int j=0; j<aSecondNbCopies; j++) {
322         for (int i=0; i<aFirstNbCopies; i++) {
323           double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
324           double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
325           double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
326           aTrsf->setTranslation(dx, dy, dz);
327           ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
328           aResultPart->setTrsf(*aContext, aTrsf);
329           setResult(aResultPart, aResultIndex);
330           aResultIndex++;
331         }
332       }*/
333     } else {
334       ListOfShape aListOfShape;
335       std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
336       std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > aListOfRotationAlgo;
337       for (int j=0; j<nbRadial; j++) {
338         // Translation
339         double dx = j*aStep*x/norm;
340         double dy = j*aStep*y/norm;
341         double dz = j*aStep*z/norm;
342         std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
343           new GeomAlgoAPI_Translation(aBaseShape, dx, dy, dz));
344
345         if (!aTranslationAlgo->check()) {
346           setError(aTranslationAlgo->getError());
347           break;
348         }
349
350         aTranslationAlgo->build();
351
352         // Checking that the algorithm worked properly.
353         if (!aTranslationAlgo->isDone()) {
354           static const std::string aFeatureError = "Error : Multirotation algorithm failed.";
355           setError(aFeatureError);
356           break;
357         }
358         if (aTranslationAlgo->shape()->isNull()) {
359           static const std::string aShapeError = "Error : Resulting shape is null.";
360           setError(aShapeError);
361           break;
362         }
363         if (!aTranslationAlgo->isValid()) {
364           static const std::string aFeatureError = "Error : Resulting shape in not valid.";
365           setError(aFeatureError);
366           break;
367         }
368         aListOfShape.push_back(aTranslationAlgo->shape());
369         aListOfTranslationAlgo.push_back(aTranslationAlgo);
370         for (int i=1; i<nbAngular; i++) {
371           std::shared_ptr<GeomAlgoAPI_Rotation> aRotationnAlgo(
372             new GeomAlgoAPI_Rotation(aTranslationAlgo->shape(), anAxis, i*anAngle));
373           if (!aRotationnAlgo->check()) {
374             setError(aTranslationAlgo->getError());
375             break;
376           }
377           aRotationnAlgo->build();// Checking that the algorithm worked properly.
378           if (!aRotationnAlgo->isDone()) {
379             static const std::string aFeatureError = "Error : Multirotation algorithm failed.";
380             setError(aFeatureError);
381             break;
382           }
383           if (aRotationnAlgo->shape()->isNull()) {
384             static const std::string aShapeError = "Error : Resulting shape is null.";
385             setError(aShapeError);
386             break;
387           }
388           if (!aRotationnAlgo->isValid()) {
389             static const std::string aFeatureError = "Error : Resulting shape in not valid.";
390             setError(aFeatureError);
391             break;
392           }
393           aListOfShape.push_back(aRotationnAlgo->shape());
394           aListOfRotationAlgo.push_back(aRotationnAlgo);
395         }
396       }
397       std::shared_ptr<GeomAPI_Shape> aCompound =
398         GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
399       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
400       aResultBody->storeModified(aBaseShape, aCompound);
401
402       loadNamingDS2(aListOfTranslationAlgo, aResultBody, aBaseShape);
403       loadNamingDS3(aListOfRotationAlgo, aResultBody, aBaseShape, nbRadial);
404       setResult(aResultBody, aResultIndex);
405     }
406     aResultIndex++;
407   }
408
409   // Remove the rest results if there were produced in the previous pass.
410   removeResults(aResultIndex);
411 }
412
413 //=================================================================================================
414 void FeaturesPlugin_MultiRotation::loadNamingDS2(
415     std::list<std::shared_ptr<GeomAlgoAPI_Translation> > theListOfTranslationAlgo,
416     std::shared_ptr<ModelAPI_ResultBody> theResultBody,
417     std::shared_ptr<GeomAPI_Shape> theBaseShape)
418 {
419   for (std::list<std::shared_ptr<GeomAlgoAPI_Translation> >::const_iterator anIt =
420     theListOfTranslationAlgo.begin(); anIt != theListOfTranslationAlgo.cend(); ++anIt) {
421     // naming of faces
422     theResultBody->loadModifiedShapes(*anIt, theBaseShape, GeomAPI_Shape::FACE, "Rotated_Face");
423
424     // naming of edges
425     theResultBody->loadModifiedShapes(*anIt, theBaseShape, GeomAPI_Shape::EDGE, "Rotated_Edge");
426
427     // naming of vertex
428     theResultBody->loadModifiedShapes(*anIt, theBaseShape, GeomAPI_Shape::VERTEX, "Rotated_Vertex");
429   }
430 }
431
432 //=================================================================================================
433 void FeaturesPlugin_MultiRotation::loadNamingDS3(
434     std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > theListOfRotationAlgo,
435     std::shared_ptr<ModelAPI_ResultBody> theResultBody,
436     std::shared_ptr<GeomAPI_Shape> theBaseShape, int nb)
437 {
438   int anIndex = nb+1;
439   std::string aRotatedName;
440
441   for (std::list<std::shared_ptr<GeomAlgoAPI_Rotation> >::const_iterator anIt =
442     theListOfRotationAlgo.begin(); anIt != theListOfRotationAlgo.cend(); ++anIt) {
443
444     // naming of faces
445     int numFace = 1;
446     GeomAPI_ShapeExplorer anExp((*anIt)->shape(), GeomAPI_Shape::FACE);
447     for(; anExp.more(); anExp.next()) {
448        aRotatedName = "Rotated_Face_" + std::to_string((long long) anIndex);
449        aRotatedName = aRotatedName + "_" + std::to_string((long long) numFace);
450        theResultBody->generated(anExp.current(), aRotatedName);
451        ++numFace;
452     }
453     ++anIndex;
454   }
455 }
456 #endif
457
458 //=================================================================================================
459 void FeaturesPlugin_MultiRotation::loadNamingDS(
460     std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > theListOfRotationAlgo,
461     std::shared_ptr<ModelAPI_ResultBody> theResultBody,
462     std::shared_ptr<GeomAPI_Shape> theBaseShape)
463 {
464   for (std::list<std::shared_ptr<GeomAlgoAPI_Rotation> >::const_iterator anIt =
465     theListOfRotationAlgo.begin(); anIt != theListOfRotationAlgo.cend(); ++anIt) {
466     // naming of faces
467     theResultBody->loadModifiedShapes(*anIt, theBaseShape, GeomAPI_Shape::FACE, "Rotated_Face");
468
469     // naming of edges
470     theResultBody->loadModifiedShapes(*anIt, theBaseShape, GeomAPI_Shape::EDGE, "Rotated_Edge");
471
472     // naming of vertex
473     theResultBody->loadModifiedShapes(*anIt, theBaseShape, GeomAPI_Shape::VERTEX, "Rotated_Vertex");
474   }
475 }