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