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_Symmetry.h>
23 #include <GeomAlgoAPI_CompoundBuilder.h>
24 #include <GeomAlgoAPI_PointBuilder.h>
25 #include <GeomAlgoAPI_FaceBuilder.h>
27 #include <GeomAPI_Edge.h>
28 #include <GeomAPI_Face.h>
29 #include <GeomAPI_Lin.h>
30 #include <GeomAPI_Pln.h>
31 #include <GeomAPI_Trsf.h>
33 #include <ModelAPI_AttributeSelectionList.h>
34 #include <ModelAPI_AttributeString.h>
35 #include <ModelAPI_ResultBody.h>
36 #include <ModelAPI_ResultPart.h>
38 #include <FeaturesPlugin_Tools.h>
40 //=================================================================================================
41 FeaturesPlugin_Symmetry::FeaturesPlugin_Symmetry()
45 //=================================================================================================
46 void FeaturesPlugin_Symmetry::initAttributes()
48 data()->addAttribute(FeaturesPlugin_Symmetry::CREATION_METHOD(),
49 ModelAPI_AttributeString::typeId());
51 AttributeSelectionListPtr aSelection =
52 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
53 FeaturesPlugin_Symmetry::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
55 data()->addAttribute(FeaturesPlugin_Symmetry::POINT_OBJECT_ID(),
56 ModelAPI_AttributeSelection::typeId());
58 data()->addAttribute(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID(),
59 ModelAPI_AttributeSelection::typeId());
61 data()->addAttribute(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID(),
62 ModelAPI_AttributeSelection::typeId());
65 //=================================================================================================
66 void FeaturesPlugin_Symmetry::execute()
68 AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Symmetry::CREATION_METHOD());
69 std::string aMethodType = aMethodTypeAttr->value();
71 if (aMethodType == CREATION_METHOD_BY_POINT()) {
72 performSymmetryByPoint();
75 if (aMethodType == CREATION_METHOD_BY_AXIS()) {
76 performSymmetryByAxis();
79 if (aMethodType == CREATION_METHOD_BY_PLANE()) {
80 performSymmetryByPlane();
84 //=================================================================================================
85 bool FeaturesPlugin_Symmetry::collectSourceObjects(ListOfShape& theSourceShapes,
86 std::list<ResultPtr>& theSourceResults)
88 AttributeSelectionListPtr anObjectsSelList =
89 selectionList(FeaturesPlugin_Symmetry::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
101 theSourceShapes.push_back(anObject);
102 theSourceResults.push_back(anObjectAttr->context());
107 //=================================================================================================
108 void FeaturesPlugin_Symmetry::performSymmetryByPoint()
111 ListOfShape anObjects;
112 std::list<ResultPtr> aContextes;
113 if (!collectSourceObjects(anObjects, aContextes))
117 std::shared_ptr<GeomAPI_Pnt> aPoint;
118 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
119 selection(FeaturesPlugin_Symmetry::POINT_OBJECT_ID());
120 if (anObjRef.get() != NULL) {
121 GeomShapePtr aShape1 = anObjRef->value();
122 if (!aShape1.get()) {
123 aShape1 = anObjRef->context()->shape();
126 aPoint = GeomAlgoAPI_PointBuilder::point(aShape1);
130 // Moving each object.
131 int aResultIndex = 0;
132 std::list<ResultPtr>::iterator aContext = aContextes.begin();
133 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
134 anObjectsIt++, aContext++) {
135 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
136 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
140 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
141 aTrsf->setSymmetry(aPoint);
142 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
143 buildResult(anOrigin, aTrsf, aResultIndex);
146 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, aPoint);
148 if (!aSymmetryAlgo.check()) {
149 setError(aSymmetryAlgo.getError());
153 aSymmetryAlgo.build();
155 // Checking that the algorithm worked properly.
156 if(!aSymmetryAlgo.isDone()) {
157 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
158 setError(aFeatureError);
161 if(aSymmetryAlgo.shape()->isNull()) {
162 static const std::string aShapeError = "Error: Resulting shape is Null.";
163 setError(aShapeError);
166 if(!aSymmetryAlgo.isValid()) {
167 std::string aFeatureError = "Error: Resulting shape is not valid.";
168 setError(aFeatureError);
172 buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
177 // Remove the rest results if there were produced in the previous pass.
178 removeResults(aResultIndex);
181 //=================================================================================================
182 void FeaturesPlugin_Symmetry::performSymmetryByAxis()
185 ListOfShape anObjects;
186 std::list<ResultPtr> aContextes;
187 if (!collectSourceObjects(anObjects, aContextes))
191 std::shared_ptr<GeomAPI_Ax1> anAxis;
192 std::shared_ptr<GeomAPI_Edge> anEdge;
193 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
194 selection(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID());
195 if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
196 anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
197 } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
198 anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
199 anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
202 anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
203 anEdge->line()->direction()));
206 // Moving each object.
207 int aResultIndex = 0;
208 std::list<ResultPtr>::iterator aContext = aContextes.begin();
209 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
210 anObjectsIt++, aContext++) {
211 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
212 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
216 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
217 aTrsf->setSymmetry(anAxis);
218 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
219 buildResult(anOrigin, aTrsf, aResultIndex);
222 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, anAxis);
224 if (!aSymmetryAlgo.check()) {
225 setError(aSymmetryAlgo.getError());
229 aSymmetryAlgo.build();
231 // Checking that the algorithm worked properly.
232 if(!aSymmetryAlgo.isDone()) {
233 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
234 setError(aFeatureError);
237 if(aSymmetryAlgo.shape()->isNull()) {
238 static const std::string aShapeError = "Error: Resulting shape is Null.";
239 setError(aShapeError);
242 if(!aSymmetryAlgo.isValid()) {
243 std::string aFeatureError = "Error: Resulting shape is not valid.";
244 setError(aFeatureError);
248 buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
253 // Remove the rest results if there were produced in the previous pass.
254 removeResults(aResultIndex);
257 //=================================================================================================
258 void FeaturesPlugin_Symmetry::performSymmetryByPlane()
261 ListOfShape anObjects;
262 std::list<ResultPtr> aContextes;
263 if (!collectSourceObjects(anObjects, aContextes))
267 std::shared_ptr<GeomAPI_Ax2> aPlane;
268 std::shared_ptr<GeomAPI_Pln> aPln;
269 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
270 selection(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID());
271 if (anObjRef && anObjRef->value() && anObjRef->value()->isFace()) {
272 aPln = std::shared_ptr<GeomAPI_Face>(new GeomAPI_Face(anObjRef->value()))->getPlane();
274 else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
275 anObjRef->context()->shape() && anObjRef->context()->shape()->isFace()) {
277 std::shared_ptr<GeomAPI_Face>(new GeomAPI_Face(anObjRef->context()->shape()))->getPlane();
280 aPlane = std::shared_ptr<GeomAPI_Ax2>(new GeomAPI_Ax2(aPln->location(),
284 // Moving each object.
285 int aResultIndex = 0;
286 std::list<ResultPtr>::iterator aContext = aContextes.begin();
287 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
288 anObjectsIt++, aContext++) {
289 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
290 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
294 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
295 aTrsf->setSymmetry(aPlane);
296 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
297 buildResult(anOrigin, aTrsf, aResultIndex);
299 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, aPlane);
301 if (!aSymmetryAlgo.check()) {
302 setError(aSymmetryAlgo.getError());
306 aSymmetryAlgo.build();
308 // Checking that the algorithm worked properly.
309 if(!aSymmetryAlgo.isDone()) {
310 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
311 setError(aFeatureError);
314 if(aSymmetryAlgo.shape()->isNull()) {
315 static const std::string aShapeError = "Error: Resulting shape is Null.";
316 setError(aShapeError);
319 if(!aSymmetryAlgo.isValid()) {
320 std::string aFeatureError = "Error: Resulting shape is not valid.";
321 setError(aFeatureError);
325 buildResult(aSymmetryAlgo, aBaseShape, aResultIndex);
330 // Remove the rest results if there were produced in the previous pass.
331 removeResults(aResultIndex);
334 //=================================================================================================
335 void FeaturesPlugin_Symmetry::buildResult(GeomAlgoAPI_Symmetry& theSymmetryAlgo,
336 std::shared_ptr<GeomAPI_Shape> theBaseShape,
339 // Compose source shape and the result of symmetry.
341 aShapes.push_back(theBaseShape);
342 aShapes.push_back(theSymmetryAlgo.shape());
343 std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
345 // Store and name the result.
346 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
347 aResultBody->storeModified(theBaseShape, aCompound);
348 loadNamingDS(theSymmetryAlgo, aResultBody, theBaseShape);
349 setResult(aResultBody, theResultIndex);
352 //=================================================================================================
353 void FeaturesPlugin_Symmetry::buildResult(ResultPartPtr theOriginal,
354 std::shared_ptr<GeomAPI_Trsf> theTrsf,
357 std::shared_ptr<GeomAPI_Trsf> anIdentity(new GeomAPI_Trsf());
358 ResultPartPtr aCopy = document()->copyPart(theOriginal, data(), theResultIndex);
359 aCopy->setTrsf(theOriginal, anIdentity);
360 setResult(aCopy, theResultIndex);
364 ResultPartPtr aResultPart = document()->copyPart(theOriginal, data(), theResultIndex);
365 aResultPart->setTrsf(theOriginal, theTrsf);
366 setResult(aResultPart, theResultIndex);
369 //=================================================================================================
370 void FeaturesPlugin_Symmetry::loadNamingDS(GeomAlgoAPI_Symmetry& theSymmetryAlgo,
371 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
372 std::shared_ptr<GeomAPI_Shape> theBaseShape)
375 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theSymmetryAlgo.mapOfSubShapes();
376 std::string aReflectedName = "Symmetried";
377 FeaturesPlugin_Tools::storeModifiedShapes(theSymmetryAlgo, theResultBody,
378 theBaseShape, 1, 2, 3, aReflectedName,