Salome HOME
[bos #40620] [CEA] XAO export for SHAPER: Allow export of brep in a separate file
[modules/shaper.git] / src / ExchangeAPI / ExchangeAPI_Export.cpp
1 // Copyright (C) 2014-2024  CEA, EDF
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "ExchangeAPI_Export.h"
21 //--------------------------------------------------------------------------------------
22 #include <ExchangePlugin_ExportPart.h>
23 //--------------------------------------------------------------------------------------
24 #include <Locale_Convert.h>
25 //--------------------------------------------------------------------------------------
26 #include <ModelAPI_Document.h>
27 #include <ModelAPI_Feature.h>
28 #include <ModelHighAPI_Tools.h>
29 #include <ModelHighAPI_Dumper.h>
30 #include <ModelHighAPI_Services.h>
31 #include <ModelHighAPI_Selection.h>
32 //--------------------------------------------------------------------------------------
33 #include <algorithm>
34 //--------------------------------------------------------------------------------------
35
36 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature)
37 : ModelHighAPI_Interface(theFeature)
38 {
39   initialize();
40 }
41
42 /// Constructor with values for XAO export.
43 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
44                                        const std::string & theFilePath,
45                                        const std::string & theAuthor,
46                                        const std::string & theGeometryName,
47                                        const std::string & theShapeFilePath)
48 : ModelHighAPI_Interface(theFeature)
49 {
50   initialize();
51   fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
52   fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID()));
53   fillAttribute(theShapeFilePath,
54                 theFeature->string(ExchangePlugin_ExportFeature::XAO_SHAPE_FILE_PATH_ID()));
55   fillAttribute(theAuthor, theFeature->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()));
56   fillAttribute(theGeometryName,
57                 theFeature->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID()));
58   fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
59   execute();
60   apply(); // finish operation to make sure the export is done on the current state of the history
61 }
62
63 // Constructor with values for STL of selected result export.
64 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
65                                        const std::string & theFilePath,
66                                        const ModelHighAPI_Selection& theSelectedShape,
67                                        const ModelHighAPI_Double& theDeflectionRelative,
68                                        const ModelHighAPI_Double& theDeflectionAbsolute,
69                                        const bool theIsRelative,
70                                        const bool theIsASCII)
71   : ModelHighAPI_Interface(theFeature)
72 {
73   initialize();
74   fillAttribute("STL", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
75   fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::STL_FILE_PATH_ID()));
76
77   if (theIsRelative) {
78     fillAttribute(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_RELATIVE(),
79       theFeature->string(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE()) );
80     fillAttribute(theDeflectionRelative,
81       theFeature->real(ExchangePlugin_ExportFeature::STL_RELATIVE()) );
82   }
83   else {
84     fillAttribute(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_ABSOLUTE(),
85       theFeature->string(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE()) );
86     fillAttribute(theDeflectionAbsolute,
87       theFeature->real(ExchangePlugin_ExportFeature::STL_ABSOLUTE()) );
88   }
89
90   if(theIsASCII){
91     fillAttribute(ExchangePlugin_ExportFeature::STL_FILE_TYPE_ASCII(),
92       theFeature->string(ExchangePlugin_ExportFeature::STL_FILE_TYPE()));
93   }
94   else
95   {
96     fillAttribute(ExchangePlugin_ExportFeature::STL_FILE_TYPE_BINARY(),
97       theFeature->string(ExchangePlugin_ExportFeature::STL_FILE_TYPE()));
98   }
99
100   fillAttribute(theSelectedShape,
101                 theFeature->selection(ExchangePlugin_ExportFeature::STL_OBJECT_SELECTED()));
102   fillAttribute("STL", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
103   execute();
104   apply(); // finish operation to make sure the export is done on the current state of the history
105 }
106
107 /// Constructor with values for XAO of selected result export.
108 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
109                                        const std::string & theFilePath,
110                                        const ModelHighAPI_Selection& theResult,
111                                        const std::string & theAuthor,
112                                        const std::string & theGeometryName,
113                                        const std::string & theShapeFilePath)
114   : ModelHighAPI_Interface(theFeature)
115 {
116   initialize();
117   fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
118   fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID()));
119   fillAttribute(theShapeFilePath,
120                 theFeature->string(ExchangePlugin_ExportFeature::XAO_SHAPE_FILE_PATH_ID()));
121   fillAttribute(theAuthor, theFeature->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()));
122   fillAttribute(theGeometryName,
123                 theFeature->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID()));
124   fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
125   std::list<ModelHighAPI_Selection> aListOfOneSel;
126   aListOfOneSel.push_back(theResult);
127   fillAttribute(aListOfOneSel,
128                 theFeature->selectionList(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID()));
129   execute();
130   apply(); // finish operation to make sure the export is done on the current state of the history
131 }
132
133 /// Constructor with values for XAO of selected result export to memory buffer.
134 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
135                                        const ModelHighAPI_Selection& theResult,
136                                        const std::string & theAuthor,
137                                        const std::string & theGeometryName)
138   : ModelHighAPI_Interface(theFeature)
139 {
140   initialize();
141   fillAttribute("XAOMem", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
142   fillAttribute(theAuthor, theFeature->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()));
143   fillAttribute(theGeometryName,
144                 theFeature->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID()));
145   fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
146   std::list<ModelHighAPI_Selection> aListOfOneSel;
147   aListOfOneSel.push_back(theResult);
148   fillAttribute(aListOfOneSel,
149                 theFeature->selectionList(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID()));
150   execute();
151   apply(); // finish operation to make sure the export is done on the current state of the history
152 }
153
154 /// Constructor with values for export in other formats than XAO.
155 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
156                               const std::string & theFilePath,
157                               const std::list<ModelHighAPI_Selection> & theSelectionList,
158                               const std::string & theFileFormat)
159 : ModelHighAPI_Interface(theFeature)
160 {
161   initialize();
162   fillAttribute("Regular", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
163   fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::FILE_PATH_ID()));
164   fillAttribute(theSelectionList,
165                 theFeature->selectionList(ExchangePlugin_ExportFeature::SELECTION_LIST_ID()));
166   fillAttribute(theFileFormat, theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
167   execute();
168   apply(); // finish operation to make sure the export is done on the current state of the history
169 }
170
171 ExchangeAPI_Export::~ExchangeAPI_Export()
172 {
173 }
174
175 // this method is needed on Windows because back-slashes in python may cause error
176 static void correctSeparators(std::string& thePath) {
177   // replace single "\" or triple "\\\" or more by double "\"
178   for (std::size_t aFind = thePath.find('\\'); aFind != std::string::npos;
179     aFind = thePath.find('\\', aFind)) {
180     // search the next
181     std::size_t aFind2 = thePath.find('\\', aFind + 1);
182     if (aFind2 == std::string::npos || aFind2 > aFind + 1) { // single, so add one more
183       thePath.replace(aFind, 1, 2, '\\');
184     } else { // if there is more than double "\", remove them
185       for (aFind2 = thePath.find('\\', aFind2 + 1);
186            aFind2 != std::string::npos && aFind2 <= aFind + 2;
187            aFind2 = thePath.find('\\', aFind2)) {
188         thePath.erase(aFind2, 1);
189       }
190     }
191     aFind += 2;
192   }
193 }
194
195 void ExchangeAPI_Export::dump(ModelHighAPI_Dumper& theDumper) const
196 {
197   FeaturePtr aBase = feature();
198   const std::string& aDocName = theDumper.name(aBase->document());
199
200   std::string exportType = aBase->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID())->value();
201
202   if (exportType == "XAOMem") {
203     std::string aGeometryName =
204       aBase->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
205
206     theDumper << "aXAOBuff";
207     std::string aGeometryNamePy;
208     if (! aGeometryName.empty()) {
209       aGeometryNamePy = aGeometryName;
210     }
211     else {
212       aGeometryNamePy = Locale::Convert::toString(aBase->data()->name());
213     }
214     if (! aGeometryNamePy.empty()) {
215       // add shape name
216       std::replace(aGeometryNamePy.begin(), aGeometryNamePy.end(), ' ', '_');
217       theDumper << "_" << aGeometryNamePy;
218     }
219     theDumper << " = model.exportToXAOMem(" << aDocName;
220     AttributeSelectionListPtr aShapeSelected =
221       aBase->selectionList(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID());
222     if (aShapeSelected->isInitialized() && aShapeSelected->size() == 1) {
223       theDumper << ", " << aShapeSelected->value(0);
224     }
225
226     std::string theAuthor = aBase->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID())->value();
227     if (! theAuthor.empty())
228       theDumper << ", '" << theAuthor << "'";
229     if (! aGeometryName.empty())
230       theDumper << ", '" << aGeometryName << "'";
231     theDumper << ")" << std::endl;
232     return;
233   }
234
235   theDumper << aBase << " = model.";
236
237   if (exportType == "XAO") {
238     std::string aTmpXAOFile =
239       aBase->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID())->value();
240     correctSeparators(aTmpXAOFile);
241     theDumper << "exportToXAO(" << aDocName << ", '" << aTmpXAOFile << "'" ;
242     AttributeSelectionListPtr aShapeSelected =
243       aBase->selectionList(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID());
244     if (aShapeSelected->isInitialized() && aShapeSelected->size() == 1) {
245       theDumper<<", "<<aShapeSelected->value(0);
246     }
247
248     std::string theAuthor = aBase->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID())->value();
249     if (! theAuthor.empty())
250       theDumper << ", '" << theAuthor << "'";
251     std::string theGeometryName =
252       aBase->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
253     if (! theGeometryName.empty())
254       theDumper << ", '" << theGeometryName << "'";
255     theDumper << ")" << std::endl;
256   }
257   else if (exportType == "STL") {
258     std::string aTmpSTLFile =
259                 aBase->string(ExchangePlugin_ExportFeature::STL_FILE_PATH_ID())->value();
260     correctSeparators(aTmpSTLFile);
261     theDumper << "exportToSTL(" << aDocName << ", '" << aTmpSTLFile << "'" ;
262     AttributeSelectionPtr aShapeSelected =
263       aBase->selection(ExchangePlugin_ExportFeature::STL_OBJECT_SELECTED());
264
265     theDumper<<","<< aShapeSelected;
266
267     theDumper <<","<<  stlabsolute() <<","<< stlrelative();
268
269     if (stldeflectionType()->value()
270          == ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_RELATIVE()){
271       theDumper <<","<< "True";
272     }
273     else {
274       theDumper <<","<< "False";
275     }
276
277     if (stlfileType()->value() == ExchangePlugin_ExportFeature::STL_FILE_TYPE_BINARY()) {
278       theDumper << "False";
279     }
280     else {
281       theDumper <<  "True";
282     }
283     theDumper << ")" << std::endl;
284   }
285   else {
286     std::string aFilePath = aBase->string(ExchangePlugin_ExportFeature::FILE_PATH_ID())->value();
287     correctSeparators(aFilePath);
288       theDumper << "exportToFile(" << aDocName << ", \"" << aFilePath << "\", " <<
289       aBase->selectionList(ExchangePlugin_ExportFeature::SELECTION_LIST_ID());
290     std::string theFileFormat =
291       aBase->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID())->value();
292     if (!theFileFormat.empty())
293       theDumper << ", '" << theFileFormat << "'";
294     theDumper << ")" << std::endl;
295   }
296 }
297
298 ExportPtr exportToFile(const std::shared_ptr<ModelAPI_Document> & thePart,
299                   const std::string & theFilePath,
300                   const std::list<ModelHighAPI_Selection> & theSelectionList,
301                   const std::string & theFileFormat)
302 {
303   apply(); // finish previous operation to make sure all previous operations are done
304   std::shared_ptr<ModelAPI_Feature> aFeature =
305     thePart->addFeature(ExchangePlugin_ExportFeature::ID());
306   return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theSelectionList, theFileFormat));
307 }
308
309 ExportPtr exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
310                       const std::string & theFilePath,
311                       const std::string & theAuthor,
312                       const std::string & theGeometryName,
313                       const std::string & theShapeFilePath)
314 {
315   apply(); // finish previous operation to make sure all previous operations are done
316   std::shared_ptr<ModelAPI_Feature> aFeature =
317     thePart->addFeature(ExchangePlugin_ExportFeature::ID());
318   return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theAuthor, theGeometryName, theShapeFilePath));
319 }
320
321 ExportPtr exportToSTL(const std::shared_ptr<ModelAPI_Document> & thePart,
322       const std::string & theFilePath,
323       const ModelHighAPI_Selection& theSelectedShape,
324       const ModelHighAPI_Double&  theDeflectionRelative,
325       const ModelHighAPI_Double&  theDeflectionAbsolute,
326       const bool theIsRelative,
327       const bool theIsASCII)
328 {
329   apply(); // finish previous operation to make sure all previous operations are done
330   std::shared_ptr<ModelAPI_Feature> aFeature =
331     thePart->addFeature(ExchangePlugin_ExportFeature::ID());
332
333   return ExportPtr(new ExchangeAPI_Export(aFeature,
334                                           theFilePath,
335                                           theSelectedShape,
336                                           theDeflectionRelative,
337                                           theDeflectionAbsolute,
338                                           theIsRelative,
339                                           theIsASCII));
340 }
341
342 ExportPtr exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
343                       const std::string & theFilePath,
344                       const ModelHighAPI_Selection& theSelectedShape,
345                       const std::string & /*theAuthor*/,
346                       const std::string & /*theGeometryName*/,
347                       const std::string & theShapeFilePath)
348 {
349   apply(); // finish previous operation to make sure all previous operations are done
350   std::shared_ptr<ModelAPI_Feature> aFeature =
351     thePart->addFeature(ExchangePlugin_ExportFeature::ID());
352   // special internal case when for XAO a selection list is filled
353   return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theSelectedShape, "XAO", "", theShapeFilePath));
354 }
355
356 PyObject* exportToXAOMem(const std::shared_ptr<ModelAPI_Document> & thePart,
357                            const ModelHighAPI_Selection& theSelectedShape,
358                            const std::string & theAuthor,
359                            const std::string & theGeometryName)
360 {
361   apply(); // finish previous operation to make sure all previous operations are done
362   std::shared_ptr<ModelAPI_Feature> aFeature =
363     thePart->addFeature(ExchangePlugin_ExportFeature::ID());
364   ExportPtr aXAOExportAPI (new ExchangeAPI_Export
365                            (aFeature, theSelectedShape, theAuthor, theGeometryName));
366   std::string aBuff = aFeature->string(ExchangePlugin_ExportFeature::MEMORY_BUFFER_ID())->value();
367   return PyBytes_FromStringAndSize(aBuff.c_str(), aBuff.length());
368 }
369
370 void exportPart(const std::shared_ptr<ModelAPI_Document> & thePart,
371                 const std::string & theFilePath,
372                 const std::list<ModelHighAPI_Selection> & theSelected)
373 {
374   FeaturePtr aFeature = thePart->addFeature(ExchangePlugin_ExportPart::ID());
375   aFeature->string(ExchangePlugin_ExportPart::FILE_PATH_ID())->setValue(theFilePath);
376   if (!theSelected.empty()) {
377     fillAttribute(theSelected,
378         aFeature->selectionList(ExchangePlugin_ExportPart::SELECTION_LIST_ID()));
379   }
380   // restart transaction to execute and delete the macro-feature
381   apply();
382 }
383 //--------------------------------------------------------------------------------------