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