1 // Copyright (C) 2014-2019 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 email : webmaster.salome@opencascade.com
20 #include <FeaturesPlugin_MultiTranslation.h>
22 #include <GeomAlgoAPI_CompoundBuilder.h>
23 #include <GeomAlgoAPI_Tools.h>
25 #include <GeomAPI_Ax1.h>
26 #include <GeomAPI_Edge.h>
27 #include <GeomAPI_Lin.h>
28 #include <GeomAPI_ShapeIterator.h>
29 #include <GeomAPI_Trsf.h>
31 #include <ModelAPI_AttributeDouble.h>
32 #include <ModelAPI_AttributeInteger.h>
33 #include <ModelAPI_AttributeSelectionList.h>
34 #include <ModelAPI_AttributeString.h>
35 #include <ModelAPI_ResultBody.h>
36 #include <ModelAPI_ResultPart.h>
40 //=================================================================================================
41 FeaturesPlugin_MultiTranslation::FeaturesPlugin_MultiTranslation()
45 //=================================================================================================
46 void FeaturesPlugin_MultiTranslation::initAttributes()
48 AttributeSelectionListPtr aSelection =
49 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
50 FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID(),
51 ModelAPI_AttributeSelectionList::typeId()));
53 data()->addAttribute(FeaturesPlugin_MultiTranslation::AXIS_FIRST_DIR_ID(),
54 ModelAPI_AttributeSelection::typeId());
55 data()->addAttribute(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID(),
56 ModelAPI_AttributeDouble::typeId());
57 data()->addAttribute(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID(),
58 ModelAPI_AttributeInteger::typeId());
60 data()->addAttribute(FeaturesPlugin_MultiTranslation::USE_SECOND_DIR_ID(),
61 ModelAPI_AttributeString::typeId());
62 data()->addAttribute(FeaturesPlugin_MultiTranslation::AXIS_SECOND_DIR_ID(),
63 ModelAPI_AttributeSelection::typeId());
64 data()->addAttribute(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID(),
65 ModelAPI_AttributeDouble::typeId());
66 data()->addAttribute(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID(),
67 ModelAPI_AttributeInteger::typeId());
70 //=================================================================================================
71 void FeaturesPlugin_MultiTranslation::execute()
73 std::string useSecondDir = string(FeaturesPlugin_MultiTranslation::USE_SECOND_DIR_ID())->value();
74 if(!useSecondDir.empty()) {
75 performTwoDirection();
77 performOneDirection();
81 //=================================================================================================
82 void FeaturesPlugin_MultiTranslation::performOneDirection()
85 ListOfShape anObjects;
86 std::list<ResultPtr> aContextes;
87 AttributeSelectionListPtr anObjectsSelList =
88 selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
89 if (anObjectsSelList->size() == 0) {
90 setError("Error: empty selection list");
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();
131 setError(aSelectionError);
135 std::shared_ptr<GeomAPI_Ax1> anAxis (new GeomAPI_Ax1(anEdge->line()->location(),
136 anEdge->line()->direction()));
139 double aStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
141 // Getting number of copies.
143 integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
146 std::string aFeatureError = "Multitranslation builder ";
147 aFeatureError+=":: the number of copies for the first direction is null or negative.";
148 setError(aFeatureError);
152 // Moving each object.
153 int aResultIndex = 0;
154 std::list<ResultPtr>::iterator aContext = aContextes.begin();
155 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
156 anObjectsIt++, aContext++) {
157 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
158 bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
162 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
163 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
164 for (int i=0; i<nbCopies; i++) {
165 aTrsf->setTranslation(anAxis, i*aStep);
166 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
167 aResultPart->setTrsf(*aContext, aTrsf);
168 setResult(aResultPart, aResultIndex);
173 ListOfShape aListOfShape;
174 std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
176 for (int i=0; i<nbCopies; i++) {
177 std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
178 new GeomAlgoAPI_Translation(aBaseShape, anAxis, i*aStep));
180 if (!aTranslationAlgo->check()) {
181 setError(aTranslationAlgo->getError());
185 aTranslationAlgo->build();
187 // Checking that the algorithm worked properly.
188 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(
189 aTranslationAlgo, getKind(), anError)) {
193 aListOfShape.push_back(aTranslationAlgo->shape());
194 aListOfTranslationAlgo.push_back(aTranslationAlgo);
196 std::shared_ptr<GeomAPI_Shape> aCompound =
197 GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
198 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
199 aResultBody->storeModified(aBaseShape, aCompound);
200 loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
202 setResult(aResultBody, aResultIndex);
207 // Remove the rest results if there were produced in the previous pass.
208 removeResults(aResultIndex);
211 //=================================================================================================
212 void FeaturesPlugin_MultiTranslation::performTwoDirection()
215 ListOfShape anObjects;
216 std::list<ResultPtr> aContextes;
217 AttributeSelectionListPtr anObjectsSelList =
218 selectionList(FeaturesPlugin_MultiTranslation::OBJECTS_LIST_ID());
219 if (anObjectsSelList->size() == 0) {
220 setError("Error: empty selection list");
223 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
224 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
225 anObjectsSelList->value(anObjectsIndex);
226 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
227 if(!anObject.get()) { // may be for not-activated parts
230 anObjects.push_back(anObject);
231 aContextes.push_back(anObjectAttr->context());
235 static const std::string aSelectionError = "Error: The axis shape selection is bad.";
236 AttributeSelectionPtr anObjRef = selection(AXIS_FIRST_DIR_ID());
237 GeomShapePtr aShape = anObjRef->value();
239 if (anObjRef->context().get()) {
240 aShape = anObjRef->context()->shape();
244 setError(aSelectionError);
249 if (aShape->isEdge())
251 anEdge = aShape->edge();
253 else if (aShape->isCompound())
255 GeomAPI_ShapeIterator anIt(aShape);
256 anEdge = anIt.current()->edge();
261 setError(aSelectionError);
265 std::shared_ptr<GeomAPI_Ax1> aFirstAxis(new GeomAPI_Ax1(anEdge->line()->location(),
266 anEdge->line()->direction()));
269 anObjRef = selection(AXIS_SECOND_DIR_ID());
270 aShape = anObjRef->value();
272 if (anObjRef->context().get()) {
273 aShape = anObjRef->context()->shape();
277 setError(aSelectionError);
281 if (aShape->isEdge())
283 anEdge = aShape->edge();
285 else if (aShape->isCompound())
287 GeomAPI_ShapeIterator anIt(aShape);
288 anEdge = anIt.current()->edge();
293 setError(aSelectionError);
297 std::shared_ptr<GeomAPI_Ax1> aSecondAxis(new GeomAPI_Ax1(anEdge->line()->location(),
298 anEdge->line()->direction()));
301 double aFirstStep = real(FeaturesPlugin_MultiTranslation::STEP_FIRST_DIR_ID())->value();
302 double aSecondStep = real(FeaturesPlugin_MultiTranslation::STEP_SECOND_DIR_ID())->value();
304 // Getting number of copies.
306 integer(FeaturesPlugin_MultiTranslation::NB_COPIES_FIRST_DIR_ID())->value();
307 int aSecondNbCopies =
308 integer(FeaturesPlugin_MultiTranslation::NB_COPIES_SECOND_DIR_ID())->value();
310 if (aFirstNbCopies <=0) {
311 std::string aFeatureError = "Multitranslation builder ";
312 aFeatureError+=":: the number of copies for the first direction is null or negative.";
313 setError(aFeatureError);
317 if (aSecondNbCopies <=0) {
318 std::string aFeatureError = "Multitranslation builder ";
319 aFeatureError+=":: the number of copies for the second direction is null or negative.";
320 setError(aFeatureError);
325 double x1 = aFirstAxis->dir()->x();
326 double y1 = aFirstAxis->dir()->y();
327 double z1 = aFirstAxis->dir()->z();
328 double norm1 = sqrt(x1*x1 + y1*y1 + z1*z1);
331 double x2 = aSecondAxis->dir()->x();
332 double y2 = aSecondAxis->dir()->y();
333 double z2 = aSecondAxis->dir()->z();
334 double norm2 = sqrt(x2*x2 + y2*y2 + z2*z2);
336 // Moving each object.
337 int aResultIndex = 0;
338 std::list<ResultPtr>::iterator aContext = aContextes.begin();
339 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
340 anObjectsIt++, aContext++) {
341 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
342 bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
346 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
347 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
348 for (int j=0; j<aSecondNbCopies; j++) {
349 for (int i=0; i<aFirstNbCopies; i++) {
350 double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
351 double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
352 double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
353 aTrsf->setTranslation(dx, dy, dz);
354 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
355 aResultPart->setTrsf(*aContext, aTrsf);
356 setResult(aResultPart, aResultIndex);
362 ListOfShape aListOfShape;
363 std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
365 for (int j=0; j<aSecondNbCopies; j++) {
366 for (int i=0; i<aFirstNbCopies; i++) {
367 double dx = i*aFirstStep*x1/norm1+j*aSecondStep*x2/norm2;
368 double dy = i*aFirstStep*y1/norm1+j*aSecondStep*y2/norm2;
369 double dz = i*aFirstStep*z1/norm1+j*aSecondStep*z2/norm2;
370 std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
371 new GeomAlgoAPI_Translation(aBaseShape, dx, dy, dz));
373 if (!aTranslationAlgo->check()) {
374 setError(aTranslationAlgo->getError());
378 aTranslationAlgo->build();
380 // Checking that the algorithm worked properly.
381 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(
382 aTranslationAlgo, getKind(), anError)) {
386 aListOfShape.push_back(aTranslationAlgo->shape());
387 aListOfTranslationAlgo.push_back(aTranslationAlgo);
390 std::shared_ptr<GeomAPI_Shape> aCompound =
391 GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
392 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
393 aResultBody->storeModified(aBaseShape, aCompound);
394 loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
395 setResult(aResultBody, aResultIndex);
400 // Remove the rest results if there were produced in the previous pass.
401 removeResults(aResultIndex);
404 //=================================================================================================
405 void FeaturesPlugin_MultiTranslation::loadNamingDS(
406 std::list<std::shared_ptr<GeomAlgoAPI_Translation> > theListOfTranslationAlgo,
407 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
408 std::shared_ptr<GeomAPI_Shape> theBaseShape)
410 for (std::list<std::shared_ptr<GeomAlgoAPI_Translation> >::const_iterator anIt =
411 theListOfTranslationAlgo.begin(); anIt != theListOfTranslationAlgo.cend(); ++anIt) {
413 theResultBody->loadModifiedShapes(*anIt,
419 theResultBody->loadModifiedShapes(*anIt,
425 theResultBody->loadModifiedShapes(*anIt,
427 GeomAPI_Shape::VERTEX,
428 "Translated_Vertex");