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 << aSeq << " = geompy.ImportBREP(\"" << theFileName.ToCString() << "\")";
307     else if (theFormatName == "IGES")
308       pd << aSeq << " = geompy.ImportIGES(\"" << theFileName.ToCString() << "\")";
309     else if (theFormatName == "IGES_SCALE")
310       pd << aSeq << " = geompy.ImportIGES(\"" << theFileName.ToCString() << "\", True)";
311     else if (theFormatName == "STEP")
312       pd << aSeq << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\")";
313     else if (theFormatName == "STEP_SCALE")
314       pd << aSeq << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\", True)";
315     else {
316       pd << aSeq << " = 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 from directories
396   Handle(Resource_Manager) aResMgr;
397   Handle(TColStd_HSequenceOfAsciiString) aFormatsToAdd;
398   for(int index = 0; index < myResMgrList.size(); index++) {
399     int anOldLen = theFormats->Length();
400     aResMgr = myResMgrList.at(index);
401     if (aResMgr->Find("Import")) {
402       TCollection_AsciiString aFormats (aResMgr->Value("Import"));
403       TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
404       for (int i = 1; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
405         int aLenFormats = theFormats->Length();
406         bool isFound = false;
407         for(int aInd=1;aInd<=aLenFormats;aInd++){
408           if( theFormats->Value(aInd) == aToken ){
409             isFound = true;
410             break;
411           }
412         }
413         if(!isFound)
414           theFormats->Append(aToken);
415       }
416     }
417
418     // Read Patterns for each supported format
419     for (int j = anOldLen+1; j <= theFormats->Length(); j++) {
420       TCollection_AsciiString aKey, aPattern;
421       aKey = theFormats->Value(j) + ".ImportPattern";
422       if (aResMgr->Find(aKey.ToCString()))
423         aPattern = aResMgr->Value(aKey.ToCString());
424       else {
425         aKey = theFormats->Value(j) + ".Pattern";
426         if (aResMgr->Find(aKey.ToCString()))
427           aPattern = aResMgr->Value(aKey.ToCString());
428         else {
429           aPattern = theFormats->Value(j);
430           aPattern += " Files ( *.* )";
431         }
432       }
433       thePatterns->Append(aPattern);
434     }
435   }
436
437   return (!theFormats->IsEmpty());
438 }
439
440 //=============================================================================
441 /*!
442  *  ExportTranslators
443  */
444 //=============================================================================
445 Standard_Boolean GEOMImpl_IInsertOperations::ExportTranslators
446                      (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
447                       Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
448 {
449   if (theFormats.IsNull())
450     theFormats = new TColStd_HSequenceOfAsciiString;
451   else
452     theFormats->Clear();
453
454   if (thePatterns.IsNull())
455     thePatterns = new TColStd_HSequenceOfAsciiString;
456   else
457     thePatterns->Clear();
458
459   if (!InitResMgr()) return Standard_False;
460
461   // Read Export formats list from directories
462   Handle(Resource_Manager) aResMgr;
463   for(int index=0; index < myResMgrList.size(); index++) {
464     int anOldLen = theFormats->Length();
465     aResMgr = myResMgrList.at(index);
466     if (aResMgr->Find("Export")) {
467       TCollection_AsciiString aFormats (aResMgr->Value("Export"));
468       TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
469       for (int i = 1; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
470         int aLenFormats = theFormats->Length();
471         bool isFound = false;
472         for(int aInd=1;aInd<=aLenFormats;aInd++){
473           if( theFormats->Value(aInd) == aToken){
474             isFound = true;
475             break;
476           }
477         }
478         if(!isFound)
479           theFormats->Append(aToken);
480       }
481     }
482
483     // Read Patterns for each supported format
484     for (int j = anOldLen+1; j <= theFormats->Length(); j++) {
485       TCollection_AsciiString aKey, aPattern;
486       aKey = theFormats->Value(j) + ".ExportPattern";
487       if (aResMgr->Find(aKey.ToCString()))
488         aPattern = aResMgr->Value(aKey.ToCString());
489       else {
490         aKey = theFormats->Value(j) + ".Pattern";
491         if (aResMgr->Find(aKey.ToCString()))
492           aPattern = aResMgr->Value(aKey.ToCString());
493         else {
494           aPattern = theFormats->Value(j);
495           aPattern += " Files ( *.* )";
496         }
497       }
498       thePatterns->Append(aPattern);
499     }
500   }
501
502   return (!theFormats->IsEmpty());
503 }
504
505 //=============================================================================
506 /*!
507  *  IsSupported
508  */
509 //=============================================================================
510 Standard_Boolean GEOMImpl_IInsertOperations::IsSupported
511                             (const Standard_Boolean isImport,
512                              const TCollection_AsciiString& theFormat,
513                              Handle(TCollection_HAsciiString)& theLibName)
514 {
515   if (!InitResMgr()) return Standard_False;
516
517   // Import/Export mode
518   TCollection_AsciiString aMode;
519   //Standard_CString aMode;
520   if (isImport) aMode = "Import";
521   else aMode = "Export";
522
523   // Read supported formats for the certain mode from user directory
524   Handle(Resource_Manager) aResMgr;
525   for(int index=0; index < myResMgrList.size(); index++) {
526     aResMgr = myResMgrList.at(index);
527     if (aResMgr->Find(aMode.ToCString())) {
528       TCollection_AsciiString aFormats (aResMgr->Value(aMode.ToCString()));
529       if (aFormats.Search(theFormat) > -1) {
530         // Read library name for the supported format
531         TCollection_AsciiString aKey (theFormat);
532         aKey += ".";
533         aKey += aMode;
534         if (aResMgr->Find(aKey.ToCString())) {
535           TCollection_AsciiString aLibName (aResMgr->Value(aKey.ToCString()));
536   #ifndef WIN32
537           if ( aLibName.Length() > 3 && aLibName.SubString(1,3) != "lib" )
538             aLibName.Prepend("lib");
539           aLibName += ".so";
540   #else
541           aLibName += ".dll";
542   #endif
543           theLibName = new TCollection_HAsciiString (aLibName);
544           return Standard_True;
545         }
546       }
547     }
548   }
549   
550   return Standard_False;
551 }
552
553 //=============================================================================
554 /*!
555  *  InitResMgr
556  */
557 //=============================================================================
558 Standard_Boolean GEOMImpl_IInsertOperations::InitResMgr()
559 {
560   bool isResourceFound = false;
561   TCollection_AsciiString aNull;
562   
563   myResMgrList.clear();
564
565   // Initialize the GEOM Resource Manager
566   TCollection_AsciiString aResDir;
567   aResDir = getenv("GEOM_ROOT_DIR");
568 #ifdef WIN32
569   aResDir += "\\share\\salome\\resources\\geom";
570 #else
571   aResDir += "/share/salome/resources/geom";
572 #endif
573   Handle(Resource_Manager) aGeomResMgr = new Resource_Manager ("ImportExport", aResDir, aNull, Standard_False);
574   if ( aGeomResMgr->Find("Import") || aGeomResMgr->Find("Export") ) {
575     myResMgrList.push_back( aGeomResMgr );
576     isResourceFound = true;
577   }
578
579   // Initialize the user's Resource Manager
580   TCollection_AsciiString aResDirsStr;
581   aResDirsStr = getenv("GEOM_ENGINE_RESOURCES_DIR");
582   if ( !aResDirsStr.IsEmpty() )
583   {
584     std::string aSep = ":";
585 #ifdef WIN32
586     aSep = ";";
587 #endif
588     aResDir = aResDirsStr.Token(aSep.c_str(), 1);
589     for (int i = 1; !aResDir.IsEmpty(); aResDir = aResDirsStr.Token(aSep.c_str(), ++i)) {
590       Handle(Resource_Manager) anUserResMgr = new Resource_Manager ("ImportExport", aNull, aResDir, Standard_False);
591       if (anUserResMgr->Find("Import") || anUserResMgr->Find("Export")) {
592         myResMgrList.push_back( anUserResMgr );
593         isResourceFound = true;
594       }
595     }
596   }
597   else
598   {
599     aResDir = getenv("HOME");
600 #ifdef WIN32
601     aResDir += "\\.config\\salome";
602 #else
603     aResDir += "/.config/salome";
604 #endif
605     Handle(Resource_Manager) anUserResMgr = new Resource_Manager ("ImportExport", aNull, aResDir, Standard_False);
606     if (anUserResMgr->Find("Import") || anUserResMgr->Find("Export")) {
607       myResMgrList.push_back( anUserResMgr );
608       isResourceFound = true;
609     }
610   }
611   return isResourceFound;
612 }
613
614 //=============================================================================
615 /*!
616  *  RestoreShape
617  */
618 //=============================================================================
619 Handle(GEOM_Object) GEOMImpl_IInsertOperations::RestoreShape (std::istringstream& theStream)
620 {
621   SetErrorCode(KO);
622
623   //Add a new result object
624   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
625
626   //Add a Copy function
627   Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF);
628   if (aFunction.IsNull()) return NULL;
629
630   //Check if the function is set correctly
631   if (aFunction->GetDriverGUID() != GEOMImpl_CopyDriver::GetID()) return NULL;
632
633   //Read a shape from the stream
634   TopoDS_Shape aShape;
635   BRep_Builder B;
636   BRepTools::Read(aShape, theStream, B);
637   if (aShape.IsNull()) {
638     SetErrorCode("RestoreShape error: BREP reading failed");
639   }
640
641   //Set function value
642   aFunction->SetValue(aShape);
643
644   //Special dump to avoid restored shapes publication.
645   //See correcponding code in GEOM_Engine.cxx (method ProcessFunction)
646   //GEOM::TPythonDump(aFunction) << "#";
647
648   GEOM::TPythonDump(aFunction) << result
649     << " = geompy.RestoreShape(\"\") # the shape string has not been dump for performance reason";
650
651   SetErrorCode(OK);
652
653   return result;
654 }
655
656 int GEOMImpl_IInsertOperations::LoadTexture(const TCollection_AsciiString& theTextureFile)
657 {
658   SetErrorCode(KO);
659
660   if (theTextureFile.IsEmpty()) return 0;
661
662 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
663   Handle(TColStd_HArray1OfByte) aTexture;
664 #else
665   Handle(TDataStd_HArray1OfByte) aTexture;
666 #endif
667
668   FILE* fp = fopen(theTextureFile.ToCString(), "r");
669   if (!fp) return 0;
670
671   std::list<std::string> lines;
672   char buffer[4096];
673   int maxlen = 0;
674   while (!feof(fp)) {
675     if ((fgets(buffer, 4096, fp)) == NULL) break;
676     int aLen = strlen(buffer);
677     if (buffer[aLen-1] == '\n') buffer[aLen-1] = '\0';
678     lines.push_back(buffer);
679     maxlen = std::max(maxlen, (int)strlen(buffer));
680   }
681
682   fclose(fp);
683
684   int lenbytes = maxlen/8;
685   if (maxlen%8) lenbytes++;
686
687   if (lenbytes == 0 || lines.empty())
688     return 0;
689
690   std::list<unsigned char> bytedata;
691   std::list<std::string>::const_iterator it;
692   for (it = lines.begin(); it != lines.end(); ++it) {
693     std::string line = *it;
694     int lenline = (line.size()/8 + (line.size()%8 ? 1 : 0)) * 8;
695     for (int i = 0; i < lenline/8; i++) {
696       unsigned char byte = 0;
697       for (int j = 0; j < 8; j++)
698         byte = (byte << 1) + ( i*8+j < line.size() && line[i*8+j] != '0' ? 1 : 0 );
699       bytedata.push_back(byte);
700     }
701     for (int i = lenline/8; i < lenbytes; i++)
702       bytedata.push_back((unsigned char)0);
703   }
704
705   if (bytedata.empty() || bytedata.size() != lines.size()*lenbytes)
706     return 0;
707
708 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
709   aTexture = new TColStd_HArray1OfByte (1, lines.size()*lenbytes);
710 #else
711   aTexture = new TDataStd_HArray1OfByte (1, lines.size()*lenbytes);
712 #endif
713
714   std::list<unsigned char>::iterator bdit;
715   int i;
716   for (i = 1, bdit = bytedata.begin(); bdit != bytedata.end(); ++bdit, ++i)
717     aTexture->SetValue(i, (Standard_Byte)(*bdit));
718
719   int aTextureId = GetEngine()->addTexture(GetDocID(), lenbytes*8, lines.size(), aTexture, theTextureFile);
720   if (aTextureId > 0) SetErrorCode(OK);
721   return aTextureId;
722 }
723   
724 int GEOMImpl_IInsertOperations::AddTexture(int theWidth, int theHeight, 
725 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
726                                            const Handle(TColStd_HArray1OfByte)& theTexture)
727 #else
728                                            const Handle(TDataStd_HArray1OfByte)& theTexture)
729 #endif
730 {
731   SetErrorCode(KO);
732   int aTextureId = GetEngine()->addTexture(GetDocID(), theWidth, theHeight, theTexture);
733   if (aTextureId > 0) SetErrorCode(OK);
734   return aTextureId;
735 }
736
737 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
738 Handle(TColStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
739 #else
740 Handle(TDataStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
741 #endif
742                                                                       int& theWidth, int& theHeight)
743 {
744   SetErrorCode(KO);
745   
746 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
747   Handle(TColStd_HArray1OfByte) aTexture;
748 #else
749   Handle(TDataStd_HArray1OfByte) aTexture;
750 #endif
751
752   theWidth = theHeight = 0;
753   TCollection_AsciiString aFileName;
754
755   if (theTextureId <= 0)
756     return aTexture;
757
758   aTexture = GetEngine()->getTexture(GetDocID(), theTextureId, theWidth, theHeight, aFileName);
759
760   if (theWidth > 0 && theHeight > 0 && aTexture->Length() > 0) SetErrorCode(OK);
761
762   return aTexture;
763 }
764
765 std::list<int> GEOMImpl_IInsertOperations::GetAllTextures()
766 {
767   SetErrorCode(KO);
768   std::list<int> id_list = GetEngine()->getAllTextures(GetDocID());
769   SetErrorCode(OK);
770   return id_list;
771 }
772
773 TopAbs_ShapeEnum getGroupDimension(XAO::Group* group)
774 {
775   XAO::Dimension dim = group->getDimension();
776   TopAbs_ShapeEnum rdim;
777   switch ( dim )
778   {
779   case XAO::VERTEX:
780     rdim = TopAbs_VERTEX; break;
781   case XAO::EDGE:
782     rdim = TopAbs_EDGE; break;
783   case XAO::FACE:
784     rdim = TopAbs_FACE; break;
785   case XAO::SOLID:
786     rdim = TopAbs_SOLID; break;
787   default:
788     rdim = TopAbs_COMPOUND; break;
789   }
790   return rdim;
791 }
792
793 XAO::Dimension shapeEnumToDimension(const TopAbs_ShapeEnum& shape)
794 {
795   XAO::Dimension dim;
796   switch( shape ) {
797   case TopAbs_VERTEX:
798     dim = XAO::VERTEX; break;
799   case TopAbs_EDGE:
800     dim = XAO::EDGE; break;
801   case TopAbs_FACE:
802     dim = XAO::FACE; break;
803   case TopAbs_SOLID:
804     dim = XAO::SOLID; break;
805   default:
806     throw SALOME_Exception("Bad type"); // TODO
807   }
808   return dim;
809 }
810
811 void GEOMImpl_IInsertOperations::exportGroups(std::list<Handle(GEOM_Object)> groupList,
812                                               XAO::Xao* xaoObject,
813                                               XAO::BrepGeometry* geometry)
814 {
815   // add the groups
816   std::list<Handle(GEOM_Object)>::iterator groupIterator = groupList.begin();
817   while (groupIterator != groupList.end())
818   {
819     Handle(GEOM_Object) currGroup = (*groupIterator++);
820     Handle(TColStd_HArray1OfInteger) groupIds = myGroupOperations->GetObjects(currGroup);
821     
822     TopAbs_ShapeEnum shapeGroup = myGroupOperations->GetType(currGroup);
823     XAO::Dimension dim = shapeEnumToDimension(shapeGroup);
824     XAO::Group* group = xaoObject->addGroup(dim, currGroup->GetName().ToCString());
825     
826     switch (shapeGroup)
827     {
828     case TopAbs_VERTEX:
829       for (int i = 1; i <= groupIds->Length(); i++)
830       {
831         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
832         int index = geometry->getVertexIndexByReference(ref);
833         group->add(index);
834       }
835       break;
836     case TopAbs_EDGE:
837       for (int i = 1; i <= groupIds->Length(); i++)
838       {
839         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
840         int index = geometry->getEdgeIndexByReference(ref);
841         group->add(index);
842       }
843       break;
844     case TopAbs_FACE:
845       for (int i = 1; i <= groupIds->Length(); i++)
846       {
847         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
848         int index = geometry->getFaceIndexByReference(ref);
849         group->add(index);
850       }
851       break;
852     case TopAbs_SOLID:
853       for (int i = 1; i <= groupIds->Length(); i++)
854       {
855         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
856         int index = geometry->getSolidIndexByReference(ref);
857         group->add(index);
858       }
859       break;
860     }
861   }
862 }
863
864 void GEOMImpl_IInsertOperations::exportFields(std::list<Handle(GEOM_Field)> fieldList,
865                                               XAO::Xao* xaoObject,
866                                               XAO::BrepGeometry* geometry)
867 {
868     std::list<Handle(GEOM_Field)>::iterator fieldIterator = fieldList.begin();
869     while (fieldIterator != fieldList.end())
870     {
871         Handle(GEOM_Field) currField = (*fieldIterator++);
872
873         int fdim = currField->GetDimension();
874         int ftype = currField->GetDataType();
875         int nbComponents = currField->GetNbComponents();
876         std::string name = currField->GetName().ToCString();
877
878         XAO::Field* field = xaoObject->addField((XAO::Type)ftype, (XAO::Dimension)fdim, nbComponents, name);
879
880         Handle(TColStd_HArray1OfExtendedString) components = currField->GetComponents();
881         for (int i = components->Lower(), j = 0; i <= components->Upper(); ++i, ++j)
882         {
883             field->setComponentName(j, TCollection_AsciiString(components->Value(i)).ToCString());
884         }
885
886         std::list< Handle(GEOM_FieldStep)> steps = currField->GetSteps();
887         std::list<Handle(GEOM_FieldStep)>::iterator stepIterator = steps.begin();
888         while (stepIterator != steps.end())
889         {
890             Handle(GEOM_FieldStep) currStep = (*stepIterator++);
891
892             XAO::Step* step = field->addNewStep(currStep->GetID());
893             step->setStamp(currStep->GetStamp());
894
895             switch (ftype)
896             {
897                 case 0: // bool
898                 {
899                     XAO::BooleanStep* bs = (XAO::BooleanStep*)step;
900                     Handle(TColStd_HArray1OfInteger) bvalues = currStep->GetIntValues();
901                     std::vector<bool> bv;
902                     bv.reserve(bvalues->Upper());
903                     for ( int i = bvalues->Lower(), nb = bvalues->Upper(); i <= nb; ++i )
904                     {
905                         bv.push_back(bvalues->Value(i) != 0);
906                     }
907                     bs->setValues(bv);
908                     break;
909                 }
910                 case 1: // integer
911                 {
912                     XAO::IntegerStep* is = (XAO::IntegerStep*)step;
913                     Handle(TColStd_HArray1OfInteger) ivalues = currStep->GetIntValues();
914                     std::vector<int> iv;
915                     iv.reserve(ivalues->Upper());
916                     for ( int i = ivalues->Lower(), nb = ivalues->Upper(); i <= nb; ++i )
917                     {
918                         iv.push_back(ivalues->Value(i));
919                     }
920                     is->setValues(iv);
921                     break;
922                 }
923                 case 2: // double
924                 {
925                     XAO::DoubleStep* ds = (XAO::DoubleStep*)step;
926                     Handle(TColStd_HArray1OfReal) dvalues = currStep->GetDoubleValues();
927                     std::vector<double> dv;
928                     dv.reserve(dvalues->Upper());
929                     for ( int i = dvalues->Lower(), nb = dvalues->Upper(); i <= nb; ++i )
930                     {
931                         dv.push_back(dvalues->Value(i));
932                     }
933                     ds->setValues(dv);
934                     break;
935                 }
936                 case 3: // string
937                 {
938                     XAO::StringStep* ss = (XAO::StringStep*)step;
939                     Handle(TColStd_HArray1OfExtendedString) svalues = currStep->GetStringValues();
940                     std::vector<std::string> sv;
941                     sv.reserve(svalues->Upper());
942                     for ( int i = svalues->Lower(), nb = svalues->Upper(); i <= nb; ++i )
943                     {
944                         sv.push_back(TCollection_AsciiString(svalues->Value(i)).ToCString());
945                     }
946                     ss->setValues(sv);
947                     break;
948                 }
949             }
950         }
951     }
952 }
953
954 void GEOMImpl_IInsertOperations::exportSubshapes(const Handle(GEOM_Object)& shape, XAO::BrepGeometry* geometry)
955 {
956   Handle(TColStd_HSequenceOfTransient) subObjects = myShapesOperations->GetExistingSubObjects(shape, false);
957   int nbSubObjects = subObjects->Length();
958   // set the names of the sub shapes
959   for (int i = 1; i <= nbSubObjects; i++)
960   {
961     Handle(Standard_Transient) transientSubObject = subObjects->Value(i);
962     if (transientSubObject.IsNull())
963       continue;
964     
965     Handle(GEOM_Object) subObject = Handle(GEOM_Object)::DownCast(transientSubObject);
966     if (subObject->GetType() != GEOM_GROUP)
967     {
968       int subIndex = myShapesOperations->GetSubShapeIndex(shape, subObject);
969       switch (subObject->GetValue().ShapeType())
970       {
971       case TopAbs_VERTEX:
972         geometry->changeVertexName(subIndex, subObject->GetName().ToCString());
973         break;
974       case TopAbs_EDGE:
975         geometry->changeEdgeName(subIndex, subObject->GetName().ToCString());
976         break;
977       case TopAbs_FACE:
978         geometry->changeFaceName(subIndex, subObject->GetName().ToCString());
979         break;
980       case TopAbs_SOLID:
981         geometry->changeSolidName(subIndex, subObject->GetName().ToCString());
982         break;
983       }
984     }
985   }
986 }
987
988 //=============================================================================
989 /*!
990  *  Export a shape to XAO format
991  *  \param shape The shape to export
992  *  \param groups The list of groups to export
993  *  \param fields The list of fields to export
994  *  \param fileName The name of the file to exported
995  *  \return boolean indicating if export was succeful.
996  */
997 //=============================================================================
998 bool GEOMImpl_IInsertOperations::ExportXAO(Handle(GEOM_Object) shape,
999                                            std::list<Handle(GEOM_Object)> groupList,
1000                                            std::list<Handle(GEOM_Field)> fieldList,
1001                                            const char* author,
1002                                            const char* fileName)
1003 {
1004   SetErrorCode(KO);
1005
1006   if (shape.IsNull()) return false;
1007   
1008   // add a new shape function with parameters
1009   Handle(GEOM_Function) lastFunction = shape->GetLastFunction();
1010   if (lastFunction.IsNull()) return false;
1011   
1012   // add a new result object
1013   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
1014   
1015   // add an Export function
1016   Handle(GEOM_Function) exportFunction = result->AddFunction(GEOMImpl_XAODriver::GetID(), IMPORTEXPORT_EXPORTXAO);
1017   if (exportFunction.IsNull()) return false;
1018   if (exportFunction->GetDriverGUID() != GEOMImpl_XAODriver::GetID()) return false;
1019   
1020   // create the XAO object
1021   XAO::Xao* xaoObject = new XAO::Xao();
1022   xaoObject->setAuthor(author);
1023   
1024   // add the geometry
1025   XAO::BrepGeometry* geometry = (XAO::BrepGeometry*)XAO::Geometry::createGeometry(XAO::BREP);
1026   TopoDS_Shape topoShape = shape->GetValue();
1027   exportFunction->SetValue(topoShape);
1028   XAO::BrepGeometry* brep = (XAO::BrepGeometry*)geometry;
1029   brep->setTopoDS_Shape(topoShape);
1030   
1031   geometry->setName(shape->GetName().ToCString());
1032   exportSubshapes(shape, geometry);
1033   xaoObject->setGeometry(geometry);
1034   
1035   exportGroups(groupList, xaoObject, geometry);
1036   exportFields(fieldList, xaoObject, geometry);
1037   
1038   // export the XAO to the file
1039   xaoObject->exportXAO(fileName);
1040   
1041   // make a Python command
1042   GEOM::TPythonDump pd(exportFunction);
1043   pd << "exported = geompy.ExportXAO(" << shape;
1044   
1045   // list of groups
1046   pd << ", [";
1047   if (groupList.size() > 0)
1048   {
1049     std::list<Handle(GEOM_Object)>::iterator itGroup = groupList.begin();
1050     pd << (*itGroup++);
1051     while (itGroup != groupList.end())
1052     {
1053       pd << ", " << (*itGroup++);
1054     }
1055   }
1056
1057   // list of fields
1058   pd << "], [";
1059   if (fieldList.size() > 0)
1060   {
1061     std::list<Handle(GEOM_Field)>::iterator itField = fieldList.begin();
1062     pd << (*itField++);
1063     while (itField != fieldList.end())
1064     {
1065       pd << ", " << (*itField++);
1066     }
1067   }
1068   pd << "], ";
1069   pd << "\"" << author << "\", \"" << fileName << "\")";
1070   
1071   SetErrorCode(OK);
1072   delete xaoObject;
1073   
1074   return true;
1075 }
1076
1077 void GEOMImpl_IInsertOperations::importSubShapes(XAO::Geometry* xaoGeometry,
1078                                                  Handle(GEOM_Function) function, int shapeType, int dim,
1079                                                  Handle(TColStd_HSequenceOfTransient)& subShapeList)
1080 {
1081   Handle(GEOM_Object) subShape;
1082   Handle(GEOM_Function) aFunction;
1083   Handle(TColStd_HArray1OfInteger) anArray;
1084   
1085   XAO::GeometricElementList::iterator elementIterator = xaoGeometry->begin((XAO::Dimension)dim);
1086   for (; elementIterator != xaoGeometry->end((XAO::Dimension)dim); elementIterator++)
1087   {
1088     XAO::GeometricElement element = elementIterator->second;
1089     if (!element.hasName())
1090       continue;
1091     
1092     std::string name = element.getName();
1093     std::string ref = element.getReference();
1094     int iref = XAO::XaoUtils::stringToInt(ref);
1095     
1096     anArray = new TColStd_HArray1OfInteger(1, 1);
1097     anArray->SetValue(1, iref);
1098     
1099     subShape = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1100     Handle(GEOM_Function) aFunction = subShape->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1101     if (aFunction.IsNull())
1102       return;
1103     
1104     subShape->SetName(name.c_str());
1105     subShape->SetType(shapeType);
1106     
1107     GEOM_ISubShape aSSI(aFunction);
1108     aSSI.SetMainShape(function);
1109     aSSI.SetIndices(anArray);
1110     
1111     //aFunction->SetValue(aValue);
1112     subShapeList->Append(subShape);
1113     
1114     // Put this subshape in the list of sub-shapes of theMainShape
1115     function->AddSubShapeReference(aFunction);
1116   }
1117 }
1118
1119 //=============================================================================
1120 /*!
1121  *  Import a shape from XAO format
1122  *  \param fileName The name of the file to import
1123  *  \param shape The imported shape
1124  *  \param subShapes The list of imported groups
1125  *  \param groups The list of imported groups
1126  *  \param fields The list of imported fields
1127  *  \return boolean indicating if import was succeful.
1128  */
1129 //=============================================================================
1130 bool GEOMImpl_IInsertOperations::ImportXAO(const char* fileName,
1131                                            Handle(GEOM_Object)& shape,
1132                                            Handle(TColStd_HSequenceOfTransient)& subShapes,
1133                                            Handle(TColStd_HSequenceOfTransient)& groups,
1134                                            Handle(TColStd_HSequenceOfTransient)& fields)
1135 {
1136   SetErrorCode(KO);
1137   
1138   if (fileName == NULL || groups.IsNull() || fields.IsNull())
1139     return false;
1140   
1141   // Read the XAO
1142   XAO::Xao* xaoObject = new XAO::Xao();
1143   try
1144   {
1145     xaoObject->importXAO(fileName);
1146   }
1147   catch (XAO::XAO_Exception& exc)
1148   {
1149     delete xaoObject;
1150     SetErrorCode(exc.what());
1151     return false;
1152   }
1153   
1154   XAO::Geometry* xaoGeometry = xaoObject->getGeometry();
1155   if (xaoGeometry == NULL)
1156   {
1157     delete xaoObject;
1158     SetErrorCode("Cannot import XAO: geometry format not supported.");
1159     return false;
1160   }
1161   
1162   // create the shape
1163   shape = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
1164   Handle(GEOM_Function) function = shape->AddFunction(GEOMImpl_XAODriver::GetID(), IMPORTEXPORT_EXPORTXAO);
1165   if (function.IsNull()) return false;
1166   if (function->GetDriverGUID() != GEOMImpl_XAODriver::GetID()) return false;
1167   
1168   // set the geometry
1169   if (xaoGeometry->getFormat() == XAO::BREP)
1170   {
1171     XAO::BrepGeometry* brep = (XAO::BrepGeometry*)xaoGeometry;
1172     TopoDS_Shape geomShape = brep->getTopoDS_Shape();
1173     function->SetValue(geomShape);
1174     shape->SetName(xaoGeometry->getName().c_str());
1175   }
1176   else
1177   {
1178     delete xaoObject;
1179     SetErrorCode("Cannot import XAO: geometry format not supported.");
1180     return false;
1181   }
1182   
1183   // create sub shapes with names
1184   importSubShapes(xaoGeometry, function, GEOM_POINT, XAO::VERTEX, subShapes);
1185   importSubShapes(xaoGeometry, function, GEOM_EDGE, XAO::EDGE, subShapes);
1186   importSubShapes(xaoGeometry, function, GEOM_FACE, XAO::FACE, subShapes);
1187   importSubShapes(xaoGeometry, function, GEOM_SOLID, XAO::SOLID, subShapes);
1188   
1189   // create groups
1190   int nbGroups = xaoObject->countGroups();
1191   for (int i = 0; i < nbGroups; ++i)
1192   {
1193     XAO::Group* xaoGroup = xaoObject->getGroup(i);
1194     
1195     // build an array with the indexes of the sub shapes
1196     int nbElt = xaoGroup->count();
1197     Handle(TColStd_HArray1OfInteger) array = new TColStd_HArray1OfInteger(1, nbElt);
1198     int j = 0;
1199     for (std::set<int>::iterator it = xaoGroup->begin(); it != xaoGroup->end(); ++it)
1200     {
1201       int index = (*it);
1202       std::string ref = xaoGeometry->getElementReference(xaoGroup->getDimension(), index);
1203       array->SetValue(++j, XAO::XaoUtils::stringToInt(ref));
1204     }
1205     
1206     // create the group with the array of sub shapes indexes
1207     Handle(GEOM_Object) group = GetEngine()->AddSubShape(shape, array);
1208     group->SetType(GEOM_GROUP);
1209     group->SetName(xaoGroup->getName().c_str());
1210     
1211     // Set a sub-shape type
1212     TDF_Label freeLabel = group->GetFreeLabel();
1213     TDataStd_Integer::Set(freeLabel, (Standard_Integer) getGroupDimension(xaoGroup));
1214     groups->Append(group);
1215     
1216     function = group->GetLastFunction();
1217   }
1218   
1219   // create the fields
1220   int nbFields = xaoObject->countFields();
1221   for (int i = 0; i < nbFields; ++i)
1222   {
1223     XAO::Field* xaoField = xaoObject->getField(i);
1224
1225     Handle(TColStd_HArray1OfExtendedString) components = new TColStd_HArray1OfExtendedString(0, xaoField->countComponents()-1);
1226     for (int j = 0; j < xaoField->countComponents(); ++j)
1227     {
1228         components->SetValue(j, (TCollection_ExtendedString)xaoField->getComponentName(j).c_str());
1229     }
1230
1231     Handle(GEOM_Field) field = myFieldOperations->CreateField(shape,
1232                  xaoField->getName().c_str(),
1233                  (int)xaoField->getType(),
1234                  (int)xaoField->getDimension(),
1235                  components);
1236
1237     switch (xaoField->getType())
1238     {
1239         case XAO::BOOLEAN:
1240         {
1241             XAO::BooleanField* bfield = (XAO::BooleanField*)xaoField;
1242             for (int j = 0; j < xaoField->countSteps(); ++j)
1243             {
1244                 XAO::BooleanStep* bstep = bfield->getStep(j);
1245                 Handle(GEOM_FieldStep) step = field->AddStep(bstep->getStep(), bstep->getStamp());
1246
1247                 Handle(TColStd_HArray1OfInteger) values = new TColStd_HArray1OfInteger(0, bstep->countValues()-1);
1248                 std::vector<bool> bvalues = bstep->getValues();
1249                 for (int k = 0; k < bstep->countValues(); ++k)
1250                 {
1251                     values->SetValue(k, bvalues[k] ? 1 : 0);
1252                 }
1253                 step->SetValues(values);
1254             }
1255             break;
1256         }
1257         case XAO::INTEGER:
1258         {
1259             XAO::IntegerField* ifield = (XAO::IntegerField*)xaoField;
1260             for (int j = 0; j < xaoField->countSteps(); ++j)
1261             {
1262                 XAO::IntegerStep* istep = ifield->getStep(j);
1263                 Handle(GEOM_FieldStep) step = field->AddStep(istep->getStep(), istep->getStamp());
1264
1265                 Handle(TColStd_HArray1OfInteger) values = new TColStd_HArray1OfInteger(0, istep->countValues()-1);
1266                 std::vector<int> ivalues = istep->getValues();
1267                 for (int k = 0; k < istep->countValues(); ++k)
1268                 {
1269                     values->SetValue(k, ivalues[k]);
1270                 }
1271                 step->SetValues(values);
1272             }
1273             break;
1274         }
1275         case XAO::DOUBLE:
1276         {
1277             XAO::DoubleField* dfield = (XAO::DoubleField*)xaoField;
1278             for (int j = 0; j < xaoField->countSteps(); ++j)
1279             {
1280                 XAO::DoubleStep* dstep = dfield->getStep(j);
1281                 Handle(GEOM_FieldStep) step = field->AddStep(dstep->getStep(), dstep->getStamp());
1282
1283                 Handle(TColStd_HArray1OfReal) values = new TColStd_HArray1OfReal(0, dstep->countValues()-1);
1284                 std::vector<double> dvalues = dstep->getValues();
1285                 for (int k = 0; k < dstep->countValues(); ++k)
1286                 {
1287                     values->SetValue(k, dvalues[k]);
1288                 }
1289                 step->SetValues(values);
1290             }
1291             break;
1292         }
1293         case XAO::STRING:
1294         {
1295             XAO::StringField* sfield = (XAO::StringField*)xaoField;
1296             for (int j = 0; j < xaoField->countSteps(); ++j)
1297             {
1298                 XAO::StringStep* sstep = sfield->getStep(j);
1299                 Handle(GEOM_FieldStep) step = field->AddStep(sstep->getStep(), sstep->getStamp());
1300
1301                 Handle(TColStd_HArray1OfExtendedString) values = new TColStd_HArray1OfExtendedString(0, sstep->countValues()-1);
1302                 std::vector<std::string> svalues = sstep->getValues();
1303                 for (int k = 0; k < sstep->countValues(); ++k)
1304                 {
1305                     values->SetValue(k, TCollection_ExtendedString(svalues[k].c_str()));
1306                 }
1307                 step->SetValues(values);
1308             }
1309             break;
1310         }
1311     }
1312
1313     fields->Append(field);
1314   }
1315   
1316   // make a Python command
1317   GEOM::TPythonDump pd(function);
1318   pd << "(imported, " << shape << ", ";
1319   
1320   // list of sub shapes
1321   pd << "[";
1322   int nbSubshapes = subShapes->Length();
1323   if (nbSubshapes > 0)
1324   {
1325     for (int i = 1; i <= nbSubshapes; i++)
1326     {
1327       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(subShapes->Value(i));
1328       pd << obj << ((i < nbSubshapes) ? ", " : "");
1329     }
1330   }
1331   pd << "], [";
1332   
1333   // list of groups
1334   if (nbGroups > 0)
1335   {
1336     for (int i = 1; i <= nbGroups; i++)
1337     {
1338       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(groups->Value(i));
1339       pd << obj << ((i < nbGroups) ? ", " : "");
1340     }
1341   }
1342   
1343   pd << "], [";
1344   
1345   // list of fields
1346   if (nbFields > 0)
1347   {
1348     for (int i = 1; i <= nbFields; i++)
1349     {
1350       Handle(GEOM_Field) obj = Handle(GEOM_Field)::DownCast(fields->Value(i));
1351       pd << obj << ((i < nbFields) ? ", " : "");
1352     }
1353   }
1354   pd << "]";
1355   pd << ") = geompy.ImportXAO(\"" << fileName << "\")";
1356   
1357   delete xaoObject;
1358   SetErrorCode(OK);
1359   
1360   return true;
1361 }
1362
1363 //=============================================================================
1364 /*!
1365  *  This method creates material groups for an imported object.
1366  *  \param theObject the imported object.
1367  */
1368 //=============================================================================
1369 void GEOMImpl_IInsertOperations::MakeMaterialGroups
1370                         (const Handle(GEOM_Object) &theObject,
1371                          const Handle(TColStd_HSequenceOfTransient) &theSeq)
1372 {
1373   TopoDS_Shape aResShape = theObject->GetValue();
1374
1375   if (aResShape.IsNull() == Standard_False) {
1376     // Group shapes by material names.
1377     Handle(GEOM_Function)      aFunction = theObject->GetLastFunction();
1378     DataMapOfStringListOfShape aMapMaterialShapes;
1379
1380     // check all named shapes using iterator
1381     TDF_ChildIDIterator anIt (aFunction->GetNamingEntry(),
1382         TNaming_NamedShape::GetID(), Standard_True);
1383
1384     for (; anIt.More(); anIt.Next()) {
1385       Handle(TNaming_NamedShape) anAttr =
1386           Handle(TNaming_NamedShape)::DownCast(anIt.Value());
1387
1388       if (anAttr.IsNull() == Standard_False) {
1389         TDF_Label                aLabel = anAttr->Label();
1390         Handle(TDataStd_Comment) aComment;
1391
1392         if (aLabel.FindAttribute(TDataStd_Comment::GetID(), aComment)) {
1393           TCollection_ExtendedString aMatName = aComment->Get();
1394           TopoDS_Shape               aShape   = anAttr->Get();
1395
1396           if (aMapMaterialShapes.IsBound(aMatName) == Standard_False) {
1397             NCollection_List<TopoDS_Shape> anEmptyList;
1398
1399             aMapMaterialShapes.Bind(aMatName, anEmptyList);
1400           }
1401
1402           aMapMaterialShapes(aMatName).Append(aShape);
1403         }
1404       }
1405     }
1406
1407     if (aMapMaterialShapes.IsEmpty() == Standard_False) {
1408       // Construct groups.
1409       TopAbs_ShapeEnum aType = aResShape.ShapeType();
1410       Standard_Integer i;
1411       DataMapOfStringListOfShape::Iterator aMapIter;
1412
1413       // Check each shape type.
1414       for(i = aType; i <= TopAbs_VERTEX; i++) {
1415         DataMapOfStringListOfShape::Iterator aMapIter(aMapMaterialShapes);
1416
1417         for (; aMapIter.More(); aMapIter.Next()) {
1418           NCollection_List<TopoDS_Shape> &aShList = aMapIter.ChangeValue();
1419           NCollection_List<TopoDS_Shape>::Iterator aShIter(aShList);
1420           NCollection_List<TopoDS_Shape>  aShListSameType;
1421
1422           while (aShIter.More()) {
1423             const TopoDS_Shape &aShape = aShIter.Value();
1424
1425             if (i == aShape.ShapeType()) {
1426               // Treat this element.
1427               aShListSameType.Append(aShape);
1428               aShList.Remove(aShIter);
1429             } else {
1430               // Go to the next element.
1431               aShIter.Next();
1432             }
1433           }
1434
1435           if (aShListSameType.IsEmpty() == Standard_False) {
1436             // Construct a group.
1437             Handle(GEOM_Object) aGroup =
1438               MakeGroup(theObject, aMapIter.Key(), aShListSameType);
1439
1440             if (aGroup.IsNull() == Standard_False) {
1441               theSeq->Append(aGroup);
1442             }
1443           }
1444         }
1445       }
1446     }
1447   }
1448 }
1449
1450
1451 //=============================================================================
1452 /*!
1453  *  This method creates a group of shapes of certain type.
1454  *  \param theObject the imported object.
1455  *  \param theName the material name.
1456  *  \param theShapes the list of shapes to be added to this group.
1457  *  \return the created group.
1458  */
1459 //=============================================================================
1460 Handle(GEOM_Object) GEOMImpl_IInsertOperations::MakeGroup
1461                   (const Handle(GEOM_Object)            &theObject,
1462                    const TCollection_ExtendedString     &theName,
1463                    const NCollection_List<TopoDS_Shape> &theShapes)
1464 {
1465   Handle(GEOM_Object)                aGroup;
1466   TopTools_IndexedMapOfShape         anIndices;
1467   Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1468   NCollection_List<TopoDS_Shape>::Iterator anIter(theShapes);
1469
1470   TopExp::MapShapes(theObject->GetValue(), anIndices);
1471
1472   // Compose shape IDs.
1473   for (; anIter.More(); anIter.Next()) {
1474     const TopoDS_Shape &aShape = anIter.Value();
1475     const Standard_Integer anIndex = anIndices.FindIndex(aShape);
1476
1477     if (anIndex > 0) {
1478       aSeqIDs->Append(anIndex);
1479     }
1480   }
1481
1482   if (aSeqIDs->IsEmpty() == Standard_False) {
1483     // Create a group.
1484     const TopAbs_ShapeEnum aType  = theShapes.First().ShapeType();
1485
1486     aGroup = myGroupOperations->CreateGroup(theObject, aType);
1487
1488     if (aGroup.IsNull() == Standard_False) {
1489       aGroup->GetLastFunction()->SetDescription("");
1490       myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1491       aGroup->GetLastFunction()->SetDescription("");
1492
1493       // Compose the group name.
1494       TCollection_AsciiString aGroupName(theName);
1495
1496       switch(aType) {
1497         case TopAbs_VERTEX:
1498           aGroupName += "_VERTEX";
1499           break;
1500         case TopAbs_EDGE:
1501           aGroupName += "_EDGE";
1502           break;
1503         case TopAbs_WIRE:
1504           aGroupName += "_WIRE";
1505           break;
1506         case TopAbs_FACE:
1507           aGroupName += "_FACE";
1508           break;
1509         case TopAbs_SHELL:
1510           aGroupName += "_SHELL";
1511           break;
1512         case TopAbs_SOLID:
1513           aGroupName += "_SOLID";
1514           break;
1515         case TopAbs_COMPSOLID:
1516           aGroupName += "_COMPSOLID";
1517           break;
1518         case TopAbs_COMPOUND:
1519           aGroupName += "_COMPOUND";
1520           break;
1521         default:
1522           aGroupName += "_SHAPE";
1523           break;
1524       }
1525
1526       aGroup->SetName(aGroupName.ToCString());
1527     }
1528   }
1529
1530   return aGroup;
1531 }