1 // Copyright (C) 2014-2016 CEA/DEN, EDF R&D
3 // File: FeaturesPlugin_Symmetry.cpp
4 // Created: 30 Nov 2016
5 // Author: Clarisse Genrault (CEA)
7 #include <FeaturesPlugin_Symmetry.h>
9 #include <ModelAPI_AttributeSelectionList.h>
10 #include <ModelAPI_AttributeString.h>
11 #include <ModelAPI_ResultBody.h>
13 #include <GeomAPI_Edge.h>
14 #include <GeomAPI_Face.h>
15 #include <GeomAPI_Lin.h>
16 #include <GeomAPI_Pln.h>
18 #include <GeomAlgoAPI_PointBuilder.h>
20 #include <ModelAPI_ResultPart.h>
22 //=================================================================================================
23 FeaturesPlugin_Symmetry::FeaturesPlugin_Symmetry()
27 //=================================================================================================
28 void FeaturesPlugin_Symmetry::initAttributes()
30 data()->addAttribute(FeaturesPlugin_Symmetry::CREATION_METHOD(),
31 ModelAPI_AttributeString::typeId());
33 AttributeSelectionListPtr aSelection =
34 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
35 FeaturesPlugin_Symmetry::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
37 data()->addAttribute(FeaturesPlugin_Symmetry::POINT_OBJECT_ID(),
38 ModelAPI_AttributeSelection::typeId());
40 data()->addAttribute(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID(),
41 ModelAPI_AttributeSelection::typeId());
43 data()->addAttribute(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID(),
44 ModelAPI_AttributeSelection::typeId());
47 //=================================================================================================
48 void FeaturesPlugin_Symmetry::execute()
50 AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Symmetry::CREATION_METHOD());
51 std::string aMethodType = aMethodTypeAttr->value();
53 if (aMethodType == CREATION_METHOD_BY_POINT()) {
54 performSymmetryByPoint();
57 if (aMethodType == CREATION_METHOD_BY_AXIS()) {
58 performSymmetryByAxis();
61 if (aMethodType == CREATION_METHOD_BY_PLANE()) {
62 performSymmetryByPlane();
66 //=================================================================================================
67 void FeaturesPlugin_Symmetry::performSymmetryByPoint()
70 ListOfShape anObjects;
71 std::list<ResultPtr> aContextes;
72 AttributeSelectionListPtr anObjectsSelList =
73 selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
74 if (anObjectsSelList->size() == 0) {
77 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
78 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
79 anObjectsSelList->value(anObjectsIndex);
80 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
81 if(!anObject.get()) { // may be for not-activated parts
85 anObjects.push_back(anObject);
86 aContextes.push_back(anObjectAttr->context());
90 std::shared_ptr<GeomAPI_Pnt> aPoint;
91 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
92 selection(FeaturesPlugin_Symmetry::POINT_OBJECT_ID());
93 if (anObjRef.get() != NULL) {
94 GeomShapePtr aShape1 = anObjRef->value();
96 aShape1 = anObjRef->context()->shape();
99 aPoint = GeomAlgoAPI_PointBuilder::point(aShape1);
103 // Moving each object.
104 int aResultIndex = 0;
105 std::list<ResultPtr>::iterator aContext = aContextes.begin();
106 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
107 anObjectsIt++, aContext++) {
108 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
109 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
113 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
114 aTrsf->setSymmetry(aPoint);
115 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
116 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
117 aResultPart->setTrsf(*aContext, aTrsf);
118 setResult(aResultPart, aResultIndex);
120 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, aPoint);
122 if (!aSymmetryAlgo.check()) {
123 setError(aSymmetryAlgo.getError());
127 aSymmetryAlgo.build();
129 // Checking that the algorithm worked properly.
130 if(!aSymmetryAlgo.isDone()) {
131 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
132 setError(aFeatureError);
135 if(aSymmetryAlgo.shape()->isNull()) {
136 static const std::string aShapeError = "Error: Resulting shape is Null.";
137 setError(aShapeError);
140 if(!aSymmetryAlgo.isValid()) {
141 std::string aFeatureError = "Error: Resulting shape is not valid.";
142 setError(aFeatureError);
146 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
147 loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
148 setResult(aResultBody, aResultIndex);
153 // Remove the rest results if there were produced in the previous pass.
154 removeResults(aResultIndex);
157 //=================================================================================================
158 void FeaturesPlugin_Symmetry::performSymmetryByAxis()
161 ListOfShape anObjects;
162 std::list<ResultPtr> aContextes;
163 AttributeSelectionListPtr anObjectsSelList =
164 selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
165 if (anObjectsSelList->size() == 0) {
168 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
169 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
170 anObjectsSelList->value(anObjectsIndex);
171 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
172 if(!anObject.get()) { // may be for not-activated parts
176 anObjects.push_back(anObject);
177 aContextes.push_back(anObjectAttr->context());
181 std::shared_ptr<GeomAPI_Ax1> anAxis;
182 std::shared_ptr<GeomAPI_Edge> anEdge;
183 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
184 selection(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID());
185 if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
186 anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
187 } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
188 anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
189 anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
192 anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
193 anEdge->line()->direction()));
196 // Moving each object.
197 int aResultIndex = 0;
198 std::list<ResultPtr>::iterator aContext = aContextes.begin();
199 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
200 anObjectsIt++, aContext++) {
201 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
202 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
206 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
207 aTrsf->setSymmetry(anAxis);
208 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
209 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
210 aResultPart->setTrsf(*aContext, aTrsf);
211 setResult(aResultPart, aResultIndex);
213 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, anAxis);
215 if (!aSymmetryAlgo.check()) {
216 setError(aSymmetryAlgo.getError());
220 aSymmetryAlgo.build();
222 // Checking that the algorithm worked properly.
223 if(!aSymmetryAlgo.isDone()) {
224 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
225 setError(aFeatureError);
228 if(aSymmetryAlgo.shape()->isNull()) {
229 static const std::string aShapeError = "Error: Resulting shape is Null.";
230 setError(aShapeError);
233 if(!aSymmetryAlgo.isValid()) {
234 std::string aFeatureError = "Error: Resulting shape is not valid.";
235 setError(aFeatureError);
239 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
240 loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
241 setResult(aResultBody, aResultIndex);
246 // Remove the rest results if there were produced in the previous pass.
247 removeResults(aResultIndex);
250 //=================================================================================================
251 void FeaturesPlugin_Symmetry::performSymmetryByPlane()
254 ListOfShape anObjects;
255 std::list<ResultPtr> aContextes;
256 AttributeSelectionListPtr anObjectsSelList =
257 selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
258 if (anObjectsSelList->size() == 0) {
261 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
262 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
263 anObjectsSelList->value(anObjectsIndex);
264 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
265 if(!anObject.get()) { // may be for not-activated parts
269 anObjects.push_back(anObject);
270 aContextes.push_back(anObjectAttr->context());
274 std::shared_ptr<GeomAPI_Ax2> aPlane;
275 std::shared_ptr<GeomAPI_Pln> aPln;
276 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
277 selection(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID());
278 if(anObjRef && anObjRef->value() && anObjRef->value()->isFace()) {
279 aPln = std::shared_ptr<GeomAPI_Face>(new GeomAPI_Face(anObjRef->value()))->getPlane();
281 else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
282 anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
284 std::shared_ptr<GeomAPI_Face>(new GeomAPI_Face(anObjRef->context()->shape()))->getPlane();
287 aPlane = std::shared_ptr<GeomAPI_Ax2>(new GeomAPI_Ax2(aPln->location(),
291 // Moving each object.
292 int aResultIndex = 0;
293 std::list<ResultPtr>::iterator aContext = aContextes.begin();
294 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
295 anObjectsIt++, aContext++) {
296 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
297 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
301 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
302 aTrsf->setSymmetry(aPlane);
303 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
304 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
305 aResultPart->setTrsf(*aContext, aTrsf);
306 setResult(aResultPart, aResultIndex);
308 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, aPlane);
310 if (!aSymmetryAlgo.check()) {
311 setError(aSymmetryAlgo.getError());
315 aSymmetryAlgo.build();
317 // Checking that the algorithm worked properly.
318 if(!aSymmetryAlgo.isDone()) {
319 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
320 setError(aFeatureError);
323 if(aSymmetryAlgo.shape()->isNull()) {
324 static const std::string aShapeError = "Error: Resulting shape is Null.";
325 setError(aShapeError);
328 if(!aSymmetryAlgo.isValid()) {
329 std::string aFeatureError = "Error: Resulting shape is not valid.";
330 setError(aFeatureError);
334 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
335 loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
336 setResult(aResultBody, aResultIndex);
341 // Remove the rest results if there were produced in the previous pass.
342 removeResults(aResultIndex);
345 //=================================================================================================
346 void FeaturesPlugin_Symmetry::loadNamingDS(GeomAlgoAPI_Symmetry& theSymmetryAlgo,
347 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
348 std::shared_ptr<GeomAPI_Shape> theBaseShape)
350 // Store and name the result.
351 theResultBody->storeModified(theBaseShape, theSymmetryAlgo.shape());
354 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theSymmetryAlgo.mapOfSubShapes();
355 int aReflectedTag = 1;
356 std::string aReflectedName = "Symmetried";
357 theResultBody->loadAndOrientModifiedShapes(&theSymmetryAlgo,
358 theBaseShape, GeomAPI_Shape::FACE,
359 aReflectedTag, aReflectedName, *aSubShapes.get());