Salome HOME
Implementation of [bos #35140] [EDF] (2023-T1) Memory communication between SHAPER...
[modules/geom.git] / src / XAOPlugin / XAOPlugin_IOperations.cxx
1 // Copyright (C) 2014-2023  CEA, EDF, 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 <Basics_DirUtils.hxx>
27 #include <utilities.h>
28 #include <Utils_SALOME_Exception.hxx>
29
30 // GEOM includes
31 #include <GEOM_PythonDump.hxx>
32 #include <GEOMImpl_Types.hxx>
33 #include <GEOMImpl_IGroupOperations.hxx>
34 #include <GEOMImpl_IShapesOperations.hxx>
35 #include <GEOMImpl_IFieldOperations.hxx>
36 #include <GEOM_ISubShape.hxx>
37 #include <GEOM_Object.hxx>
38 #include <GEOM_Field.hxx>
39
40 #include <XAO_Geometry.hxx>
41 #include <XAO_BrepGeometry.hxx>
42 #include <XAO_Xao.hxx>
43 #include <XAO_Group.hxx>
44 #include <XAO_Field.hxx>
45 #include <XAO_BooleanField.hxx>
46 #include <XAO_IntegerField.hxx>
47 #include <XAO_DoubleField.hxx>
48 #include <XAO_StringField.hxx>
49 #include <XAO_DoubleStep.hxx>
50 #include <XAO_StringStep.hxx>
51
52 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
53
54 // OCC includes
55 #include <TColStd_HArray1OfByte.hxx>
56 #include <TColStd_HArray1OfReal.hxx>
57 #include <TDataStd_Integer.hxx>
58
59 #include <TopExp.hxx>
60
61 #include <algorithm>
62
63 XAO::Dimension shapeEnumToDimension(const TopAbs_ShapeEnum& shape)
64 {
65   XAO::Dimension dim;
66   switch( shape ) {
67   case TopAbs_VERTEX:
68     dim = XAO::VERTEX; break;
69   case TopAbs_EDGE:
70     dim = XAO::EDGE; break;
71   case TopAbs_FACE:
72     dim = XAO::FACE; break;
73   case TopAbs_SOLID:
74     dim = XAO::SOLID; break;
75   default:
76     throw SALOME_Exception("Bad type"); // TODO
77   }
78   return dim;
79 }
80
81 TopAbs_ShapeEnum getGroupDimension(XAO::Group* group)
82 {
83   XAO::Dimension dim = group->getDimension();
84   TopAbs_ShapeEnum rdim;
85   switch ( dim )
86   {
87   case XAO::VERTEX:
88     rdim = TopAbs_VERTEX; break;
89   case XAO::EDGE:
90     rdim = TopAbs_EDGE; break;
91   case XAO::FACE:
92     rdim = TopAbs_FACE; break;
93   case XAO::SOLID:
94     rdim = TopAbs_SOLID; break;
95   default:
96     rdim = TopAbs_COMPOUND; break;
97   }
98   return rdim;
99 }
100
101 //=============================================================================
102 /*!
103  *  Constructor
104  */
105 //=============================================================================
106 XAOPlugin_IOperations::XAOPlugin_IOperations( GEOM_Engine* theEngine )
107 : GEOMImpl_IBaseIEOperations( theEngine )
108 {
109   MESSAGE( "XAOPlugin_IOperations::XAOPlugin_IOperations" );
110 }
111
112 //=============================================================================
113 /*!
114  *  Destructor
115  */
116 //=============================================================================
117 XAOPlugin_IOperations::~XAOPlugin_IOperations()
118 {
119   MESSAGE( "XAOPlugin_IOperations::~XAOPlugin_IOperations" );
120 }
121
122 bool XAOPlugin_IOperations::exportGroups( std::list<Handle(GEOM_Object)> groupList,
123                                           XAO::Xao* xaoObject,
124                                           XAO::BrepGeometry* geometry )
125 {
126   // add the groups
127   std::list<Handle(GEOM_Object)>::iterator groupIterator = groupList.begin();
128   while (groupIterator != groupList.end())
129   {
130     Handle(GEOM_Object) currGroup = (*groupIterator++);
131     if (currGroup->GetType() != GEOM_GROUP) {
132       SetErrorCode("Error when export groups: you could perform this operation only with group.");
133       return false;
134     }
135     Handle(TColStd_HArray1OfInteger) groupIds = myGroupOperations->GetObjects(currGroup);
136
137     TopAbs_ShapeEnum shapeGroup = myGroupOperations->GetType(currGroup);
138     XAO::Dimension dim = shapeEnumToDimension(shapeGroup);
139     XAO::Group* group = xaoObject->addGroup(dim, currGroup->GetName().ToCString());
140
141     // Group can be empty
142     if (groupIds.IsNull()) continue;
143
144     switch (shapeGroup)
145     {
146     case TopAbs_VERTEX:
147       for (int i = 1; i <= groupIds->Length(); i++)
148       {
149         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
150         int index = geometry->getVertexIndexByReference(ref);
151         group->add(index);
152       }
153       break;
154     case TopAbs_EDGE:
155       for (int i = 1; i <= groupIds->Length(); i++)
156       {
157         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
158         int index = geometry->getEdgeIndexByReference(ref);
159         group->add(index);
160       }
161       break;
162     case TopAbs_FACE:
163       for (int i = 1; i <= groupIds->Length(); i++)
164       {
165         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
166         int index = geometry->getFaceIndexByReference(ref);
167         group->add(index);
168       }
169       break;
170     case TopAbs_SOLID:
171       for (int i = 1; i <= groupIds->Length(); i++)
172       {
173         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
174         int index = geometry->getSolidIndexByReference(ref);
175         group->add(index);
176       }
177       break;
178     default:
179       ;
180     }
181   }
182   return true;
183 }
184
185 void XAOPlugin_IOperations::exportFields( std::list<Handle(GEOM_Field)> fieldList,
186                                           XAO::Xao* xaoObject,
187                                           XAO::BrepGeometry* /*geometry*/ )
188 {
189   std::list<Handle(GEOM_Field)>::iterator fieldIterator = fieldList.begin();
190   while (fieldIterator != fieldList.end())
191   {
192     Handle(GEOM_Field) currField = (*fieldIterator++);
193
194     int fdim = currField->GetDimension();
195     int ftype = currField->GetDataType();
196     int nbComponents = currField->GetNbComponents();
197     std::string name = currField->GetName().ToCString();
198
199     XAO::Field* field = xaoObject->addField((XAO::Type)ftype, (XAO::Dimension)fdim, nbComponents, name);
200
201     Handle(TColStd_HArray1OfExtendedString) components = currField->GetComponents();
202     for (int i = components->Lower(), j = 0; i <= components->Upper(); ++i, ++j)
203     {
204       field->setComponentName(j, TCollection_AsciiString(components->Value(i)).ToCString());
205     }
206
207     std::list< Handle(GEOM_FieldStep)> steps = currField->GetSteps();
208     std::list<Handle(GEOM_FieldStep)>::iterator stepIterator = steps.begin();
209     while (stepIterator != steps.end())
210     {
211       Handle(GEOM_FieldStep) currStep = (*stepIterator++);
212
213       XAO::Step* step = field->addNewStep(currStep->GetID());
214       step->setStamp(currStep->GetStamp());
215
216       switch (ftype)
217       {
218         case 0: // bool
219         {
220           XAO::BooleanStep* bs = (XAO::BooleanStep*)step;
221           Handle(TColStd_HArray1OfInteger) bvalues = currStep->GetIntValues();
222           std::vector<bool> bv;
223           bv.reserve(bvalues->Upper());
224           for ( int i = bvalues->Lower(), nb = bvalues->Upper(); i <= nb; ++i )
225           {
226             bv.push_back(bvalues->Value(i) != 0);
227           }
228           bs->setValues(bv);
229           break;
230         }
231         case 1: // integer
232         {
233           XAO::IntegerStep* is = (XAO::IntegerStep*)step;
234           Handle(TColStd_HArray1OfInteger) ivalues = currStep->GetIntValues();
235           std::vector<int> iv;
236           iv.reserve(ivalues->Upper());
237           for ( int i = ivalues->Lower(), nb = ivalues->Upper(); i <= nb; ++i )
238           {
239             iv.push_back(ivalues->Value(i));
240           }
241           is->setValues(iv);
242           break;
243         }
244         case 2: // double
245         {
246           XAO::DoubleStep* ds = (XAO::DoubleStep*)step;
247           Handle(TColStd_HArray1OfReal) dvalues = currStep->GetDoubleValues();
248           std::vector<double> dv;
249           dv.reserve(dvalues->Upper());
250           for ( int i = dvalues->Lower(), nb = dvalues->Upper(); i <= nb; ++i )
251           {
252             dv.push_back(dvalues->Value(i));
253           }
254           ds->setValues(dv);
255             break;
256         }
257         case 3: // string
258         {
259           XAO::StringStep* ss = (XAO::StringStep*)step;
260           Handle(TColStd_HArray1OfExtendedString) svalues = currStep->GetStringValues();
261           std::vector<std::string> sv;
262           sv.reserve(svalues->Upper());
263           for ( int i = svalues->Lower(), nb = svalues->Upper(); i <= nb; ++i )
264           {
265             sv.push_back(TCollection_AsciiString(svalues->Value(i)).ToCString());
266           }
267           ss->setValues(sv);
268           break;
269         }
270       }
271     }
272   }
273 }
274
275 void XAOPlugin_IOperations::exportSubshapes( const Handle(GEOM_Object)& shape, XAO::BrepGeometry* geometry )
276 {
277   Handle(TColStd_HSequenceOfTransient) subObjects = myShapesOperations->GetExistingSubObjects( shape, GEOMImpl_IShapesOperations::SubShapes );
278   int nbSubObjects = subObjects->Length();
279   if (!nbSubObjects) return;
280
281   TopoDS_Shape aMainShape = shape->GetValue();
282   if (aMainShape.IsNull()) return;
283   TopTools_IndexedMapOfShape anIndices;
284   TopExp::MapShapes(aMainShape, anIndices);
285
286   // set the names of the sub shapes
287   for (int i = 1; i <= nbSubObjects; i++)
288   {
289     Handle(Standard_Transient) transientSubObject = subObjects->Value(i);
290     if (transientSubObject.IsNull())
291       continue;
292
293     Handle(GEOM_Object) subObject = Handle(GEOM_Object)::DownCast( transientSubObject );
294     if (subObject->GetType() != GEOM_GROUP)
295     {
296       TopoDS_Shape aSubShape = subObject->GetValue();
297       if (aSubShape.IsNull()) continue;
298
299       // Do not call GEOMImpl_IShapesOperations::GetSubShapeIndex() here
300       // for time optimization reason (it invokes TopExp::MapShapes())
301       //int subIndex = myShapesOperations->GetSubShapeIndex( shape, subObject );
302       int subIndex = anIndices.FindIndex(aSubShape);
303       if (!subIndex) continue;
304
305       switch (aSubShape.ShapeType())
306       {
307       case TopAbs_VERTEX:
308         geometry->changeVertexName(subIndex, subObject->GetName().ToCString());
309         break;
310       case TopAbs_EDGE:
311         geometry->changeEdgeName(subIndex, subObject->GetName().ToCString());
312         break;
313       case TopAbs_FACE:
314         geometry->changeFaceName(subIndex, subObject->GetName().ToCString());
315         break;
316       case TopAbs_SOLID:
317         geometry->changeSolidName(subIndex, subObject->GetName().ToCString());
318         break;
319       default:
320         ;
321       }
322     }
323   }
324 }
325
326 //=============================================================================
327 /*!
328  *  Export a shape to XAO format file.
329  *  \param shape The shape to export.
330  *  \param groups The list of groups to export.
331  *  \param fields The list of fields to export.
332  *  \param fileName The name of the file to be exported.
333  *  \param shapeFileName The name of the file for shape, if it should be exported separately.
334  *  \return boolean indicating if export was successful.
335  */
336 //=============================================================================
337 bool XAOPlugin_IOperations::ExportXAO( Handle(GEOM_Object) shape,
338                                        std::list<Handle(GEOM_Object)> groupList,
339                                        std::list<Handle(GEOM_Field)> fieldList,
340                                        const char* author,
341                                        const char* fileName,
342                                        const char* shapeFileName )
343 {
344   if (!fileName || !strlen(fileName)) {
345     SetErrorCode("Empty file name");
346     return false;
347   }
348
349   exportXAO( shape, groupList, fieldList, author, fileName, shapeFileName );
350   return IsDone();
351 }
352
353 //=============================================================================
354 /*!
355  *  Export a shape to XAO format string.
356  *  \param shape The shape to export.
357  *  \param groups The list of groups to export.
358  *  \param fields The list of fields to export.
359  *  \return The exported string.
360  */
361 //=============================================================================
362 std::string XAOPlugin_IOperations::ExportXAOMem( Handle(GEOM_Object) shape,
363                                                  std::list<Handle(GEOM_Object)> groupList,
364                                                  std::list<Handle(GEOM_Field)> fieldList,
365                                                  const char* author )
366 {
367   std::string anXML = exportXAO( shape, groupList, fieldList, author, NULL, NULL );
368   return anXML;
369 }
370
371 //=============================================================================
372 /*!
373  *  Export a shape to XAO format file or string.
374  *  \param shape The shape to export.
375  *  \param groups The list of groups to export.
376  *  \param fields The list of fields to export.
377  *  \param fileName The name of the file to be exported. If empty, export to string.
378  *  \param shapeFileName The name of the file for shape, if it should be exported separately.
379  *  \return The exported string, if fileName is empty, or empty string.
380  */
381 //=============================================================================
382 std::string XAOPlugin_IOperations::exportXAO( Handle(GEOM_Object) shape,
383                                               std::list<Handle(GEOM_Object)> groupList,
384                                               std::list<Handle(GEOM_Field)> fieldList,
385                                               const char* author,
386                                               const char* fileName,
387                                               const char* shapeFileName )
388 {
389   SetErrorCode(KO);
390   std::string anXML ("");
391
392   if (shape.IsNull()) return anXML;
393
394   // add a new shape function with parameters
395   Handle(GEOM_Function) lastFunction = shape->GetLastFunction();
396   if (lastFunction.IsNull()) return anXML;
397
398   // add a new result object
399   Handle(GEOM_Object) result = GetEngine()->AddObject(GEOM_IMPORT);
400
401   // add an Export function
402   Handle(GEOM_Function) exportFunction = result->AddFunction(XAOPlugin_Driver::GetID(), EXPORT_SHAPE);
403   if (exportFunction.IsNull()) return anXML;
404   if (exportFunction->GetDriverGUID() != XAOPlugin_Driver::GetID()) return anXML;
405
406   // create the XAO object
407   XAO::Xao* xaoObject = new XAO::Xao();
408   xaoObject->setAuthor(author);
409
410   // add the geometry
411   XAO::BrepGeometry* geometry = (XAO::BrepGeometry*)XAO::Geometry::createGeometry(XAO::BREP);
412   TopoDS_Shape topoShape = shape->GetValue();
413   exportFunction->SetValue(topoShape);
414   XAO::BrepGeometry* brep = (XAO::BrepGeometry*)geometry;
415   brep->setTopoDS_Shape(topoShape);
416
417   geometry->setName(shape->GetName().ToCString());
418   exportSubshapes(shape, geometry);
419   xaoObject->setGeometry(geometry);
420
421   if (!exportGroups(groupList, xaoObject, geometry)) return anXML;
422   exportFields(fieldList, xaoObject, geometry);
423
424   bool isFile = (fileName && strlen(fileName));
425   if (isFile) {
426     // export the XAO to the file
427     xaoObject->exportXAO(fileName, shapeFileName);
428   }
429   else {
430     // export the XAO to the string
431     anXML = xaoObject->getXML();
432   }
433
434   // make a Python command
435   GEOM::TPythonDump pd (exportFunction);
436   if (isFile) {
437     pd << "exported = geompy.ExportXAO(";
438   }
439   else {
440     if (!shape->GetName().IsEmpty()) {
441       std::string aGeometryNamePy (shape->GetName().ToCString());
442       std::replace(aGeometryNamePy.begin(), aGeometryNamePy.end(), ' ', '_');
443       pd << "aXAOBuff_" << aGeometryNamePy.c_str() << " = geompy.ExportXAOMem(";
444     }
445     else
446       pd << "aXAOBuff = geompy.ExportXAOMem(";
447   }
448
449   // shape
450   pd << shape;
451
452   // list of groups
453   pd << ", [";
454   if (groupList.size() > 0)
455   {
456     std::list<Handle(GEOM_Object)>::iterator itGroup = groupList.begin();
457     pd << (*itGroup++);
458     while (itGroup != groupList.end())
459     {
460       pd << ", " << (*itGroup++);
461     }
462   }
463
464   // list of fields
465   pd << "], [";
466   if (fieldList.size() > 0)
467   {
468     std::list<Handle(GEOM_Field)>::iterator itField = fieldList.begin();
469     pd << (*itField++);
470     while (itField != fieldList.end())
471     {
472       pd << ", " << (*itField++);
473     }
474   }
475   pd << "], ";
476
477   // author
478   pd << "\"" << author << "\"";
479
480   // files
481   if (isFile) {
482     std::string convFileName = Kernel_Utils::BackSlashToSlash(fileName);
483     std::string convShapeFileName;
484     if (shapeFileName && strlen(shapeFileName))
485       convShapeFileName = Kernel_Utils::BackSlashToSlash(shapeFileName);
486     pd << ", \"" << convFileName.c_str() << "\", \"" << convShapeFileName.c_str() << "\"";
487   }
488   pd << ")";
489
490   SetErrorCode(OK);
491   delete xaoObject;
492
493   return anXML;
494 }
495
496 void XAOPlugin_IOperations::importSubShapes( XAO::Geometry* xaoGeometry,
497                                              Handle(GEOM_Function) function, int shapeType, int dim,
498                                              Handle(TColStd_HSequenceOfTransient)& subShapeList )
499 {
500   Handle(GEOM_Object) subShape;
501   Handle(GEOM_Function) aFunction;
502   Handle(TColStd_HArray1OfInteger) anArray;
503
504   XAO::GeometricElementList::iterator elementIterator = xaoGeometry->begin((XAO::Dimension)dim);
505   for (; elementIterator != xaoGeometry->end((XAO::Dimension)dim); elementIterator++)
506   {
507     XAO::GeometricElement element = elementIterator->second;
508     if (!element.hasName())
509       continue;
510
511     std::string name = element.getName();
512     std::string ref = element.getReference();
513     int iref = XAO::XaoUtils::stringToInt(ref);
514
515     anArray = new TColStd_HArray1OfInteger(1, 1);
516     anArray->SetValue(1, iref);
517
518     subShape = GetEngine()->AddObject(GEOM_SUBSHAPE);
519     Handle(GEOM_Function) aFunction = subShape->AddFunction(GEOM_Object::GetSubShapeID(), 1);
520     if (aFunction.IsNull())
521       return;
522
523     subShape->SetName(name.c_str());
524
525     // commented out, as it prevents correct operation information filling
526     // type should be a GEOM_SUBSHAPE
527     //subShape->SetType(shapeType);
528
529     GEOM_ISubShape aSSI(aFunction);
530     aSSI.SetMainShape(function);
531     aSSI.SetIndices(anArray);
532
533     //aFunction->SetValue(aValue);
534     subShapeList->Append(subShape);
535
536     // Put this subshape in the list of sub-shapes of theMainShape
537     function->AddSubShapeReference(aFunction);
538   }
539 }
540
541 //=============================================================================
542 /*!
543  *  Import a shape from XAO format file.
544  *  \param fileName The name of the file to import.
545  *  \param shape The imported shape.
546  *  \param subShapes The list of imported sub-shapes.
547  *  \param groups The list of imported groups.
548  *  \param fields The list of imported fields.
549  *  \return boolean indicating if import was successful.
550  */
551 //=============================================================================
552 bool XAOPlugin_IOperations::ImportXAO( const char* fileName,
553                                        Handle(GEOM_Object)& shape,
554                                        Handle(TColStd_HSequenceOfTransient)& subShapes,
555                                        Handle(TColStd_HSequenceOfTransient)& groups,
556                                        Handle(TColStd_HSequenceOfTransient)& fields )
557 {
558   if (fileName == NULL || !strlen(fileName)) {
559     SetErrorCode("Empty file name");
560   }
561
562   importXAO( fileName, "", shape, subShapes, groups, fields );
563   return IsDone();
564 }
565
566 //=============================================================================
567 /*!
568  *  Import a shape from XAO format string.
569  *  \param theXML The input buffer.
570  *  \param shape The imported shape.
571  *  \param subShapes The list of imported sub-shapes.
572  *  \param groups The list of imported groups.
573  *  \param fields The list of imported fields.
574  *  \return boolean indicating if import was successful.
575  */
576 //=============================================================================
577 bool XAOPlugin_IOperations::ImportXAOMem( const std::string& theXML,
578                                           Handle(GEOM_Object)& shape,
579                                           Handle(TColStd_HSequenceOfTransient)& subShapes,
580                                           Handle(TColStd_HSequenceOfTransient)& groups,
581                                           Handle(TColStd_HSequenceOfTransient)& fields )
582 {
583   importXAO( NULL, theXML, shape, subShapes, groups, fields );
584   return IsDone();
585 }
586
587 //=============================================================================
588 /*!
589  *  Import a shape from XAO format file.
590  *  \param fileName The name of the file to import.
591  *  \param shape The imported shape.
592  *  \param subShapes The list of imported sub-shapes.
593  *  \param groups The list of imported groups.
594  *  \param fields The list of imported fields.
595  *  \return boolean indicating if import was successful.
596  */
597 //=============================================================================
598 bool XAOPlugin_IOperations::importXAO( const char* fileName,
599                                        const std::string& theXML,
600                                        Handle(GEOM_Object)& shape,
601                                        Handle(TColStd_HSequenceOfTransient)& subShapes,
602                                        Handle(TColStd_HSequenceOfTransient)& groups,
603                                        Handle(TColStd_HSequenceOfTransient)& fields )
604 {
605   SetErrorCode(KO);
606
607   if (groups.IsNull() || fields.IsNull())
608     return false;
609
610   bool isFile = (fileName && strlen(fileName));
611
612   // Read the XAO
613   XAO::Xao* xaoObject = new XAO::Xao();
614   try
615   {
616     if (isFile)
617       xaoObject->importXAO(fileName);
618     else {
619      xaoObject->setXML(theXML);
620     }
621   }
622   catch (XAO::XAO_Exception& exc)
623   {
624     delete xaoObject;
625     SetErrorCode(exc.what());
626     return false;
627   }
628
629   XAO::Geometry* xaoGeometry = xaoObject->getGeometry();
630   if (xaoGeometry == NULL)
631   {
632     delete xaoObject;
633     SetErrorCode("Cannot import XAO: geometry format not supported.");
634     return false;
635   }
636
637   // create the shape
638   shape = GetEngine()->AddObject(GEOM_IMPORT);
639   Handle(GEOM_Function) function = shape->AddFunction(XAOPlugin_Driver::GetID(), IMPORT_SHAPE);
640   if (function.IsNull()) return false;
641   if (function->GetDriverGUID() != XAOPlugin_Driver::GetID()) return false;
642
643   // Initialize python dimp here to prevent dumping of sub shapes, groups and fields
644   GEOM::TPythonDump pd(function);
645
646   if (isFile)
647     function->SetString( XAOPlugin_Driver::GetFileNameTag(), fileName );
648   else {
649     function->SetString( XAOPlugin_Driver::GetFileNameTag(), "NO, imported from byte array" );
650   }
651
652   // set the geometry
653   if (xaoGeometry->getFormat() == XAO::BREP)
654   {
655     XAO::BrepGeometry* brep = (XAO::BrepGeometry*)xaoGeometry;
656     TopoDS_Shape geomShape = brep->getTopoDS_Shape();
657     function->SetValue(geomShape);
658     shape->SetName(xaoGeometry->getName().c_str());
659   }
660   else
661   {
662     delete xaoObject;
663     SetErrorCode("Cannot import XAO: geometry format not supported.");
664     return false;
665   }
666
667   // create sub shapes with names
668   importSubShapes(xaoGeometry, function, GEOM_POINT, XAO::VERTEX, subShapes);
669   importSubShapes(xaoGeometry, function, GEOM_EDGE, XAO::EDGE, subShapes);
670   importSubShapes(xaoGeometry, function, GEOM_FACE, XAO::FACE, subShapes);
671   importSubShapes(xaoGeometry, function, GEOM_SOLID, XAO::SOLID, subShapes);
672
673   // create groups
674   int nbGroups = xaoObject->countGroups();
675   for (int i = 0; i < nbGroups; ++i)
676   {
677     XAO::Group* xaoGroup = xaoObject->getGroup(i);
678
679     // build an array with the indexes of the sub shapes
680     int nbElt = xaoGroup->count();
681     Handle(TColStd_HArray1OfInteger) array;
682     if (nbElt > 0) {
683       array = new TColStd_HArray1OfInteger(1, nbElt);
684       int j = 0;
685       for (std::set<int>::iterator it = xaoGroup->begin(); it != xaoGroup->end(); ++it) {
686         int index = (*it);
687         std::string ref = xaoGeometry->getElementReference(xaoGroup->getDimension(), index);
688         array->SetValue(++j, XAO::XaoUtils::stringToInt(ref));
689       }
690     }
691     else { // empty group
692       array = new TColStd_HArray1OfInteger(1, 1);
693       array->SetValue(1, -1);
694     }
695
696     // create the group with the array of sub shapes indexes
697     Handle(GEOM_Object) group = GetEngine()->AddSubShape(shape, array);
698     group->SetType(GEOM_GROUP);
699     group->SetName(xaoGroup->getName().c_str());
700
701     // Set a sub-shape type
702     TDF_Label freeLabel = group->GetFreeLabel();
703     TDataStd_Integer::Set(freeLabel, (Standard_Integer) getGroupDimension(xaoGroup));
704     groups->Append(group);
705   }
706
707   // create the fields
708   int nbFields = xaoObject->countFields();
709   for (int i = 0; i < nbFields; ++i)
710   {
711     XAO::Field* xaoField = xaoObject->getField(i);
712
713     Handle(TColStd_HArray1OfExtendedString) components = new TColStd_HArray1OfExtendedString(0, xaoField->countComponents()-1);
714     for (int j = 0; j < xaoField->countComponents(); ++j)
715     {
716         components->SetValue(j, (TCollection_ExtendedString)xaoField->getComponentName(j).c_str());
717     }
718
719     Handle(GEOM_Field) field = myFieldOperations->CreateField(shape,
720                  xaoField->getName().c_str(),
721                  (int)xaoField->getType(),
722                  (int)xaoField->getDimension(),
723                  components);
724
725     switch (xaoField->getType())
726     {
727         case XAO::BOOLEAN:
728         {
729             XAO::BooleanField* bfield = (XAO::BooleanField*)xaoField;
730             for (int j = 0; j < xaoField->countSteps(); ++j)
731             {
732                 XAO::BooleanStep* bstep = bfield->getStep(j);
733                 Handle(GEOM_FieldStep) step = field->AddStep(bstep->getStep(), bstep->getStamp());
734
735                 Handle(TColStd_HArray1OfInteger) values = new TColStd_HArray1OfInteger(0, bstep->countValues()-1);
736                 std::vector<bool> bvalues = bstep->getValues();
737                 for (int k = 0; k < bstep->countValues(); ++k)
738                 {
739                     values->SetValue(k, bvalues[k] ? 1 : 0);
740                 }
741                 step->SetValues(values);
742             }
743             break;
744         }
745         case XAO::INTEGER:
746         {
747             XAO::IntegerField* ifield = (XAO::IntegerField*)xaoField;
748             for (int j = 0; j < xaoField->countSteps(); ++j)
749             {
750                 XAO::IntegerStep* istep = ifield->getStep(j);
751                 Handle(GEOM_FieldStep) step = field->AddStep(istep->getStep(), istep->getStamp());
752
753                 Handle(TColStd_HArray1OfInteger) values = new TColStd_HArray1OfInteger(0, istep->countValues()-1);
754                 std::vector<int> ivalues = istep->getValues();
755                 for (int k = 0; k < istep->countValues(); ++k)
756                 {
757                     values->SetValue(k, ivalues[k]);
758                 }
759                 step->SetValues(values);
760             }
761             break;
762         }
763         case XAO::DOUBLE:
764         {
765             XAO::DoubleField* dfield = (XAO::DoubleField*)xaoField;
766             for (int j = 0; j < xaoField->countSteps(); ++j)
767             {
768                 XAO::DoubleStep* dstep = dfield->getStep(j);
769                 Handle(GEOM_FieldStep) step = field->AddStep(dstep->getStep(), dstep->getStamp());
770
771                 Handle(TColStd_HArray1OfReal) values = new TColStd_HArray1OfReal(0, dstep->countValues()-1);
772                 std::vector<double> dvalues = dstep->getValues();
773                 for (int k = 0; k < dstep->countValues(); ++k)
774                 {
775                     values->SetValue(k, dvalues[k]);
776                 }
777                 step->SetValues(values);
778             }
779             break;
780         }
781         case XAO::STRING:
782         {
783             XAO::StringField* sfield = (XAO::StringField*)xaoField;
784             for (int j = 0; j < xaoField->countSteps(); ++j)
785             {
786                 XAO::StringStep* sstep = sfield->getStep(j);
787                 Handle(GEOM_FieldStep) step = field->AddStep(sstep->getStep(), sstep->getStamp());
788
789                 Handle(TColStd_HArray1OfExtendedString) values = new TColStd_HArray1OfExtendedString(0, sstep->countValues()-1);
790                 std::vector<std::string> svalues = sstep->getValues();
791                 for (int k = 0; k < sstep->countValues(); ++k)
792                 {
793                     values->SetValue(k, TCollection_ExtendedString(svalues[k].c_str()));
794                 }
795                 step->SetValues(values);
796             }
797             break;
798         }
799     }
800
801     fields->Append(field);
802   }
803
804   // make a Python command
805   pd << "(imported, " << shape << ", ";
806
807   // list of sub shapes
808   pd << "[";
809   int nbSubshapes = subShapes->Length();
810   if (nbSubshapes > 0)
811   {
812     for (int i = 1; i <= nbSubshapes; i++)
813     {
814       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(subShapes->Value(i));
815       pd << obj << ((i < nbSubshapes) ? ", " : "");
816     }
817   }
818   pd << "], [";
819
820   // list of groups
821   if (nbGroups > 0)
822   {
823     for (int i = 1; i <= nbGroups; i++)
824     {
825       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(groups->Value(i));
826       pd << obj << ((i < nbGroups) ? ", " : "");
827     }
828   }
829
830   pd << "], [";
831
832   // list of fields
833   if (nbFields > 0)
834   {
835     for (int i = 1; i <= nbFields; i++)
836     {
837       Handle(GEOM_Field) obj = Handle(GEOM_Field)::DownCast(fields->Value(i));
838       pd << obj << ((i < nbFields) ? ", " : "");
839     }
840   }
841   pd << "]) = geompy.";
842
843   if (isFile) {
844     std::string convFileName =  Kernel_Utils::BackSlashToSlash( fileName );
845     pd << "ImportXAO(\"" << convFileName.c_str() << "\")";
846   }
847   else {
848     if (!shape->GetName().IsEmpty()) {
849       std::string aGeometryNamePy (shape->GetName().ToCString());
850       std::replace(aGeometryNamePy.begin(), aGeometryNamePy.end(), ' ', '_');
851       pd << "ImportXAOMem(aXAOBuff_" << aGeometryNamePy.c_str() << ")";
852     }
853     else
854       pd << "ImportXAOMem(aXAOBuff)";
855   }
856
857   delete xaoObject;
858   SetErrorCode(OK);
859
860   return true;
861 }