]> SALOME platform Git repositories - modules/shaper.git/blob - src/FeaturesPlugin/FeaturesPlugin_MultiTranslation.cpp
Salome HOME
4657f8e0a450380c02fc147fbeaeacf9c50e08d4
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_MultiTranslation.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include <FeaturesPlugin_MultiTranslation.h>
22
23 #include <GeomAlgoAPI_CompoundBuilder.h>
24 #include <GeomAlgoAPI_Tools.h>
25
26 #include <GeomAPI_Ax1.h>
27 #include <GeomAPI_Edge.h>
28 #include <GeomAPI_Lin.h>
29 #include <GeomAPI_ShapeIterator.h>
30 #include <GeomAPI_Trsf.h>
31
32 #include <ModelAPI_AttributeDouble.h>
33 #include <ModelAPI_AttributeInteger.h>
34 #include <ModelAPI_AttributeSelectionList.h>
35 #include <ModelAPI_AttributeString.h>
36 #include <ModelAPI_ResultBody.h>
37 #include <ModelAPI_ResultPart.h>
38
39 #include <math.h>
40
41 //=================================================================================================
42 FeaturesPlugin_MultiTranslation::FeaturesPlugin_MultiTranslation()
43 {
44 }
45
46 //=================================================================================================
47 void FeaturesPlugin_MultiTranslation::initAttributes()
48 {
49   AttributeSelectionListPtr aSelection =
50     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
51     FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID(),
52     ModelAPI_AttributeSelectionList::typeId()));
53
54   data()->addAttribute(FeaturesPlugin_MultiTranslation::AXIS_FIRST_DIR_ID(),
55                        ModelAPI_AttributeSelection::typeId());
56   data()->addAttribute(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID(),
57                        ModelAPI_AttributeDouble::typeId());
58   data()->addAttribute(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID(),
59                        ModelAPI_AttributeInteger::typeId());
60
61   data()->addAttribute(FeaturesPlugin_MultiTranslation::USE_SECOND_DIR_ID(),
62                        ModelAPI_AttributeString::typeId());
63   data()->addAttribute(FeaturesPlugin_MultiTranslation::AXIS_SECOND_DIR_ID(),
64                        ModelAPI_AttributeSelection::typeId());
65   data()->addAttribute(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID(),
66                        ModelAPI_AttributeDouble::typeId());
67   data()->addAttribute(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID(),
68                        ModelAPI_AttributeInteger::typeId());
69 }
70
71 //=================================================================================================
72 void FeaturesPlugin_MultiTranslation::execute()
73 {
74   std::string useSecondDir = string(FeaturesPlugin_MultiTranslation::USE_SECOND_DIR_ID())->value();
75   if(!useSecondDir.empty()) {
76     performTwoDirection();
77   } else {
78     performOneDirection();
79   }
80 }
81
82 //=================================================================================================
83 void FeaturesPlugin_MultiTranslation::performOneDirection()
84 {
85   // Getting objects.
86   ListOfShape anObjects;
87   std::list<ResultPtr> aContextes;
88   AttributeSelectionListPtr anObjectsSelList =
89     selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
90   if (anObjectsSelList->size() == 0) {
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_FIRST_DIR_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   else
129   {
130     setError(aSelectionError);
131     return;
132   }
133
134   if (!anEdge.get())
135   {
136     setError(aSelectionError);
137     return;
138   }
139
140   std::shared_ptr<GeomAPI_Ax1> anAxis (new GeomAPI_Ax1(anEdge->line()->location(),
141                                                        anEdge->line()->direction()));
142
143   // Getting step.
144   double aStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
145
146   // Getting number of copies.
147   int nbCopies =
148     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
149
150   if (nbCopies <=0) {
151     std::string aFeatureError = "Multitranslation builder ";
152     aFeatureError+=":: the number of copies for the first direction is null or negative.";
153     setError(aFeatureError);
154     return;
155   }
156
157   // Moving each object.
158   int aResultIndex = 0;
159   std::list<ResultPtr>::iterator aContext = aContextes.begin();
160   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
161         anObjectsIt++, aContext++) {
162     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
163     bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
164
165     // Setting result.
166     if (isPart) {
167       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
168       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
169       for (int i=0; i<nbCopies; i++) {
170         aTrsf->setTranslation(anAxis, i*aStep);
171         ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
172         aResultPart->setTrsf(*aContext, aTrsf);
173         setResult(aResultPart, aResultIndex);
174         aResultIndex++;
175       }
176     } else {
177       std::string anError;
178       ListOfShape aListOfShape;
179       std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
180
181       for (int i=0; i<nbCopies; i++) {
182         std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
183           new GeomAlgoAPI_Translation(aBaseShape, anAxis, i*aStep));
184
185         if (!aTranslationAlgo->check()) {
186           setError(aTranslationAlgo->getError());
187           break;
188         }
189
190         aTranslationAlgo->build();
191
192         // Checking that the algorithm worked properly.
193         if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aTranslationAlgo, getKind(), anError)) {
194           setError(anError);
195           break;
196         }
197         aListOfShape.push_back(aTranslationAlgo->shape());
198         aListOfTranslationAlgo.push_back(aTranslationAlgo);
199       }
200       std::shared_ptr<GeomAPI_Shape> aCompound =
201         GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
202       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
203       aResultBody->storeModified(aBaseShape, aCompound);
204       loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
205
206       setResult(aResultBody, aResultIndex);
207     }
208     aResultIndex++;
209   }
210
211   // Remove the rest results if there were produced in the previous pass.
212   removeResults(aResultIndex);
213 }
214
215 //=================================================================================================
216 void FeaturesPlugin_MultiTranslation::performTwoDirection()
217 {
218   // Getting objects.
219   ListOfShape anObjects;
220   std::list<ResultPtr> aContextes;
221   AttributeSelectionListPtr anObjectsSelList =
222     selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
223   if (anObjectsSelList->size() == 0) {
224     return;
225   }
226   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
227     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
228       anObjectsSelList->value(anObjectsIndex);
229     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
230     if(!anObject.get()) { // may be for not-activated parts
231       return;
232     }
233     anObjects.push_back(anObject);
234     aContextes.push_back(anObjectAttr->context());
235   }
236
237   //Getting axis.
238   static const std::string aSelectionError = "Error: The axis shape selection is bad.";
239   AttributeSelectionPtr anObjRef = selection(AXIS_FIRST_DIR_ID());
240   GeomShapePtr aShape = anObjRef->value();
241   if (!aShape.get()) {
242     if (anObjRef->context().get()) {
243       aShape = anObjRef->context()->shape();
244     }
245   }
246   if (!aShape.get()) {
247     setError(aSelectionError);
248     return;
249   }
250
251   GeomEdgePtr anEdge;
252   if (aShape->isEdge())
253   {
254     anEdge = aShape->edge();
255   }
256   else if (aShape->isCompound())
257   {
258     GeomAPI_ShapeIterator anIt(aShape);
259     anEdge = anIt.current()->edge();
260   }
261   else
262   {
263     setError(aSelectionError);
264     return;
265   }
266
267   if (!anEdge.get())
268   {
269     setError(aSelectionError);
270     return;
271   }
272
273   std::shared_ptr<GeomAPI_Ax1> aFirstAxis(new GeomAPI_Ax1(anEdge->line()->location(),
274                                                           anEdge->line()->direction()));
275
276   //Getting axis.
277   anObjRef = selection(AXIS_SECOND_DIR_ID());
278   aShape = anObjRef->value();
279   if (!aShape.get()) {
280     if (anObjRef->context().get()) {
281       aShape = anObjRef->context()->shape();
282     }
283   }
284   if (!aShape.get()) {
285     setError(aSelectionError);
286     return;
287   }
288
289   if (aShape->isEdge())
290   {
291     anEdge = aShape->edge();
292   }
293   else if (aShape->isCompound())
294   {
295     GeomAPI_ShapeIterator anIt(aShape);
296     anEdge = anIt.current()->edge();
297   }
298   else
299   {
300     setError(aSelectionError);
301     return;
302   }
303
304   if (!anEdge.get())
305   {
306     setError(aSelectionError);
307     return;
308   }
309
310   std::shared_ptr<GeomAPI_Ax1> aSecondAxis(new GeomAPI_Ax1(anEdge->line()->location(),
311                                                            anEdge->line()->direction()));
312
313   // Getting step.
314   double aFirstStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
315   double aSecondStep = real(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID())->value();
316
317   // Getting number of copies.
318   int aFirstNbCopies =
319     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
320   int aSecondNbCopies =
321     integer(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID())->value();
322
323   if (aFirstNbCopies <=0) {
324     std::string aFeatureError = "Multitranslation builder ";
325     aFeatureError+=":: the number of copies for the first direction is null or negative.";
326     setError(aFeatureError);
327     return;
328   }
329
330   if (aSecondNbCopies <=0) {
331     std::string aFeatureError = "Multitranslation builder ";
332     aFeatureError+=":: the number of copies for the second direction is null or negative.";
333     setError(aFeatureError);
334     return;
335   }
336
337   // Coord aFirstAxis
338   double x1 = aFirstAxis->dir()->x();
339   double y1 = aFirstAxis->dir()->y();
340   double z1 = aFirstAxis->dir()->z();
341   double norm1 = sqrt(x1*x1 + y1*y1 + z1*z1);
342
343   // Coord aSecondAxis
344   double x2 = aSecondAxis->dir()->x();
345   double y2 = aSecondAxis->dir()->y();
346   double z2 = aSecondAxis->dir()->z();
347   double norm2 = sqrt(x2*x2 + y2*y2 + z2*z2);
348
349   // Moving each object.
350   int aResultIndex = 0;
351   std::list<ResultPtr>::iterator aContext = aContextes.begin();
352   for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
353         anObjectsIt++, aContext++) {
354     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
355     bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
356
357     // Setting result.
358     if (isPart) {
359       ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
360       std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
361       for (int j=0; j<aSecondNbCopies; j++) {
362         for (int i=0; i<aFirstNbCopies; i++) {
363           double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
364           double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
365           double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
366           aTrsf->setTranslation(dx, dy, dz);
367           ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
368           aResultPart->setTrsf(*aContext, aTrsf);
369           setResult(aResultPart, aResultIndex);
370           aResultIndex++;
371         }
372       }
373     } else {
374       std::string anError;
375       ListOfShape aListOfShape;
376       std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
377
378       for (int j=0; j<aSecondNbCopies; j++) {
379         for (int i=0; i<aFirstNbCopies; i++) {
380           double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
381           double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
382           double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
383           std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
384             new GeomAlgoAPI_Translation(aBaseShape, dx, dy, dz));
385
386           if (!aTranslationAlgo->check()) {
387             setError(aTranslationAlgo->getError());
388             break;
389           }
390
391           aTranslationAlgo->build();
392
393           // Checking that the algorithm worked properly.
394           if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aTranslationAlgo, getKind(), anError)) {
395             setError(anError);
396             break;
397           }
398           aListOfShape.push_back(aTranslationAlgo->shape());
399           aListOfTranslationAlgo.push_back(aTranslationAlgo);
400         }
401       }
402       std::shared_ptr<GeomAPI_Shape> aCompound =
403         GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
404       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
405       aResultBody->storeModified(aBaseShape, aCompound);
406       loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
407       setResult(aResultBody, aResultIndex);
408     }
409     aResultIndex++;
410   }
411
412   // Remove the rest results if there were produced in the previous pass.
413   removeResults(aResultIndex);
414 }
415
416 //=================================================================================================
417 void FeaturesPlugin_MultiTranslation::loadNamingDS(
418     std::list<std::shared_ptr<GeomAlgoAPI_Translation> > theListOfTranslationAlgo,
419     std::shared_ptr<ModelAPI_ResultBody> theResultBody,
420     std::shared_ptr<GeomAPI_Shape> theBaseShape)
421 {
422   for (std::list<std::shared_ptr<GeomAlgoAPI_Translation> >::const_iterator anIt =
423     theListOfTranslationAlgo.begin(); anIt != theListOfTranslationAlgo.cend(); ++anIt) {
424     // naming of faces
425     theResultBody->loadModifiedShapes(*anIt,
426                                       theBaseShape,
427                                       GeomAPI_Shape::FACE,
428                                       "Translated_Face");
429
430     // naming of edges
431     theResultBody->loadModifiedShapes(*anIt,
432                                       theBaseShape,
433                                       GeomAPI_Shape::EDGE,
434                                       "Translated_Edge");
435
436     // naming of vertex
437     theResultBody->loadModifiedShapes(*anIt,
438                                       theBaseShape,
439                                       GeomAPI_Shape::VERTEX,
440                                       "Translated_Vertex");
441   }
442 }