1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include <FeaturesPlugin_MultiTranslation.h>
23 #include <GeomAlgoAPI_CompoundBuilder.h>
24 #include <GeomAlgoAPI_Tools.h>
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>
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>
41 //=================================================================================================
42 FeaturesPlugin_MultiTranslation::FeaturesPlugin_MultiTranslation()
46 //=================================================================================================
47 void FeaturesPlugin_MultiTranslation::initAttributes()
49 AttributeSelectionListPtr aSelection =
50 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
51 FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID(),
52 ModelAPI_AttributeSelectionList::typeId()));
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());
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());
71 //=================================================================================================
72 void FeaturesPlugin_MultiTranslation::execute()
74 std::string useSecondDir = string(FeaturesPlugin_MultiTranslation::USE_SECOND_DIR_ID())->value();
75 if(!useSecondDir.empty()) {
76 performTwoDirection();
78 performOneDirection();
82 //=================================================================================================
83 void FeaturesPlugin_MultiTranslation::performOneDirection()
86 ListOfShape anObjects;
87 std::list<ResultPtr> aContextes;
88 AttributeSelectionListPtr anObjectsSelList =
89 selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
90 if (anObjectsSelList->size() == 0) {
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
100 anObjects.push_back(anObject);
101 aContextes.push_back(anObjectAttr->context());
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();
109 if (anObjRef->context().get()) {
110 aShape = anObjRef->context()->shape();
114 setError(aSelectionError);
119 if (aShape->isEdge())
121 anEdge = aShape->edge();
123 else if (aShape->isCompound())
125 GeomAPI_ShapeIterator anIt(aShape);
126 anEdge = anIt.current()->edge();
130 setError(aSelectionError);
136 setError(aSelectionError);
140 std::shared_ptr<GeomAPI_Ax1> anAxis (new GeomAPI_Ax1(anEdge->line()->location(),
141 anEdge->line()->direction()));
144 double aStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
146 // Getting number of copies.
148 integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
151 std::string aFeatureError = "Multitranslation builder ";
152 aFeatureError+=":: the number of copies for the first direction is null or negative.";
153 setError(aFeatureError);
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();
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);
178 ListOfShape aListOfShape;
179 std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
181 for (int i=0; i<nbCopies; i++) {
182 std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
183 new GeomAlgoAPI_Translation(aBaseShape, anAxis, i*aStep));
185 if (!aTranslationAlgo->check()) {
186 setError(aTranslationAlgo->getError());
190 aTranslationAlgo->build();
192 // Checking that the algorithm worked properly.
193 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aTranslationAlgo, getKind(), anError)) {
197 aListOfShape.push_back(aTranslationAlgo->shape());
198 aListOfTranslationAlgo.push_back(aTranslationAlgo);
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);
206 setResult(aResultBody, aResultIndex);
211 // Remove the rest results if there were produced in the previous pass.
212 removeResults(aResultIndex);
215 //=================================================================================================
216 void FeaturesPlugin_MultiTranslation::performTwoDirection()
219 ListOfShape anObjects;
220 std::list<ResultPtr> aContextes;
221 AttributeSelectionListPtr anObjectsSelList =
222 selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
223 if (anObjectsSelList->size() == 0) {
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
233 anObjects.push_back(anObject);
234 aContextes.push_back(anObjectAttr->context());
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();
242 if (anObjRef->context().get()) {
243 aShape = anObjRef->context()->shape();
247 setError(aSelectionError);
252 if (aShape->isEdge())
254 anEdge = aShape->edge();
256 else if (aShape->isCompound())
258 GeomAPI_ShapeIterator anIt(aShape);
259 anEdge = anIt.current()->edge();
263 setError(aSelectionError);
269 setError(aSelectionError);
273 std::shared_ptr<GeomAPI_Ax1> aFirstAxis(new GeomAPI_Ax1(anEdge->line()->location(),
274 anEdge->line()->direction()));
277 anObjRef = selection(AXIS_SECOND_DIR_ID());
278 aShape = anObjRef->value();
280 if (anObjRef->context().get()) {
281 aShape = anObjRef->context()->shape();
285 setError(aSelectionError);
289 if (aShape->isEdge())
291 anEdge = aShape->edge();
293 else if (aShape->isCompound())
295 GeomAPI_ShapeIterator anIt(aShape);
296 anEdge = anIt.current()->edge();
300 setError(aSelectionError);
306 setError(aSelectionError);
310 std::shared_ptr<GeomAPI_Ax1> aSecondAxis(new GeomAPI_Ax1(anEdge->line()->location(),
311 anEdge->line()->direction()));
314 double aFirstStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
315 double aSecondStep = real(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID())->value();
317 // Getting number of copies.
319 integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
320 int aSecondNbCopies =
321 integer(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID())->value();
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);
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);
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);
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);
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();
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);
375 ListOfShape aListOfShape;
376 std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
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));
386 if (!aTranslationAlgo->check()) {
387 setError(aTranslationAlgo->getError());
391 aTranslationAlgo->build();
393 // Checking that the algorithm worked properly.
394 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aTranslationAlgo, getKind(), anError)) {
398 aListOfShape.push_back(aTranslationAlgo->shape());
399 aListOfTranslationAlgo.push_back(aTranslationAlgo);
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);
412 // Remove the rest results if there were produced in the previous pass.
413 removeResults(aResultIndex);
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)
422 for (std::list<std::shared_ptr<GeomAlgoAPI_Translation> >::const_iterator anIt =
423 theListOfTranslationAlgo.begin(); anIt != theListOfTranslationAlgo.cend(); ++anIt) {
425 theResultBody->loadModifiedShapes(*anIt,
431 theResultBody->loadModifiedShapes(*anIt,
437 theResultBody->loadModifiedShapes(*anIt,
439 GeomAPI_Shape::VERTEX,
440 "Translated_Vertex");