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 <GeomAlgoAPI_PointBuilder.h>
11 #include <GeomAPI_Edge.h>
12 #include <GeomAPI_Face.h>
13 #include <GeomAPI_Lin.h>
14 #include <GeomAPI_Pln.h>
16 #include <ModelAPI_AttributeSelectionList.h>
17 #include <ModelAPI_AttributeString.h>
18 #include <ModelAPI_ResultBody.h>
19 #include <ModelAPI_ResultPart.h>
21 //=================================================================================================
22 FeaturesPlugin_Symmetry::FeaturesPlugin_Symmetry()
26 //=================================================================================================
27 void FeaturesPlugin_Symmetry::initAttributes()
29 data()->addAttribute(FeaturesPlugin_Symmetry::CREATION_METHOD(),
30 ModelAPI_AttributeString::typeId());
32 AttributeSelectionListPtr aSelection =
33 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
34 FeaturesPlugin_Symmetry::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
36 data()->addAttribute(FeaturesPlugin_Symmetry::POINT_OBJECT_ID(),
37 ModelAPI_AttributeSelection::typeId());
39 data()->addAttribute(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID(),
40 ModelAPI_AttributeSelection::typeId());
42 data()->addAttribute(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID(),
43 ModelAPI_AttributeSelection::typeId());
46 //=================================================================================================
47 void FeaturesPlugin_Symmetry::execute()
49 AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Symmetry::CREATION_METHOD());
50 std::string aMethodType = aMethodTypeAttr->value();
52 if (aMethodType == CREATION_METHOD_BY_POINT()) {
53 performSymmetryByPoint();
56 if (aMethodType == CREATION_METHOD_BY_AXIS()) {
57 performSymmetryByAxis();
60 if (aMethodType == CREATION_METHOD_BY_PLANE()) {
61 performSymmetryByPlane();
65 //=================================================================================================
66 void FeaturesPlugin_Symmetry::performSymmetryByPoint()
69 ListOfShape anObjects;
70 std::list<ResultPtr> aContextes;
71 AttributeSelectionListPtr anObjectsSelList =
72 selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
73 if (anObjectsSelList->size() == 0) {
76 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
77 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
78 anObjectsSelList->value(anObjectsIndex);
79 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
80 if(!anObject.get()) { // may be for not-activated parts
84 anObjects.push_back(anObject);
85 aContextes.push_back(anObjectAttr->context());
89 std::shared_ptr<GeomAPI_Pnt> aPoint;
90 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
91 selection(FeaturesPlugin_Symmetry::POINT_OBJECT_ID());
92 if (anObjRef.get() != NULL) {
93 GeomShapePtr aShape1 = anObjRef->value();
95 aShape1 = anObjRef->context()->shape();
98 aPoint = GeomAlgoAPI_PointBuilder::point(aShape1);
102 // Moving each object.
103 int aResultIndex = 0;
104 std::list<ResultPtr>::iterator aContext = aContextes.begin();
105 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
106 anObjectsIt++, aContext++) {
107 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
108 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
112 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
113 aTrsf->setSymmetry(aPoint);
114 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
115 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
116 aResultPart->setTrsf(*aContext, aTrsf);
117 setResult(aResultPart, aResultIndex);
119 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, aPoint);
121 if (!aSymmetryAlgo.check()) {
122 setError(aSymmetryAlgo.getError());
126 aSymmetryAlgo.build();
128 // Checking that the algorithm worked properly.
129 if(!aSymmetryAlgo.isDone()) {
130 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
131 setError(aFeatureError);
134 if(aSymmetryAlgo.shape()->isNull()) {
135 static const std::string aShapeError = "Error: Resulting shape is Null.";
136 setError(aShapeError);
139 if(!aSymmetryAlgo.isValid()) {
140 std::string aFeatureError = "Error: Resulting shape is not valid.";
141 setError(aFeatureError);
145 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
146 loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
147 setResult(aResultBody, aResultIndex);
152 // Remove the rest results if there were produced in the previous pass.
153 removeResults(aResultIndex);
156 //=================================================================================================
157 void FeaturesPlugin_Symmetry::performSymmetryByAxis()
160 ListOfShape anObjects;
161 std::list<ResultPtr> aContextes;
162 AttributeSelectionListPtr anObjectsSelList =
163 selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
164 if (anObjectsSelList->size() == 0) {
167 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
168 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
169 anObjectsSelList->value(anObjectsIndex);
170 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
171 if(!anObject.get()) { // may be for not-activated parts
175 anObjects.push_back(anObject);
176 aContextes.push_back(anObjectAttr->context());
180 std::shared_ptr<GeomAPI_Ax1> anAxis;
181 std::shared_ptr<GeomAPI_Edge> anEdge;
182 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
183 selection(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID());
184 if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
185 anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
186 } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
187 anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
188 anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
191 anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
192 anEdge->line()->direction()));
195 // Moving each object.
196 int aResultIndex = 0;
197 std::list<ResultPtr>::iterator aContext = aContextes.begin();
198 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
199 anObjectsIt++, aContext++) {
200 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
201 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
205 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
206 aTrsf->setSymmetry(anAxis);
207 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
208 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
209 aResultPart->setTrsf(*aContext, aTrsf);
210 setResult(aResultPart, aResultIndex);
212 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, anAxis);
214 if (!aSymmetryAlgo.check()) {
215 setError(aSymmetryAlgo.getError());
219 aSymmetryAlgo.build();
221 // Checking that the algorithm worked properly.
222 if(!aSymmetryAlgo.isDone()) {
223 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
224 setError(aFeatureError);
227 if(aSymmetryAlgo.shape()->isNull()) {
228 static const std::string aShapeError = "Error: Resulting shape is Null.";
229 setError(aShapeError);
232 if(!aSymmetryAlgo.isValid()) {
233 std::string aFeatureError = "Error: Resulting shape is not valid.";
234 setError(aFeatureError);
238 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
239 loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
240 setResult(aResultBody, aResultIndex);
245 // Remove the rest results if there were produced in the previous pass.
246 removeResults(aResultIndex);
249 //=================================================================================================
250 void FeaturesPlugin_Symmetry::performSymmetryByPlane()
253 ListOfShape anObjects;
254 std::list<ResultPtr> aContextes;
255 AttributeSelectionListPtr anObjectsSelList =
256 selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
257 if (anObjectsSelList->size() == 0) {
260 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
261 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
262 anObjectsSelList->value(anObjectsIndex);
263 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
264 if(!anObject.get()) { // may be for not-activated parts
268 anObjects.push_back(anObject);
269 aContextes.push_back(anObjectAttr->context());
273 std::shared_ptr<GeomAPI_Ax2> aPlane;
274 std::shared_ptr<GeomAPI_Pln> aPln;
275 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
276 selection(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID());
277 if(anObjRef && anObjRef->value() && anObjRef->value()->isFace()) {
278 aPln = std::shared_ptr<GeomAPI_Face>(new GeomAPI_Face(anObjRef->value()))->getPlane();
280 else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
281 anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
283 std::shared_ptr<GeomAPI_Face>(new GeomAPI_Face(anObjRef->context()->shape()))->getPlane();
286 aPlane = std::shared_ptr<GeomAPI_Ax2>(new GeomAPI_Ax2(aPln->location(),
290 // Moving each object.
291 int aResultIndex = 0;
292 std::list<ResultPtr>::iterator aContext = aContextes.begin();
293 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
294 anObjectsIt++, aContext++) {
295 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
296 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
300 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
301 aTrsf->setSymmetry(aPlane);
302 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
303 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
304 aResultPart->setTrsf(*aContext, aTrsf);
305 setResult(aResultPart, aResultIndex);
307 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, aPlane);
309 if (!aSymmetryAlgo.check()) {
310 setError(aSymmetryAlgo.getError());
314 aSymmetryAlgo.build();
316 // Checking that the algorithm worked properly.
317 if(!aSymmetryAlgo.isDone()) {
318 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
319 setError(aFeatureError);
322 if(aSymmetryAlgo.shape()->isNull()) {
323 static const std::string aShapeError = "Error: Resulting shape is Null.";
324 setError(aShapeError);
327 if(!aSymmetryAlgo.isValid()) {
328 std::string aFeatureError = "Error: Resulting shape is not valid.";
329 setError(aFeatureError);
333 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
334 loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
335 setResult(aResultBody, aResultIndex);
340 // Remove the rest results if there were produced in the previous pass.
341 removeResults(aResultIndex);
344 //=================================================================================================
345 void FeaturesPlugin_Symmetry::loadNamingDS(GeomAlgoAPI_Symmetry& theSymmetryAlgo,
346 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
347 std::shared_ptr<GeomAPI_Shape> theBaseShape)
349 // Store and name the result.
350 theResultBody->storeModified(theBaseShape, theSymmetryAlgo.shape());
353 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theSymmetryAlgo.mapOfSubShapes();
354 int aReflectedTag = 1;
355 std::string aReflectedName = "Symmetried";
356 theResultBody->loadAndOrientModifiedShapes(&theSymmetryAlgo,
357 theBaseShape, GeomAPI_Shape::FACE,
358 aReflectedTag, aReflectedName, *aSubShapes.get());