Salome HOME
8923fd6e13bf01788622a586a564361eccb44709
[modules/shaper.git] / src / ModelHighAPI / ModelHighAPI_Tools.cpp
1 // Name   : ModelHighAPI_Tools.cpp
2 // Purpose: 
3 //
4 // History:
5 // 07/06/16 - Sergey POKHODENKO - Creation of the file
6
7 //--------------------------------------------------------------------------------------
8 #include "ModelHighAPI_Tools.h"
9 #include <ModelHighAPI_FeatureStore.h>
10 //--------------------------------------------------------------------------------------
11 #include <GeomAPI_Dir.h>
12 #include <GeomAPI_Pnt.h>
13 #include <GeomAPI_Pnt2d.h>
14 //--------------------------------------------------------------------------------------
15 #include <GeomDataAPI_Dir.h>
16 #include <GeomDataAPI_Point.h>
17 #include <GeomDataAPI_Point2D.h>
18 //--------------------------------------------------------------------------------------
19 #include <ModelAPI_AttributeBoolean.h>
20 #include <ModelAPI_AttributeDocRef.h>
21 #include <ModelAPI_AttributeDouble.h>
22 #include <ModelAPI_AttributeIntArray.h>
23 #include <ModelAPI_AttributeInteger.h>
24 #include <ModelAPI_AttributeRefAttr.h>
25 #include <ModelAPI_AttributeRefAttrList.h>
26 #include <ModelAPI_AttributeReference.h>
27 #include <ModelAPI_AttributeRefList.h>
28 #include <ModelAPI_AttributeSelection.h>
29 #include <ModelAPI_AttributeSelectionList.h>
30 #include <ModelAPI_AttributeString.h>
31 #include <ModelAPI_AttributeDoubleArray.h>
32 #include <ModelAPI_Session.h>
33 #include <ModelAPI_Tools.h>
34 #include <ModelAPI_ResultPart.h>
35 //--------------------------------------------------------------------------------------
36 #include <Config_ModuleReader.h>
37 //--------------------------------------------------------------------------------------
38 #include "ModelHighAPI_Double.h"
39 #include "ModelHighAPI_Integer.h"
40 #include "ModelHighAPI_RefAttr.h"
41 #include "ModelHighAPI_Reference.h"
42 #include "ModelHighAPI_Selection.h"
43
44 #include <Events_InfoMessage.h>
45
46 #include <algorithm>
47 #include <iostream>
48
49 //--------------------------------------------------------------------------------------
50 void fillAttribute(const std::shared_ptr<GeomAPI_Pnt2d> & theValue,
51                    const std::shared_ptr<GeomDataAPI_Point2D> & theAttribute)
52 {
53   theAttribute->setValue(theValue);
54 }
55
56 void fillAttribute(const std::shared_ptr<GeomDataAPI_Point2D> & theAttribute,
57                    double theX, double theY)
58 {
59   theAttribute->setValue(theX, theY);
60 }
61
62 //--------------------------------------------------------------------------------------
63 void fillAttribute(const std::shared_ptr<GeomAPI_Dir> & theValue,
64                    const std::shared_ptr<GeomDataAPI_Dir> & theAttribute)
65 {
66   theAttribute->setValue(theValue);
67 }
68
69 //--------------------------------------------------------------------------------------
70 void fillAttribute(const std::shared_ptr<GeomAPI_Pnt> & theValue,
71                    const std::shared_ptr<GeomDataAPI_Point> & theAttribute)
72 {
73   theAttribute->setValue(theValue);
74 }
75
76 //--------------------------------------------------------------------------------------
77 void fillAttribute(bool theValue,
78                    const std::shared_ptr<ModelAPI_AttributeBoolean> & theAttribute)
79 {
80   theAttribute->setValue(theValue);
81 }
82
83 //--------------------------------------------------------------------------------------
84 void fillAttribute(const ModelHighAPI_Double & theValue,
85                    const std::shared_ptr<ModelAPI_AttributeDouble> & theAttribute)
86 {
87   theValue.fillAttribute(theAttribute);
88 }
89 void fillAttribute(double theValue,
90                    const std::shared_ptr<ModelAPI_AttributeDouble> & theAttribute)
91 {
92   theAttribute->setValue(theValue);
93 }
94
95 //--------------------------------------------------------------------------------------
96 void fillAttribute(const ModelHighAPI_Integer & theValue,
97                    const std::shared_ptr<ModelAPI_AttributeInteger> & theAttribute)
98 {
99   theValue.fillAttribute(theAttribute);
100 }
101 void fillAttribute(int theValue,
102                    const std::shared_ptr<ModelAPI_AttributeInteger> & theAttribute)
103 {
104   theAttribute->setValue(theValue);
105 }
106
107 //--------------------------------------------------------------------------------------
108 void fillAttribute(const ModelHighAPI_RefAttr & theValue,
109                    const std::shared_ptr<ModelAPI_AttributeRefAttr> & theAttribute)
110 {
111   theValue.fillAttribute(theAttribute);
112 }
113
114 //--------------------------------------------------------------------------------------
115 void fillAttribute(const std::list<ModelHighAPI_RefAttr> & theValue,
116                    const std::shared_ptr<ModelAPI_AttributeRefAttrList> & theAttribute)
117 {
118   theAttribute->clear();
119   for (auto it = theValue.begin(); it != theValue.end(); ++it)
120     it->appendToList(theAttribute);
121 }
122
123 //--------------------------------------------------------------------------------------
124 void fillAttribute(const ModelHighAPI_Reference & theValue,
125                    const std::shared_ptr<ModelAPI_AttributeReference> & theAttribute)
126 {
127   theValue.fillAttribute(theAttribute);
128 }
129
130 //--------------------------------------------------------------------------------------
131 void fillAttribute(const std::list<ModelHighAPI_Reference> & theValue,
132                    const std::shared_ptr<ModelAPI_AttributeRefList> & theAttribute)
133 {
134   theAttribute->clear();
135   for (auto it = theValue.begin(); it != theValue.end(); ++it)
136     it->appendToList(theAttribute);
137 }
138
139 //--------------------------------------------------------------------------------------
140 void fillAttribute(const std::shared_ptr<ModelAPI_Object> & theValue,
141                    const std::shared_ptr<ModelAPI_AttributeReference> & theAttribute)
142 {
143   theAttribute->setValue(theValue);
144 }
145
146 //--------------------------------------------------------------------------------------
147 void fillAttribute(const std::list<std::shared_ptr<ModelAPI_Object> > & theValue,
148                    const std::shared_ptr<ModelAPI_AttributeRefList> & theAttribute)
149 {
150   theAttribute->clear();
151   for (auto it = theValue.begin(); it != theValue.end(); ++it)
152     theAttribute->append(*it);
153 }
154
155 MODELHIGHAPI_EXPORT
156 void fillAttribute(const std::list<ModelHighAPI_Selection> & theValue,
157                    const std::shared_ptr<ModelAPI_AttributeRefList> & theAttribute)
158 {
159   theAttribute->clear();
160   for (auto it = theValue.begin(); it != theValue.end(); ++it)
161     theAttribute->append(it->resultSubShapePair().first); // use only context
162 }
163
164 //--------------------------------------------------------------------------------------
165 void fillAttribute(const ModelHighAPI_Selection & theValue,
166                    const std::shared_ptr<ModelAPI_AttributeSelection> & theAttribute)
167 {
168   theValue.fillAttribute(theAttribute);
169 }
170
171 //--------------------------------------------------------------------------------------
172 void fillAttribute(const std::list<ModelHighAPI_Selection> & theValue,
173                    const std::shared_ptr<ModelAPI_AttributeSelectionList> & theAttribute)
174 {
175   theAttribute->clear();
176
177   if(!theValue.empty()) {
178     std::string aSelectionType;
179     const ModelHighAPI_Selection& aSelection = theValue.front();
180     theAttribute->setSelectionType(aSelection.shapeType());
181   }
182
183   for (auto it = theValue.begin(); it != theValue.end(); ++it)
184     it->appendToList(theAttribute);
185 }
186
187 //--------------------------------------------------------------------------------------
188 void fillAttribute(const std::string & theValue,
189                    const std::shared_ptr<ModelAPI_AttributeString> & theAttribute)
190 {
191   theAttribute->setValue(theValue);
192 }
193 void fillAttribute(const char * theValue,
194                    const std::shared_ptr<ModelAPI_AttributeString> & theAttribute)
195 {
196   theAttribute->setValue(theValue);
197 }
198
199 //==================================================================================================
200 GeomAPI_Shape::ShapeType shapeTypeByStr(std::string theShapeTypeStr)
201 {
202   GeomAPI_Shape::ShapeType aShapeType = GeomAPI_Shape::SHAPE;
203
204   std::transform(theShapeTypeStr.begin(), theShapeTypeStr.end(), theShapeTypeStr.begin(), ::tolower);
205
206   if(theShapeTypeStr == "compound") {
207     aShapeType = GeomAPI_Shape::COMPOUND;
208   } else if(theShapeTypeStr == "compsolid") {
209     aShapeType = GeomAPI_Shape::COMPSOLID;
210   } else if(theShapeTypeStr == "solid") {
211     aShapeType = GeomAPI_Shape::SOLID;
212   } else if(theShapeTypeStr == "shell") {
213     aShapeType = GeomAPI_Shape::SHELL;
214   } else if(theShapeTypeStr == "face") {
215     aShapeType = GeomAPI_Shape::FACE;
216   } else if(theShapeTypeStr == "wire") {
217     aShapeType = GeomAPI_Shape::WIRE;
218   } else if(theShapeTypeStr == "edge") {
219     aShapeType = GeomAPI_Shape::EDGE;
220   } else if(theShapeTypeStr == "vertex") {
221     aShapeType = GeomAPI_Shape::VERTEX;
222   } else if(theShapeTypeStr == "shape") {
223     aShapeType = GeomAPI_Shape::SHAPE;
224   }
225
226   return aShapeType;
227 }
228
229 //==================================================================================================
230 GeomAPI_Shape::ShapeType getShapeType(const ModelHighAPI_Selection& theSelection)
231 {
232   GeomAPI_Shape::ShapeType aShapeType = GeomAPI_Shape::SHAPE;
233
234   switch(theSelection.variantType()) {
235     case ModelHighAPI_Selection::VT_ResultSubShapePair: {
236       ResultSubShapePair aPair = theSelection.resultSubShapePair();
237       GeomShapePtr aShape = aPair.second;
238       if(!aShape.get()) {
239         aShape = aPair.first->shape();
240       }
241       if(!aShape.get()) {
242         return aShapeType;
243       }
244       aShapeType = aShape->shapeType();
245       break;
246     }
247     case ModelHighAPI_Selection::VT_TypeSubShapeNamePair: {
248       TypeSubShapeNamePair aPair = theSelection.typeSubShapeNamePair();
249       std::string aType = aPair.first;
250       aShapeType = shapeTypeByStr(aType);
251       break;
252     }
253   }
254
255   return aShapeType;
256 }
257
258 /// stores the features information, recoursively stores sub-documetns features
259 std::string storeFeatures(const std::string& theDocName, DocumentPtr theDoc,
260   std::map<std::string, std::map<std::string, ModelHighAPI_FeatureStore> >& theStore,
261   const bool theCompare) // if false => store
262 {
263   std::map<std::string, std::map<std::string, ModelHighAPI_FeatureStore> >::iterator aDocFind;
264   if (theCompare) {
265      aDocFind = theStore.find(theDocName);
266      if (aDocFind == theStore.end()) {
267        return "Document '" + theDocName + "' not found";
268      }
269   }
270   // store the model features information: iterate all features
271   int aFeaturesCount = 0; // stores the number of compared features for this document to compate
272   std::set<std::string> aProcessed; // processed features names (that are in the current document)
273   std::list<FeaturePtr> allFeatures = theDoc->allFeatures();
274   std::list<FeaturePtr>::iterator allIter = allFeatures.begin();
275   for(; allIter != allFeatures.end(); allIter++) {
276     FeaturePtr aFeat = *allIter;
277     if (theCompare) {
278       std::map<std::string, ModelHighAPI_FeatureStore>::iterator 
279         aFeatFind = aDocFind->second.find(aFeat->name());
280       if (aFeatFind == aDocFind->second.end()) {
281         return "Document '" + theDocName + "' feature '" + aFeat->name() + "' not found";
282       }
283       std::string anError = aFeatFind->second.compare(aFeat);
284       if (!anError.empty()) {
285         return anError;
286       }
287       aFeaturesCount++;
288       aProcessed.insert(aFeat->name());
289     } else {
290       theStore[theDocName][aFeat->name()] = ModelHighAPI_FeatureStore(aFeat);
291     }
292     // iterate all results of this feature
293     std::list<ResultPtr> allResults;
294     ModelAPI_Tools::allResults(aFeat, allResults);
295     std::list<ResultPtr>::iterator aRes = allResults.begin();
296     for(; aRes != allResults.end(); aRes++) {
297       if ((*aRes)->groupName() == ModelAPI_ResultPart::group()) { // recoursively store features of sub-documents
298         DocumentPtr aDoc = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes)->partDoc();
299         if (aDoc.get()) {
300           std::string anError = storeFeatures((*aRes)->data()->name(), aDoc, theStore, theCompare);
301           if (!anError.empty())
302             return anError;
303         }
304       }
305     }
306   }
307   // checks the number of compared features
308   if (theCompare) {
309     if (aDocFind->second.size() != aFeaturesCount) {
310       // search for disappeared feature
311       std::string aLostName;
312       std::map<std::string, ModelHighAPI_FeatureStore>::iterator aLostIter;
313       for(aLostIter = aDocFind->second.begin(); aLostIter != aDocFind->second.end(); aLostIter++) {
314         if (aProcessed.find(aLostIter->first) == aProcessed.end()) {
315           aLostName = aLostIter->first;
316         }
317       }
318       return "For document '" + theDocName + 
319         "' the number of features is decreased, there is no feature '" + aLostName + "'";
320     }
321   }
322   return ""; // ok
323 }
324
325 //==================================================================================================
326 bool checkPythonDump()
327 {
328   SessionPtr aSession = ModelAPI_Session::get();
329   // dump all to the python file
330   aSession->startOperation("Check python dump");
331   FeaturePtr aDump = aSession->moduleDocument()->addFeature("Dump");
332   if (aDump.get()) {
333     aDump->string("file_path")->setValue("check_dump.py"); // to the current folder
334     aDump->string("file_format")->setValue("py"); // to the current folder
335     aDump->execute();
336   }
337   bool isProblem = !aDump.get() || !aDump->error().empty(); // after "finish" dump will be removed
338   aSession->finishOperation();
339   if (isProblem)
340     return false; // something is wrong during dump
341
342    // map from document name to feature name to feature data
343   std::map<std::string, std::map<std::string, ModelHighAPI_FeatureStore> > aStore;
344   std::string anError = storeFeatures(
345     aSession->moduleDocument()->kind(), aSession->moduleDocument(), aStore, false);
346   if (!anError.empty()) {
347     Events_InfoMessage anError("checkPythonDump", anError);
348     anError.send();
349     return false;
350   }
351   // close all before importation of the script
352   aSession->closeAll();
353   // execute the dumped
354   Config_ModuleReader::loadScript("check_dump");
355
356   // compare with the stored data
357   anError = storeFeatures(
358     aSession->moduleDocument()->kind(), aSession->moduleDocument(), aStore, true);
359   if (!anError.empty()) {
360     std::cout<<anError<<std::endl;
361     Events_InfoMessage anError("checkPythonDump", anError);
362     anError.send();
363     return false;
364   }
365
366   return true;
367 }
368
369 //--------------------------------------------------------------------------------------