Salome HOME
Fix crashes of Sketcher and Import/Export
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IInsertOperations.cxx
1 #include <Standard_Stream.hxx>
2
3 #include <GEOMImpl_IInsertOperations.hxx>
4
5 #include "utilities.h"
6 #include <OpUtil.hxx>
7 #include <Utils_ExceptHandlers.hxx>
8
9 #include <TFunction_DriverTable.hxx>
10 #include <TFunction_Driver.hxx>
11 #include <TFunction_Logbook.hxx>
12 #include <TDF_Tool.hxx>
13
14 #include <GEOM_Function.hxx>
15 #include <GEOM_PythonDump.hxx>
16
17 #include <GEOMImpl_CopyDriver.hxx>
18 #include <GEOMImpl_ExportDriver.hxx>
19 #include <GEOMImpl_ImportDriver.hxx>
20
21 #include <GEOMImpl_ICopy.hxx>
22 #include <GEOMImpl_IImportExport.hxx>
23
24 #include <GEOMImpl_Types.hxx>
25
26 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
27
28 //=============================================================================
29 /*!
30  *   constructor:
31  */
32 //=============================================================================
33
34 GEOMImpl_IInsertOperations::GEOMImpl_IInsertOperations(GEOM_Engine* theEngine, int theDocID)
35 : GEOM_IOperations(theEngine, theDocID)
36 {
37   MESSAGE("GEOMImpl_IInsertOperations::GEOMImpl_IInsertOperations");
38 }
39
40 //=============================================================================
41 /*!
42  *  destructor
43  */
44 //=============================================================================
45
46 GEOMImpl_IInsertOperations::~GEOMImpl_IInsertOperations()
47 {
48   MESSAGE("GEOMImpl_IInsertOperations::~GEOMImpl_IInsertOperations");
49 }
50
51
52
53 //=============================================================================
54 /*!
55  *  MakeCopy
56  */
57 //=============================================================================
58 Handle(GEOM_Object) GEOMImpl_IInsertOperations::MakeCopy(Handle(GEOM_Object) theOriginal)
59 {
60   SetErrorCode(KO);
61
62   if (theOriginal.IsNull()) return NULL;
63
64   //Add a new Copy object
65   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
66
67   //Add a Copy function for creation a copy object
68   Handle(GEOM_Function) aFunction = aCopy->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITH_REF);
69
70   //Check if the function is set correctly
71   if(aFunction->GetDriverGUID() != GEOMImpl_CopyDriver::GetID()) return NULL;
72
73   GEOMImpl_ICopy aCI(aFunction);
74
75   Handle(GEOM_Function) aRefFunction = theOriginal->GetLastFunction();
76   if (aRefFunction.IsNull()) return NULL;
77
78   aCI.SetOriginal(aRefFunction);
79
80   //Compute the Copy value
81   try {
82     if (!GetSolver()->ComputeFunction(aFunction)) {
83       SetErrorCode("Copy driver failed");
84       return NULL;
85     }
86   }
87   catch (Standard_Failure) {
88     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
89     SetErrorCode(aFail->GetMessageString());
90     return NULL;
91   }
92
93   //Make a Python command
94   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeCopy(" << theOriginal << ")";
95
96   SetErrorCode(OK);
97   return aCopy;
98 }
99
100 //=============================================================================
101 /*!
102  *  Export
103  */
104 //=============================================================================
105 void GEOMImpl_IInsertOperations::Export
106                      (const Handle(GEOM_Object)      theOriginal,
107                       const TCollection_AsciiString& theFileName,
108                       const TCollection_AsciiString& theFormatName)
109 {
110   SetErrorCode(KO);
111
112   if (theOriginal.IsNull()) return;
113
114   Handle(GEOM_Function) aRefFunction = theOriginal->GetLastFunction();
115   if (aRefFunction.IsNull()) return;  //There is no function which creates an object to be exported
116
117   //Add an Export function
118   Handle(GEOM_Function) aFunction = theOriginal->AddFunction(GEOMImpl_ExportDriver::GetID(), EXPORT_SHAPE);
119   if (aFunction.IsNull()) return;
120
121   //Check if the function is set correctly
122   if (aFunction->GetDriverGUID() != GEOMImpl_ExportDriver::GetID()) return;
123
124   //Set parameters
125   GEOMImpl_IImportExport aCI (aFunction);
126   aCI.SetOriginal(aRefFunction);
127   aCI.SetFileName(theFileName);
128
129   Handle(TCollection_HAsciiString) aHLibName;
130   if (!IsSupported(Standard_False, theFormatName, aHLibName)) {
131     return;
132   }
133   TCollection_AsciiString aLibName = aHLibName->String();
134   aCI.SetPluginName(aLibName);
135
136   //Perform the Export
137   try {
138     if (!GetSolver()->ComputeFunction(aFunction)) {
139       SetErrorCode("Export driver failed");
140       return;
141     }
142   }
143   catch (Standard_Failure) {
144     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
145     SetErrorCode(aFail->GetMessageString());
146     return;
147   }
148
149   //Make a Python command
150   GEOM::TPythonDump(aFunction) << "geompy.Export(" << theOriginal << ", \""
151     << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")";
152
153   SetErrorCode(OK);
154 }
155
156 //=============================================================================
157 /*!
158  *  Import
159  */
160 //=============================================================================
161 Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import
162                                  (const TCollection_AsciiString& theFileName,
163                                   const TCollection_AsciiString& theFormatName)
164 {
165   SetErrorCode(KO);
166
167   if (theFileName.IsEmpty() || theFormatName.IsEmpty()) return NULL;
168
169   //Add a new result object
170   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
171
172   //Add an Import function
173   Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_ImportDriver::GetID(), IMPORT_SHAPE);
174   if (aFunction.IsNull()) return result;
175
176   //Check if the function is set correctly
177   if (aFunction->GetDriverGUID() != GEOMImpl_ImportDriver::GetID()) return result;
178
179   //Set parameters
180   GEOMImpl_IImportExport aCI (aFunction);
181   aCI.SetFileName(theFileName);
182
183   Handle(TCollection_HAsciiString) aHLibName;
184   if (!IsSupported(Standard_True, theFormatName, aHLibName)) {
185     return result;
186   }
187   TCollection_AsciiString aLibName = aHLibName->String();
188   aCI.SetPluginName(aLibName);
189
190   //Perform the Import
191   try {
192     if (!GetSolver()->ComputeFunction(aFunction)) {
193       SetErrorCode("Import driver failed");
194       return NULL;
195     }
196   }
197   catch (Standard_Failure) {
198     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
199     SetErrorCode(aFail->GetMessageString());
200     return NULL;
201   }
202
203   //Make a Python command
204   GEOM::TPythonDump(aFunction) << result << " = geompy.Import(\""
205     << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")";
206
207   SetErrorCode(OK);
208   return result;
209 }
210
211 //=============================================================================
212 /*!
213  *  ImportTranslators
214  */
215 //=============================================================================
216 Standard_Boolean GEOMImpl_IInsertOperations::ImportTranslators
217                      (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
218                       Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
219 {
220   if (theFormats.IsNull())
221     theFormats = new TColStd_HSequenceOfAsciiString;
222   else
223     theFormats->Clear();
224
225   if (thePatterns.IsNull())
226     thePatterns = new TColStd_HSequenceOfAsciiString;
227   else
228     thePatterns->Clear();
229
230   if (!InitResMgr()) return Standard_False;
231
232   // Read Import formats list
233   if (myResMgr->Find("Import")) {
234     TCollection_AsciiString aFormats (myResMgr->Value("Import"));
235     TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
236     int i = 1;
237     for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
238       theFormats->Append(aToken);
239     }
240   }
241
242   // Read Patterns for each supported format
243   int j = 1, len = theFormats->Length();
244   for (; j <= len; j++) {
245     TCollection_AsciiString aPattern;
246     TCollection_AsciiString aKey (theFormats->Value(j));
247     aKey += ".Pattern";
248     if (myResMgr->Find(aKey.ToCString()))
249       aPattern = myResMgr->Value(aKey.ToCString());
250     else {
251       aPattern = theFormats->Value(j);
252       aPattern += " Files ( *.* )";
253     }
254     thePatterns->Append(aPattern);
255   }
256
257   return (!theFormats->IsEmpty());
258 }
259
260 //=============================================================================
261 /*!
262  *  ExportTranslators
263  */
264 //=============================================================================
265 Standard_Boolean GEOMImpl_IInsertOperations::ExportTranslators
266                      (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
267                       Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
268 {
269   if (theFormats.IsNull())
270     theFormats = new TColStd_HSequenceOfAsciiString;
271   else
272     theFormats->Clear();
273
274   if (thePatterns.IsNull())
275     thePatterns = new TColStd_HSequenceOfAsciiString;
276   else
277     thePatterns->Clear();
278
279   if (!InitResMgr()) return Standard_False;
280
281   // Read Export formats list
282   if (myResMgr->Find("Export")) {
283     TCollection_AsciiString aFormats (myResMgr->Value("Export"));
284     TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
285     int i = 1;
286     for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
287       theFormats->Append(aToken);
288     }
289   }
290
291   // Read Patterns for each supported format
292   int j = 1, len = theFormats->Length();
293   for (; j <= len; j++) {
294     TCollection_AsciiString aPattern;
295     TCollection_AsciiString aKey (theFormats->Value(j));
296     aKey += ".Pattern";
297     if (myResMgr->Find(aKey.ToCString()))
298       aPattern = myResMgr->Value(aKey.ToCString());
299     else {
300       aPattern = theFormats->Value(j);
301       aPattern += " Files ( *.* )";
302     }
303     thePatterns->Append(aPattern);
304   }
305
306   return (!theFormats->IsEmpty());
307 }
308
309 //=============================================================================
310 /*!
311  *  IsSupported
312  */
313 //=============================================================================
314 Standard_Boolean GEOMImpl_IInsertOperations::IsSupported
315                             (const Standard_Boolean isImport,
316                              const TCollection_AsciiString& theFormat,
317                              Handle(TCollection_HAsciiString)& theLibName)
318 {
319   if (!InitResMgr()) return Standard_False;
320
321   // Import/Export mode
322   TCollection_AsciiString aMode;
323   //Standard_CString aMode;
324   if (isImport) aMode = "Import";
325   else aMode = "Export";
326
327   // Read supported formats for the certain mode
328   if (myResMgr->Find(aMode.ToCString())) {
329     TCollection_AsciiString aFormats (myResMgr->Value(aMode.ToCString()));
330     if (aFormats.Search(theFormat) > -1) {
331       // Read library name for the supported format
332       TCollection_AsciiString aKey (theFormat);
333       aKey += ".";
334       aKey += aMode;
335       if (myResMgr->Find(aKey.ToCString())) {
336         TCollection_AsciiString aLibName (myResMgr->Value(aKey.ToCString()));
337         theLibName = new TCollection_HAsciiString (aLibName);
338         return Standard_True;
339       }
340     }
341   }
342
343   return Standard_False;
344 }
345
346 //=============================================================================
347 /*!
348  *  InitResMgr
349  */
350 //=============================================================================
351 Standard_Boolean GEOMImpl_IInsertOperations::InitResMgr()
352 {
353   if (myResMgr.IsNull()) {
354     // Initialize the Resource Manager
355     TCollection_AsciiString aResDir (getenv("GEOM_ROOT_DIR"));
356 #ifdef WNT
357     aResDir += "\\share\\salome\\resources";
358 #else
359     aResDir += "/share/salome/resources";
360 #endif
361     TCollection_AsciiString aUserResDir (getenv("HOME"));
362 #ifdef WNT
363     aUserResDir += "\\.salome\\resources";
364 #else
365     aUserResDir += "/.salome/resources";
366 #endif
367     myResMgr = new Resource_Manager ("ImportExport", aResDir, aUserResDir, Standard_False);
368
369     if (!myResMgr->Find("Import") && !myResMgr->Find("Export")) {
370       // instead of complains in Resource_Manager
371       INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString() <<
372             " and in " << aUserResDir.ToCString() );
373     }
374   }
375
376   return ( myResMgr->Find("Import") || myResMgr->Find("Export") );
377 }