1 // Copyright (C) 2014-201x CEA/DEN, EDF R&D
3 // File: FeaturesPlugin_Scale.cpp
4 // Created: 13 Jan 2017
5 // Author: Clarisse Genrault (CEA)
7 #include <FeaturesPlugin_Scale.h>
9 #include <GeomAlgoAPI_PointBuilder.h>
11 #include <ModelAPI_AttributeDouble.h>
12 #include <ModelAPI_AttributeSelectionList.h>
13 #include <ModelAPI_AttributeString.h>
14 #include <ModelAPI_ResultBody.h>
15 #include <ModelAPI_ResultPart.h>
17 //=================================================================================================
18 FeaturesPlugin_Scale::FeaturesPlugin_Scale()
22 //=================================================================================================
23 void FeaturesPlugin_Scale::initAttributes()
25 data()->addAttribute(FeaturesPlugin_Scale::CREATION_METHOD(),
26 ModelAPI_AttributeString::typeId());
28 AttributeSelectionListPtr aSelection =
29 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
30 FeaturesPlugin_Scale::OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
32 data()->addAttribute(FeaturesPlugin_Scale::CENTER_POINT_ID(),
33 ModelAPI_AttributeSelection::typeId());
35 data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_ID(),
36 ModelAPI_AttributeDouble::typeId());
38 data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID(),
39 ModelAPI_AttributeDouble::typeId());
40 data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID(),
41 ModelAPI_AttributeDouble::typeId());
42 data()->addAttribute(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID(),
43 ModelAPI_AttributeDouble::typeId());
46 //=================================================================================================
47 void FeaturesPlugin_Scale::execute()
49 AttributeStringPtr aMethodTypeAttr = string(FeaturesPlugin_Scale::CREATION_METHOD());
50 std::string aMethodType = aMethodTypeAttr->value();
52 if (aMethodType == FeaturesPlugin_Scale::CREATION_METHOD_BY_FACTOR()) {
53 performScaleByFactor();
56 if (aMethodType == FeaturesPlugin_Scale::CREATION_METHOD_BY_DIMENSIONS()) {
57 performScaleByDimensions();
61 //=================================================================================================
62 void FeaturesPlugin_Scale::performScaleByFactor()
65 ListOfShape anObjects;
66 std::list<ResultPtr> aContextes;
67 AttributeSelectionListPtr anObjectsSelList =
68 selectionList(FeaturesPlugin_Scale::OBJECTS_LIST_ID());
69 if (anObjectsSelList->size() == 0) {
72 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
73 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
74 anObjectsSelList->value(anObjectsIndex);
75 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
76 if(!anObject.get()) { // may be for not-activated parts
80 anObjects.push_back(anObject);
81 aContextes.push_back(anObjectAttr->context());
84 // Getting the center point
85 std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
86 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
87 selection(FeaturesPlugin_Scale::CENTER_POINT_ID());
88 if (anObjRef.get() != NULL) {
89 GeomShapePtr aShape = anObjRef->value();
91 aShape = anObjRef->context()->shape();
94 aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape);
98 // Getting scale factor
99 double aScaleFactor = real(FeaturesPlugin_Scale::SCALE_FACTOR_ID())->value();
101 // Moving each object.
102 int aResultIndex = 0;
103 std::list<ResultPtr>::iterator aContext = aContextes.begin();
104 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
105 anObjectsIt++, aContext++) {
106 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
107 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
111 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
112 //aTrsf->setSymmetry(anAxis);
113 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
114 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
115 aResultPart->setTrsf(*aContext, aTrsf);
116 setResult(aResultPart, aResultIndex);
118 GeomAlgoAPI_Scale aScaleAlgo(aBaseShape, aCenterPoint, aScaleFactor);
120 if (!aScaleAlgo.check()) {
121 setError(aScaleAlgo.getError());
127 // Checking that the algorithm worked properly.
128 if(!aScaleAlgo.isDone()) {
129 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
130 setError(aFeatureError);
133 if(aScaleAlgo.shape()->isNull()) {
134 static const std::string aShapeError = "Error: Resulting shape is Null.";
135 setError(aShapeError);
138 if(!aScaleAlgo.isValid()) {
139 std::string aFeatureError = "Error: Resulting shape is not valid.";
140 setError(aFeatureError);
144 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
145 loadNamingDS(aScaleAlgo, aResultBody, aBaseShape);
146 setResult(aResultBody, aResultIndex);
151 // Remove the rest results if there were produced in the previous pass.
152 removeResults(aResultIndex);
155 //=================================================================================================
156 void FeaturesPlugin_Scale::performScaleByDimensions()
159 ListOfShape anObjects;
160 std::list<ResultPtr> aContextes;
161 AttributeSelectionListPtr anObjectsSelList =
162 selectionList(FeaturesPlugin_Scale::OBJECTS_LIST_ID());
163 if (anObjectsSelList->size() == 0) {
166 for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
167 std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
168 anObjectsSelList->value(anObjectsIndex);
169 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
170 if(!anObject.get()) { // may be for not-activated parts
174 anObjects.push_back(anObject);
175 aContextes.push_back(anObjectAttr->context());
178 // Getting the center point
179 std::shared_ptr<GeomAPI_Pnt> aCenterPoint;
180 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef =
181 selection(FeaturesPlugin_Scale::CENTER_POINT_ID());
182 if (anObjRef.get() != NULL) {
183 GeomShapePtr aShape = anObjRef->value();
185 aShape = anObjRef->context()->shape();
188 aCenterPoint = GeomAlgoAPI_PointBuilder::point(aShape);
192 // Getting dimensions
193 double aScaleFactorX = real(FeaturesPlugin_Scale::SCALE_FACTOR_X_ID())->value();
194 double aScaleFactorY = real(FeaturesPlugin_Scale::SCALE_FACTOR_Y_ID())->value();
195 double aScaleFactorZ = real(FeaturesPlugin_Scale::SCALE_FACTOR_Z_ID())->value();
197 // Moving each object.
198 int aResultIndex = 0;
199 std::list<ResultPtr>::iterator aContext = aContextes.begin();
200 for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
201 anObjectsIt++, aContext++) {
202 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
203 bool isPart = (*aContext)->groupName() == ModelAPI_ResultPart::group();
207 std::shared_ptr<GeomAPI_Trsf> aTrsf(new GeomAPI_Trsf());
208 //aTrsf->setSymmetry(anAxis);
209 ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
210 ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
211 aResultPart->setTrsf(*aContext, aTrsf);
212 setResult(aResultPart, aResultIndex);
214 GeomAlgoAPI_Scale aScaleAlgo(aBaseShape, aCenterPoint,
215 aScaleFactorX, aScaleFactorY, aScaleFactorZ);
217 if (!aScaleAlgo.check()) {
218 setError(aScaleAlgo.getError());
224 // Checking that the algorithm worked properly.
225 if(!aScaleAlgo.isDone()) {
226 static const std::string aFeatureError = "Error: Symmetry algorithm failed.";
227 setError(aFeatureError);
230 if(aScaleAlgo.shape()->isNull()) {
231 static const std::string aShapeError = "Error: Resulting shape is Null.";
232 setError(aShapeError);
235 if(!aScaleAlgo.isValid()) {
236 std::string aFeatureError = "Error: Resulting shape is not valid.";
237 setError(aFeatureError);
241 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
242 loadNamingDS(aScaleAlgo, aResultBody, aBaseShape);
243 setResult(aResultBody, aResultIndex);
248 // Remove the rest results if there were produced in the previous pass.
249 removeResults(aResultIndex);
252 //=================================================================================================
253 void FeaturesPlugin_Scale::loadNamingDS(GeomAlgoAPI_Scale& theScaleAlgo,
254 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
255 std::shared_ptr<GeomAPI_Shape> theBaseShape)
257 // Store and name the result.
258 theResultBody->storeModified(theBaseShape, theScaleAlgo.shape());
261 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theScaleAlgo.mapOfSubShapes();
262 int aReflectedTag = 1;
263 std::string aReflectedName = "Scaled";
264 theResultBody->loadAndOrientModifiedShapes(&theScaleAlgo,
265 theBaseShape, GeomAPI_Shape::FACE,
266 aReflectedTag, aReflectedName, *aSubShapes.get());