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_Edge.h>
30 #include <GeomAPI_Face.h>
31 #include <GeomAPI_Lin.h>
32 #include <GeomAPI_Pln.h>
33 #include <GeomAPI_ShapeIterator.h>
34 #include <GeomAPI_Trsf.h>
36 #include <ModelAPI_AttributeBoolean.h>
37 #include <ModelAPI_AttributeSelectionList.h>
38 #include <ModelAPI_AttributeString.h>
39 #include <ModelAPI_ResultBody.h>
40 #include <ModelAPI_ResultPart.h>
42 #include <FeaturesPlugin_Tools.h>
44 //=================================================================================================
45 FeaturesPlugin_Symmetry::FeaturesPlugin_Symmetry()
49 //=================================================================================================
50 void FeaturesPlugin_Symmetry::initAttributes()
52 data()->addAttribute(FeaturesPlugin_Symmetry::CREATION_METHOD(),
53 ModelAPI_AttributeString::typeId());
55 AttributeSelectionListPtr aSelection =
56 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
57 FeaturesPlugin_Symmetry::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
59 data()->addAttribute(FeaturesPlugin_Symmetry::POINT_OBJECT_ID(),
60 ModelAPI_AttributeSelection::typeId());
62 data()->addAttribute(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID(),
63 ModelAPI_AttributeSelection::typeId());
65 data()->addAttribute(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID(),
66 ModelAPI_AttributeSelection::typeId());
68 data()->addAttribute(FeaturesPlugin_Symmetry::KEEP_ORIGINAL_RESULT(),
69 ModelAPI_AttributeBoolean::typeId());
72 //=================================================================================================
73 void FeaturesPlugin_Symmetry::execute()
75 AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Symmetry::CREATION_METHOD());
76 std::string aMethodType = aMethodTypeAttr->value();
78 if (aMethodType == CREATION_METHOD_BY_POINT()) {
79 performSymmetryByPoint();
82 if (aMethodType == CREATION_METHOD_BY_AXIS()) {
83 performSymmetryByAxis();
86 if (aMethodType == CREATION_METHOD_BY_PLANE()) {
87 performSymmetryByPlane();
91 //=================================================================================================
92 bool FeaturesPlugin_Symmetry::collectSourceObjects(ListOfShape& theSourceShapes,
93 std::list<ResultPtr>& theSourceResults)
95 AttributeSelectionListPtr anObjectsSelList =
96 selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
97 if (anObjectsSelList->size() == 0) {
100 for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
101 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
102 anObjectsSelList->value(anObjectsIndex);
103 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
104 if (!anObject.get()) { // may be for not-activated parts
107 theSourceShapes.push_back(anObject);
108 theSourceResults.push_back(anObjectAttr->context());
113 //=================================================================================================
114 void FeaturesPlugin_Symmetry::performSymmetryByPoint()
117 ListOfShape anObjects;
118 std::list<ResultPtr> aContextes;
119 if (!collectSourceObjects(anObjects, aContextes))
123 std::shared_ptr<GeomAPI_Pnt> aPoint;
124 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
125 selection(FeaturesPlugin_Symmetry::POINT_OBJECT_ID());
126 if (anObjRef.get() != NULL) {
127 GeomShapePtr aShape1 = anObjRef->value();
128 if (!aShape1.get()) {
129 aShape1 = anObjRef->context()->shape();
132 aPoint = GeomAlgoAPI_PointBuilder::point(aShape1);
136 // Moving each object.
138 int aResultIndex = 0;
139 std::list<ResultPtr>::iterator aContext = aContextes.begin();
140 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
141 anObjectsIt++, aContext++) {
142 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
143 bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
147 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
148 aTrsf->setSymmetry(aPoint);
149 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
150 buildResult(anOrigin, aTrsf, aResultIndex);
153 std::shared_ptr<GeomAlgoAPI_Symmetry> aSymmetryAlgo(
154 new GeomAlgoAPI_Symmetry(aBaseShape, aPoint));
156 if (!aSymmetryAlgo->check()) {
157 setError(aSymmetryAlgo->getError());
161 aSymmetryAlgo->build();
163 // Checking that the algorithm worked properly.
164 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aSymmetryAlgo, getKind(), anError)) {
169 buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
174 // Remove the rest results if there were produced in the previous pass.
175 removeResults(aResultIndex);
178 //=================================================================================================
179 void FeaturesPlugin_Symmetry::performSymmetryByAxis()
182 ListOfShape anObjects;
183 std::list<ResultPtr> aContextes;
184 if (!collectSourceObjects(anObjects, aContextes))
188 static const std::string aSelectionError = "Error: The axis shape selection is bad.";
189 AttributeSelectionPtr anObjRef = selection(AXIS_OBJECT_ID());
190 GeomShapePtr aShape = anObjRef->value();
192 if (anObjRef->context().get()) {
193 aShape = anObjRef->context()->shape();
197 setError(aSelectionError);
202 if (aShape->isEdge())
204 anEdge = aShape->edge();
206 else if (aShape->isCompound())
208 GeomAPI_ShapeIterator anIt(aShape);
209 anEdge = anIt.current()->edge();
214 setError(aSelectionError);
218 std::shared_ptr<GeomAPI_Ax1> anAxis (new GeomAPI_Ax1(anEdge->line()->location(),
219 anEdge->line()->direction()));
222 // Moving each object.
224 int aResultIndex = 0;
225 std::list<ResultPtr>::iterator aContext = aContextes.begin();
226 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
227 anObjectsIt++, aContext++) {
228 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
229 bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
233 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
234 aTrsf->setSymmetry(anAxis);
235 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
236 buildResult(anOrigin, aTrsf, aResultIndex);
239 std::shared_ptr<GeomAlgoAPI_Symmetry> aSymmetryAlgo(
240 new GeomAlgoAPI_Symmetry(aBaseShape, anAxis));
242 if (!aSymmetryAlgo->check()) {
243 setError(aSymmetryAlgo->getError());
247 aSymmetryAlgo->build();
249 // Checking that the algorithm worked properly.
250 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aSymmetryAlgo, getKind(), anError)) {
255 buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
260 // Remove the rest results if there were produced in the previous pass.
261 removeResults(aResultIndex);
264 //=================================================================================================
265 void FeaturesPlugin_Symmetry::performSymmetryByPlane()
268 ListOfShape anObjects;
269 std::list<ResultPtr> aContextes;
270 if (!collectSourceObjects(anObjects, aContextes))
274 static const std::string aSelectionError = "Error: The plane shape selection is bad.";
275 AttributeSelectionPtr anObjRef = selection(PLANE_OBJECT_ID());
276 GeomShapePtr aShape = anObjRef->value();
278 if (anObjRef->context().get()) {
279 aShape = anObjRef->context()->shape();
283 setError(aSelectionError);
288 if (aShape->isFace())
290 aFace = aShape->face();
292 else if (aShape->isCompound())
294 GeomAPI_ShapeIterator anIt(aShape);
295 aFace = anIt.current()->face();
300 setError(aSelectionError);
304 std::shared_ptr<GeomAPI_Ax2> aPlane(new GeomAPI_Ax2(aFace->getPlane()->location(),
305 aFace->getPlane()->direction()));
308 // Moving each object.
310 int aResultIndex = 0;
311 std::list<ResultPtr>::iterator aContext = aContextes.begin();
312 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
313 anObjectsIt++, aContext++) {
314 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
315 bool isPart = aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group();
319 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
320 aTrsf->setSymmetry(aPlane);
321 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
322 buildResult(anOrigin, aTrsf, aResultIndex);
324 std::shared_ptr<GeomAlgoAPI_Symmetry> aSymmetryAlgo(
325 new GeomAlgoAPI_Symmetry(aBaseShape, aPlane));
327 if (!aSymmetryAlgo->check()) {
328 setError(aSymmetryAlgo->getError());
332 aSymmetryAlgo->build();
334 // Checking that the algorithm worked properly.
335 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aSymmetryAlgo, getKind(), anError)) {
340 buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
345 // Remove the rest results if there were produced in the previous pass.
346 removeResults(aResultIndex);
349 //=================================================================================================
350 void FeaturesPlugin_Symmetry::buildResult(
351 std::shared_ptr<GeomAlgoAPI_Symmetry>& theSymmetryAlgo,
352 std::shared_ptr<GeomAPI_Shape> theBaseShape, int theResultIndex)
354 std::shared_ptr<GeomAlgoAPI_MakeShapeList> anAlgoList(new GeomAlgoAPI_MakeShapeList());
355 anAlgoList->appendAlgo(theSymmetryAlgo);
356 // Compose source shape and the result of symmetry.
357 GeomShapePtr aCompound;
358 if (boolean(KEEP_ORIGINAL_RESULT())->value()) {
360 // add a copy of a base shape otherwise selection of this base shape is bad (2592)
361 std::shared_ptr<GeomAlgoAPI_Copy> aCopyAlgo(new GeomAlgoAPI_Copy(theBaseShape));
362 aShapes.push_back(aCopyAlgo->shape());
363 anAlgoList->appendAlgo(aCopyAlgo);
365 aShapes.push_back(theSymmetryAlgo->shape());
366 aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
368 aCompound = theSymmetryAlgo->shape();
370 // Store and name the result.
371 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
373 ListOfShape aBaseShapes;
374 aBaseShapes.push_back(theBaseShape);
375 FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
376 anAlgoList, aCompound, "Symmetried");
378 setResult(aResultBody, theResultIndex);
381 //=================================================================================================
382 void FeaturesPlugin_Symmetry::buildResult(ResultPartPtr theOriginal,
383 std::shared_ptr<GeomAPI_Trsf> theTrsf,
386 if (boolean(KEEP_ORIGINAL_RESULT())->value()) {
387 std::shared_ptr<GeomAPI_Trsf> anIdentity(new GeomAPI_Trsf());
388 ResultPartPtr aCopy = document()->copyPart(theOriginal, data(), theResultIndex);
389 aCopy->setTrsf(theOriginal, anIdentity);
390 setResult(aCopy, theResultIndex);
394 ResultPartPtr aResultPart = document()->copyPart(theOriginal, data(), theResultIndex);
395 aResultPart->setTrsf(theOriginal, theTrsf);
396 setResult(aResultPart, theResultIndex);