]> SALOME platform Git repositories - modules/shaper.git/blob - src/FeaturesPlugin/FeaturesPlugin_MultiTranslation.cpp
Salome HOME
Added "Multitranslation" feature.
[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   
112   int aResultIndex = 0;
113   std::list<ResultPtr>::iterator aContext = aContextes.begin();
114   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
115         anObjectsIt++, aContext++) {
116     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
117     
118     ListOfShape aListOfShape;
119     std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
120   
121     for (int i=0; i<nbCopies; i++) {
122       std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
123         new GeomAlgoAPI_Translation(aBaseShape, anAxis, i*aStep));
124       
125       if (!aTranslationAlgo->check()) {
126         setError(aTranslationAlgo->getError());
127         break;
128       }
129       
130       aTranslationAlgo->build();
131       
132       // Checking that the algorithm worked properly.
133       if (!aTranslationAlgo->isDone()) {
134         static const std::string aFeatureError = "Error : Multitranslation algorithm failed.";
135         setError(aFeatureError);
136         break;
137       }
138       if (aTranslationAlgo->shape()->isNull()) {
139         static const std::string aShapeError = "Error : Resulting shape is null.";
140         setError(aShapeError);
141         break;
142       }
143       if (!aTranslationAlgo->isValid()) {
144         static const std::string aFeatureError = "Error : Resulting shape in not valid.";
145         setError(aFeatureError);
146         break;
147       }
148       aListOfShape.push_back(aTranslationAlgo->shape());
149       aListOfTranslationAlgo.push_back(aTranslationAlgo);
150     }
151     std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
152     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
153     aResultBody->storeModified(aBaseShape, aCompound);
154     loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
155     
156     setResult(aResultBody, aResultIndex);
157     aResultIndex++;
158   }
159
160   // Remove the rest results if there were produced in the previous pass.
161   removeResults(aResultIndex);
162 }
163
164 //=================================================================================================
165 void FeaturesPlugin_MultiTranslation::performTwoDirection()
166
167   // Getting objects.
168   ListOfShape anObjects;
169   std::list<ResultPtr> aContextes;
170   AttributeSelectionListPtr anObjectsSelList =
171     selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
172   if (anObjectsSelList->size() == 0) {
173     return;
174   }
175   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
176     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
177       anObjectsSelList->value(anObjectsIndex);
178     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
179     if(!anObject.get()) { // may be for not-activated parts
180       eraseResults();
181       return;
182     }
183     anObjects.push_back(anObject);
184     aContextes.push_back(anObjectAttr->context());
185   }
186
187   //Getting axis.
188   std::shared_ptr<GeomAPI_Ax1> aFirstAxis;
189   std::shared_ptr<GeomAPI_Edge> anEdge;
190   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
191     selection(FeaturesPlugin_MultiTranslation::AXIS_FIRST_DIR_ID());
192   if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
193     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
194   } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
195              anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
196     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
197   }
198   if(anEdge) {
199     aFirstAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
200                                                               anEdge->line()->direction()));
201   }
202   std::shared_ptr<GeomAPI_Ax1> aSecondAxis;
203   anObjRef = selection(FeaturesPlugin_MultiTranslation::AXIS_SECOND_DIR_ID());
204   if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
205     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
206   } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
207              anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
208     anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
209   }
210   if(anEdge) {
211     aSecondAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
212                                                                anEdge->line()->direction()));
213   }
214
215   // Getting step.
216   double aFirstStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
217   double aSecondStep = real(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID())->value();
218   
219   // Getting number of copies.
220   int aFirstNbCopies = 
221     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
222   int aSecondNbCopies = 
223     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID())->value();
224     
225   // Coord aFirstAxis
226   double x1 = aFirstAxis->dir()->x();
227   double y1 = aFirstAxis->dir()->y();
228   double z1 = aFirstAxis->dir()->z();
229   double norm1 = sqrt(x1*x1 + y1*y1 + z1*z1);
230   
231   // Coord aSecondAxis
232   double x2 = aSecondAxis->dir()->x();
233   double y2 = aSecondAxis->dir()->y();
234   double z2 = aSecondAxis->dir()->z();
235   double norm2 = sqrt(x2*x2 + y2*y2 + z2*z2);
236  
237   // Moving each object.
238   int aResultIndex = 0;
239   std::list<ResultPtr>::iterator aContext = aContextes.begin();
240   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
241         anObjectsIt++, aContext++) {
242     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
243     
244     ListOfShape aListOfShape;
245     std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
246   
247     for (int j=0; j<aSecondNbCopies; j++) {
248       for (int i=0; i<aFirstNbCopies; i++) {
249         double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
250         double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
251         double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
252         std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
253           new GeomAlgoAPI_Translation(aBaseShape, dx, dy, dz));
254       
255         if (!aTranslationAlgo->check()) {
256           setError(aTranslationAlgo->getError());
257           break;
258         }
259       
260         aTranslationAlgo->build();
261       
262         // Checking that the algorithm worked properly.
263         if (!aTranslationAlgo->isDone()) {
264           static const std::string aFeatureError = "Error : Multitranslation algorithm failed.";
265           setError(aFeatureError);
266           break;
267         }
268         if (aTranslationAlgo->shape()->isNull()) {
269           static const std::string aShapeError = "Error : Resulting shape is null.";
270           setError(aShapeError);
271           break;
272         }
273         if (!aTranslationAlgo->isValid()) {
274           static const std::string aFeatureError = "Error : Resulting shape in not valid.";
275           setError(aFeatureError);
276           break;
277         }
278         aListOfShape.push_back(aTranslationAlgo->shape());
279         aListOfTranslationAlgo.push_back(aTranslationAlgo);
280       }
281     }
282     std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
283     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
284     aResultBody->storeModified(aBaseShape, aCompound);
285     loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
286     setResult(aResultBody, aResultIndex);
287     aResultIndex++;
288   }
289
290   // Remove the rest results if there were produced in the previous pass.
291   removeResults(aResultIndex);
292 }
293
294 //=================================================================================================
295 void FeaturesPlugin_MultiTranslation::loadNamingDS(
296     std::list<std::shared_ptr<GeomAlgoAPI_Translation> > theListOfTranslationAlgo,
297     std::shared_ptr<ModelAPI_ResultBody> theResultBody,
298     std::shared_ptr<GeomAPI_Shape> theBaseShape)
299 {
300   int aTag = 1;
301   int anIndex = 1;
302   std::string aTranslatedName;
303   
304   for (std::list<std::shared_ptr<GeomAlgoAPI_Translation> >::const_iterator anIt =
305     theListOfTranslationAlgo.begin(); anIt != theListOfTranslationAlgo.cend(); ++anIt) {
306     std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = (*anIt)->mapOfSubShapes();
307
308     // naming of faces
309     aTranslatedName = "Translated_Face_" + std::to_string((long long) anIndex);
310     theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::FACE,
311                                                aTag++, aTranslatedName, *aSubShapes.get(),
312                                                false, true);
313
314     // naming of edges
315     aTranslatedName = "Translated_Edge_" + std::to_string((long long) anIndex);
316     theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::EDGE,
317                                                aTag++, aTranslatedName, *aSubShapes.get(),
318                                                false, true);
319
320     // naming of vertex
321     aTranslatedName = "Translated_Vertex_" + std::to_string((long long) anIndex);
322     theResultBody->loadAndOrientModifiedShapes((*anIt).get(), theBaseShape, GeomAPI_Shape::VERTEX,
323                                                aTag++, aTranslatedName, *aSubShapes.get(),
324                                                false, true);
325     
326     ++anIndex;
327   }
328 }