Salome HOME
Issue #1865 : implementation of import/export fields in XAO format
[modules/shaper.git] / src / ExchangePlugin / ExchangePlugin_ExportFeature.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:    ExchangePlugin_ExportFeature.cpp
4 // Created: May 14, 2015
5 // Author:  Sergey POKHODENKO
6
7 #include <ExchangePlugin_ExportFeature.h>
8
9 #include <algorithm>
10 #include <iterator>
11 #include <string>
12 #ifdef _DEBUG
13 #include <iostream>
14 #include <ostream>
15 #endif
16
17 #include <Config_Common.h>
18 #include <Config_PropManager.h>
19
20 #include <GeomAlgoAPI_BREPExport.h>
21 #include <GeomAlgoAPI_CompoundBuilder.h>
22 #include <GeomAlgoAPI_IGESExport.h>
23 #include <GeomAlgoAPI_STEPExport.h>
24 #include <GeomAlgoAPI_Tools.h>
25 #include <GeomAlgoAPI_XAOExport.h>
26
27 #include <GeomAPI_Shape.h>
28
29 #include <ModelAPI_AttributeSelectionList.h>
30 #include <ModelAPI_AttributeString.h>
31 #include <ModelAPI_AttributeStringArray.h>
32 #include <ModelAPI_AttributeIntArray.h>
33 #include <ModelAPI_AttributeTables.h>
34 #include <ModelAPI_Data.h>
35 #include <ModelAPI_Document.h>
36 #include <ModelAPI_Object.h>
37 #include <ModelAPI_ResultBody.h>
38 #include <ModelAPI_ResultGroup.h>
39 #include <ModelAPI_ResultField.h>
40 #include <ModelAPI_Session.h>
41 #include <ModelAPI_Validator.h>
42
43 #include <XAO_Group.hxx>
44 #include <XAO_Field.hxx>
45 #include <XAO_Xao.hxx>
46
47 #include <ExchangePlugin_Tools.h>
48
49 ExchangePlugin_ExportFeature::ExchangePlugin_ExportFeature()
50 {
51 }
52
53 ExchangePlugin_ExportFeature::~ExchangePlugin_ExportFeature()
54 {
55   // TODO Auto-generated destructor stub
56 }
57
58 /*
59  * Request for initialization of data model of the feature: adding all attributes
60  */
61 void ExchangePlugin_ExportFeature::initAttributes()
62 {
63   data()->addAttribute(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID(),
64     ModelAPI_AttributeString::typeId());
65   data()->addAttribute(ExchangePlugin_ExportFeature::FILE_PATH_ID(),
66     ModelAPI_AttributeString::typeId());
67   data()->addAttribute(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID(),
68     ModelAPI_AttributeString::typeId());
69   data()->addAttribute(ExchangePlugin_ExportFeature::FILE_FORMAT_ID(),
70     ModelAPI_AttributeString::typeId());
71   data()->addAttribute(ExchangePlugin_ExportFeature::SELECTION_LIST_ID(),
72     ModelAPI_AttributeSelectionList::typeId());
73   data()->addAttribute(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID(),
74     ModelAPI_AttributeString::typeId());
75   data()->addAttribute(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID(),
76     ModelAPI_AttributeString::typeId());
77
78   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
79     ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID());
80   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
81     ExchangePlugin_ExportFeature::XAO_AUTHOR_ID());
82   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
83     ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID());
84 }
85
86 void ExchangePlugin_ExportFeature::attributeChanged(const std::string& theID)
87 {
88   if (theID == XAO_FILE_PATH_ID()) {
89     string(ExchangePlugin_ExportFeature::FILE_PATH_ID())->setValue(
90       string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID())->value());
91   }
92 }
93
94 /*
95  * Computes or recomputes the results
96  */
97 void ExchangePlugin_ExportFeature::execute()
98 {
99   AttributeStringPtr aFormatAttr =
100       this->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID());
101   std::string aFormat = aFormatAttr->value();
102
103   AttributeStringPtr aFilePathAttr =
104       this->string(ExchangePlugin_ExportFeature::FILE_PATH_ID());
105   std::string aFilePath = aFilePathAttr->value();
106   if (aFilePath.empty())
107     return;
108
109   exportFile(aFilePath, aFormat);
110 }
111
112 void ExchangePlugin_ExportFeature::exportFile(const std::string& theFileName,
113                                               const std::string& theFormat)
114 {
115   std::string aFormatName = theFormat;
116
117   if (aFormatName.empty()) { // get default format for the extension
118     // ".brep" -> "BREP"
119     std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(theFileName);
120     if (anExtension == "BREP" || anExtension == "BRP") {
121       aFormatName = "BREP";
122     } else if (anExtension == "STEP" || anExtension == "STP") {
123       aFormatName = "STEP";
124     } else if (anExtension == "IGES" || anExtension == "IGS") {
125       aFormatName = "IGES-5.1";
126     } else if (anExtension == "XAO") {
127       aFormatName = "XAO";
128     } else {
129       aFormatName = anExtension;
130     }
131   }
132
133   if (aFormatName == "XAO") {
134     exportXAO(theFileName);
135     return;
136   }
137
138   // make shape for export from selected shapes
139   AttributeSelectionListPtr aSelectionListAttr =
140       this->selectionList(ExchangePlugin_ExportFeature::SELECTION_LIST_ID());
141   std::list<GeomShapePtr> aShapes;
142   for (int i = 0, aSize = aSelectionListAttr->size(); i < aSize; ++i) {
143     AttributeSelectionPtr anAttrSelection = aSelectionListAttr->value(i);
144     std::shared_ptr<GeomAPI_Shape> aCurShape = anAttrSelection->value();
145     if (aCurShape.get() == NULL)
146       aCurShape = anAttrSelection->context()->shape();
147     if (aCurShape.get() != NULL)
148       aShapes.push_back(aCurShape);
149   }
150
151   // Store compound if we have more than one shape.
152   std::shared_ptr<GeomAPI_Shape> aShape;
153   if(aShapes.size() == 1) {
154     aShape = aShapes.front();
155   } else {
156     aShape = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
157   }
158
159   // Perform the export
160   std::string anError;
161   bool aResult = false;
162   if (aFormatName == "BREP") {
163     aResult = BREPExport(theFileName, aFormatName, aShape, anError);
164   } else if (aFormatName == "STEP") {
165     aResult = STEPExport(theFileName, aFormatName, aShape, anError);
166   } else if (aFormatName.substr(0, 4) == "IGES") {
167     aResult = IGESExport(theFileName, aFormatName, aShape, anError);
168   } else {
169     anError = "Unsupported format: " + aFormatName;
170   }
171
172   if (!anError.empty()) {
173     setError("An error occurred while exporting " + theFileName + ": " + anError);
174     return;
175   }
176 }
177
178 void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName)
179 {
180   try {
181
182   std::string anError;
183   XAO::Xao aXao;
184
185   // author
186
187   std::string anAuthor = string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID())->value();
188   aXao.setAuthor(anAuthor);
189
190   // make shape for export from all results
191   std::list<GeomShapePtr> aShapes;
192   int aBodyCount = document()->size(ModelAPI_ResultBody::group());
193   for (int aBodyIndex = 0; aBodyIndex < aBodyCount; ++aBodyIndex) {
194     ResultBodyPtr aResultBody =
195         std::dynamic_pointer_cast<ModelAPI_ResultBody>(
196             document()->object(ModelAPI_ResultBody::group(), aBodyIndex));
197     if (!aResultBody.get())
198       continue;
199     aShapes.push_back(aResultBody->shape());
200   }
201   GeomShapePtr aShape = (aShapes.size() == 1)
202       ? *aShapes.begin()
203       : GeomAlgoAPI_CompoundBuilder::compound(aShapes);
204
205   SetShapeToXAO(aShape, &aXao, anError);
206
207   if (!anError.empty()) {
208     setError("An error occurred while exporting " + theFileName + ": " + anError);
209     return;
210   }
211
212   // geometry name
213
214   std::string aGeometryName = string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
215   aXao.getGeometry()->setName(aGeometryName);
216
217   // groups
218
219   int aGroupCount = document()->size(ModelAPI_ResultGroup::group());
220   for (int aGroupIndex = 0; aGroupIndex < aGroupCount; ++aGroupIndex) {
221     ResultGroupPtr aResultGroup =
222         std::dynamic_pointer_cast<ModelAPI_ResultGroup>(
223             document()->object(ModelAPI_ResultGroup::group(), aGroupIndex));
224
225     FeaturePtr aGroupFeature = document()->feature(aResultGroup);
226
227     AttributeSelectionListPtr aSelectionList =
228         aGroupFeature->selectionList("group_list");
229
230     // conversion of dimension
231     std::string aSelectionType = aSelectionList->selectionType();
232     std::string aDimensionString = 
233       ExchangePlugin_Tools::selectionType2xaoDimension(aSelectionType);
234     XAO::Dimension aGroupDimension = XAO::XaoUtils::stringToDimension(aDimensionString);
235
236     XAO::Group* aXaoGroup = aXao.addGroup(aGroupDimension,
237                                           aResultGroup->data()->name());
238
239     for (int aSelectionIndex = 0; aSelectionIndex < aSelectionList->size(); ++aSelectionIndex) {
240       AttributeSelectionPtr aSelection = aSelectionList->value(aSelectionIndex);
241
242       // complex conversion of reference id to element index
243       int aReferenceID = aSelection->Id();
244       std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID);
245       int anElementID =
246         aXao.getGeometry()->getElementIndexByReference(aGroupDimension, aReferenceString);
247
248       aXaoGroup->add(anElementID);
249     }
250   }
251
252   // fields
253   int aFieldCount = document()->size(ModelAPI_ResultField::group());
254   for (int aFieldIndex = 0; aFieldIndex < aFieldCount; ++aFieldIndex) {
255     ResultFieldPtr aResultField =
256         std::dynamic_pointer_cast<ModelAPI_ResultField>(
257             document()->object(ModelAPI_ResultField::group(), aFieldIndex));
258
259     FeaturePtr aFieldFeature = document()->feature(aResultField);
260
261     AttributeSelectionListPtr aSelectionList =
262         aFieldFeature->selectionList("selected");
263
264     // conversion of dimension
265     std::string aSelectionType = aSelectionList->selectionType();
266     std::string aDimensionString = 
267       ExchangePlugin_Tools::selectionType2xaoDimension(aSelectionType);
268     XAO::Dimension aFieldDimension = XAO::XaoUtils::stringToDimension(aDimensionString);
269     bool isWholePart = aSelectionType == "part";
270     // get tables and their type
271     std::shared_ptr<ModelAPI_AttributeTables> aTables = aFieldFeature->tables("values");
272     std::string aTypeString = ExchangePlugin_Tools::valuesType2xaoType(aTables->type());
273     XAO::Type aFieldType = XAO::XaoUtils::stringToFieldType(aTypeString);
274
275     XAO::Field* aXaoField = aXao.addField(aFieldType, aFieldDimension, aTables->columns(),
276                                           aResultField->data()->name());
277     // set components names
278     AttributeStringArrayPtr aComponents = aFieldFeature->stringArray("components_names");
279     for(int aComp = 0; aComp < aComponents->size(); aComp++) {
280       std::string aName = aComponents->value(aComp);
281       aXaoField->setComponentName(aComp, aName);
282     }
283
284     AttributeIntArrayPtr aStamps = aFieldFeature->intArray("stamps");
285     for (int aStepIndex = 0; aStepIndex < aTables->tables(); aStepIndex++) {
286       XAO::Step* aStep = aXaoField->addNewStep(aStepIndex);
287       aStep->setStep(aStepIndex);
288       int aStampIndex = aStamps->value(aStepIndex);
289       aStep->setStamp(aStampIndex);
290       int aNumElements = isWholePart ? aXaoField->countElements() : aTables->rows();
291       int aNumComps = aTables->columns();
292       // omit default values first row
293       for(int aRow = isWholePart ? 0 : 1; aRow < aNumElements; aRow++) {
294         for(int aCol = 0; aCol < aNumComps; aCol++) {
295           int anElementID = 0;
296           if (!isWholePart) {
297             // element index actually is the ID of the selection
298             AttributeSelectionPtr aSelection = aSelectionList->value(aRow - 1);
299
300             // complex conversion of reference id to element index
301             int aReferenceID = aSelection->Id();
302             std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID);
303             int anElementID =
304               aXao.getGeometry()->getElementIndexByReference(aFieldDimension, aReferenceString);
305           }
306
307           ModelAPI_AttributeTables::Value aVal = aTables->value(
308             isWholePart ? 0 : aRow, aCol, aStepIndex);
309           std::ostringstream aStr; // string value
310           switch(aTables->type()) {
311           case ModelAPI_AttributeTables::BOOLEAN:
312             aStr<<(aVal.myBool ? "True" : "False");
313             break;
314           case ModelAPI_AttributeTables::INTEGER:
315             aStr<<aVal.myInt;
316             break;
317           case ModelAPI_AttributeTables::DOUBLE:
318             aStr<<aVal.myDouble;
319             break;
320           case ModelAPI_AttributeTables::STRING:
321             aStr<<aVal.myStr;
322             break;
323           }
324           std::string aStrVal = aStr.str();
325           aStep->setStringValue(isWholePart ? aRow : anElementID, aCol, aStrVal);
326         }
327       }
328     }
329   }
330
331
332   // exporting
333
334   XAOExport(theFileName, &aXao, anError);
335
336   if (!anError.empty()) {
337     setError("An error occurred while exporting " + theFileName + ": " + anError);
338     return;
339   }
340
341   } catch (XAO::XAO_Exception& e) {
342     std::string anError = e.what();
343     setError("An error occurred while exporting " + theFileName + ": " + anError);
344     return;
345   }
346 }