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) {
91 setError("Error: empty selection list");
94 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
95 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
96 anObjectsSelList->value(anObjectsIndex);
97 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
98 if(!anObject.get()) { // may be for not-activated parts
101 anObjects.push_back(anObject);
102 aContextes.push_back(anObjectAttr->context());
106 static const std::string aSelectionError = "Error: The axis shape selection is bad.";
107 AttributeSelectionPtr anObjRef = selection(AXIS_FIRST_DIR_ID());
108 GeomShapePtr aShape = anObjRef->value();
110 if (anObjRef->context().get()) {
111 aShape = anObjRef->context()->shape();
115 setError(aSelectionError);
120 if (aShape->isEdge())
122 anEdge = aShape->edge();
124 else if (aShape->isCompound())
126 GeomAPI_ShapeIterator anIt(aShape);
127 anEdge = anIt.current()->edge();
132 setError(aSelectionError);
136 std::shared_ptr<GeomAPI_Ax1> anAxis (new GeomAPI_Ax1(anEdge->line()->location(),
137 anEdge->line()->direction()));
140 double aStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
142 // Getting number of copies.
144 integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
147 std::string aFeatureError = "Multitranslation builder ";
148 aFeatureError+=":: the number of copies for the first direction is null or negative.";
149 setError(aFeatureError);
153 // Moving each object.
154 int aResultIndex = 0;
155 std::list<ResultPtr>::iterator aContext = aContextes.begin();
156 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
157 anObjectsIt++, aContext++) {
158 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
159 bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
163 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
164 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
165 for (int i=0; i<nbCopies; i++) {
166 aTrsf->setTranslation(anAxis, i*aStep);
167 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
168 aResultPart->setTrsf(*aContext, aTrsf);
169 setResult(aResultPart, aResultIndex);
174 ListOfShape aListOfShape;
175 std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
177 for (int i=0; i<nbCopies; i++) {
178 std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
179 new GeomAlgoAPI_Translation(aBaseShape, anAxis, i*aStep));
181 if (!aTranslationAlgo->check()) {
182 setError(aTranslationAlgo->getError());
186 aTranslationAlgo->build();
188 // Checking that the algorithm worked properly.
189 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(
190 aTranslationAlgo, getKind(), anError)) {
194 aListOfShape.push_back(aTranslationAlgo->shape());
195 aListOfTranslationAlgo.push_back(aTranslationAlgo);
197 std::shared_ptr<GeomAPI_Shape> aCompound =
198 GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
199 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
200 aResultBody->storeModified(aBaseShape, aCompound);
201 loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
203 setResult(aResultBody, aResultIndex);
208 // Remove the rest results if there were produced in the previous pass.
209 removeResults(aResultIndex);
212 //=================================================================================================
213 void FeaturesPlugin_MultiTranslation::performTwoDirection()
216 ListOfShape anObjects;
217 std::list<ResultPtr> aContextes;
218 AttributeSelectionListPtr anObjectsSelList =
219 selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
220 if (anObjectsSelList->size() == 0) {
221 setError("Error: empty selection list");
224 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
225 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
226 anObjectsSelList->value(anObjectsIndex);
227 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
228 if(!anObject.get()) { // may be for not-activated parts
231 anObjects.push_back(anObject);
232 aContextes.push_back(anObjectAttr->context());
236 static const std::string aSelectionError = "Error: The axis shape selection is bad.";
237 AttributeSelectionPtr anObjRef = selection(AXIS_FIRST_DIR_ID());
238 GeomShapePtr aShape = anObjRef->value();
240 if (anObjRef->context().get()) {
241 aShape = anObjRef->context()->shape();
245 setError(aSelectionError);
250 if (aShape->isEdge())
252 anEdge = aShape->edge();
254 else if (aShape->isCompound())
256 GeomAPI_ShapeIterator anIt(aShape);
257 anEdge = anIt.current()->edge();
262 setError(aSelectionError);
266 std::shared_ptr<GeomAPI_Ax1> aFirstAxis(new GeomAPI_Ax1(anEdge->line()->location(),
267 anEdge->line()->direction()));
270 anObjRef = selection(AXIS_SECOND_DIR_ID());
271 aShape = anObjRef->value();
273 if (anObjRef->context().get()) {
274 aShape = anObjRef->context()->shape();
278 setError(aSelectionError);
282 if (aShape->isEdge())
284 anEdge = aShape->edge();
286 else if (aShape->isCompound())
288 GeomAPI_ShapeIterator anIt(aShape);
289 anEdge = anIt.current()->edge();
294 setError(aSelectionError);
298 std::shared_ptr<GeomAPI_Ax1> aSecondAxis(new GeomAPI_Ax1(anEdge->line()->location(),
299 anEdge->line()->direction()));
302 double aFirstStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
303 double aSecondStep = real(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID())->value();
305 // Getting number of copies.
307 integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
308 int aSecondNbCopies =
309 integer(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID())->value();
311 if (aFirstNbCopies <=0) {
312 std::string aFeatureError = "Multitranslation builder ";
313 aFeatureError+=":: the number of copies for the first direction is null or negative.";
314 setError(aFeatureError);
318 if (aSecondNbCopies <=0) {
319 std::string aFeatureError = "Multitranslation builder ";
320 aFeatureError+=":: the number of copies for the second direction is null or negative.";
321 setError(aFeatureError);
326 double x1 = aFirstAxis->dir()->x();
327 double y1 = aFirstAxis->dir()->y();
328 double z1 = aFirstAxis->dir()->z();
329 double norm1 = sqrt(x1*x1 + y1*y1 + z1*z1);
332 double x2 = aSecondAxis->dir()->x();
333 double y2 = aSecondAxis->dir()->y();
334 double z2 = aSecondAxis->dir()->z();
335 double norm2 = sqrt(x2*x2 + y2*y2 + z2*z2);
337 // Moving each object.
338 int aResultIndex = 0;
339 std::list<ResultPtr>::iterator aContext = aContextes.begin();
340 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
341 anObjectsIt++, aContext++) {
342 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
343 bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
347 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
348 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
349 for (int j=0; j<aSecondNbCopies; j++) {
350 for (int i=0; i<aFirstNbCopies; i++) {
351 double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
352 double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
353 double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
354 aTrsf->setTranslation(dx, dy, dz);
355 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
356 aResultPart->setTrsf(*aContext, aTrsf);
357 setResult(aResultPart, aResultIndex);
363 ListOfShape aListOfShape;
364 std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
366 for (int j=0; j<aSecondNbCopies; j++) {
367 for (int i=0; i<aFirstNbCopies; i++) {
368 double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
369 double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
370 double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
371 std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
372 new GeomAlgoAPI_Translation(aBaseShape, dx, dy, dz));
374 if (!aTranslationAlgo->check()) {
375 setError(aTranslationAlgo->getError());
379 aTranslationAlgo->build();
381 // Checking that the algorithm worked properly.
382 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(
383 aTranslationAlgo, getKind(), anError)) {
387 aListOfShape.push_back(aTranslationAlgo->shape());
388 aListOfTranslationAlgo.push_back(aTranslationAlgo);
391 std::shared_ptr<GeomAPI_Shape> aCompound =
392 GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
393 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
394 aResultBody->storeModified(aBaseShape, aCompound);
395 loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
396 setResult(aResultBody, aResultIndex);
401 // Remove the rest results if there were produced in the previous pass.
402 removeResults(aResultIndex);
405 //=================================================================================================
406 void FeaturesPlugin_MultiTranslation::loadNamingDS(
407 std::list<std::shared_ptr<GeomAlgoAPI_Translation> > theListOfTranslationAlgo,
408 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
409 std::shared_ptr<GeomAPI_Shape> theBaseShape)
411 for (std::list<std::shared_ptr<GeomAlgoAPI_Translation> >::const_iterator anIt =
412 theListOfTranslationAlgo.begin(); anIt != theListOfTranslationAlgo.cend(); ++anIt) {
414 theResultBody->loadModifiedShapes(*anIt,
420 theResultBody->loadModifiedShapes(*anIt,
426 theResultBody->loadModifiedShapes(*anIt,
428 GeomAPI_Shape::VERTEX,
429 "Translated_Vertex");