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