Salome HOME
Fix bos #38359 exportToXAOMem calls exportXAO twice
[modules/shaper.git] / src / ExchangeAPI / ExchangeAPI_Export.cpp
1 // Copyright (C) 2014-2023  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 : ModelHighAPI_Interface(theFeature)
48 {
49   initialize();
50   fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
51   fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID()));
52   fillAttribute(theAuthor, theFeature->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()));
53   fillAttribute(theGeometryName,
54                 theFeature->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID()));
55   fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
56   execute();
57   apply(); // finish operation to make sure the export is done on the current state of the history
58 }
59
60 // Constructor with values for STL of selected result export.
61 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
62                                        const std::string & theFilePath,
63                                        const ModelHighAPI_Selection& theSelectedShape,
64                                        const ModelHighAPI_Double& theDeflectionRelative,
65                                        const ModelHighAPI_Double& theDeflectionAbsolute,
66                                        const bool theIsRelative,
67                                        const bool theIsASCII)
68   : ModelHighAPI_Interface(theFeature)
69 {
70   initialize();
71   fillAttribute("STL", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
72   fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::STL_FILE_PATH_ID()));
73
74   if (theIsRelative) {
75     fillAttribute(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_RELATIVE(),
76       theFeature->string(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE()) );
77     fillAttribute(theDeflectionRelative,
78       theFeature->real(ExchangePlugin_ExportFeature::STL_RELATIVE()) );
79   }
80   else {
81     fillAttribute(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_ABSOLUTE(),
82       theFeature->string(ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE()) );
83     fillAttribute(theDeflectionAbsolute,
84       theFeature->real(ExchangePlugin_ExportFeature::STL_ABSOLUTE()) );
85   }
86
87   if(theIsASCII){
88     fillAttribute(ExchangePlugin_ExportFeature::STL_FILE_TYPE_ASCII(),
89       theFeature->string(ExchangePlugin_ExportFeature::STL_FILE_TYPE()));
90   }
91   else
92   {
93     fillAttribute(ExchangePlugin_ExportFeature::STL_FILE_TYPE_BINARY(),
94       theFeature->string(ExchangePlugin_ExportFeature::STL_FILE_TYPE()));
95   }
96
97   fillAttribute(theSelectedShape,
98                 theFeature->selection(ExchangePlugin_ExportFeature::STL_OBJECT_SELECTED()));
99   fillAttribute("STL", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
100   execute();
101   apply(); // finish operation to make sure the export is done on the current state of the history
102 }
103
104 /// Constructor with values for XAO of selected result export.
105 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
106                                        const std::string & theFilePath,
107                                        const ModelHighAPI_Selection& theResult,
108                                        const std::string & theAuthor,
109                                        const std::string & theGeometryName)
110   : ModelHighAPI_Interface(theFeature)
111 {
112   initialize();
113   fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
114   fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID()));
115   fillAttribute(theAuthor, theFeature->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()));
116   fillAttribute(theGeometryName,
117     theFeature->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID()));
118   fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
119   std::list<ModelHighAPI_Selection> aListOfOneSel;
120   aListOfOneSel.push_back(theResult);
121   fillAttribute(aListOfOneSel,
122     theFeature->selectionList(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID()));
123   execute();
124   apply(); // finish operation to make sure the export is done on the current state of the history
125 }
126
127 /// Constructor with values for XAO of selected result export to memory buffer.
128 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
129                                        const ModelHighAPI_Selection& theResult,
130                                        const std::string & theAuthor,
131                                        const std::string & theGeometryName)
132   : ModelHighAPI_Interface(theFeature)
133 {
134   initialize();
135   fillAttribute("XAOMem", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
136   fillAttribute(theAuthor, theFeature->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()));
137   fillAttribute(theGeometryName,
138                 theFeature->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID()));
139   fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
140   std::list<ModelHighAPI_Selection> aListOfOneSel;
141   aListOfOneSel.push_back(theResult);
142   fillAttribute(aListOfOneSel,
143                 theFeature->selectionList(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID()));
144   execute();
145   apply(); // finish operation to make sure the export is done on the current state of the history
146 }
147
148 /// Constructor with values for export in other formats than XAO.
149 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
150                               const std::string & theFilePath,
151                               const std::list<ModelHighAPI_Selection> & theSelectionList,
152                               const std::string & theFileFormat)
153 : ModelHighAPI_Interface(theFeature)
154 {
155   initialize();
156   fillAttribute("Regular", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
157   fillAttribute(theFilePath, theFeature->string(ExchangePlugin_ExportFeature::FILE_PATH_ID()));
158   fillAttribute(theSelectionList,
159                 theFeature->selectionList(ExchangePlugin_ExportFeature::SELECTION_LIST_ID()));
160   fillAttribute(theFileFormat, theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
161   execute();
162   apply(); // finish operation to make sure the export is done on the current state of the history
163 }
164
165 ExchangeAPI_Export::~ExchangeAPI_Export()
166 {
167 }
168
169 // this method is needed on Windows because back-slashes in python may cause error
170 static void correctSeparators(std::string& thePath) {
171   // replace single "\" or triple "\\\" or more by double "\"
172   for (std::size_t aFind = thePath.find('\\'); aFind != std::string::npos;
173     aFind = thePath.find('\\', aFind)) {
174     // search the next
175     std::size_t aFind2 = thePath.find('\\', aFind + 1);
176     if (aFind2 == std::string::npos || aFind2 > aFind + 1) { // single, so add one more
177       thePath.replace(aFind, 1, 2, '\\');
178     } else { // if there is more than double "\", remove them
179       for (aFind2 = thePath.find('\\', aFind2 + 1);
180            aFind2 != std::string::npos && aFind2 <= aFind + 2;
181            aFind2 = thePath.find('\\', aFind2)) {
182         thePath.erase(aFind2, 1);
183       }
184     }
185     aFind += 2;
186   }
187 }
188
189 void ExchangeAPI_Export::dump(ModelHighAPI_Dumper& theDumper) const
190 {
191   FeaturePtr aBase = feature();
192   const std::string& aDocName = theDumper.name(aBase->document());
193
194   std::string exportType = aBase->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID())->value();
195
196   if (exportType == "XAOMem") {
197     std::string aGeometryName =
198       aBase->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
199
200     theDumper << "aXAOBuff";
201     std::string aGeometryNamePy;
202     if (! aGeometryName.empty()) {
203       aGeometryNamePy = aGeometryName;
204     }
205     else {
206       aGeometryNamePy = Locale::Convert::toString(aBase->data()->name());
207     }
208     if (! aGeometryNamePy.empty()) {
209       // add shape name
210       std::replace(aGeometryNamePy.begin(), aGeometryNamePy.end(), ' ', '_');
211       theDumper << "_" << aGeometryNamePy;
212     }
213     theDumper << " = model.exportToXAOMem(" << aDocName;
214     AttributeSelectionListPtr aShapeSelected =
215       aBase->selectionList(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID());
216     if (aShapeSelected->isInitialized() && aShapeSelected->size() == 1) {
217       theDumper << ", " << aShapeSelected->value(0);
218     }
219
220     std::string theAuthor = aBase->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID())->value();
221     if (! theAuthor.empty())
222       theDumper << ", '" << theAuthor << "'";
223     if (! aGeometryName.empty())
224       theDumper << ", '" << aGeometryName << "'";
225     theDumper << ")" << std::endl;
226     return;
227   }
228
229   theDumper << aBase << " = model.";
230
231   if (exportType == "XAO") {
232     std::string aTmpXAOFile =
233       aBase->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID())->value();
234     correctSeparators(aTmpXAOFile);
235     theDumper << "exportToXAO(" << aDocName << ", '" << aTmpXAOFile << "'" ;
236     AttributeSelectionListPtr aShapeSelected =
237       aBase->selectionList(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID());
238     if (aShapeSelected->isInitialized() && aShapeSelected->size() == 1) {
239       theDumper<<", "<<aShapeSelected->value(0);
240     }
241
242     std::string theAuthor = aBase->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID())->value();
243     if (! theAuthor.empty())
244       theDumper << ", '" << theAuthor << "'";
245     std::string theGeometryName =
246       aBase->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
247     if (! theGeometryName.empty())
248       theDumper << ", '" << theGeometryName << "'";
249     theDumper << ")" << std::endl;
250   }
251   else if (exportType == "STL") {
252     std::string aTmpSTLFile =
253                 aBase->string(ExchangePlugin_ExportFeature::STL_FILE_PATH_ID())->value();
254     correctSeparators(aTmpSTLFile);
255     theDumper << "exportToSTL(" << aDocName << ", '" << aTmpSTLFile << "'" ;
256     AttributeSelectionPtr aShapeSelected =
257       aBase->selection(ExchangePlugin_ExportFeature::STL_OBJECT_SELECTED());
258
259     theDumper<<","<< aShapeSelected;
260
261     theDumper <<","<<  stlabsolute() <<","<< stlrelative();
262
263     if (stldeflectionType()->value()
264          == ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_RELATIVE()){
265       theDumper <<","<< "True";
266     }
267     else {
268       theDumper <<","<< "False";
269     }
270
271     if (stlfileType()->value() == ExchangePlugin_ExportFeature::STL_FILE_TYPE_BINARY()) {
272       theDumper << "False";
273     }
274     else {
275       theDumper <<  "True";
276     }
277     theDumper << ")" << std::endl;
278   }
279   else {
280     std::string aFilePath = aBase->string(ExchangePlugin_ExportFeature::FILE_PATH_ID())->value();
281     correctSeparators(aFilePath);
282       theDumper << "exportToFile(" << aDocName << ", \"" << aFilePath << "\", " <<
283       aBase->selectionList(ExchangePlugin_ExportFeature::SELECTION_LIST_ID());
284     std::string theFileFormat =
285       aBase->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID())->value();
286     if (!theFileFormat.empty())
287       theDumper << ", '" << theFileFormat << "'";
288     theDumper << ")" << std::endl;
289   }
290 }
291
292 ExportPtr exportToFile(const std::shared_ptr<ModelAPI_Document> & thePart,
293                   const std::string & theFilePath,
294                   const std::list<ModelHighAPI_Selection> & theSelectionList,
295                   const std::string & theFileFormat)
296 {
297   apply(); // finish previous operation to make sure all previous operations are done
298   std::shared_ptr<ModelAPI_Feature> aFeature =
299     thePart->addFeature(ExchangePlugin_ExportFeature::ID());
300   return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theSelectionList, theFileFormat));
301 }
302
303 ExportPtr exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
304                  const std::string & theFilePath,
305                  const std::string & theAuthor,
306                  const std::string & theGeometryName)
307 {
308   apply(); // finish previous operation to make sure all previous operations are done
309   std::shared_ptr<ModelAPI_Feature> aFeature =
310     thePart->addFeature(ExchangePlugin_ExportFeature::ID());
311   return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theAuthor, theGeometryName));
312 }
313
314 ExportPtr exportToSTL(const std::shared_ptr<ModelAPI_Document> & thePart,
315       const std::string & theFilePath,
316       const ModelHighAPI_Selection& theSelectedShape,
317       const ModelHighAPI_Double&  theDeflectionRelative,
318       const ModelHighAPI_Double&  theDeflectionAbsolute,
319       const bool theIsRelative,
320       const bool theIsASCII)
321 {
322   apply(); // finish previous operation to make sure all previous operations are done
323   std::shared_ptr<ModelAPI_Feature> aFeature =
324     thePart->addFeature(ExchangePlugin_ExportFeature::ID());
325
326   return ExportPtr(new ExchangeAPI_Export(aFeature,
327                                           theFilePath,
328                                           theSelectedShape,
329                                           theDeflectionRelative,
330                                           theDeflectionAbsolute,
331                                           theIsRelative,
332                                           theIsASCII));
333 }
334
335 ExportPtr exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
336                       const std::string & theFilePath,
337                       const ModelHighAPI_Selection& theSelectedShape,
338                       const std::string & /*theAuthor*/,
339                       const std::string & /*theGeometryName*/)
340 {
341   apply(); // finish previous operation to make sure all previous operations are done
342   std::shared_ptr<ModelAPI_Feature> aFeature =
343     thePart->addFeature(ExchangePlugin_ExportFeature::ID());
344   // special internal case when for XAO a selection list is filled
345   return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theSelectedShape, "XAO"));
346 }
347
348 PyObject* exportToXAOMem(const std::shared_ptr<ModelAPI_Document> & thePart,
349                            const ModelHighAPI_Selection& theSelectedShape,
350                            const std::string & theAuthor,
351                            const std::string & theGeometryName)
352 {
353   apply(); // finish previous operation to make sure all previous operations are done
354   std::shared_ptr<ModelAPI_Feature> aFeature =
355     thePart->addFeature(ExchangePlugin_ExportFeature::ID());
356   ExportPtr aXAOExportAPI (new ExchangeAPI_Export
357                            (aFeature, theSelectedShape, theAuthor, theGeometryName));
358   std::string aBuff = aFeature->string(ExchangePlugin_ExportFeature::MEMORY_BUFFER_ID())->value();
359   return PyBytes_FromStringAndSize(aBuff.c_str(), aBuff.length());
360 }
361
362 void exportPart(const std::shared_ptr<ModelAPI_Document> & thePart,
363                 const std::string & theFilePath,
364                 const std::list<ModelHighAPI_Selection> & theSelected)
365 {
366   FeaturePtr aFeature = thePart->addFeature(ExchangePlugin_ExportPart::ID());
367   aFeature->string(ExchangePlugin_ExportPart::FILE_PATH_ID())->setValue(theFilePath);
368   if (!theSelected.empty()) {
369     fillAttribute(theSelected,
370         aFeature->selectionList(ExchangePlugin_ExportPart::SELECTION_LIST_ID()));
371   }
372   // restart transaction to execute and delete the macro-feature
373   apply();
374 }
375 //--------------------------------------------------------------------------------------