Salome HOME
Process plugin libraries names correctly on Windows and Linux
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IInsertOperations.cxx
1 // Copyright (C) 2007-2013  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.
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_XAODriver.hxx"
36 #include "GEOMImpl_IImportExportXAO.hxx"
37
38 #include <GEOM_Function.hxx>
39 #include <GEOM_PythonDump.hxx>
40 #include "GEOM_ISubShape.hxx"
41
42 #include <XAO_Xao.hxx>
43 #include <XAO_Geometry.hxx>
44 #include <XAO_BrepGeometry.hxx>
45 #include <XAO_Group.hxx>
46 #include <XAO_Field.hxx>
47 #include <XAO_XaoUtils.hxx>
48
49 #include <Basics_OCCTVersion.hxx>
50
51 #include "utilities.h"
52 #include <OpUtil.hxx>
53 #include <Utils_ExceptHandlers.hxx>
54
55 #include <TFunction_DriverTable.hxx>
56 #include <TFunction_Driver.hxx>
57 #include <TFunction_Logbook.hxx>
58 #include <TDF_Tool.hxx>
59 #include <TDataStd_Integer.hxx>
60
61 #include <TopoDS.hxx>
62 #include <TopoDS_Vertex.hxx>
63 #include <BRep_Builder.hxx>
64 #include <BRep_Tool.hxx>
65 #include <BRepTools.hxx>
66 #include <gp_Pnt.hxx>
67
68 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
69 #include <TColStd_HArray1OfByte.hxx>
70 #else
71 #include <TDataStd_HArray1OfByte.hxx>
72 #endif
73
74 #include <Standard_Failure.hxx>
75 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
76
77 //=============================================================================
78 /*!
79  *  constructor
80  */
81 //=============================================================================
82 GEOMImpl_IInsertOperations::GEOMImpl_IInsertOperations(GEOM_Engine* theEngine, int theDocID)
83 : GEOM_IOperations(theEngine, theDocID)
84 {
85   MESSAGE("GEOMImpl_IInsertOperations::GEOMImpl_IInsertOperations");
86   myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
87   myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
88 }
89
90 //=============================================================================
91 /*!
92  *  destructor
93  */
94 //=============================================================================
95 GEOMImpl_IInsertOperations::~GEOMImpl_IInsertOperations()
96 {
97   MESSAGE("GEOMImpl_IInsertOperations::~GEOMImpl_IInsertOperations");
98   delete myShapesOperations;
99   delete myGroupOperations;
100 }
101
102 //=============================================================================
103 /*!
104  *  MakeCopy
105  */
106 //=============================================================================
107 Handle(GEOM_Object) GEOMImpl_IInsertOperations::MakeCopy (Handle(GEOM_Object) theOriginal)
108 {
109   SetErrorCode(KO);
110
111   if (theOriginal.IsNull()) return NULL;
112
113   //Add a new Copy object
114   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
115
116   //Add a Copy function for creation a copy object
117   Handle(GEOM_Function) aFunction = aCopy->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITH_REF);
118
119   //Check if the function is set correctly
120   if(aFunction->GetDriverGUID() != GEOMImpl_CopyDriver::GetID()) return NULL;
121
122   GEOMImpl_ICopy aCI(aFunction);
123
124   Handle(GEOM_Function) aRefFunction = theOriginal->GetLastFunction();
125   if (aRefFunction.IsNull()) return NULL;
126
127   aCI.SetOriginal(aRefFunction);
128
129   //Compute the Copy value
130   try {
131 #if OCC_VERSION_LARGE > 0x06010000
132     OCC_CATCH_SIGNALS;
133 #endif
134     if (!GetSolver()->ComputeFunction(aFunction)) {
135       SetErrorCode("Copy driver failed");
136       return NULL;
137     }
138   }
139   catch (Standard_Failure) {
140     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
141     SetErrorCode(aFail->GetMessageString());
142     return NULL;
143   }
144
145   //Make a Python command
146   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeCopy(" << theOriginal << ")";
147
148   SetErrorCode(OK);
149   return aCopy;
150 }
151
152 //=============================================================================
153 /*!
154  *  Export
155  */
156 //=============================================================================
157 void GEOMImpl_IInsertOperations::Export
158                      (const Handle(GEOM_Object)      theOriginal,
159                       const TCollection_AsciiString& theFileName,
160                       const TCollection_AsciiString& theFormatName)
161 {
162   SetErrorCode(KO);
163
164   if (theOriginal.IsNull()) return;
165
166   Handle(GEOM_Function) aRefFunction = theOriginal->GetLastFunction();
167   if (aRefFunction.IsNull()) return;  //There is no function which creates an object to be exported
168
169   //Add a new result object
170   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
171
172   //Add an Export function
173   Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_ExportDriver::GetID(), EXPORT_SHAPE);
174   if (aFunction.IsNull()) return;
175
176   //Check if the function is set correctly
177   if (aFunction->GetDriverGUID() != GEOMImpl_ExportDriver::GetID()) return;
178
179   Handle(TCollection_HAsciiString) aHLibName;
180   if (!IsSupported(Standard_False, theFormatName, aHLibName)) {
181     return;
182   }
183   TCollection_AsciiString aLibName = aHLibName->String();
184
185   //Set parameters
186   GEOMImpl_IImportExport aCI (aFunction);
187   aCI.SetOriginal(aRefFunction);
188   aCI.SetFileName(theFileName);
189   aCI.SetFormatName(theFormatName);
190   aCI.SetPluginName(aLibName);
191
192   //Perform the Export
193   try {
194 #if OCC_VERSION_LARGE > 0x06010000
195     OCC_CATCH_SIGNALS;
196 #endif
197     if (!GetSolver()->ComputeFunction(aFunction)) {
198       SetErrorCode("Not enough space on disk, or you haven't permissions to write this directory");
199       return;
200     }
201   }
202   catch (Standard_Failure) {
203     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
204     SetErrorCode(aFail->GetMessageString());
205     return;
206   }
207
208   //Make a Python command
209   GEOM::TPythonDump(aFunction) << "geompy.Export(" << theOriginal << ", \""
210     << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")";
211
212   SetErrorCode(OK);
213 }
214
215 //=============================================================================
216 /*!
217  *  Import
218  */
219 //=============================================================================
220 Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import
221                                  (const TCollection_AsciiString& theFileName,
222                                   const TCollection_AsciiString& theFormatName)
223 {
224   SetErrorCode(KO);
225
226   if (theFileName.IsEmpty() || theFormatName.IsEmpty()) return NULL;
227
228   //Add a new result object
229   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
230
231   //Add an Import function
232   Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_ImportDriver::GetID(), IMPORT_SHAPE);
233   if (aFunction.IsNull()) return result;
234
235   //Check if the function is set correctly
236   if (aFunction->GetDriverGUID() != GEOMImpl_ImportDriver::GetID()) return result;
237
238   Handle(TCollection_HAsciiString) aHLibName;
239   if (!IsSupported(Standard_True, theFormatName.SubString(1,4), aHLibName)) {
240     return result;
241   }
242   TCollection_AsciiString aLibName = aHLibName->String();
243
244   //Set parameters
245   GEOMImpl_IImportExport aCI (aFunction);
246   aCI.SetFileName(theFileName);
247   aCI.SetFormatName(theFormatName);
248   aCI.SetPluginName(aLibName);
249
250   //Perform the Import
251   try {
252 #if OCC_VERSION_LARGE > 0x06010000
253     OCC_CATCH_SIGNALS;
254 #endif
255     if (!GetSolver()->ComputeFunction(aFunction)) {
256       SetErrorCode("Import driver failed");
257       return NULL;
258     }
259   }
260   catch (Standard_Failure) {
261     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
262     SetErrorCode(aFail->GetMessageString());
263     return NULL;
264   }
265
266   //Make a Python command
267   if (theFormatName != "IGES_UNIT") {
268     GEOM::TPythonDump pd (aFunction);
269     if (theFormatName == "BREP")
270       pd << result << " = geompy.ImportBREP(\"" << theFileName.ToCString() << "\")";
271     else if (theFormatName == "IGES")
272       pd << result << " = geompy.ImportIGES(\"" << theFileName.ToCString() << "\")";
273     else if (theFormatName == "IGES_SCALE")
274       pd << result << " = geompy.ImportIGES(\"" << theFileName.ToCString() << "\", True)";
275     else if (theFormatName == "STEP")
276       pd << result << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\")";
277     else if (theFormatName == "STEP_SCALE")
278       pd << result << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\", True)";
279     else {
280       pd << result << " = geompy.ImportFile(\""
281          << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")";
282     }
283   }
284
285   SetErrorCode(OK);
286
287   // OLD CODE: begin
288   if (theFormatName == "IGES_UNIT") {
289     TopoDS_Shape S = aFunction->GetValue();
290     TopoDS_Vertex V = TopoDS::Vertex(S);
291     gp_Pnt P = BRep_Tool::Pnt(V);
292     double scale = P.X();
293     TCollection_AsciiString aUnitName = "UNIT_M";
294     if (fabs(scale-0.01) < 1.e-6)
295       aUnitName = "UNIT_CM";
296     else if (fabs(scale-0.001) < 1.e-6)
297       aUnitName = "UNIT_MM";
298     //cout<<"IIO: aUnitName = "<<aUnitName.ToCString()<<endl;
299     SetErrorCode(aUnitName);
300   }
301   // OLD CODE: end
302
303   return result;
304 }
305
306 //=============================================================================
307 /*!
308  *  ReadValue
309  */
310 //=============================================================================
311 TCollection_AsciiString GEOMImpl_IInsertOperations::ReadValue
312                                  (const TCollection_AsciiString& theFileName,
313                                   const TCollection_AsciiString& theFormatName,
314                                   const TCollection_AsciiString& theParameterName)
315 {
316   SetErrorCode(KO);
317
318   TCollection_AsciiString aValue, anError;
319
320   if (theFileName.IsEmpty() || theFormatName.IsEmpty() || theParameterName.IsEmpty()) return aValue;
321
322   Handle(TCollection_HAsciiString) aHLibName;
323   if (!IsSupported(Standard_True, theFormatName.SubString(1,4), aHLibName)) {
324     return aValue;
325   }
326   TCollection_AsciiString aLibName = aHLibName->String();
327
328   aValue = GEOMImpl_ImportDriver::ReadValue(theFileName, aLibName, theParameterName, anError);
329   if (anError.IsEmpty())
330     SetErrorCode(OK);
331   else
332     SetErrorCode(anError.ToCString());
333
334   return aValue;
335 }
336
337 //=============================================================================
338 /*!
339  *  ImportTranslators
340  */
341 //=============================================================================
342 Standard_Boolean GEOMImpl_IInsertOperations::ImportTranslators
343                      (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
344                       Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
345 {
346   if (theFormats.IsNull())
347     theFormats = new TColStd_HSequenceOfAsciiString;
348   else
349     theFormats->Clear();
350
351   if (thePatterns.IsNull())
352     thePatterns = new TColStd_HSequenceOfAsciiString;
353   else
354     thePatterns->Clear();
355
356   if (!InitResMgr()) return Standard_False;
357
358   // Read Import formats list from install directory
359   if (myResMgr->Find("Import")) {
360     TCollection_AsciiString aFormats (myResMgr->Value("Import"));
361     TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
362     int i = 1;
363     for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
364       theFormats->Append(aToken);
365     }
366   }
367
368   // Read Import formats from user directory
369   if (myResMgrUser->Find("Import")) {
370     TCollection_AsciiString aFormats (myResMgrUser->Value("Import"));
371     TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
372     int i = 1;
373     for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
374       int aLenFormats = theFormats->Length();
375       bool isFound = false;
376       for(int aInd=1;aInd<=aLenFormats;aInd++){
377         if( theFormats->Value(aInd) == aToken){
378           isFound = true;
379           break;
380         }
381       }
382       if(!isFound)
383         theFormats->Append(aToken);
384     }
385   }
386
387   // Read Patterns for each supported format
388   int j = 1, len = theFormats->Length();
389   for (; j <= len; j++) {
390     TCollection_AsciiString aKey, aPattern;
391     aKey = theFormats->Value(j) + ".ImportPattern";
392     if (myResMgr->Find(aKey.ToCString()))
393       aPattern = myResMgr->Value(aKey.ToCString());
394     else if(myResMgrUser->Find(aKey.ToCString()))
395       aPattern = myResMgrUser->Value(aKey.ToCString());
396     else {
397       aKey = theFormats->Value(j) + ".Pattern";
398       if (myResMgr->Find(aKey.ToCString()))
399         aPattern = myResMgr->Value(aKey.ToCString());
400       else if(myResMgrUser->Find(aKey.ToCString()))
401         aPattern = myResMgrUser->Value(aKey.ToCString());
402       else {
403         aPattern = theFormats->Value(j);
404         aPattern += " Files ( *.* )";
405       }
406     }
407     thePatterns->Append(aPattern);
408   }
409
410   return (!theFormats->IsEmpty());
411 }
412
413 //=============================================================================
414 /*!
415  *  ExportTranslators
416  */
417 //=============================================================================
418 Standard_Boolean GEOMImpl_IInsertOperations::ExportTranslators
419                      (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
420                       Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
421 {
422   if (theFormats.IsNull())
423     theFormats = new TColStd_HSequenceOfAsciiString;
424   else
425     theFormats->Clear();
426
427   if (thePatterns.IsNull())
428     thePatterns = new TColStd_HSequenceOfAsciiString;
429   else
430     thePatterns->Clear();
431
432   if (!InitResMgr()) return Standard_False;
433
434   // Read Export formats list from install directory
435   if (myResMgr->Find("Export")) {
436     TCollection_AsciiString aFormats (myResMgr->Value("Export"));
437     TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
438     int i = 1;
439     for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
440       theFormats->Append(aToken);
441     }
442   }
443
444   // Read Export formats list from user directory
445   if (myResMgrUser->Find("Export")) {
446     TCollection_AsciiString aFormats (myResMgrUser->Value("Export"));
447     TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
448     int i = 1;
449     for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
450       int aLenFormats = theFormats->Length();
451       bool isFound = false;
452       for(int aInd=1;aInd<=aLenFormats;aInd++){
453         if( theFormats->Value(aInd) == aToken){
454           isFound = true;
455           break;
456         }
457       }
458       if(!isFound)
459         theFormats->Append(aToken);
460     }
461   }
462
463   // Read Patterns for each supported format
464   int j = 1, len = theFormats->Length();
465   for (; j <= len; j++) {
466     TCollection_AsciiString aKey, aPattern;
467     aKey = theFormats->Value(j) + ".ExportPattern";
468     if (myResMgr->Find(aKey.ToCString()))
469       aPattern = myResMgr->Value(aKey.ToCString());
470     else if (myResMgrUser->Find(aKey.ToCString()))
471       aPattern = myResMgrUser->Value(aKey.ToCString());
472     else {
473       aKey = theFormats->Value(j) + ".Pattern";
474       if (myResMgr->Find(aKey.ToCString()))
475         aPattern = myResMgr->Value(aKey.ToCString());
476       else if (myResMgrUser->Find(aKey.ToCString()))
477         aPattern = myResMgrUser->Value(aKey.ToCString());
478       else {
479         aPattern = theFormats->Value(j);
480         aPattern += " Files ( *.* )";
481       }
482     }
483     thePatterns->Append(aPattern);
484   }
485
486   return (!theFormats->IsEmpty());
487 }
488
489 //=============================================================================
490 /*!
491  *  IsSupported
492  */
493 //=============================================================================
494 Standard_Boolean GEOMImpl_IInsertOperations::IsSupported
495                             (const Standard_Boolean isImport,
496                              const TCollection_AsciiString& theFormat,
497                              Handle(TCollection_HAsciiString)& theLibName)
498 {
499   if (!InitResMgr()) return Standard_False;
500
501   // Import/Export mode
502   TCollection_AsciiString aMode;
503   //Standard_CString aMode;
504   if (isImport) aMode = "Import";
505   else aMode = "Export";
506
507   // Read supported formats for the certain mode from install directory
508   if (myResMgr->Find(aMode.ToCString())) {
509     TCollection_AsciiString aFormats (myResMgr->Value(aMode.ToCString()));
510     if (aFormats.Search(theFormat) > -1) {
511       // Read library name for the supported format
512       TCollection_AsciiString aKey (theFormat);
513       aKey += ".";
514       aKey += aMode;
515       if (myResMgr->Find(aKey.ToCString())) {
516         TCollection_AsciiString aLibName (myResMgr->Value(aKey.ToCString()));        
517 #ifndef WIN32
518         if ( aLibName.Length() > 3 && aLibName.SubString(1,3) != "lib" )
519           aLibName.Prepend("lib");
520         aLibName += ".so";
521 #else
522         aLibName += ".dll";
523 #endif
524         theLibName = new TCollection_HAsciiString (aLibName);
525         return Standard_True;
526       }
527     }
528   }
529   
530   // Read supported formats for the certain mode from user directory
531   if (myResMgrUser->Find(aMode.ToCString())) {
532     TCollection_AsciiString aFormats (myResMgrUser->Value(aMode.ToCString()));
533     if (aFormats.Search(theFormat) > -1) {
534       // Read library name for the supported format
535       TCollection_AsciiString aKey (theFormat);
536       aKey += ".";
537       aKey += aMode;
538       if (myResMgrUser->Find(aKey.ToCString())) {
539         TCollection_AsciiString aLibName (myResMgrUser->Value(aKey.ToCString()));
540 #ifndef WIN32
541         if ( aLibName.Length() > 3 && aLibName.SubString(1,3) != "lib" )
542           aLibName.Prepend("lib");
543         aLibName += ".so";
544 #else
545         aLibName += ".dll";
546 #endif
547         theLibName = new TCollection_HAsciiString (aLibName);
548         return Standard_True;
549       }
550     }
551   }
552   
553   return Standard_False;
554 }
555
556 //=============================================================================
557 /*!
558  *  InitResMgr
559  */
560 //=============================================================================
561 Standard_Boolean GEOMImpl_IInsertOperations::InitResMgr()
562 {
563   bool isResourceFound     = false;
564   bool isResourceFoundUser = false;
565   TCollection_AsciiString aUserResDir,aResDir;
566   
567   if (myResMgr.IsNull()) {
568     // Initialize the Resource Manager
569     TCollection_AsciiString aNull;
570     aResDir = TCollection_AsciiString(getenv("GEOM_ROOT_DIR"));
571 #ifdef WIN32
572     aResDir += "\\share\\salome\\resources\\geom";
573 #else
574     aResDir += "/share/salome/resources/geom";
575 #endif
576     
577     myResMgr = new Resource_Manager ("ImportExport", aResDir, aNull, Standard_False);
578
579     isResourceFound = true;
580     if (!myResMgr->Find("Import") && !myResMgr->Find("Export")) {
581       // instead of complains in Resource_Manager
582       isResourceFound = false;
583       INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString());
584     }
585   } else
586     isResourceFound = true;
587
588   if (myResMgrUser.IsNull()) {
589     char * dir = getenv("GEOM_ENGINE_RESOURCES_DIR");
590     TCollection_AsciiString aNull;
591     if ( dir )
592     {
593       aUserResDir = dir;
594     }
595     else
596     {
597       aUserResDir = getenv("HOME");
598 #ifdef WIN32
599       aUserResDir += "\\.salome\\resources";
600 #else
601       aUserResDir += "/.salome/resources";
602 #endif
603     }
604
605     myResMgrUser = new Resource_Manager ("ImportExport", aNull, aUserResDir, Standard_False);
606
607     isResourceFoundUser = true;
608     
609     if (!myResMgrUser->Find("Import") && !myResMgrUser->Find("Export")) {
610       // instead of complains in Resource_Manager
611       isResourceFoundUser = false;
612     }
613       
614   } else
615     isResourceFoundUser = true;
616     
617   if(!isResourceFound && !isResourceFoundUser){
618     INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString());
619     INFOS("No valid file \"ImportExport\" found in " << aUserResDir.ToCString() );
620   }
621
622   return ( myResMgr->Find("Import") || myResMgr->Find("Export") ||
623            myResMgrUser->Find("Import") || myResMgrUser->Find("Export"));
624 }
625
626 //=============================================================================
627 /*!
628  *  RestoreShape
629  */
630 //=============================================================================
631 Handle(GEOM_Object) GEOMImpl_IInsertOperations::RestoreShape (std::istringstream& theStream)
632 {
633   SetErrorCode(KO);
634
635   //Add a new result object
636   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
637
638   //Add a Copy function
639   Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF);
640   if (aFunction.IsNull()) return NULL;
641
642   //Check if the function is set correctly
643   if (aFunction->GetDriverGUID() != GEOMImpl_CopyDriver::GetID()) return NULL;
644
645   //Read a shape from the stream
646   TopoDS_Shape aShape;
647   BRep_Builder B;
648   BRepTools::Read(aShape, theStream, B);
649   if (aShape.IsNull()) {
650     SetErrorCode("RestoreShape error: BREP reading failed");
651   }
652
653   //Set function value
654   aFunction->SetValue(aShape);
655
656   //Special dump to avoid restored shapes publication.
657   //See correcponding code in GEOM_Engine.cxx (method ProcessFunction)
658   //GEOM::TPythonDump(aFunction) << "#";
659
660   GEOM::TPythonDump(aFunction) << result
661     << " = geompy.RestoreShape(\"\") # the shape string has not been dump for performance reason";
662
663   SetErrorCode(OK);
664
665   return result;
666 }
667
668 int GEOMImpl_IInsertOperations::LoadTexture(const TCollection_AsciiString& theTextureFile)
669 {
670   SetErrorCode(KO);
671
672   if (theTextureFile.IsEmpty()) return 0;
673
674 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
675   Handle(TColStd_HArray1OfByte) aTexture;
676 #else
677   Handle(TDataStd_HArray1OfByte) aTexture;
678 #endif
679
680   FILE* fp = fopen(theTextureFile.ToCString(), "r");
681   if (!fp) return 0;
682
683   std::list<std::string> lines;
684   char buffer[4096];
685   int maxlen = 0;
686   while (!feof(fp)) {
687     if ((fgets(buffer, 4096, fp)) == NULL) break;
688     int aLen = strlen(buffer);
689     if (buffer[aLen-1] == '\n') buffer[aLen-1] = '\0';
690     lines.push_back(buffer);
691     maxlen = std::max(maxlen, (int)strlen(buffer));
692   }
693
694   fclose(fp);
695
696   int lenbytes = maxlen/8;
697   if (maxlen%8) lenbytes++;
698
699   if (lenbytes == 0 || lines.empty())
700     return 0;
701
702   std::list<unsigned char> bytedata;
703   std::list<std::string>::const_iterator it;
704   for (it = lines.begin(); it != lines.end(); ++it) {
705     std::string line = *it;
706     int lenline = (line.size()/8 + (line.size()%8 ? 1 : 0)) * 8;
707     for (int i = 0; i < lenline/8; i++) {
708       unsigned char byte = 0;
709       for (int j = 0; j < 8; j++)
710         byte = (byte << 1) + ( i*8+j < line.size() && line[i*8+j] != '0' ? 1 : 0 );
711       bytedata.push_back(byte);
712     }
713     for (int i = lenline/8; i < lenbytes; i++)
714       bytedata.push_back((unsigned char)0);
715   }
716
717   if (bytedata.empty() || bytedata.size() != lines.size()*lenbytes)
718     return 0;
719
720 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
721   aTexture = new TColStd_HArray1OfByte (1, lines.size()*lenbytes);
722 #else
723   aTexture = new TDataStd_HArray1OfByte (1, lines.size()*lenbytes);
724 #endif
725
726   std::list<unsigned char>::iterator bdit;
727   int i;
728   for (i = 1, bdit = bytedata.begin(); bdit != bytedata.end(); ++bdit, ++i)
729     aTexture->SetValue(i, (Standard_Byte)(*bdit));
730
731   int aTextureId = GetEngine()->addTexture(GetDocID(), lenbytes*8, lines.size(), aTexture, theTextureFile);
732   if (aTextureId > 0) SetErrorCode(OK);
733   return aTextureId;
734 }
735   
736 int GEOMImpl_IInsertOperations::AddTexture(int theWidth, int theHeight, 
737 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
738                                            const Handle(TColStd_HArray1OfByte)& theTexture)
739 #else
740                                            const Handle(TDataStd_HArray1OfByte)& theTexture)
741 #endif
742 {
743   SetErrorCode(KO);
744   int aTextureId = GetEngine()->addTexture(GetDocID(), theWidth, theHeight, theTexture);
745   if (aTextureId > 0) SetErrorCode(OK);
746   return aTextureId;
747 }
748
749 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
750 Handle(TColStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
751 #else
752 Handle(TDataStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
753 #endif
754                                                                       int& theWidth, int& theHeight)
755 {
756   SetErrorCode(KO);
757   
758 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
759   Handle(TColStd_HArray1OfByte) aTexture;
760 #else
761   Handle(TDataStd_HArray1OfByte) aTexture;
762 #endif
763
764   theWidth = theHeight = 0;
765   TCollection_AsciiString aFileName;
766
767   if (theTextureId <= 0)
768     return aTexture;
769
770   aTexture = GetEngine()->getTexture(GetDocID(), theTextureId, theWidth, theHeight, aFileName);
771
772   if (theWidth > 0 && theHeight > 0 && aTexture->Length() > 0) SetErrorCode(OK);
773
774   return aTexture;
775 }
776
777 std::list<int> GEOMImpl_IInsertOperations::GetAllTextures()
778 {
779   SetErrorCode(KO);
780   std::list<int> id_list = GetEngine()->getAllTextures(GetDocID());
781   SetErrorCode(OK);
782   return id_list;
783 }
784
785 TopAbs_ShapeEnum getGroupDimension(XAO::Group* group)
786 {
787   XAO::Dimension dim = group->getDimension();
788   TopAbs_ShapeEnum rdim;
789   switch ( dim )
790   {
791   case XAO::VERTEX:
792     rdim = TopAbs_VERTEX; break;
793   case XAO::EDGE:
794     rdim = TopAbs_EDGE; break;
795   case XAO::FACE:
796     rdim = TopAbs_FACE; break;
797   case XAO::SOLID:
798     rdim = TopAbs_SOLID; break;
799   default:
800     rdim = TopAbs_COMPOUND; break;
801   }
802   return rdim;
803 }
804
805 XAO::Dimension shapeEnumToDimension(const TopAbs_ShapeEnum& shape)
806 {
807   XAO::Dimension dim;
808   switch( shape ) {
809   case TopAbs_VERTEX:
810     dim = XAO::VERTEX; break;
811   case TopAbs_EDGE:
812     dim = XAO::EDGE; break;
813   case TopAbs_FACE:
814     dim = XAO::FACE; break;
815   case TopAbs_SOLID:
816     dim = XAO::SOLID; break;
817   default:
818     throw SALOME_Exception("Bad type"); // TODO
819   }
820   return dim;
821 }
822
823 void GEOMImpl_IInsertOperations::exportGroups(std::list<Handle(GEOM_Object)> groupList, XAO::Xao* xaoObject, XAO::BrepGeometry* geometry)
824 {
825   // add the groups
826   std::list<Handle(GEOM_Object)>::iterator groupIterator = groupList.begin();
827   while (groupIterator != groupList.end())
828   {
829     Handle(GEOM_Object) currGroup = (*groupIterator++);
830     Handle(TColStd_HArray1OfInteger) groupIds = myGroupOperations->GetObjects(currGroup);
831     
832     TopAbs_ShapeEnum shapeGroup = myGroupOperations->GetType(currGroup);
833     XAO::Dimension dim = shapeEnumToDimension(shapeGroup);
834     XAO::Group* group = xaoObject->addGroup(dim, currGroup->GetName().ToCString());
835     
836     switch (shapeGroup)
837     {
838     case TopAbs_VERTEX:
839       for (int i = 1; i <= groupIds->Length(); i++)
840       {
841         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
842         int index = geometry->getVertexIndexByReference(ref);
843         group->add(index);
844       }
845       break;
846     case TopAbs_EDGE:
847       for (int i = 1; i <= groupIds->Length(); i++)
848       {
849         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
850         int index = geometry->getEdgeIndexByReference(ref);
851         group->add(index);
852       }
853       break;
854     case TopAbs_FACE:
855       for (int i = 1; i <= groupIds->Length(); i++)
856       {
857         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
858         int index = geometry->getFaceIndexByReference(ref);
859         group->add(index);
860       }
861       break;
862     case TopAbs_SOLID:
863       for (int i = 1; i <= groupIds->Length(); i++)
864       {
865         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
866         int index = geometry->getSolidIndexByReference(ref);
867         group->add(index);
868       }
869       break;
870     }
871   }
872 }
873
874 void GEOMImpl_IInsertOperations::exportFields(std::list<Handle(GEOM_Object)> fieldList, XAO::Xao* xaoObject, XAO::BrepGeometry* geometry)
875 {
876   // TODO
877 }
878
879 void GEOMImpl_IInsertOperations::exportSubshapes(const Handle(GEOM_Object)& shape, XAO::BrepGeometry* geometry)
880 {
881   Handle(TColStd_HSequenceOfTransient) subObjects = myShapesOperations->GetExistingSubObjects(shape, false);
882   int nbSubObjects = subObjects->Length();
883   // set the names of the sub shapes
884   for (int i = 1; i <= nbSubObjects; i++)
885   {
886     Handle(Standard_Transient) transientSubObject = subObjects->Value(i);
887     if (transientSubObject.IsNull())
888       continue;
889     
890     Handle(GEOM_Object) subObject = Handle(GEOM_Object)::DownCast(transientSubObject);
891     if (subObject->GetType() != GEOM_GROUP)
892     {
893       int subIndex = myShapesOperations->GetSubShapeIndex(shape, subObject);
894       switch (subObject->GetValue().ShapeType())
895       {
896       case TopAbs_VERTEX:
897         geometry->changeVertexName(subIndex, subObject->GetName().ToCString());
898         break;
899       case TopAbs_EDGE:
900         geometry->changeEdgeName(subIndex, subObject->GetName().ToCString());
901         break;
902       case TopAbs_FACE:
903         geometry->changeFaceName(subIndex, subObject->GetName().ToCString());
904         break;
905       case TopAbs_SOLID:
906         geometry->changeSolidName(subIndex, subObject->GetName().ToCString());
907         break;
908       }
909     }
910   }
911 }
912
913 //=============================================================================
914 /*!
915  *  Export a shape to XAO format
916  *  \param shape The shape to export
917  *  \param groups The list of groups to export
918  *  \param fields The list of fields to export
919  *  \param fileName The name of the file to exported
920  *  \return boolean indicating if export was succeful.
921  */
922 //=============================================================================
923 bool GEOMImpl_IInsertOperations::ExportXAO(Handle(GEOM_Object) shape,
924                                            std::list<Handle(GEOM_Object)> groupList,
925                                            std::list<Handle(GEOM_Object)> fieldList,
926                                            const char* author,
927                                            const char* fileName)
928 {
929   SetErrorCode(KO);
930   
931   if (shape.IsNull()) return false;
932   
933   // add a new shape function with parameters
934   Handle(GEOM_Function) lastFunction = shape->GetLastFunction();
935   if (lastFunction.IsNull()) return false;
936   
937   // add a new result object
938   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
939   
940   // add an Export function
941   Handle(GEOM_Function) exportFunction = result->AddFunction(GEOMImpl_XAODriver::GetID(), IMPORTEXPORT_EXPORTXAO);
942   if (exportFunction.IsNull()) return false;
943   if (exportFunction->GetDriverGUID() != GEOMImpl_XAODriver::GetID()) return false;
944   
945   // create the XAO object
946   XAO::Xao* xaoObject = new XAO::Xao();
947   xaoObject->setAuthor(author);
948   
949   // add the geometry
950   XAO::BrepGeometry* geometry = (XAO::BrepGeometry*)XAO::Geometry::createGeometry(XAO::BREP);
951   TopoDS_Shape topoShape = shape->GetValue();
952   exportFunction->SetValue(topoShape);
953   XAO::BrepGeometry* brep = (XAO::BrepGeometry*)geometry;
954   brep->setTopoDS_Shape(topoShape);
955   
956   geometry->setName(shape->GetName().ToCString());
957   exportSubshapes(shape, geometry);
958   xaoObject->setGeometry(geometry);
959   
960   exportGroups(groupList, xaoObject, geometry);
961   exportFields(fieldList, xaoObject, geometry);
962   
963   // export the XAO to the file
964   xaoObject->exportXAO(fileName);
965   
966   // make a Python command
967   GEOM::TPythonDump pd(exportFunction);
968   pd << "exported = geompy.ExportXAO(" << shape;
969   
970   // list of groups
971   pd << ", [";
972   if (groupList.size() > 0)
973   {
974     std::list<Handle(GEOM_Object)>::iterator itGroup = groupList.begin();
975     pd << (*itGroup++);
976     while (itGroup != groupList.end())
977     {
978       pd << ", " << (*itGroup++);
979     }
980   }
981   
982   // list of fields
983   pd << "], [";
984   if (fieldList.size() > 0)
985   {
986     std::list<Handle(GEOM_Object)>::iterator itField = fieldList.begin();
987     pd << (*itField++);
988     while (itField != fieldList.end())
989     {
990       pd << ", " << (*itField++);
991     }
992   }
993   pd << "], ";
994   pd << author << ", \"" << fileName << "\")";
995   
996   SetErrorCode(OK);
997   delete xaoObject;
998   
999   return true;
1000 }
1001
1002 void GEOMImpl_IInsertOperations::importSubShapes(XAO::Geometry* xaoGeometry,
1003                                                  Handle(GEOM_Function) function, int shapeType, int dim,
1004                                                  Handle(TColStd_HSequenceOfTransient)& subShapeList)
1005 {
1006   Handle(GEOM_Object) subShape;
1007   Handle(GEOM_Function) aFunction;
1008   Handle(TColStd_HArray1OfInteger) anArray;
1009   
1010   XAO::GeometricElementList::iterator elementIterator = xaoGeometry->begin((XAO::Dimension)dim);
1011   for (; elementIterator != xaoGeometry->end((XAO::Dimension)dim); elementIterator++)
1012   {
1013     XAO::GeometricElement element = elementIterator->second;
1014     if (!element.hasName())
1015       continue;
1016     
1017     std::string name = element.getName();
1018     std::string ref = element.getReference();
1019     int iref = XAO::XaoUtils::stringToInt(ref);
1020     
1021     anArray = new TColStd_HArray1OfInteger(1, 1);
1022     anArray->SetValue(1, iref);
1023     
1024     subShape = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1025     Handle(GEOM_Function) aFunction = subShape->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1026     if (aFunction.IsNull())
1027       return;
1028     
1029     subShape->SetName(name.c_str());
1030     subShape->SetType(shapeType);
1031     
1032     GEOM_ISubShape aSSI(aFunction);
1033     aSSI.SetMainShape(function);
1034     aSSI.SetIndices(anArray);
1035     
1036     //aFunction->SetValue(aValue);
1037     subShapeList->Append(subShape);
1038     
1039     // Put this subshape in the list of sub-shapes of theMainShape
1040     function->AddSubShapeReference(aFunction);
1041   }
1042 }
1043
1044 //=============================================================================
1045 /*!
1046  *  Import a shape from XAO format
1047  *  \param fileName The name of the file to import
1048  *  \param shape The imported shape
1049  *  \param subShapes The list of imported groups
1050  *  \param groups The list of imported groups
1051  *  \param fields The list of imported fields
1052  *  \return boolean indicating if import was succeful.
1053  */
1054 //=============================================================================
1055 bool GEOMImpl_IInsertOperations::ImportXAO(const char* fileName,
1056                                            Handle(GEOM_Object)& shape,
1057                                            Handle(TColStd_HSequenceOfTransient)& subShapes,
1058                                            Handle(TColStd_HSequenceOfTransient)& groups,
1059                                            Handle(TColStd_HSequenceOfTransient)& fields)
1060 {
1061   SetErrorCode(KO);
1062   
1063   if (fileName == NULL || groups.IsNull() || fields.IsNull())
1064     return false;
1065   
1066   // Read the XAO
1067   XAO::Xao* xaoObject = new XAO::Xao();
1068   try
1069   {
1070     xaoObject->importXAO(fileName);
1071   }
1072   catch (XAO::XAO_Exception& exc)
1073   {
1074     delete xaoObject;
1075     SetErrorCode(exc.what());
1076     return false;
1077   }
1078   
1079   XAO::Geometry* xaoGeometry = xaoObject->getGeometry();
1080   if (xaoGeometry == NULL)
1081   {
1082     delete xaoObject;
1083     SetErrorCode("Cannot import XAO: geometry format not supported.");
1084     return false;
1085   }
1086   
1087   // create the shape
1088   shape = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
1089   Handle(GEOM_Function) function = shape->AddFunction(GEOMImpl_XAODriver::GetID(), IMPORTEXPORT_EXPORTXAO);
1090   if (function.IsNull()) return false;
1091   if (function->GetDriverGUID() != GEOMImpl_XAODriver::GetID()) return false;
1092   
1093   // set the geometry
1094   if (xaoGeometry->getFormat() == XAO::BREP)
1095   {
1096     XAO::BrepGeometry* brep = (XAO::BrepGeometry*)xaoGeometry;
1097     TopoDS_Shape geomShape = brep->getTopoDS_Shape();
1098     function->SetValue(geomShape);
1099     shape->SetName(xaoGeometry->getName().c_str());
1100   }
1101   else
1102   {
1103     delete xaoObject;
1104     SetErrorCode("Cannot import XAO: geometry format not supported.");
1105     return false;
1106   }
1107   
1108   // create sub shapes with names
1109   importSubShapes(xaoGeometry, function, GEOM_POINT, XAO::VERTEX, subShapes);
1110   importSubShapes(xaoGeometry, function, GEOM_EDGE, XAO::EDGE, subShapes);
1111   importSubShapes(xaoGeometry, function, GEOM_FACE, XAO::FACE, subShapes);
1112   importSubShapes(xaoGeometry, function, GEOM_SOLID, XAO::SOLID, subShapes);
1113   
1114   // create groups
1115   int nbGroups = xaoObject->countGroups();
1116   for (int i = 0; i < nbGroups; ++i)
1117   {
1118     XAO::Group* xaoGroup = xaoObject->getGroup(i);
1119     
1120     // build an array with the indexes of the sub shapes
1121     int nbElt = xaoGroup->count();
1122     Handle(TColStd_HArray1OfInteger) array = new TColStd_HArray1OfInteger(1, nbElt);
1123     int j = 0;
1124     for (std::set<int>::iterator it = xaoGroup->begin(); it != xaoGroup->end(); ++it)
1125     {
1126       int index = (*it);
1127       std::string ref = xaoGeometry->getElementReference(xaoGroup->getDimension(), index);
1128       array->SetValue(++j, XAO::XaoUtils::stringToInt(ref));
1129     }
1130     
1131     // create the group with the array of sub shapes indexes
1132     Handle(GEOM_Object) group = GetEngine()->AddSubShape(shape, array);
1133     group->SetType(GEOM_GROUP);
1134     group->SetName(xaoGroup->getName().c_str());
1135     
1136     // Set a sub-shape type
1137     TDF_Label freeLabel = group->GetFreeLabel();
1138     TDataStd_Integer::Set(freeLabel, (Standard_Integer) getGroupDimension(xaoGroup));
1139     groups->Append(group);
1140     
1141     function = group->GetLastFunction();
1142   }
1143   
1144   // TODO: create the fields
1145   
1146   // make a Python command
1147   GEOM::TPythonDump pd(function);
1148   pd << "(imported, " << shape << ", ";
1149   
1150   // list of sub shapes
1151   pd << "[";
1152   int nbSubshapes = subShapes->Length();
1153   std::cout << "Nb SubShapes = " << nbSubshapes << std::endl;
1154   if (nbSubshapes > 0)
1155   {
1156     for (int i = 1; i <= nbSubshapes; i++)
1157     {
1158       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(subShapes->Value(i));
1159       pd << obj << ((i < nbSubshapes) ? ", " : "");
1160     }
1161   }
1162   pd << "], [";
1163   
1164   // list of groups
1165   if (nbGroups > 0)
1166   {
1167     for (int i = 1; i <= nbGroups; i++)
1168     {
1169       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(groups->Value(i));
1170       pd << obj << ((i < nbGroups) ? ", " : "");
1171     }
1172   }
1173   
1174   pd << "], [";
1175   
1176   // list of fields
1177   pd << "]";
1178   pd << ") = geompy.ImportXAO(\"" << fileName << "\")";
1179   
1180   delete xaoObject;
1181   SetErrorCode(OK);
1182   
1183   return true;
1184 }