Salome HOME
0022616: [CEA 1038] Improve the quality of stl and vtk exports
[modules/geom.git] / src / XAOPlugin / XAOPlugin_IOperations.cxx
1 // Copyright (C) 2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // internal includes
21 #include "XAOPlugin_IOperations.hxx"
22 #include "XAOPlugin_Driver.hxx"
23 #include "XAOPlugin_IImportExport.hxx"
24
25 // KERNEL includes
26 #include <utilities.h>
27 #include <Utils_SALOME_Exception.hxx>
28
29 // GEOM includes
30 #include "GEOM_PythonDump.hxx"
31 #include "GEOMImpl_Types.hxx"
32 #include "GEOMImpl_IGroupOperations.hxx"
33 #include "GEOMImpl_IShapesOperations.hxx"
34 #include "GEOMImpl_IFieldOperations.hxx"
35 #include "GEOM_ISubShape.hxx"
36
37 #include <XAO_Geometry.hxx>
38 #include <XAO_BrepGeometry.hxx>
39 #include <XAO_Xao.hxx>
40 #include <XAO_Group.hxx>
41 #include <XAO_Field.hxx>
42 #include <XAO_BooleanField.hxx>
43 #include <XAO_IntegerField.hxx>
44 #include <XAO_DoubleField.hxx>
45 #include <XAO_StringField.hxx>
46 #include <XAO_DoubleStep.hxx>
47 #include <XAO_StringStep.hxx>
48
49 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
50
51 // OCC includes
52 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
53 #include <TColStd_HArray1OfByte.hxx>
54 #include <TColStd_HArray1OfReal.hxx>
55 #else
56 #include <TDataStd_HArray1OfByte.hxx>
57 #endif
58 #include <TDataStd_Integer.hxx>
59
60
61 XAO::Dimension shapeEnumToDimension(const TopAbs_ShapeEnum& shape)
62 {
63   XAO::Dimension dim;
64   switch( shape ) {
65   case TopAbs_VERTEX:
66     dim = XAO::VERTEX; break;
67   case TopAbs_EDGE:
68     dim = XAO::EDGE; break;
69   case TopAbs_FACE:
70     dim = XAO::FACE; break;
71   case TopAbs_SOLID:
72     dim = XAO::SOLID; break;
73   default:
74     throw SALOME_Exception("Bad type"); // TODO
75   }
76   return dim;
77 }
78
79 TopAbs_ShapeEnum getGroupDimension(XAO::Group* group)
80 {
81   XAO::Dimension dim = group->getDimension();
82   TopAbs_ShapeEnum rdim;
83   switch ( dim )
84   {
85   case XAO::VERTEX:
86     rdim = TopAbs_VERTEX; break;
87   case XAO::EDGE:
88     rdim = TopAbs_EDGE; break;
89   case XAO::FACE:
90     rdim = TopAbs_FACE; break;
91   case XAO::SOLID:
92     rdim = TopAbs_SOLID; break;
93   default:
94     rdim = TopAbs_COMPOUND; break;
95   }
96   return rdim;
97 }
98
99 //=============================================================================
100 /*!
101  *  Constructor
102  */
103 //=============================================================================
104 XAOPlugin_IOperations::XAOPlugin_IOperations( GEOM_Engine* theEngine, int theDocID )
105 : GEOMImpl_IBaseIEOperations( theEngine, theDocID )
106 {
107   MESSAGE( "XAOPlugin_IOperations::XAOPlugin_IOperations" );
108 }
109
110 //=============================================================================
111 /*!
112  *  Destructor
113  */
114 //=============================================================================
115 XAOPlugin_IOperations::~XAOPlugin_IOperations()
116 {
117   MESSAGE( "XAOPlugin_IOperations::~XAOPlugin_IOperations" );
118 }
119
120 void XAOPlugin_IOperations::exportGroups( std::list<Handle(GEOM_Object)> groupList,
121                                                   XAO::Xao* xaoObject,
122                                                   XAO::BrepGeometry* geometry )
123 {
124   // add the groups
125   std::list<Handle(GEOM_Object)>::iterator groupIterator = groupList.begin();
126   while (groupIterator != groupList.end())
127   {
128     Handle(GEOM_Object) currGroup = (*groupIterator++);
129     Handle(TColStd_HArray1OfInteger) groupIds = myGroupOperations->GetObjects(currGroup);
130
131     TopAbs_ShapeEnum shapeGroup = myGroupOperations->GetType(currGroup);
132     XAO::Dimension dim = shapeEnumToDimension(shapeGroup);
133     XAO::Group* group = xaoObject->addGroup(dim, currGroup->GetName().ToCString());
134
135     switch (shapeGroup)
136     {
137     case TopAbs_VERTEX:
138       for (int i = 1; i <= groupIds->Length(); i++)
139       {
140         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
141         int index = geometry->getVertexIndexByReference(ref);
142         group->add(index);
143       }
144       break;
145     case TopAbs_EDGE:
146       for (int i = 1; i <= groupIds->Length(); i++)
147       {
148         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
149         int index = geometry->getEdgeIndexByReference(ref);
150         group->add(index);
151       }
152       break;
153     case TopAbs_FACE:
154       for (int i = 1; i <= groupIds->Length(); i++)
155       {
156         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
157         int index = geometry->getFaceIndexByReference(ref);
158         group->add(index);
159       }
160       break;
161     case TopAbs_SOLID:
162       for (int i = 1; i <= groupIds->Length(); i++)
163       {
164         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
165         int index = geometry->getSolidIndexByReference(ref);
166         group->add(index);
167       }
168       break;
169     }
170   }
171 }
172
173 void XAOPlugin_IOperations::exportFields( std::list<Handle(GEOM_Field)> fieldList,
174                                                   XAO::Xao* xaoObject,
175                                                   XAO::BrepGeometry* geometry )
176 {
177   std::list<Handle(GEOM_Field)>::iterator fieldIterator = fieldList.begin();
178   while (fieldIterator != fieldList.end())
179   {
180     Handle(GEOM_Field) currField = (*fieldIterator++);
181
182     int fdim = currField->GetDimension();
183     int ftype = currField->GetDataType();
184     int nbComponents = currField->GetNbComponents();
185     std::string name = currField->GetName().ToCString();
186
187     XAO::Field* field = xaoObject->addField((XAO::Type)ftype, (XAO::Dimension)fdim, nbComponents, name);
188
189     Handle(TColStd_HArray1OfExtendedString) components = currField->GetComponents();
190     for (int i = components->Lower(), j = 0; i <= components->Upper(); ++i, ++j)
191     {
192       field->setComponentName(j, TCollection_AsciiString(components->Value(i)).ToCString());
193     }
194
195     std::list< Handle(GEOM_FieldStep)> steps = currField->GetSteps();
196     std::list<Handle(GEOM_FieldStep)>::iterator stepIterator = steps.begin();
197     while (stepIterator != steps.end())
198     {
199       Handle(GEOM_FieldStep) currStep = (*stepIterator++);
200
201       XAO::Step* step = field->addNewStep(currStep->GetID());
202       step->setStamp(currStep->GetStamp());
203
204       switch (ftype)
205       {
206         case 0: // bool
207         {
208           XAO::BooleanStep* bs = (XAO::BooleanStep*)step;
209           Handle(TColStd_HArray1OfInteger) bvalues = currStep->GetIntValues();
210           std::vector<bool> bv;
211           bv.reserve(bvalues->Upper());
212           for ( int i = bvalues->Lower(), nb = bvalues->Upper(); i <= nb; ++i )
213           {
214             bv.push_back(bvalues->Value(i) != 0);
215           }
216           bs->setValues(bv);
217           break;
218         }
219         case 1: // integer
220         {
221           XAO::IntegerStep* is = (XAO::IntegerStep*)step;
222           Handle(TColStd_HArray1OfInteger) ivalues = currStep->GetIntValues();
223           std::vector<int> iv;
224           iv.reserve(ivalues->Upper());
225           for ( int i = ivalues->Lower(), nb = ivalues->Upper(); i <= nb; ++i )
226           {
227             iv.push_back(ivalues->Value(i));
228           }
229           is->setValues(iv);
230           break;
231         }
232         case 2: // double
233         {
234           XAO::DoubleStep* ds = (XAO::DoubleStep*)step;
235           Handle(TColStd_HArray1OfReal) dvalues = currStep->GetDoubleValues();
236           std::vector<double> dv;
237           dv.reserve(dvalues->Upper());
238           for ( int i = dvalues->Lower(), nb = dvalues->Upper(); i <= nb; ++i )
239           {
240             dv.push_back(dvalues->Value(i));
241           }
242           ds->setValues(dv);
243             break;
244         }
245         case 3: // string
246         {
247           XAO::StringStep* ss = (XAO::StringStep*)step;
248           Handle(TColStd_HArray1OfExtendedString) svalues = currStep->GetStringValues();
249           std::vector<std::string> sv;
250           sv.reserve(svalues->Upper());
251           for ( int i = svalues->Lower(), nb = svalues->Upper(); i <= nb; ++i )
252           {
253             sv.push_back(TCollection_AsciiString(svalues->Value(i)).ToCString());
254           }
255           ss->setValues(sv);
256           break;
257         }
258       }
259     }
260   }
261 }
262
263 void XAOPlugin_IOperations::exportSubshapes( const Handle(GEOM_Object)& shape, XAO::BrepGeometry* geometry )
264 {
265   Handle(TColStd_HSequenceOfTransient) subObjects = myShapesOperations->GetExistingSubObjects( shape, false );
266   int nbSubObjects = subObjects->Length();
267   // set the names of the sub shapes
268   for (int i = 1; i <= nbSubObjects; i++)
269   {
270     Handle(Standard_Transient) transientSubObject = subObjects->Value(i);
271     if (transientSubObject.IsNull())
272       continue;
273
274     Handle(GEOM_Object) subObject = Handle(GEOM_Object)::DownCast( transientSubObject );
275     if (subObject->GetType() != GEOM_GROUP)
276     {
277       int subIndex = myShapesOperations->GetSubShapeIndex( shape, subObject );
278       switch (subObject->GetValue().ShapeType())
279       {
280       case TopAbs_VERTEX:
281         geometry->changeVertexName(subIndex, subObject->GetName().ToCString());
282         break;
283       case TopAbs_EDGE:
284         geometry->changeEdgeName(subIndex, subObject->GetName().ToCString());
285         break;
286       case TopAbs_FACE:
287         geometry->changeFaceName(subIndex, subObject->GetName().ToCString());
288         break;
289       case TopAbs_SOLID:
290         geometry->changeSolidName(subIndex, subObject->GetName().ToCString());
291         break;
292       }
293     }
294   }
295 }
296
297 //=============================================================================
298 /*!
299  *  Export a shape to XAO format
300  *  \param shape The shape to export
301  *  \param groups The list of groups to export
302  *  \param fields The list of fields to export
303  *  \param fileName The name of the file to exported
304  *  \return boolean indicating if export was succeful.
305  */
306 //=============================================================================
307 bool XAOPlugin_IOperations::ExportXAO( Handle(GEOM_Object) shape,
308                                        std::list<Handle(GEOM_Object)> groupList,
309                                        std::list<Handle(GEOM_Field)> fieldList,
310                                        const char* author,
311                                        const char* fileName )
312 {
313   SetErrorCode(KO);
314
315   if (shape.IsNull()) return false;
316
317   // add a new shape function with parameters
318   Handle(GEOM_Function) lastFunction = shape->GetLastFunction();
319   if (lastFunction.IsNull()) return false;
320
321   // add a new result object
322   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
323
324   // add an Export function
325   Handle(GEOM_Function) exportFunction = result->AddFunction(XAOPlugin_Driver::GetID(), EXPORT_SHAPE);
326   if (exportFunction.IsNull()) return false;
327   if (exportFunction->GetDriverGUID() != XAOPlugin_Driver::GetID()) return false;
328
329   // create the XAO object
330   XAO::Xao* xaoObject = new XAO::Xao();
331   xaoObject->setAuthor(author);
332
333   // add the geometry
334   XAO::BrepGeometry* geometry = (XAO::BrepGeometry*)XAO::Geometry::createGeometry(XAO::BREP);
335   TopoDS_Shape topoShape = shape->GetValue();
336   exportFunction->SetValue(topoShape);
337   XAO::BrepGeometry* brep = (XAO::BrepGeometry*)geometry;
338   brep->setTopoDS_Shape(topoShape);
339
340   geometry->setName(shape->GetName().ToCString());
341   exportSubshapes(shape, geometry);
342   xaoObject->setGeometry(geometry);
343
344   exportGroups(groupList, xaoObject, geometry);
345   exportFields(fieldList, xaoObject, geometry);
346
347   // export the XAO to the file
348   xaoObject->exportXAO(fileName);
349
350   // make a Python command
351   GEOM::TPythonDump pd(exportFunction);
352   pd << "exported = geompy.ExportXAO(" << shape;
353
354   // list of groups
355   pd << ", [";
356   if (groupList.size() > 0)
357   {
358     std::list<Handle(GEOM_Object)>::iterator itGroup = groupList.begin();
359     pd << (*itGroup++);
360     while (itGroup != groupList.end())
361     {
362       pd << ", " << (*itGroup++);
363     }
364   }
365
366   // list of fields
367   pd << "], [";
368   if (fieldList.size() > 0)
369   {
370     std::list<Handle(GEOM_Field)>::iterator itField = fieldList.begin();
371     pd << (*itField++);
372     while (itField != fieldList.end())
373     {
374       pd << ", " << (*itField++);
375     }
376   }
377   pd << "], ";
378   pd << "\"" << author << "\", \"" << fileName << "\")";
379
380   SetErrorCode(OK);
381   delete xaoObject;
382
383   return true;
384 }
385
386 void XAOPlugin_IOperations::importSubShapes( XAO::Geometry* xaoGeometry,
387                                                      Handle(GEOM_Function) function, int shapeType, int dim,
388                                                      Handle(TColStd_HSequenceOfTransient)& subShapeList )
389 {
390   Handle(GEOM_Object) subShape;
391   Handle(GEOM_Function) aFunction;
392   Handle(TColStd_HArray1OfInteger) anArray;
393
394   XAO::GeometricElementList::iterator elementIterator = xaoGeometry->begin((XAO::Dimension)dim);
395   for (; elementIterator != xaoGeometry->end((XAO::Dimension)dim); elementIterator++)
396   {
397     XAO::GeometricElement element = elementIterator->second;
398     if (!element.hasName())
399       continue;
400
401     std::string name = element.getName();
402     std::string ref = element.getReference();
403     int iref = XAO::XaoUtils::stringToInt(ref);
404
405     anArray = new TColStd_HArray1OfInteger(1, 1);
406     anArray->SetValue(1, iref);
407
408     subShape = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
409     Handle(GEOM_Function) aFunction = subShape->AddFunction(GEOM_Object::GetSubShapeID(), 1);
410     if (aFunction.IsNull())
411       return;
412
413     subShape->SetName(name.c_str());
414     subShape->SetType(shapeType);
415
416     GEOM_ISubShape aSSI(aFunction);
417     aSSI.SetMainShape(function);
418     aSSI.SetIndices(anArray);
419
420     //aFunction->SetValue(aValue);
421     subShapeList->Append(subShape);
422
423     // Put this subshape in the list of sub-shapes of theMainShape
424     function->AddSubShapeReference(aFunction);
425   }
426 }
427
428 //=============================================================================
429 /*!
430  *  Import a shape from XAO format
431  *  \param fileName The name of the file to import
432  *  \param shape The imported shape
433  *  \param subShapes The list of imported groups
434  *  \param groups The list of imported groups
435  *  \param fields The list of imported fields
436  *  \return boolean indicating if import was succeful.
437  */
438 //=============================================================================
439 bool XAOPlugin_IOperations::ImportXAO( const char* fileName,
440                                                Handle(GEOM_Object)& shape,
441                                                Handle(TColStd_HSequenceOfTransient)& subShapes,
442                                                Handle(TColStd_HSequenceOfTransient)& groups,
443                                                Handle(TColStd_HSequenceOfTransient)& fields )
444 {
445   SetErrorCode(KO);
446
447   if (fileName == NULL || groups.IsNull() || fields.IsNull())
448     return false;
449
450   // Read the XAO
451   XAO::Xao* xaoObject = new XAO::Xao();
452   try
453   {
454     xaoObject->importXAO(fileName);
455   }
456   catch (XAO::XAO_Exception& exc)
457   {
458     delete xaoObject;
459     SetErrorCode(exc.what());
460     return false;
461   }
462
463   XAO::Geometry* xaoGeometry = xaoObject->getGeometry();
464   if (xaoGeometry == NULL)
465   {
466     delete xaoObject;
467     SetErrorCode("Cannot import XAO: geometry format not supported.");
468     return false;
469   }
470
471   // create the shape
472   shape = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
473   Handle(GEOM_Function) function = shape->AddFunction(XAOPlugin_Driver::GetID(), IMPORT_SHAPE);
474   if (function.IsNull()) return false;
475   if (function->GetDriverGUID() != XAOPlugin_Driver::GetID()) return false;
476
477   // set the geometry
478   if (xaoGeometry->getFormat() == XAO::BREP)
479   {
480     XAO::BrepGeometry* brep = (XAO::BrepGeometry*)xaoGeometry;
481     TopoDS_Shape geomShape = brep->getTopoDS_Shape();
482     function->SetValue(geomShape);
483     shape->SetName(xaoGeometry->getName().c_str());
484   }
485   else
486   {
487     delete xaoObject;
488     SetErrorCode("Cannot import XAO: geometry format not supported.");
489     return false;
490   }
491
492   // create sub shapes with names
493   importSubShapes(xaoGeometry, function, GEOM_POINT, XAO::VERTEX, subShapes);
494   importSubShapes(xaoGeometry, function, GEOM_EDGE, XAO::EDGE, subShapes);
495   importSubShapes(xaoGeometry, function, GEOM_FACE, XAO::FACE, subShapes);
496   importSubShapes(xaoGeometry, function, GEOM_SOLID, XAO::SOLID, subShapes);
497
498   // create groups
499   int nbGroups = xaoObject->countGroups();
500   for (int i = 0; i < nbGroups; ++i)
501   {
502     XAO::Group* xaoGroup = xaoObject->getGroup(i);
503
504     // build an array with the indexes of the sub shapes
505     int nbElt = xaoGroup->count();
506     Handle(TColStd_HArray1OfInteger) array = new TColStd_HArray1OfInteger(1, nbElt);
507     int j = 0;
508     for (std::set<int>::iterator it = xaoGroup->begin(); it != xaoGroup->end(); ++it)
509     {
510       int index = (*it);
511       std::string ref = xaoGeometry->getElementReference(xaoGroup->getDimension(), index);
512       array->SetValue(++j, XAO::XaoUtils::stringToInt(ref));
513     }
514
515     // create the group with the array of sub shapes indexes
516     Handle(GEOM_Object) group = GetEngine()->AddSubShape(shape, array);
517     group->SetType(GEOM_GROUP);
518     group->SetName(xaoGroup->getName().c_str());
519
520     // Set a sub-shape type
521     TDF_Label freeLabel = group->GetFreeLabel();
522     TDataStd_Integer::Set(freeLabel, (Standard_Integer) getGroupDimension(xaoGroup));
523     groups->Append(group);
524
525     function = group->GetLastFunction();
526   }
527
528   // create the fields
529   int nbFields = xaoObject->countFields();
530   for (int i = 0; i < nbFields; ++i)
531   {
532     XAO::Field* xaoField = xaoObject->getField(i);
533
534     Handle(TColStd_HArray1OfExtendedString) components = new TColStd_HArray1OfExtendedString(0, xaoField->countComponents()-1);
535     for (int j = 0; j < xaoField->countComponents(); ++j)
536     {
537         components->SetValue(j, (TCollection_ExtendedString)xaoField->getComponentName(j).c_str());
538     }
539
540     Handle(GEOM_Field) field = myFieldOperations->CreateField(shape,
541                  xaoField->getName().c_str(),
542                  (int)xaoField->getType(),
543                  (int)xaoField->getDimension(),
544                  components);
545
546     switch (xaoField->getType())
547     {
548         case XAO::BOOLEAN:
549         {
550             XAO::BooleanField* bfield = (XAO::BooleanField*)xaoField;
551             for (int j = 0; j < xaoField->countSteps(); ++j)
552             {
553                 XAO::BooleanStep* bstep = bfield->getStep(j);
554                 Handle(GEOM_FieldStep) step = field->AddStep(bstep->getStep(), bstep->getStamp());
555
556                 Handle(TColStd_HArray1OfInteger) values = new TColStd_HArray1OfInteger(0, bstep->countValues()-1);
557                 std::vector<bool> bvalues = bstep->getValues();
558                 for (int k = 0; k < bstep->countValues(); ++k)
559                 {
560                     values->SetValue(k, bvalues[k] ? 1 : 0);
561                 }
562                 step->SetValues(values);
563             }
564             break;
565         }
566         case XAO::INTEGER:
567         {
568             XAO::IntegerField* ifield = (XAO::IntegerField*)xaoField;
569             for (int j = 0; j < xaoField->countSteps(); ++j)
570             {
571                 XAO::IntegerStep* istep = ifield->getStep(j);
572                 Handle(GEOM_FieldStep) step = field->AddStep(istep->getStep(), istep->getStamp());
573
574                 Handle(TColStd_HArray1OfInteger) values = new TColStd_HArray1OfInteger(0, istep->countValues()-1);
575                 std::vector<int> ivalues = istep->getValues();
576                 for (int k = 0; k < istep->countValues(); ++k)
577                 {
578                     values->SetValue(k, ivalues[k]);
579                 }
580                 step->SetValues(values);
581             }
582             break;
583         }
584         case XAO::DOUBLE:
585         {
586             XAO::DoubleField* dfield = (XAO::DoubleField*)xaoField;
587             for (int j = 0; j < xaoField->countSteps(); ++j)
588             {
589                 XAO::DoubleStep* dstep = dfield->getStep(j);
590                 Handle(GEOM_FieldStep) step = field->AddStep(dstep->getStep(), dstep->getStamp());
591
592                 Handle(TColStd_HArray1OfReal) values = new TColStd_HArray1OfReal(0, dstep->countValues()-1);
593                 std::vector<double> dvalues = dstep->getValues();
594                 for (int k = 0; k < dstep->countValues(); ++k)
595                 {
596                     values->SetValue(k, dvalues[k]);
597                 }
598                 step->SetValues(values);
599             }
600             break;
601         }
602         case XAO::STRING:
603         {
604             XAO::StringField* sfield = (XAO::StringField*)xaoField;
605             for (int j = 0; j < xaoField->countSteps(); ++j)
606             {
607                 XAO::StringStep* sstep = sfield->getStep(j);
608                 Handle(GEOM_FieldStep) step = field->AddStep(sstep->getStep(), sstep->getStamp());
609
610                 Handle(TColStd_HArray1OfExtendedString) values = new TColStd_HArray1OfExtendedString(0, sstep->countValues()-1);
611                 std::vector<std::string> svalues = sstep->getValues();
612                 for (int k = 0; k < sstep->countValues(); ++k)
613                 {
614                     values->SetValue(k, TCollection_ExtendedString(svalues[k].c_str()));
615                 }
616                 step->SetValues(values);
617             }
618             break;
619         }
620     }
621
622     fields->Append(field);
623   }
624
625   // make a Python command
626   GEOM::TPythonDump pd(function);
627   pd << "(imported, " << shape << ", ";
628
629   // list of sub shapes
630   pd << "[";
631   int nbSubshapes = subShapes->Length();
632   if (nbSubshapes > 0)
633   {
634     for (int i = 1; i <= nbSubshapes; i++)
635     {
636       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(subShapes->Value(i));
637       pd << obj << ((i < nbSubshapes) ? ", " : "");
638     }
639   }
640   pd << "], [";
641
642   // list of groups
643   if (nbGroups > 0)
644   {
645     for (int i = 1; i <= nbGroups; i++)
646     {
647       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(groups->Value(i));
648       pd << obj << ((i < nbGroups) ? ", " : "");
649     }
650   }
651
652   pd << "], [";
653
654   // list of fields
655   if (nbFields > 0)
656   {
657     for (int i = 1; i <= nbFields; i++)
658     {
659       Handle(GEOM_Field) obj = Handle(GEOM_Field)::DownCast(fields->Value(i));
660       pd << obj << ((i < nbFields) ? ", " : "");
661     }
662   }
663   pd << "]";
664   pd << ") = geompy.ImportXAO(\"" << fileName << "\")";
665
666   delete xaoObject;
667   SetErrorCode(OK);
668
669   return true;
670 }