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