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