1 // Copyright (C) 2016-20xx CEA/DEN, EDF R&D -->
3 // File: ModelHighAPI_FeatureStore.cpp
4 // Created: 12 August 2016
5 // Author: Mikhail PONIKAROV
7 #include <ModelHighAPI_FeatureStore.h>
9 #include <ModelAPI_Tools.h>
10 #include <ModelAPI_ResultPart.h>
11 #include <ModelAPI_Session.h>
12 #include <ModelAPI_AttributeBoolean.h>
13 #include <ModelAPI_AttributeDocRef.h>
14 #include <ModelAPI_AttributeDouble.h>
15 #include <ModelAPI_AttributeIntArray.h>
16 #include <ModelAPI_AttributeInteger.h>
17 #include <ModelAPI_AttributeRefAttr.h>
18 #include <ModelAPI_AttributeRefAttrList.h>
19 #include <ModelAPI_AttributeReference.h>
20 #include <ModelAPI_AttributeRefList.h>
21 #include <ModelAPI_AttributeSelection.h>
22 #include <ModelAPI_AttributeSelectionList.h>
23 #include <ModelAPI_AttributeString.h>
24 #include <ModelAPI_AttributeDoubleArray.h>
26 #include <GeomDataAPI_Dir.h>
27 #include <GeomDataAPI_Point.h>
28 #include <GeomDataAPI_Point2D.h>
29 #include <GeomAlgoAPI_ShapeTools.h>
30 #include <GeomAPI_Pnt.h>
32 #include <TopoDS_Shape.hxx>
33 #include <TopExp_Explorer.hxx>
35 ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(FeaturePtr theFeature) {
36 storeData(theFeature->data(), myAttrs);
37 // iterate results to store
38 std::list<ResultPtr> allResults;
39 ModelAPI_Tools::allResults(theFeature, allResults);
40 std::list<ResultPtr>::iterator aRes = allResults.begin();
41 for(; aRes != allResults.end(); aRes++) {
42 std::map<std::string, std::string> aResDump;
43 storeData((*aRes)->data(), aResDump);
44 myRes.push_back(aResDump);
48 std::string ModelHighAPI_FeatureStore::compare(FeaturePtr theFeature) {
49 std::string anError = compareData(theFeature->data(), myAttrs);
50 if (!anError.empty()) {
51 return "Features '" + theFeature->name() + "' differ:" + anError;
53 std::list<ResultPtr> allResults;
54 ModelAPI_Tools::allResults(theFeature, allResults);
55 std::list<ResultPtr>::iterator aRes = allResults.begin();
56 std::list<std::map<std::string, std::string> >::iterator aResIter = myRes.begin();
57 for(; aRes != allResults.end() && aResIter != myRes.end(); aRes++, aResIter++) {
58 anError = compareData((*aRes)->data(), *aResIter);
60 return "Results of feature '" + theFeature->name() + "' '" + (*aRes)->data()->name() +
61 "' differ:" + anError;
63 if (aRes != allResults.end()) {
64 return "Current model has more results '" + (*aRes)->data()->name() + "'";
66 if (aResIter != myRes.end()) {
67 return "Original model had more results '" + (*aResIter)["__name__"] + "'";
72 void ModelHighAPI_FeatureStore::storeData(std::shared_ptr<ModelAPI_Data> theData,
73 std::map<std::string, std::string>& theAttrs)
75 theAttrs["__name__"] = theData->name(); // store name to keep also this information and output if needed
76 std::list<std::shared_ptr<ModelAPI_Attribute> > allAttrs = theData->attributes("");
77 std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = allAttrs.begin();
78 for(; anAttr != allAttrs.end(); anAttr++) {
79 theAttrs[(*anAttr)->id()] = dumpAttr(*anAttr);
81 ResultPtr aShapeOwner = std::dynamic_pointer_cast<ModelAPI_Result>(theData->owner());
82 if (aShapeOwner.get() && aShapeOwner->shape().get()) {
83 theAttrs["__shape__"] = dumpShape(aShapeOwner->shape());
87 std::string ModelHighAPI_FeatureStore::compareData(std::shared_ptr<ModelAPI_Data> theData,
88 std::map<std::string, std::string>& theAttrs)
90 std::map<std::string, std::string> aThis;
91 storeData(theData, aThis);
92 std::map<std::string, std::string>::iterator aThisIter = aThis.begin();
93 for(; aThisIter != aThis.end(); aThisIter++) {
94 if (theAttrs.find(aThisIter->first) == theAttrs.end()) {
95 return "original model had no attribute '" + aThisIter->first + "'";
97 if (theAttrs[aThisIter->first] != aThisIter->second) {
98 return "attribute '" + aThisIter->first + "' is different '" +
99 theAttrs[aThisIter->first] + "' != '" + aThisIter->second;
102 // iterate back to find lack attribute in the current model
103 std::map<std::string, std::string>::iterator anOrigIter = theAttrs.begin();
104 for(; anOrigIter != theAttrs.end(); anOrigIter++) {
105 if (aThis.find(anOrigIter->first) == aThis.end()) {
106 return "current model had no attribute '" + anOrigIter->first + "'";
112 std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
113 if (!theAttr->isInitialized()) {
114 return "__notinitialized__";
116 std::string aType = theAttr->attributeType();
117 std::ostringstream aResult;
118 if (aType == ModelAPI_AttributeDocRef::typeId()) {
119 AttributeDocRefPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDocRef>(theAttr);
120 DocumentPtr aDoc = ModelAPI_Session::get()->moduleDocument();
121 if (anAttr->value() != aDoc) {
122 ResultPtr aRes = ModelAPI_Tools::findPartResult(aDoc, anAttr->value());
124 aResult<<aRes->data()->name(); // Part result name (the same as saved file name)
127 aResult<<aDoc->kind(); // PartSet
129 } else if (aType == ModelAPI_AttributeInteger::typeId()) {
130 AttributeIntegerPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(theAttr);
131 if (anAttr->text().empty())
132 aResult<<anAttr->value();
134 aResult<<anAttr->text();
135 } else if (aType == ModelAPI_AttributeDouble::typeId()) {
136 AttributeDoublePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttr);
137 if (anAttr->text().empty())
138 aResult<<anAttr->value();
140 aResult<<anAttr->text();
141 } else if (aType == ModelAPI_AttributeBoolean::typeId()) {
142 AttributeBooleanPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(theAttr);
143 aResult<<anAttr->value();
144 } else if (aType == ModelAPI_AttributeString::typeId()) {
145 AttributeStringPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeString>(theAttr);
146 aResult<<anAttr->value();
147 } else if (aType == ModelAPI_AttributeReference::typeId()) {
148 AttributeReferencePtr anAttr =
149 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttr);
150 if (anAttr->value().get()) {
151 aResult<<anAttr->value()->data()->name();
153 aResult<<"__empty__";
155 } else if (aType == ModelAPI_AttributeSelection::typeId()) {
156 AttributeSelectionPtr anAttr =
157 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttr);
158 aResult<<anAttr->namingName();
159 } else if (aType == ModelAPI_AttributeSelectionList::typeId()) {
160 AttributeSelectionListPtr anAttr =
161 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttr);
162 for(int a = 0; a < anAttr->size(); a++) {
165 aResult<<anAttr->value(a)->namingName();
167 } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
168 AttributeRefAttrPtr anAttr =
169 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttr);
170 ObjectPtr anObj = anAttr->isObject() ? anAttr->object() : anAttr->attr()->owner();
172 aResult<<anObj->data()->name();
173 if (!anAttr->isObject()) {
174 aResult<<" "<<anAttr->attr()->id();
177 aResult<<"__empty__";
179 } else if (aType == ModelAPI_AttributeRefList::typeId()) {
180 AttributeRefListPtr anAttr =
181 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttr);
182 std::list<ObjectPtr> aList = anAttr->list();
183 for(std::list<ObjectPtr>::iterator aL = aList.begin(); aL != aList.end(); aL++) {
184 if (aL != aList.begin())
187 aResult<<(*aL)->data()->name();
189 aResult<<"__empty__";
192 } else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
193 AttributeRefAttrListPtr anAttr =
194 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttr);
195 std::list<std::pair<ObjectPtr, AttributePtr> > aList = anAttr->list();
196 std::list<std::pair<ObjectPtr, AttributePtr> >::iterator aL = aList.begin();
197 for(; aL != aList.end(); aL++) {
198 if (aL != aList.begin())
200 ObjectPtr anObj = aL->second.get() ? aL->second->owner() : aL->first;
202 aResult<<anObj->data()->name();
203 if (aL->second.get()) {
204 aResult<<" "<<aL->second->id();
207 aResult<<"__empty__";
210 } else if (aType == ModelAPI_AttributeIntArray::typeId()) {
211 AttributeIntArrayPtr anAttr =
212 std::dynamic_pointer_cast<ModelAPI_AttributeIntArray>(theAttr);
213 for(int a = 0; a < anAttr->size(); a++)
214 aResult<<anAttr->value(a)<<" ";
215 } else if (aType == ModelAPI_AttributeDoubleArray::typeId()) {
216 AttributeDoubleArrayPtr anAttr =
217 std::dynamic_pointer_cast<ModelAPI_AttributeDoubleArray>(theAttr);
218 for(int a = 0; a < anAttr->size(); a++)
219 aResult<<anAttr->value(a)<<" ";
220 } else if (aType == GeomDataAPI_Point::typeId()) {
221 AttributePointPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttr);
222 aResult<<anAttr->x()<<" "<<anAttr->y()<<" "<<anAttr->z();
223 } else if (aType == GeomDataAPI_Dir::typeId()) {
224 AttributeDirPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Dir>(theAttr);
225 aResult<<anAttr->x()<<" "<<anAttr->y()<<" "<<anAttr->z();
226 } else if (aType == GeomDataAPI_Point2D::typeId()) {
227 AttributePoint2DPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttr);
228 aResult<<anAttr->x()<<" "<<anAttr->y()<<" ";
230 aResult<<"__unknownattribute__";
232 return aResult.str();
235 std::string ModelHighAPI_FeatureStore::dumpShape(std::shared_ptr<GeomAPI_Shape>& theShape) {
236 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
237 if (aShape.IsNull()) {
240 std::ostringstream aResult;
241 // output the number of shapes of different types
242 TopAbs_ShapeEnum aType = TopAbs_COMPOUND;
243 for(; aType <= TopAbs_VERTEX; aType = TopAbs_ShapeEnum((int)aType + 1)) {
244 TopExp_Explorer anExp(aShape, aType);
246 for(; anExp.More(); anExp.Next()) aCount++;
247 TopAbs::Print(aType, aResult);
248 aResult<<": "<<aCount<<std::endl;
250 // output the main characteristics
251 aResult<<"Volume: "<<setprecision(2)<<GeomAlgoAPI_ShapeTools::volume(theShape)<<std::endl;
252 std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
253 aResult<<"Center of mass: "
254 <<aCenter->x()<<" "<<aCenter->y()<<" "<<aCenter->z()<<std::endl;
255 return aResult.str();