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 email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
20 #include <FeaturesPlugin_Symmetry.h>
22 #include <GeomAlgoAPI_PointBuilder.h>
24 #include <GeomAPI_Edge.h>
25 #include <GeomAPI_Face.h>
26 #include <GeomAPI_Lin.h>
27 #include <GeomAPI_Pln.h>
28 #include <GeomAPI_Trsf.h>
30 #include <ModelAPI_AttributeSelectionList.h>
31 #include <ModelAPI_AttributeString.h>
32 #include <ModelAPI_ResultBody.h>
33 #include <ModelAPI_ResultPart.h>
36 #include <GeomAlgoAPI_FaceBuilder.h>
38 //=================================================================================================
39 FeaturesPlugin_Symmetry::FeaturesPlugin_Symmetry()
43 //=================================================================================================
44 void FeaturesPlugin_Symmetry::initAttributes()
46 data()->addAttribute(FeaturesPlugin_Symmetry::CREATION_METHOD(),
47 ModelAPI_AttributeString::typeId());
49 AttributeSelectionListPtr aSelection =
50 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
51 FeaturesPlugin_Symmetry::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
53 data()->addAttribute(FeaturesPlugin_Symmetry::POINT_OBJECT_ID(),
54 ModelAPI_AttributeSelection::typeId());
56 data()->addAttribute(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID(),
57 ModelAPI_AttributeSelection::typeId());
59 data()->addAttribute(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID(),
60 ModelAPI_AttributeSelection::typeId());
63 //=================================================================================================
64 void FeaturesPlugin_Symmetry::execute()
66 AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Symmetry::CREATION_METHOD());
67 std::string aMethodType = aMethodTypeAttr->value();
69 if (aMethodType == CREATION_METHOD_BY_POINT()) {
70 performSymmetryByPoint();
73 if (aMethodType == CREATION_METHOD_BY_AXIS()) {
74 performSymmetryByAxis();
77 if (aMethodType == CREATION_METHOD_BY_PLANE()) {
78 performSymmetryByPlane();
82 //=================================================================================================
83 void FeaturesPlugin_Symmetry::performSymmetryByPoint()
86 ListOfShape anObjects;
87 std::list<ResultPtr> aContextes;
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 anObjects.push_back(anObject);
102 aContextes.push_back(anObjectAttr->context());
106 std::shared_ptr<GeomAPI_Pnt> aPoint;
107 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
108 selection(FeaturesPlugin_Symmetry::POINT_OBJECT_ID());
109 if (anObjRef.get() != NULL) {
110 GeomShapePtr aShape1 = anObjRef->value();
111 if (!aShape1.get()) {
112 aShape1 = anObjRef->context()->shape();
115 aPoint = GeomAlgoAPI_PointBuilder::point(aShape1);
119 // Moving each object.
120 int aResultIndex = 0;
121 std::list<ResultPtr>::iterator aContext = aContextes.begin();
122 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
123 anObjectsIt++, aContext++) {
124 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
125 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
129 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
130 aTrsf->setSymmetry(aPoint);
131 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
132 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
133 aResultPart->setTrsf(*aContext, aTrsf);
134 setResult(aResultPart, aResultIndex);
136 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, aPoint);
138 if (!aSymmetryAlgo.check()) {
139 setError(aSymmetryAlgo.getError());
143 aSymmetryAlgo.build();
145 // Checking that the algorithm worked properly.
146 if(!aSymmetryAlgo.isDone()) {
147 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
148 setError(aFeatureError);
151 if(aSymmetryAlgo.shape()->isNull()) {
152 static const std::string aShapeError = "Error: Resulting shape is Null.";
153 setError(aShapeError);
156 if(!aSymmetryAlgo.isValid()) {
157 std::string aFeatureError = "Error: Resulting shape is not valid.";
158 setError(aFeatureError);
162 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
163 loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
164 setResult(aResultBody, 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 AttributeSelectionListPtr anObjectsSelList =
180 selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
181 if (anObjectsSelList->size() == 0) {
184 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
185 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
186 anObjectsSelList->value(anObjectsIndex);
187 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
188 if(!anObject.get()) { // may be for not-activated parts
192 anObjects.push_back(anObject);
193 aContextes.push_back(anObjectAttr->context());
197 std::shared_ptr<GeomAPI_Ax1> anAxis;
198 std::shared_ptr<GeomAPI_Edge> anEdge;
199 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
200 selection(FeaturesPlugin_Symmetry::AXIS_OBJECT_ID());
201 if(anObjRef && anObjRef->value() && anObjRef->value()->isEdge()) {
202 anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->value()));
203 } else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
204 anObjRef->context()->shape() && anObjRef->context()->shape()->isEdge()) {
205 anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(anObjRef->context()->shape()));
208 anAxis = std::shared_ptr<GeomAPI_Ax1>(new GeomAPI_Ax1(anEdge->line()->location(),
209 anEdge->line()->direction()));
212 // Moving each object.
213 int aResultIndex = 0;
214 std::list<ResultPtr>::iterator aContext = aContextes.begin();
215 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
216 anObjectsIt++, aContext++) {
217 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
218 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
222 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
223 aTrsf->setSymmetry(anAxis);
224 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
225 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
226 aResultPart->setTrsf(*aContext, aTrsf);
227 setResult(aResultPart, aResultIndex);
229 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, anAxis);
231 if (!aSymmetryAlgo.check()) {
232 setError(aSymmetryAlgo.getError());
236 aSymmetryAlgo.build();
238 // Checking that the algorithm worked properly.
239 if(!aSymmetryAlgo.isDone()) {
240 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
241 setError(aFeatureError);
244 if(aSymmetryAlgo.shape()->isNull()) {
245 static const std::string aShapeError = "Error: Resulting shape is Null.";
246 setError(aShapeError);
249 if(!aSymmetryAlgo.isValid()) {
250 std::string aFeatureError = "Error: Resulting shape is not valid.";
251 setError(aFeatureError);
255 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
256 loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
257 setResult(aResultBody, aResultIndex);
262 // Remove the rest results if there were produced in the previous pass.
263 removeResults(aResultIndex);
266 //=================================================================================================
267 void FeaturesPlugin_Symmetry::performSymmetryByPlane()
270 ListOfShape anObjects;
271 std::list<ResultPtr> aContextes;
272 AttributeSelectionListPtr anObjectsSelList =
273 selectionList(FeaturesPlugin_Symmetry::OBJECTS_LIST_ID());
274 if (anObjectsSelList->size() == 0) {
277 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
278 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
279 anObjectsSelList->value(anObjectsIndex);
280 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
281 if(!anObject.get()) { // may be for not-activated parts
285 anObjects.push_back(anObject);
286 aContextes.push_back(anObjectAttr->context());
290 std::shared_ptr<GeomAPI_Ax2> aPlane;
291 std::shared_ptr<GeomAPI_Pln> aPln;
292 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
293 selection(FeaturesPlugin_Symmetry::PLANE_OBJECT_ID());
294 if (anObjRef && anObjRef->value() && anObjRef->value()->isFace()) {
295 aPln = std::shared_ptr<GeomAPI_Face>(new GeomAPI_Face(anObjRef->value()))->getPlane();
297 else if (anObjRef && !anObjRef->value() && anObjRef->context() &&
298 anObjRef->context()->shape() && anObjRef->context()->shape()->isFace()) {
300 std::shared_ptr<GeomAPI_Face>(new GeomAPI_Face(anObjRef->context()->shape()))->getPlane();
303 aPlane = std::shared_ptr<GeomAPI_Ax2>(new GeomAPI_Ax2(aPln->location(),
307 // Moving each object.
308 int aResultIndex = 0;
309 std::list<ResultPtr>::iterator aContext = aContextes.begin();
310 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
311 anObjectsIt++, aContext++) {
312 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
313 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
317 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
318 aTrsf->setSymmetry(aPlane);
319 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
320 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
321 aResultPart->setTrsf(*aContext, aTrsf);
322 setResult(aResultPart, aResultIndex);
324 GeomAlgoAPI_Symmetry aSymmetryAlgo(aBaseShape, aPlane);
326 if (!aSymmetryAlgo.check()) {
327 setError(aSymmetryAlgo.getError());
331 aSymmetryAlgo.build();
333 // Checking that the algorithm worked properly.
334 if(!aSymmetryAlgo.isDone()) {
335 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
336 setError(aFeatureError);
339 if(aSymmetryAlgo.shape()->isNull()) {
340 static const std::string aShapeError = "Error: Resulting shape is Null.";
341 setError(aShapeError);
344 if(!aSymmetryAlgo.isValid()) {
345 std::string aFeatureError = "Error: Resulting shape is not valid.";
346 setError(aFeatureError);
350 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
351 loadNamingDS(aSymmetryAlgo, aResultBody, aBaseShape);
352 setResult(aResultBody, aResultIndex);
357 // Remove the rest results if there were produced in the previous pass.
358 removeResults(aResultIndex);
361 //=================================================================================================
362 void FeaturesPlugin_Symmetry::loadNamingDS(GeomAlgoAPI_Symmetry& theSymmetryAlgo,
363 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
364 std::shared_ptr<GeomAPI_Shape> theBaseShape)
366 // Store and name the result.
367 theResultBody->storeModified(theBaseShape, theSymmetryAlgo.shape());
370 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theSymmetryAlgo.mapOfSubShapes();
371 int aReflectedTag = 1;
372 std::string aReflectedName = "Symmetried";
373 theResultBody->loadAndOrientModifiedShapes(&theSymmetryAlgo,
374 theBaseShape, GeomAPI_Shape::FACE,
375 aReflectedTag, aReflectedName, *aSubShapes.get());