Salome HOME
Fix issue with XAO import
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IInsertOperations.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include <Standard_Stream.hxx>
24
25 #include <GEOMImpl_IInsertOperations.hxx>
26
27 #include <GEOMImpl_CopyDriver.hxx>
28 #include <GEOMImpl_ExportDriver.hxx>
29 #include <GEOMImpl_ImportDriver.hxx>
30 #include <GEOMImpl_ICopy.hxx>
31 #include <GEOMImpl_IImportExport.hxx>
32 #include <GEOMImpl_Types.hxx>
33 #include "GEOMImpl_IShapesOperations.hxx"
34 #include "GEOMImpl_IGroupOperations.hxx"
35 #include "GEOMImpl_IFieldOperations.hxx"
36 #include "GEOMImpl_XAODriver.hxx"
37 #include "GEOMImpl_IImportExportXAO.hxx"
38
39 #include <GEOM_Function.hxx>
40 #include <GEOM_PythonDump.hxx>
41 #include "GEOM_ISubShape.hxx"
42
43 #include <XAO_Xao.hxx>
44 #include <XAO_Geometry.hxx>
45 #include <XAO_BrepGeometry.hxx>
46 #include <XAO_Group.hxx>
47 #include <XAO_Field.hxx>
48 #include <XAO_XaoUtils.hxx>
49 #include <XAO_BooleanField.hxx>
50 #include <XAO_IntegerField.hxx>
51 #include <XAO_DoubleField.hxx>
52 #include <XAO_StringField.hxx>
53 #include <XAO_BooleanStep.hxx>
54 #include <XAO_IntegerStep.hxx>
55 #include <XAO_DoubleStep.hxx>
56 #include <XAO_StringStep.hxx>
57
58 #include <Basics_OCCTVersion.hxx>
59
60 #include "utilities.h"
61 #include <OpUtil.hxx>
62 #include <Utils_ExceptHandlers.hxx>
63
64 #include <TFunction_DriverTable.hxx>
65 #include <TFunction_Driver.hxx>
66 #include <TFunction_Logbook.hxx>
67 #include <TDF_Tool.hxx>
68 #include <TDataStd_Integer.hxx>
69
70 #include <TopoDS.hxx>
71 #include <TopoDS_Vertex.hxx>
72 #include <BRep_Builder.hxx>
73 #include <BRep_Tool.hxx>
74 #include <BRepTools.hxx>
75 #include <gp_Pnt.hxx>
76
77 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
78 #include <TColStd_HArray1OfByte.hxx>
79 #include <TColStd_HArray1OfReal.hxx>
80 #else
81 #include <TDataStd_HArray1OfByte.hxx>
82 #endif
83
84 #include <Standard_Failure.hxx>
85 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
86
87 /**
88  * This function returns the input format name from the original format name.
89  */
90 static TCollection_AsciiString GetImportFormatName
91         (const TCollection_AsciiString& theFormatName)
92 {
93   Standard_Integer aLastInd = 4;
94
95   if (theFormatName.Search("STL") == 1) {
96     aLastInd = 3;
97   }
98
99   return theFormatName.SubString(1, aLastInd);
100 }
101
102 //=============================================================================
103 /*!
104  *  constructor
105  */
106 //=============================================================================
107 GEOMImpl_IInsertOperations::GEOMImpl_IInsertOperations(GEOM_Engine* theEngine, int theDocID)
108 : GEOM_IOperations(theEngine, theDocID)
109 {
110   MESSAGE("GEOMImpl_IInsertOperations::GEOMImpl_IInsertOperations");
111   myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
112   myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
113   myFieldOperations = new GEOMImpl_IFieldOperations(GetEngine(), GetDocID());
114 }
115
116 //=============================================================================
117 /*!
118  *  destructor
119  */
120 //=============================================================================
121 GEOMImpl_IInsertOperations::~GEOMImpl_IInsertOperations()
122 {
123   MESSAGE("GEOMImpl_IInsertOperations::~GEOMImpl_IInsertOperations");
124   delete myShapesOperations;
125   delete myGroupOperations;
126   delete myFieldOperations;
127 }
128
129 //=============================================================================
130 /*!
131  *  MakeCopy
132  */
133 //=============================================================================
134 Handle(GEOM_Object) GEOMImpl_IInsertOperations::MakeCopy (Handle(GEOM_Object) theOriginal)
135 {
136   SetErrorCode(KO);
137
138   if (theOriginal.IsNull()) return NULL;
139
140   //Add a new Copy object
141   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
142
143   //Add a Copy function for creation a copy object
144   Handle(GEOM_Function) aFunction = aCopy->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITH_REF);
145
146   //Check if the function is set correctly
147   if(aFunction->GetDriverGUID() != GEOMImpl_CopyDriver::GetID()) return NULL;
148
149   GEOMImpl_ICopy aCI(aFunction);
150
151   Handle(GEOM_Function) aRefFunction = theOriginal->GetLastFunction();
152   if (aRefFunction.IsNull()) return NULL;
153
154   aCI.SetOriginal(aRefFunction);
155
156   //Compute the Copy value
157   try {
158 #if OCC_VERSION_LARGE > 0x06010000
159     OCC_CATCH_SIGNALS;
160 #endif
161     if (!GetSolver()->ComputeFunction(aFunction)) {
162       SetErrorCode("Copy driver failed");
163       return NULL;
164     }
165   }
166   catch (Standard_Failure) {
167     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
168     SetErrorCode(aFail->GetMessageString());
169     return NULL;
170   }
171
172   //Make a Python command
173   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeCopy(" << theOriginal << ")";
174
175   SetErrorCode(OK);
176   return aCopy;
177 }
178
179 //=============================================================================
180 /*!
181  *  Export
182  */
183 //=============================================================================
184 void GEOMImpl_IInsertOperations::Export
185                      (const Handle(GEOM_Object)      theOriginal,
186                       const TCollection_AsciiString& theFileName,
187                       const TCollection_AsciiString& theFormatName)
188 {
189   SetErrorCode(KO);
190
191   if (theOriginal.IsNull()) return;
192
193   Handle(GEOM_Function) aRefFunction = theOriginal->GetLastFunction();
194   if (aRefFunction.IsNull()) return;  //There is no function which creates an object to be exported
195
196   //Add a new result object
197   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
198
199   //Add an Export function
200   Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_ExportDriver::GetID(), EXPORT_SHAPE);
201   if (aFunction.IsNull()) return;
202
203   //Check if the function is set correctly
204   if (aFunction->GetDriverGUID() != GEOMImpl_ExportDriver::GetID()) return;
205
206   Handle(TCollection_HAsciiString) aHLibName;
207   if (!IsSupported(Standard_False, theFormatName, aHLibName)) {
208     return;
209   }
210   TCollection_AsciiString aLibName = aHLibName->String();
211
212   //Set parameters
213   GEOMImpl_IImportExport aCI (aFunction);
214   aCI.SetOriginal(aRefFunction);
215   aCI.SetFileName(theFileName);
216   aCI.SetFormatName(theFormatName);
217   aCI.SetPluginName(aLibName);
218
219   //Perform the Export
220   try {
221 #if OCC_VERSION_LARGE > 0x06010000
222     OCC_CATCH_SIGNALS;
223 #endif
224     if (!GetSolver()->ComputeFunction(aFunction)) {
225       SetErrorCode("Not enough space on disk, or you haven't permissions to write this directory");
226       return;
227     }
228   }
229   catch (Standard_Failure) {
230     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
231     SetErrorCode(aFail->GetMessageString());
232     return;
233   }
234
235   //Make a Python command
236   GEOM::TPythonDump(aFunction) << "geompy.Export(" << theOriginal << ", \""
237     << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")";
238
239   SetErrorCode(OK);
240 }
241
242 //=============================================================================
243 /*!
244  *  Import
245  */
246 //=============================================================================
247 Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import
248                                  (const TCollection_AsciiString& theFileName,
249                                   const TCollection_AsciiString& theFormatName)
250 {
251   SetErrorCode(KO);
252
253   if (theFileName.IsEmpty() || theFormatName.IsEmpty()) return NULL;
254
255   //Add a new result object
256   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
257
258   //Add an Import function
259   Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_ImportDriver::GetID(), IMPORT_SHAPE);
260   if (aFunction.IsNull()) return result;
261
262   //Check if the function is set correctly
263   if (aFunction->GetDriverGUID() != GEOMImpl_ImportDriver::GetID()) return result;
264
265   Handle(TCollection_HAsciiString) aHLibName;
266   if (!IsSupported
267           (Standard_True, GetImportFormatName(theFormatName), aHLibName)) {
268     return result;
269   }
270   TCollection_AsciiString aLibName = aHLibName->String();
271
272   //Set parameters
273   GEOMImpl_IImportExport aCI (aFunction);
274   aCI.SetFileName(theFileName);
275   aCI.SetFormatName(theFormatName);
276   aCI.SetPluginName(aLibName);
277
278   //Perform the Import
279   try {
280 #if OCC_VERSION_LARGE > 0x06010000
281     OCC_CATCH_SIGNALS;
282 #endif
283     if (!GetSolver()->ComputeFunction(aFunction)) {
284       SetErrorCode("Import driver failed");
285       return NULL;
286     }
287   }
288   catch (Standard_Failure) {
289     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
290     SetErrorCode(aFail->GetMessageString());
291     return NULL;
292   }
293
294   //Make a Python command
295   if (theFormatName != "IGES_UNIT") {
296     GEOM::TPythonDump pd (aFunction);
297     if (theFormatName == "BREP")
298       pd << result << " = geompy.ImportBREP(\"" << theFileName.ToCString() << "\")";
299     else if (theFormatName == "IGES")
300       pd << result << " = geompy.ImportIGES(\"" << theFileName.ToCString() << "\")";
301     else if (theFormatName == "IGES_SCALE")
302       pd << result << " = geompy.ImportIGES(\"" << theFileName.ToCString() << "\", True)";
303     else if (theFormatName == "STEP")
304       pd << result << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\")";
305     else if (theFormatName == "STEP_SCALE")
306       pd << result << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\", True)";
307     else {
308       pd << result << " = geompy.ImportFile(\""
309          << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")";
310     }
311   }
312
313   SetErrorCode(OK);
314
315   // OLD CODE: begin
316   if (theFormatName == "IGES_UNIT") {
317     TopoDS_Shape S = aFunction->GetValue();
318     TopoDS_Vertex V = TopoDS::Vertex(S);
319     gp_Pnt P = BRep_Tool::Pnt(V);
320     double scale = P.X();
321     TCollection_AsciiString aUnitName = "UNIT_M";
322     if (fabs(scale-0.01) < 1.e-6)
323       aUnitName = "UNIT_CM";
324     else if (fabs(scale-0.001) < 1.e-6)
325       aUnitName = "UNIT_MM";
326     //cout<<"IIO: aUnitName = "<<aUnitName.ToCString()<<endl;
327     SetErrorCode(aUnitName);
328   }
329   // OLD CODE: end
330
331   return result;
332 }
333
334 //=============================================================================
335 /*!
336  *  ReadValue
337  */
338 //=============================================================================
339 TCollection_AsciiString GEOMImpl_IInsertOperations::ReadValue
340                                  (const TCollection_AsciiString& theFileName,
341                                   const TCollection_AsciiString& theFormatName,
342                                   const TCollection_AsciiString& theParameterName)
343 {
344   SetErrorCode(KO);
345
346   TCollection_AsciiString aValue, anError;
347
348   if (theFileName.IsEmpty() || theFormatName.IsEmpty() || theParameterName.IsEmpty()) return aValue;
349
350   Handle(TCollection_HAsciiString) aHLibName;
351   if (!IsSupported
352           (Standard_True, GetImportFormatName(theFormatName), aHLibName)) {
353     return aValue;
354   }
355   TCollection_AsciiString aLibName = aHLibName->String();
356
357   aValue = GEOMImpl_ImportDriver::ReadValue(theFileName, aLibName, theParameterName, anError);
358   if (anError.IsEmpty())
359     SetErrorCode(OK);
360   else
361     SetErrorCode(anError.ToCString());
362
363   return aValue;
364 }
365
366 //=============================================================================
367 /*!
368  *  ImportTranslators
369  */
370 //=============================================================================
371 Standard_Boolean GEOMImpl_IInsertOperations::ImportTranslators
372                      (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
373                       Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
374 {
375   if (theFormats.IsNull())
376     theFormats = new TColStd_HSequenceOfAsciiString;
377   else
378     theFormats->Clear();
379
380   if (thePatterns.IsNull())
381     thePatterns = new TColStd_HSequenceOfAsciiString;
382   else
383     thePatterns->Clear();
384
385   if (!InitResMgr()) return Standard_False;
386
387   // Read Import formats list from install directory
388   if (myResMgr->Find("Import")) {
389     TCollection_AsciiString aFormats (myResMgr->Value("Import"));
390     TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
391     int i = 1;
392     for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
393       theFormats->Append(aToken);
394     }
395   }
396
397   // Read Import formats from user directory
398   if (myResMgrUser->Find("Import")) {
399     TCollection_AsciiString aFormats (myResMgrUser->Value("Import"));
400     TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
401     int i = 1;
402     for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
403       int aLenFormats = theFormats->Length();
404       bool isFound = false;
405       for(int aInd=1;aInd<=aLenFormats;aInd++){
406         if( theFormats->Value(aInd) == aToken){
407           isFound = true;
408           break;
409         }
410       }
411       if(!isFound)
412         theFormats->Append(aToken);
413     }
414   }
415
416   // Read Patterns for each supported format
417   int j = 1, len = theFormats->Length();
418   for (; j <= len; j++) {
419     TCollection_AsciiString aKey, aPattern;
420     aKey = theFormats->Value(j) + ".ImportPattern";
421     if (myResMgr->Find(aKey.ToCString()))
422       aPattern = myResMgr->Value(aKey.ToCString());
423     else if(myResMgrUser->Find(aKey.ToCString()))
424       aPattern = myResMgrUser->Value(aKey.ToCString());
425     else {
426       aKey = theFormats->Value(j) + ".Pattern";
427       if (myResMgr->Find(aKey.ToCString()))
428         aPattern = myResMgr->Value(aKey.ToCString());
429       else if(myResMgrUser->Find(aKey.ToCString()))
430         aPattern = myResMgrUser->Value(aKey.ToCString());
431       else {
432         aPattern = theFormats->Value(j);
433         aPattern += " Files ( *.* )";
434       }
435     }
436     thePatterns->Append(aPattern);
437   }
438
439   return (!theFormats->IsEmpty());
440 }
441
442 //=============================================================================
443 /*!
444  *  ExportTranslators
445  */
446 //=============================================================================
447 Standard_Boolean GEOMImpl_IInsertOperations::ExportTranslators
448                      (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
449                       Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
450 {
451   if (theFormats.IsNull())
452     theFormats = new TColStd_HSequenceOfAsciiString;
453   else
454     theFormats->Clear();
455
456   if (thePatterns.IsNull())
457     thePatterns = new TColStd_HSequenceOfAsciiString;
458   else
459     thePatterns->Clear();
460
461   if (!InitResMgr()) return Standard_False;
462
463   // Read Export formats list from install directory
464   if (myResMgr->Find("Export")) {
465     TCollection_AsciiString aFormats (myResMgr->Value("Export"));
466     TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
467     int i = 1;
468     for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
469       theFormats->Append(aToken);
470     }
471   }
472
473   // Read Export formats list from user directory
474   if (myResMgrUser->Find("Export")) {
475     TCollection_AsciiString aFormats (myResMgrUser->Value("Export"));
476     TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
477     int i = 1;
478     for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
479       int aLenFormats = theFormats->Length();
480       bool isFound = false;
481       for(int aInd=1;aInd<=aLenFormats;aInd++){
482         if( theFormats->Value(aInd) == aToken){
483           isFound = true;
484           break;
485         }
486       }
487       if(!isFound)
488         theFormats->Append(aToken);
489     }
490   }
491
492   // Read Patterns for each supported format
493   int j = 1, len = theFormats->Length();
494   for (; j <= len; j++) {
495     TCollection_AsciiString aKey, aPattern;
496     aKey = theFormats->Value(j) + ".ExportPattern";
497     if (myResMgr->Find(aKey.ToCString()))
498       aPattern = myResMgr->Value(aKey.ToCString());
499     else if (myResMgrUser->Find(aKey.ToCString()))
500       aPattern = myResMgrUser->Value(aKey.ToCString());
501     else {
502       aKey = theFormats->Value(j) + ".Pattern";
503       if (myResMgr->Find(aKey.ToCString()))
504         aPattern = myResMgr->Value(aKey.ToCString());
505       else if (myResMgrUser->Find(aKey.ToCString()))
506         aPattern = myResMgrUser->Value(aKey.ToCString());
507       else {
508         aPattern = theFormats->Value(j);
509         aPattern += " Files ( *.* )";
510       }
511     }
512     thePatterns->Append(aPattern);
513   }
514
515   return (!theFormats->IsEmpty());
516 }
517
518 //=============================================================================
519 /*!
520  *  IsSupported
521  */
522 //=============================================================================
523 Standard_Boolean GEOMImpl_IInsertOperations::IsSupported
524                             (const Standard_Boolean isImport,
525                              const TCollection_AsciiString& theFormat,
526                              Handle(TCollection_HAsciiString)& theLibName)
527 {
528   if (!InitResMgr()) return Standard_False;
529
530   // Import/Export mode
531   TCollection_AsciiString aMode;
532   //Standard_CString aMode;
533   if (isImport) aMode = "Import";
534   else aMode = "Export";
535
536   // Read supported formats for the certain mode from install directory
537   if (myResMgr->Find(aMode.ToCString())) {
538     TCollection_AsciiString aFormats (myResMgr->Value(aMode.ToCString()));
539     if (aFormats.Search(theFormat) > -1) {
540       // Read library name for the supported format
541       TCollection_AsciiString aKey (theFormat);
542       aKey += ".";
543       aKey += aMode;
544       if (myResMgr->Find(aKey.ToCString())) {
545         TCollection_AsciiString aLibName (myResMgr->Value(aKey.ToCString()));        
546 #ifndef WIN32
547         if ( aLibName.Length() > 3 && aLibName.SubString(1,3) != "lib" )
548           aLibName.Prepend("lib");
549         aLibName += ".so";
550 #else
551         aLibName += ".dll";
552 #endif
553         theLibName = new TCollection_HAsciiString (aLibName);
554         return Standard_True;
555       }
556     }
557   }
558   
559   // Read supported formats for the certain mode from user directory
560   if (myResMgrUser->Find(aMode.ToCString())) {
561     TCollection_AsciiString aFormats (myResMgrUser->Value(aMode.ToCString()));
562     if (aFormats.Search(theFormat) > -1) {
563       // Read library name for the supported format
564       TCollection_AsciiString aKey (theFormat);
565       aKey += ".";
566       aKey += aMode;
567       if (myResMgrUser->Find(aKey.ToCString())) {
568         TCollection_AsciiString aLibName (myResMgrUser->Value(aKey.ToCString()));
569 #ifndef WIN32
570         if ( aLibName.Length() > 3 && aLibName.SubString(1,3) != "lib" )
571           aLibName.Prepend("lib");
572         aLibName += ".so";
573 #else
574         aLibName += ".dll";
575 #endif
576         theLibName = new TCollection_HAsciiString (aLibName);
577         return Standard_True;
578       }
579     }
580   }
581   
582   return Standard_False;
583 }
584
585 //=============================================================================
586 /*!
587  *  InitResMgr
588  */
589 //=============================================================================
590 Standard_Boolean GEOMImpl_IInsertOperations::InitResMgr()
591 {
592   bool isResourceFound     = false;
593   bool isResourceFoundUser = false;
594   TCollection_AsciiString aUserResDir,aResDir;
595   
596   if (myResMgr.IsNull()) {
597     // Initialize the Resource Manager
598     TCollection_AsciiString aNull;
599     aResDir = TCollection_AsciiString(getenv("GEOM_ROOT_DIR"));
600 #ifdef WIN32
601     aResDir += "\\share\\salome\\resources\\geom";
602 #else
603     aResDir += "/share/salome/resources/geom";
604 #endif
605     
606     myResMgr = new Resource_Manager ("ImportExport", aResDir, aNull, Standard_False);
607
608     isResourceFound = true;
609     if (!myResMgr->Find("Import") && !myResMgr->Find("Export")) {
610       // instead of complains in Resource_Manager
611       isResourceFound = false;
612       INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString());
613     }
614   } else
615     isResourceFound = true;
616
617   if (myResMgrUser.IsNull()) {
618     char * dir = getenv("GEOM_ENGINE_RESOURCES_DIR");
619     TCollection_AsciiString aNull;
620     if ( dir )
621     {
622       aUserResDir = dir;
623     }
624     else
625     {
626       aUserResDir = getenv("HOME");
627 #ifdef WIN32
628       aUserResDir += "\\.salome\\resources";
629 #else
630       aUserResDir += "/.salome/resources";
631 #endif
632     }
633
634     myResMgrUser = new Resource_Manager ("ImportExport", aNull, aUserResDir, Standard_False);
635
636     isResourceFoundUser = true;
637     
638     if (!myResMgrUser->Find("Import") && !myResMgrUser->Find("Export")) {
639       // instead of complains in Resource_Manager
640       isResourceFoundUser = false;
641     }
642       
643   } else
644     isResourceFoundUser = true;
645     
646   if(!isResourceFound && !isResourceFoundUser){
647     INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString());
648     INFOS("No valid file \"ImportExport\" found in " << aUserResDir.ToCString() );
649   }
650
651   return ( myResMgr->Find("Import") || myResMgr->Find("Export") ||
652            myResMgrUser->Find("Import") || myResMgrUser->Find("Export"));
653 }
654
655 //=============================================================================
656 /*!
657  *  RestoreShape
658  */
659 //=============================================================================
660 Handle(GEOM_Object) GEOMImpl_IInsertOperations::RestoreShape (std::istringstream& theStream)
661 {
662   SetErrorCode(KO);
663
664   //Add a new result object
665   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
666
667   //Add a Copy function
668   Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF);
669   if (aFunction.IsNull()) return NULL;
670
671   //Check if the function is set correctly
672   if (aFunction->GetDriverGUID() != GEOMImpl_CopyDriver::GetID()) return NULL;
673
674   //Read a shape from the stream
675   TopoDS_Shape aShape;
676   BRep_Builder B;
677   BRepTools::Read(aShape, theStream, B);
678   if (aShape.IsNull()) {
679     SetErrorCode("RestoreShape error: BREP reading failed");
680   }
681
682   //Set function value
683   aFunction->SetValue(aShape);
684
685   //Special dump to avoid restored shapes publication.
686   //See correcponding code in GEOM_Engine.cxx (method ProcessFunction)
687   //GEOM::TPythonDump(aFunction) << "#";
688
689   GEOM::TPythonDump(aFunction) << result
690     << " = geompy.RestoreShape(\"\") # the shape string has not been dump for performance reason";
691
692   SetErrorCode(OK);
693
694   return result;
695 }
696
697 int GEOMImpl_IInsertOperations::LoadTexture(const TCollection_AsciiString& theTextureFile)
698 {
699   SetErrorCode(KO);
700
701   if (theTextureFile.IsEmpty()) return 0;
702
703 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
704   Handle(TColStd_HArray1OfByte) aTexture;
705 #else
706   Handle(TDataStd_HArray1OfByte) aTexture;
707 #endif
708
709   FILE* fp = fopen(theTextureFile.ToCString(), "r");
710   if (!fp) return 0;
711
712   std::list<std::string> lines;
713   char buffer[4096];
714   int maxlen = 0;
715   while (!feof(fp)) {
716     if ((fgets(buffer, 4096, fp)) == NULL) break;
717     int aLen = strlen(buffer);
718     if (buffer[aLen-1] == '\n') buffer[aLen-1] = '\0';
719     lines.push_back(buffer);
720     maxlen = std::max(maxlen, (int)strlen(buffer));
721   }
722
723   fclose(fp);
724
725   int lenbytes = maxlen/8;
726   if (maxlen%8) lenbytes++;
727
728   if (lenbytes == 0 || lines.empty())
729     return 0;
730
731   std::list<unsigned char> bytedata;
732   std::list<std::string>::const_iterator it;
733   for (it = lines.begin(); it != lines.end(); ++it) {
734     std::string line = *it;
735     int lenline = (line.size()/8 + (line.size()%8 ? 1 : 0)) * 8;
736     for (int i = 0; i < lenline/8; i++) {
737       unsigned char byte = 0;
738       for (int j = 0; j < 8; j++)
739         byte = (byte << 1) + ( i*8+j < line.size() && line[i*8+j] != '0' ? 1 : 0 );
740       bytedata.push_back(byte);
741     }
742     for (int i = lenline/8; i < lenbytes; i++)
743       bytedata.push_back((unsigned char)0);
744   }
745
746   if (bytedata.empty() || bytedata.size() != lines.size()*lenbytes)
747     return 0;
748
749 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
750   aTexture = new TColStd_HArray1OfByte (1, lines.size()*lenbytes);
751 #else
752   aTexture = new TDataStd_HArray1OfByte (1, lines.size()*lenbytes);
753 #endif
754
755   std::list<unsigned char>::iterator bdit;
756   int i;
757   for (i = 1, bdit = bytedata.begin(); bdit != bytedata.end(); ++bdit, ++i)
758     aTexture->SetValue(i, (Standard_Byte)(*bdit));
759
760   int aTextureId = GetEngine()->addTexture(GetDocID(), lenbytes*8, lines.size(), aTexture, theTextureFile);
761   if (aTextureId > 0) SetErrorCode(OK);
762   return aTextureId;
763 }
764   
765 int GEOMImpl_IInsertOperations::AddTexture(int theWidth, int theHeight, 
766 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
767                                            const Handle(TColStd_HArray1OfByte)& theTexture)
768 #else
769                                            const Handle(TDataStd_HArray1OfByte)& theTexture)
770 #endif
771 {
772   SetErrorCode(KO);
773   int aTextureId = GetEngine()->addTexture(GetDocID(), theWidth, theHeight, theTexture);
774   if (aTextureId > 0) SetErrorCode(OK);
775   return aTextureId;
776 }
777
778 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
779 Handle(TColStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
780 #else
781 Handle(TDataStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
782 #endif
783                                                                       int& theWidth, int& theHeight)
784 {
785   SetErrorCode(KO);
786   
787 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
788   Handle(TColStd_HArray1OfByte) aTexture;
789 #else
790   Handle(TDataStd_HArray1OfByte) aTexture;
791 #endif
792
793   theWidth = theHeight = 0;
794   TCollection_AsciiString aFileName;
795
796   if (theTextureId <= 0)
797     return aTexture;
798
799   aTexture = GetEngine()->getTexture(GetDocID(), theTextureId, theWidth, theHeight, aFileName);
800
801   if (theWidth > 0 && theHeight > 0 && aTexture->Length() > 0) SetErrorCode(OK);
802
803   return aTexture;
804 }
805
806 std::list<int> GEOMImpl_IInsertOperations::GetAllTextures()
807 {
808   SetErrorCode(KO);
809   std::list<int> id_list = GetEngine()->getAllTextures(GetDocID());
810   SetErrorCode(OK);
811   return id_list;
812 }
813
814 TopAbs_ShapeEnum getGroupDimension(XAO::Group* group)
815 {
816   XAO::Dimension dim = group->getDimension();
817   TopAbs_ShapeEnum rdim;
818   switch ( dim )
819   {
820   case XAO::VERTEX:
821     rdim = TopAbs_VERTEX; break;
822   case XAO::EDGE:
823     rdim = TopAbs_EDGE; break;
824   case XAO::FACE:
825     rdim = TopAbs_FACE; break;
826   case XAO::SOLID:
827     rdim = TopAbs_SOLID; break;
828   default:
829     rdim = TopAbs_COMPOUND; break;
830   }
831   return rdim;
832 }
833
834 XAO::Dimension shapeEnumToDimension(const TopAbs_ShapeEnum& shape)
835 {
836   XAO::Dimension dim;
837   switch( shape ) {
838   case TopAbs_VERTEX:
839     dim = XAO::VERTEX; break;
840   case TopAbs_EDGE:
841     dim = XAO::EDGE; break;
842   case TopAbs_FACE:
843     dim = XAO::FACE; break;
844   case TopAbs_SOLID:
845     dim = XAO::SOLID; break;
846   default:
847     throw SALOME_Exception("Bad type"); // TODO
848   }
849   return dim;
850 }
851
852 void GEOMImpl_IInsertOperations::exportGroups(std::list<Handle(GEOM_Object)> groupList,
853                                               XAO::Xao* xaoObject,
854                                               XAO::BrepGeometry* geometry)
855 {
856   // add the groups
857   std::list<Handle(GEOM_Object)>::iterator groupIterator = groupList.begin();
858   while (groupIterator != groupList.end())
859   {
860     Handle(GEOM_Object) currGroup = (*groupIterator++);
861     Handle(TColStd_HArray1OfInteger) groupIds = myGroupOperations->GetObjects(currGroup);
862     
863     TopAbs_ShapeEnum shapeGroup = myGroupOperations->GetType(currGroup);
864     XAO::Dimension dim = shapeEnumToDimension(shapeGroup);
865     XAO::Group* group = xaoObject->addGroup(dim, currGroup->GetName().ToCString());
866     
867     switch (shapeGroup)
868     {
869     case TopAbs_VERTEX:
870       for (int i = 1; i <= groupIds->Length(); i++)
871       {
872         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
873         int index = geometry->getVertexIndexByReference(ref);
874         group->add(index);
875       }
876       break;
877     case TopAbs_EDGE:
878       for (int i = 1; i <= groupIds->Length(); i++)
879       {
880         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
881         int index = geometry->getEdgeIndexByReference(ref);
882         group->add(index);
883       }
884       break;
885     case TopAbs_FACE:
886       for (int i = 1; i <= groupIds->Length(); i++)
887       {
888         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
889         int index = geometry->getFaceIndexByReference(ref);
890         group->add(index);
891       }
892       break;
893     case TopAbs_SOLID:
894       for (int i = 1; i <= groupIds->Length(); i++)
895       {
896         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
897         int index = geometry->getSolidIndexByReference(ref);
898         group->add(index);
899       }
900       break;
901     }
902   }
903 }
904
905 void GEOMImpl_IInsertOperations::exportFields(std::list<Handle(GEOM_Field)> fieldList,
906                                               XAO::Xao* xaoObject,
907                                               XAO::BrepGeometry* geometry)
908 {
909     std::list<Handle(GEOM_Field)>::iterator fieldIterator = fieldList.begin();
910     while (fieldIterator != fieldList.end())
911     {
912         Handle(GEOM_Field) currField = (*fieldIterator++);
913
914         int fdim = currField->GetDimension();
915         int ftype = currField->GetDataType();
916         int nbComponents = currField->GetNbComponents();
917         std::string name = currField->GetName().ToCString();
918
919         XAO::Field* field = xaoObject->addField((XAO::Type)ftype, (XAO::Dimension)fdim, nbComponents, name);
920
921         Handle(TColStd_HArray1OfExtendedString) components = currField->GetComponents();
922         for (int i = components->Lower(), j = 0; i <= components->Upper(); ++i, ++j)
923         {
924             field->setComponentName(j, TCollection_AsciiString(components->Value(i)).ToCString());
925         }
926
927         std::list< Handle(GEOM_FieldStep)> steps = currField->GetSteps();
928         std::list<Handle(GEOM_FieldStep)>::iterator stepIterator = steps.begin();
929         while (stepIterator != steps.end())
930         {
931             Handle(GEOM_FieldStep) currStep = (*stepIterator++);
932
933             XAO::Step* step = field->addNewStep(currStep->GetID());
934             step->setStamp(currStep->GetStamp());
935
936             switch (ftype)
937             {
938                 case 0: // bool
939                 {
940                     XAO::BooleanStep* bs = (XAO::BooleanStep*)step;
941                     Handle(TColStd_HArray1OfInteger) bvalues = currStep->GetIntValues();
942                     std::vector<bool> bv;
943                     bv.reserve(bvalues->Upper());
944                     for ( int i = bvalues->Lower(), nb = bvalues->Upper(); i <= nb; ++i )
945                     {
946                         bv.push_back(bvalues->Value(i) != 0);
947                     }
948                     bs->setValues(bv);
949                     break;
950                 }
951                 case 1: // integer
952                 {
953                     XAO::IntegerStep* is = (XAO::IntegerStep*)step;
954                     Handle(TColStd_HArray1OfInteger) ivalues = currStep->GetIntValues();
955                     std::vector<int> iv;
956                     iv.reserve(ivalues->Upper());
957                     for ( int i = ivalues->Lower(), nb = ivalues->Upper(); i <= nb; ++i )
958                     {
959                         iv.push_back(ivalues->Value(i));
960                     }
961                     is->setValues(iv);
962                     break;
963                 }
964                 case 2: // double
965                 {
966                     XAO::DoubleStep* ds = (XAO::DoubleStep*)step;
967                     Handle(TColStd_HArray1OfReal) dvalues = currStep->GetDoubleValues();
968                     std::vector<double> dv;
969                     dv.reserve(dvalues->Upper());
970                     for ( int i = dvalues->Lower(), nb = dvalues->Upper(); i <= nb; ++i )
971                     {
972                         dv.push_back(dvalues->Value(i));
973                     }
974                     ds->setValues(dv);
975                     break;
976                 }
977                 case 3: // string
978                 {
979                     XAO::StringStep* ss = (XAO::StringStep*)step;
980                     Handle(TColStd_HArray1OfExtendedString) svalues = currStep->GetStringValues();
981                     std::vector<std::string> sv;
982                     sv.reserve(svalues->Upper());
983                     for ( int i = svalues->Lower(), nb = svalues->Upper(); i <= nb; ++i )
984                     {
985                         sv.push_back(TCollection_AsciiString(svalues->Value(i)).ToCString());
986                     }
987                     ss->setValues(sv);
988                     break;
989                 }
990             }
991         }
992     }
993 }
994
995 void GEOMImpl_IInsertOperations::exportSubshapes(const Handle(GEOM_Object)& shape, XAO::BrepGeometry* geometry)
996 {
997   Handle(TColStd_HSequenceOfTransient) subObjects = myShapesOperations->GetExistingSubObjects(shape, false);
998   int nbSubObjects = subObjects->Length();
999   // set the names of the sub shapes
1000   for (int i = 1; i <= nbSubObjects; i++)
1001   {
1002     Handle(Standard_Transient) transientSubObject = subObjects->Value(i);
1003     if (transientSubObject.IsNull())
1004       continue;
1005     
1006     Handle(GEOM_Object) subObject = Handle(GEOM_Object)::DownCast(transientSubObject);
1007     if (subObject->GetType() != GEOM_GROUP)
1008     {
1009       int subIndex = myShapesOperations->GetSubShapeIndex(shape, subObject);
1010       switch (subObject->GetValue().ShapeType())
1011       {
1012       case TopAbs_VERTEX:
1013         geometry->changeVertexName(subIndex, subObject->GetName().ToCString());
1014         break;
1015       case TopAbs_EDGE:
1016         geometry->changeEdgeName(subIndex, subObject->GetName().ToCString());
1017         break;
1018       case TopAbs_FACE:
1019         geometry->changeFaceName(subIndex, subObject->GetName().ToCString());
1020         break;
1021       case TopAbs_SOLID:
1022         geometry->changeSolidName(subIndex, subObject->GetName().ToCString());
1023         break;
1024       }
1025     }
1026   }
1027 }
1028
1029 //=============================================================================
1030 /*!
1031  *  Export a shape to XAO format
1032  *  \param shape The shape to export
1033  *  \param groups The list of groups to export
1034  *  \param fields The list of fields to export
1035  *  \param fileName The name of the file to exported
1036  *  \return boolean indicating if export was succeful.
1037  */
1038 //=============================================================================
1039 bool GEOMImpl_IInsertOperations::ExportXAO(Handle(GEOM_Object) shape,
1040                                            std::list<Handle(GEOM_Object)> groupList,
1041                                            std::list<Handle(GEOM_Field)> fieldList,
1042                                            const char* author,
1043                                            const char* fileName)
1044 {
1045   SetErrorCode(KO);
1046
1047   if (shape.IsNull()) return false;
1048   
1049   // add a new shape function with parameters
1050   Handle(GEOM_Function) lastFunction = shape->GetLastFunction();
1051   if (lastFunction.IsNull()) return false;
1052   
1053   // add a new result object
1054   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
1055   
1056   // add an Export function
1057   Handle(GEOM_Function) exportFunction = result->AddFunction(GEOMImpl_XAODriver::GetID(), IMPORTEXPORT_EXPORTXAO);
1058   if (exportFunction.IsNull()) return false;
1059   if (exportFunction->GetDriverGUID() != GEOMImpl_XAODriver::GetID()) return false;
1060   
1061   // create the XAO object
1062   XAO::Xao* xaoObject = new XAO::Xao();
1063   xaoObject->setAuthor(author);
1064   
1065   // add the geometry
1066   XAO::BrepGeometry* geometry = (XAO::BrepGeometry*)XAO::Geometry::createGeometry(XAO::BREP);
1067   TopoDS_Shape topoShape = shape->GetValue();
1068   exportFunction->SetValue(topoShape);
1069   XAO::BrepGeometry* brep = (XAO::BrepGeometry*)geometry;
1070   brep->setTopoDS_Shape(topoShape);
1071   
1072   geometry->setName(shape->GetName().ToCString());
1073   exportSubshapes(shape, geometry);
1074   xaoObject->setGeometry(geometry);
1075   
1076   exportGroups(groupList, xaoObject, geometry);
1077   exportFields(fieldList, xaoObject, geometry);
1078   
1079   // export the XAO to the file
1080   xaoObject->exportXAO(fileName);
1081   
1082   // make a Python command
1083   GEOM::TPythonDump pd(exportFunction);
1084   pd << "exported = geompy.ExportXAO(" << shape;
1085   
1086   // list of groups
1087   pd << ", [";
1088   if (groupList.size() > 0)
1089   {
1090     std::list<Handle(GEOM_Object)>::iterator itGroup = groupList.begin();
1091     pd << (*itGroup++);
1092     while (itGroup != groupList.end())
1093     {
1094       pd << ", " << (*itGroup++);
1095     }
1096   }
1097   
1098   // list of fields
1099   pd << "], [";
1100   if (fieldList.size() > 0)
1101   {
1102     std::list<Handle(GEOM_Field)>::iterator itField = fieldList.begin();
1103     pd << (*itField++);
1104     while (itField != fieldList.end())
1105     {
1106       pd << ", " << (*itField++);
1107     }
1108   }
1109   pd << "], ";
1110   pd << author << ", \"" << fileName << "\")";
1111   
1112   SetErrorCode(OK);
1113   delete xaoObject;
1114   
1115   return true;
1116 }
1117
1118 void GEOMImpl_IInsertOperations::importSubShapes(XAO::Geometry* xaoGeometry,
1119                                                  Handle(GEOM_Function) function, int shapeType, int dim,
1120                                                  Handle(TColStd_HSequenceOfTransient)& subShapeList)
1121 {
1122   Handle(GEOM_Object) subShape;
1123   Handle(GEOM_Function) aFunction;
1124   Handle(TColStd_HArray1OfInteger) anArray;
1125   
1126   XAO::GeometricElementList::iterator elementIterator = xaoGeometry->begin((XAO::Dimension)dim);
1127   for (; elementIterator != xaoGeometry->end((XAO::Dimension)dim); elementIterator++)
1128   {
1129     XAO::GeometricElement element = elementIterator->second;
1130     if (!element.hasName())
1131       continue;
1132     
1133     std::string name = element.getName();
1134     std::string ref = element.getReference();
1135     int iref = XAO::XaoUtils::stringToInt(ref);
1136     
1137     anArray = new TColStd_HArray1OfInteger(1, 1);
1138     anArray->SetValue(1, iref);
1139     
1140     subShape = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1141     Handle(GEOM_Function) aFunction = subShape->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1142     if (aFunction.IsNull())
1143       return;
1144     
1145     subShape->SetName(name.c_str());
1146     subShape->SetType(shapeType);
1147     
1148     GEOM_ISubShape aSSI(aFunction);
1149     aSSI.SetMainShape(function);
1150     aSSI.SetIndices(anArray);
1151     
1152     //aFunction->SetValue(aValue);
1153     subShapeList->Append(subShape);
1154     
1155     // Put this subshape in the list of sub-shapes of theMainShape
1156     function->AddSubShapeReference(aFunction);
1157   }
1158 }
1159
1160 //=============================================================================
1161 /*!
1162  *  Import a shape from XAO format
1163  *  \param fileName The name of the file to import
1164  *  \param shape The imported shape
1165  *  \param subShapes The list of imported groups
1166  *  \param groups The list of imported groups
1167  *  \param fields The list of imported fields
1168  *  \return boolean indicating if import was succeful.
1169  */
1170 //=============================================================================
1171 bool GEOMImpl_IInsertOperations::ImportXAO(const char* fileName,
1172                                            Handle(GEOM_Object)& shape,
1173                                            Handle(TColStd_HSequenceOfTransient)& subShapes,
1174                                            Handle(TColStd_HSequenceOfTransient)& groups,
1175                                            Handle(TColStd_HSequenceOfTransient)& fields)
1176 {
1177   SetErrorCode(KO);
1178   
1179   if (fileName == NULL || groups.IsNull() || fields.IsNull())
1180     return false;
1181   
1182   // Read the XAO
1183   XAO::Xao* xaoObject = new XAO::Xao();
1184   try
1185   {
1186     xaoObject->importXAO(fileName);
1187   }
1188   catch (XAO::XAO_Exception& exc)
1189   {
1190     delete xaoObject;
1191     SetErrorCode(exc.what());
1192     return false;
1193   }
1194   
1195   XAO::Geometry* xaoGeometry = xaoObject->getGeometry();
1196   if (xaoGeometry == NULL)
1197   {
1198     delete xaoObject;
1199     SetErrorCode("Cannot import XAO: geometry format not supported.");
1200     return false;
1201   }
1202   
1203   // create the shape
1204   shape = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
1205   Handle(GEOM_Function) function = shape->AddFunction(GEOMImpl_XAODriver::GetID(), IMPORTEXPORT_EXPORTXAO);
1206   if (function.IsNull()) return false;
1207   if (function->GetDriverGUID() != GEOMImpl_XAODriver::GetID()) return false;
1208   
1209   // set the geometry
1210   if (xaoGeometry->getFormat() == XAO::BREP)
1211   {
1212     XAO::BrepGeometry* brep = (XAO::BrepGeometry*)xaoGeometry;
1213     TopoDS_Shape geomShape = brep->getTopoDS_Shape();
1214     function->SetValue(geomShape);
1215     shape->SetName(xaoGeometry->getName().c_str());
1216   }
1217   else
1218   {
1219     delete xaoObject;
1220     SetErrorCode("Cannot import XAO: geometry format not supported.");
1221     return false;
1222   }
1223   
1224   // create sub shapes with names
1225   importSubShapes(xaoGeometry, function, GEOM_POINT, XAO::VERTEX, subShapes);
1226   importSubShapes(xaoGeometry, function, GEOM_EDGE, XAO::EDGE, subShapes);
1227   importSubShapes(xaoGeometry, function, GEOM_FACE, XAO::FACE, subShapes);
1228   importSubShapes(xaoGeometry, function, GEOM_SOLID, XAO::SOLID, subShapes);
1229   
1230   // create groups
1231   int nbGroups = xaoObject->countGroups();
1232   for (int i = 0; i < nbGroups; ++i)
1233   {
1234     XAO::Group* xaoGroup = xaoObject->getGroup(i);
1235     
1236     // build an array with the indexes of the sub shapes
1237     int nbElt = xaoGroup->count();
1238     Handle(TColStd_HArray1OfInteger) array = new TColStd_HArray1OfInteger(1, nbElt);
1239     int j = 0;
1240     for (std::set<int>::iterator it = xaoGroup->begin(); it != xaoGroup->end(); ++it)
1241     {
1242       int index = (*it);
1243       std::string ref = xaoGeometry->getElementReference(xaoGroup->getDimension(), index);
1244       array->SetValue(++j, XAO::XaoUtils::stringToInt(ref));
1245     }
1246     
1247     // create the group with the array of sub shapes indexes
1248     Handle(GEOM_Object) group = GetEngine()->AddSubShape(shape, array);
1249     group->SetType(GEOM_GROUP);
1250     group->SetName(xaoGroup->getName().c_str());
1251     
1252     // Set a sub-shape type
1253     TDF_Label freeLabel = group->GetFreeLabel();
1254     TDataStd_Integer::Set(freeLabel, (Standard_Integer) getGroupDimension(xaoGroup));
1255     groups->Append(group);
1256     
1257     function = group->GetLastFunction();
1258   }
1259   
1260   // create the fields
1261   int nbFields = xaoObject->countFields();
1262   for (int i = 0; i < nbFields; ++i)
1263   {
1264     XAO::Field* xaoField = xaoObject->getField(i);
1265
1266     Handle(TColStd_HArray1OfExtendedString) components = new TColStd_HArray1OfExtendedString(0, xaoField->countComponents()-1);
1267     for (int j = 0; j < xaoField->countComponents(); ++j)
1268     {
1269         components->SetValue(j, (TCollection_ExtendedString)xaoField->getComponentName(j).c_str());
1270     }
1271
1272     Handle(GEOM_Field) field = myFieldOperations->CreateField(shape,
1273                  xaoField->getName().c_str(),
1274                  (int)xaoField->getType(),
1275                  (int)xaoField->getDimension(),
1276                  components);
1277
1278     switch (xaoField->getType())
1279     {
1280         case XAO::BOOLEAN:
1281         {
1282             XAO::BooleanField* bfield = (XAO::BooleanField*)xaoField;
1283             for (int j = 0; j < xaoField->countSteps(); ++j)
1284             {
1285                 XAO::BooleanStep* bstep = bfield->getStep(j);
1286                 Handle(GEOM_FieldStep) step = field->AddStep(bstep->getStep(), bstep->getStamp());
1287
1288                 Handle(TColStd_HArray1OfInteger) values = new TColStd_HArray1OfInteger(0, bstep->countValues()-1);
1289                 std::vector<bool> bvalues = bstep->getValues();
1290                 for (int k = 0; k < bstep->countValues(); ++k)
1291                 {
1292                     values->SetValue(k, bvalues[k] ? 1 : 0);
1293                 }
1294                 step->SetValues(values);
1295             }
1296             break;
1297         }
1298         case XAO::INTEGER:
1299         {
1300             XAO::IntegerField* ifield = (XAO::IntegerField*)xaoField;
1301             for (int j = 0; j < xaoField->countSteps(); ++j)
1302             {
1303                 XAO::IntegerStep* istep = ifield->getStep(j);
1304                 Handle(GEOM_FieldStep) step = field->AddStep(istep->getStep(), istep->getStamp());
1305
1306                 Handle(TColStd_HArray1OfInteger) values = new TColStd_HArray1OfInteger(0, istep->countValues()-1);
1307                 std::vector<int> ivalues = istep->getValues();
1308                 for (int k = 0; k < istep->countValues(); ++k)
1309                 {
1310                     values->SetValue(k, ivalues[k]);
1311                 }
1312                 step->SetValues(values);
1313             }
1314             break;
1315         }
1316         case XAO::DOUBLE:
1317         {
1318             XAO::DoubleField* dfield = (XAO::DoubleField*)xaoField;
1319             for (int j = 0; j < xaoField->countSteps(); ++j)
1320             {
1321                 XAO::DoubleStep* dstep = dfield->getStep(j);
1322                 Handle(GEOM_FieldStep) step = field->AddStep(dstep->getStep(), dstep->getStamp());
1323
1324                 Handle(TColStd_HArray1OfReal) values = new TColStd_HArray1OfReal(0, dstep->countValues()-1);
1325                 std::vector<double> dvalues = dstep->getValues();
1326                 for (int k = 0; k < dstep->countValues(); ++k)
1327                 {
1328                     values->SetValue(k, dvalues[k]);
1329                 }
1330                 step->SetValues(values);
1331             }
1332             break;
1333         }
1334         case XAO::STRING:
1335         {
1336             XAO::StringField* sfield = (XAO::StringField*)xaoField;
1337             for (int j = 0; j < xaoField->countSteps(); ++j)
1338             {
1339                 XAO::StringStep* sstep = sfield->getStep(j);
1340                 Handle(GEOM_FieldStep) step = field->AddStep(sstep->getStep(), sstep->getStamp());
1341
1342                 Handle(TColStd_HArray1OfExtendedString) values = new TColStd_HArray1OfExtendedString(0, sstep->countValues()-1);
1343                 std::vector<std::string> svalues = sstep->getValues();
1344                 for (int k = 0; k < sstep->countValues(); ++k)
1345                 {
1346                     values->SetValue(k, TCollection_ExtendedString(svalues[k].c_str()));
1347                 }
1348                 step->SetValues(values);
1349             }
1350             break;
1351         }
1352     }
1353
1354     fields->Append(field);
1355   }
1356   
1357   // make a Python command
1358   GEOM::TPythonDump pd(function);
1359   pd << "(imported, " << shape << ", ";
1360   
1361   // list of sub shapes
1362   pd << "[";
1363   int nbSubshapes = subShapes->Length();
1364   if (nbSubshapes > 0)
1365   {
1366     for (int i = 1; i <= nbSubshapes; i++)
1367     {
1368       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(subShapes->Value(i));
1369       pd << obj << ((i < nbSubshapes) ? ", " : "");
1370     }
1371   }
1372   pd << "], [";
1373   
1374   // list of groups
1375   if (nbGroups > 0)
1376   {
1377     for (int i = 1; i <= nbGroups; i++)
1378     {
1379       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(groups->Value(i));
1380       pd << obj << ((i < nbGroups) ? ", " : "");
1381     }
1382   }
1383   
1384   pd << "], [";
1385   
1386   // list of fields
1387   pd << "]";
1388   pd << ") = geompy.ImportXAO(\"" << fileName << "\")";
1389   
1390   delete xaoObject;
1391   SetErrorCode(OK);
1392   
1393   return true;
1394 }