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_Symmetry.h>
22 #include <GeomAlgoAPI_CompoundBuilder.h>
23 #include <GeomAlgoAPI_PointBuilder.h>
24 #include <GeomAlgoAPI_FaceBuilder.h>
25 #include <GeomAlgoAPI_Copy.h>
26 #include <GeomAlgoAPI_MakeShapeList.h>
27 #include <GeomAlgoAPI_Tools.h>
29 #include <GeomAPI_Ax1.h>
30 #include <GeomAPI_Ax2.h>
31 #include <GeomAPI_Edge.h>
32 #include <GeomAPI_Face.h>
33 #include <GeomAPI_Lin.h>
34 #include <GeomAPI_Pln.h>
35 #include <GeomAPI_ShapeIterator.h>
36 #include <GeomAPI_Trsf.h>
38 #include <ModelAPI_AttributeBoolean.h>
39 #include <ModelAPI_AttributeSelectionList.h>
40 #include <ModelAPI_AttributeString.h>
41 #include <ModelAPI_ResultBody.h>
42 #include <ModelAPI_ResultPart.h>
44 #include <FeaturesPlugin_Tools.h>
46 //=================================================================================================
47 FeaturesPlugin_Symmetry::FeaturesPlugin_Symmetry()
51 //=================================================================================================
52 void FeaturesPlugin_Symmetry::initAttributes()
54 data()->addAttribute(FeaturesPlugin_Symmetry::CREATION_METHOD(),
55 ModelAPI_AttributeString::typeId());
57 AttributeSelectionListPtr aSelection =
58 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
59 FeaturesPlugin_Symmetry::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
61 data()->addAttribute(FeaturesPlugin_Symmetry::POINT_OBJECT_ID(),
62 ModelAPI_AttributeSelection::typeId());
64 data()->addAttribute(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID(),
65 ModelAPI_AttributeSelection::typeId());
67 data()->addAttribute(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID(),
68 ModelAPI_AttributeSelection::typeId());
70 data()->addAttribute(FeaturesPlugin_Symmetry::KEEP_ORIGINAL_RESULT(),
71 ModelAPI_AttributeBoolean::typeId());
74 //=================================================================================================
75 void FeaturesPlugin_Symmetry::execute()
77 AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Symmetry::CREATION_METHOD());
78 std::string aMethodType = aMethodTypeAttr->value();
80 if (aMethodType == CREATION_METHOD_BY_POINT()) {
81 performSymmetryByPoint();
84 if (aMethodType == CREATION_METHOD_BY_AXIS()) {
85 performSymmetryByAxis();
88 if (aMethodType == CREATION_METHOD_BY_PLANE()) {
89 performSymmetryByPlane();
93 //=================================================================================================
94 bool FeaturesPlugin_Symmetry::collectSourceObjects(ListOfShape& theSourceShapes,
95 std::list<ResultPtr>& theSourceResults)
97 AttributeSelectionListPtr anObjectsSelList =
98 selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
99 if (anObjectsSelList->size() == 0) {
102 for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
103 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
104 anObjectsSelList->value(anObjectsIndex);
105 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
106 if (!anObject.get()) { // may be for not-activated parts
109 theSourceShapes.push_back(anObject);
110 theSourceResults.push_back(anObjectAttr->context());
115 //=================================================================================================
116 void FeaturesPlugin_Symmetry::performSymmetryByPoint()
119 ListOfShape anObjects;
120 std::list<ResultPtr> aContextes;
121 if (!collectSourceObjects(anObjects, aContextes))
125 std::shared_ptr<GeomAPI_Pnt> aPoint;
126 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
127 selection(FeaturesPlugin_Symmetry::POINT_OBJECT_ID());
128 if (anObjRef.get() != NULL) {
129 GeomShapePtr aShape1 = anObjRef->value();
130 if (!aShape1.get()) {
131 aShape1 = anObjRef->context()->shape();
134 aPoint = GeomAlgoAPI_PointBuilder::point(aShape1);
138 // Moving each object.
140 int aResultIndex = 0;
141 std::list<ResultPtr>::iterator aContext = aContextes.begin();
142 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
143 anObjectsIt++, aContext++) {
144 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
145 bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
149 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
150 aTrsf->setSymmetry(aPoint);
151 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
152 buildResult(anOrigin, aTrsf, aResultIndex);
155 std::shared_ptr<GeomAlgoAPI_Symmetry> aSymmetryAlgo(
156 new GeomAlgoAPI_Symmetry(aBaseShape, aPoint));
158 // Checking that the algorithm worked properly.
159 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aSymmetryAlgo, getKind(), anError)) {
164 buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
169 // Remove the rest results if there were produced in the previous pass.
170 removeResults(aResultIndex);
173 //=================================================================================================
174 void FeaturesPlugin_Symmetry::performSymmetryByAxis()
177 ListOfShape anObjects;
178 std::list<ResultPtr> aContextes;
179 if (!collectSourceObjects(anObjects, aContextes))
183 static const std::string aSelectionError = "Error: The axis shape selection is bad.";
184 AttributeSelectionPtr anObjRef = selection(AXIS_OBJECT_ID());
185 GeomShapePtr aShape = anObjRef->value();
187 if (anObjRef->context().get()) {
188 aShape = anObjRef->context()->shape();
192 setError(aSelectionError);
197 if (aShape->isEdge())
199 anEdge = aShape->edge();
201 else if (aShape->isCompound())
203 GeomAPI_ShapeIterator anIt(aShape);
204 anEdge = anIt.current()->edge();
209 setError(aSelectionError);
213 std::shared_ptr<GeomAPI_Ax1> anAxis (new GeomAPI_Ax1(anEdge->line()->location(),
214 anEdge->line()->direction()));
217 // Moving each object.
219 int aResultIndex = 0;
220 std::list<ResultPtr>::iterator aContext = aContextes.begin();
221 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
222 anObjectsIt++, aContext++) {
223 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
224 bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
228 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
229 aTrsf->setSymmetry(anAxis);
230 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
231 buildResult(anOrigin, aTrsf, aResultIndex);
234 std::shared_ptr<GeomAlgoAPI_Symmetry> aSymmetryAlgo(
235 new GeomAlgoAPI_Symmetry(aBaseShape, anAxis));
237 // Checking that the algorithm worked properly.
238 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aSymmetryAlgo, getKind(), anError)) {
243 buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
248 // Remove the rest results if there were produced in the previous pass.
249 removeResults(aResultIndex);
252 //=================================================================================================
253 void FeaturesPlugin_Symmetry::performSymmetryByPlane()
256 ListOfShape anObjects;
257 std::list<ResultPtr> aContextes;
258 if (!collectSourceObjects(anObjects, aContextes))
262 static const std::string aSelectionError = "Error: The plane shape selection is bad.";
263 AttributeSelectionPtr anObjRef = selection(PLANE_OBJECT_ID());
264 GeomShapePtr aShape = anObjRef->value();
266 if (anObjRef->context().get()) {
267 aShape = anObjRef->context()->shape();
271 setError(aSelectionError);
276 if (aShape->isFace())
278 aFace = aShape->face();
280 else if (aShape->isCompound())
282 GeomAPI_ShapeIterator anIt(aShape);
283 aFace = anIt.current()->face();
288 setError(aSelectionError);
292 std::shared_ptr<GeomAPI_Ax2> aPlane(new GeomAPI_Ax2(aFace->getPlane()->location(),
293 aFace->getPlane()->direction()));
296 // Moving each object.
298 int aResultIndex = 0;
299 std::list<ResultPtr>::iterator aContext = aContextes.begin();
300 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
301 anObjectsIt++, aContext++) {
302 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
303 bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
307 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
308 aTrsf->setSymmetry(aPlane);
309 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
310 buildResult(anOrigin, aTrsf, aResultIndex);
312 std::shared_ptr<GeomAlgoAPI_Symmetry> aSymmetryAlgo(
313 new GeomAlgoAPI_Symmetry(aBaseShape, aPlane));
315 // Checking that the algorithm worked properly.
316 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aSymmetryAlgo, getKind(), anError)) {
321 buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
326 // Remove the rest results if there were produced in the previous pass.
327 removeResults(aResultIndex);
330 //=================================================================================================
331 void FeaturesPlugin_Symmetry::buildResult(
332 std::shared_ptr<GeomAlgoAPI_Symmetry>& theSymmetryAlgo,
333 std::shared_ptr<GeomAPI_Shape> theBaseShape, int theResultIndex)
335 std::shared_ptr<GeomAlgoAPI_MakeShapeList> anAlgoList(new GeomAlgoAPI_MakeShapeList());
336 anAlgoList->appendAlgo(theSymmetryAlgo);
337 // Compose source shape and the result of symmetry.
338 GeomShapePtr aCompound;
339 if (boolean(KEEP_ORIGINAL_RESULT())->value()) {
341 // add a copy of a base shape otherwise selection of this base shape is bad (2592)
342 std::shared_ptr<GeomAlgoAPI_Copy> aCopyAlgo(new GeomAlgoAPI_Copy(theBaseShape));
343 aShapes.push_back(aCopyAlgo->shape());
344 anAlgoList->appendAlgo(aCopyAlgo);
346 aShapes.push_back(theSymmetryAlgo->shape());
347 aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
349 aCompound = theSymmetryAlgo->shape();
351 // Store and name the result.
352 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
354 ListOfShape aBaseShapes;
355 aBaseShapes.push_back(theBaseShape);
356 FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
357 anAlgoList, aCompound, "Symmetried");
359 setResult(aResultBody, theResultIndex);
362 //=================================================================================================
363 void FeaturesPlugin_Symmetry::buildResult(ResultPartPtr theOriginal,
364 std::shared_ptr<GeomAPI_Trsf> theTrsf,
367 if (boolean(KEEP_ORIGINAL_RESULT())->value()) {
368 std::shared_ptr<GeomAPI_Trsf> anIdentity(new GeomAPI_Trsf());
369 ResultPartPtr aCopy = document()->copyPart(theOriginal, data(), theResultIndex);
370 aCopy->setTrsf(theOriginal, anIdentity);
371 setResult(aCopy, theResultIndex);
375 ResultPartPtr aResultPart = document()->copyPart(theOriginal, data(), theResultIndex);
376 aResultPart->setTrsf(theOriginal, theTrsf);
377 setResult(aResultPart, theResultIndex);