Salome HOME
Replace deprecated WNT macro definition by WIN32.
[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         aLibName += ".so";     
519 #else
520         aLibName += ".dll";
521 #endif
522         theLibName = new TCollection_HAsciiString (aLibName);
523         return Standard_True;
524       }
525     }
526   }
527   
528   // Read supported formats for the certain mode from user directory
529   if (myResMgrUser->Find(aMode.ToCString())) {
530     TCollection_AsciiString aFormats (myResMgrUser->Value(aMode.ToCString()));
531     if (aFormats.Search(theFormat) > -1) {
532       // Read library name for the supported format
533       TCollection_AsciiString aKey (theFormat);
534       aKey += ".";
535       aKey += aMode;
536       if (myResMgrUser->Find(aKey.ToCString())) {
537         TCollection_AsciiString aLibName (myResMgrUser->Value(aKey.ToCString()));
538         theLibName = new TCollection_HAsciiString (aLibName);
539         return Standard_True;
540       }
541     }
542   }
543   
544   return Standard_False;
545 }
546
547 //=============================================================================
548 /*!
549  *  InitResMgr
550  */
551 //=============================================================================
552 Standard_Boolean GEOMImpl_IInsertOperations::InitResMgr()
553 {
554   bool isResourceFound     = false;
555   bool isResourceFoundUser = false;
556   TCollection_AsciiString aUserResDir,aResDir;
557   
558   if (myResMgr.IsNull()) {
559     // Initialize the Resource Manager
560     TCollection_AsciiString aNull;
561     aResDir = TCollection_AsciiString(getenv("GEOM_ROOT_DIR"));
562 #ifdef WIN32
563     aResDir += "\\share\\salome\\resources\\geom";
564 #else
565     aResDir += "/share/salome/resources/geom";
566 #endif
567     
568     myResMgr = new Resource_Manager ("ImportExport", aResDir, aNull, Standard_False);
569
570     isResourceFound = true;
571     if (!myResMgr->Find("Import") && !myResMgr->Find("Export")) {
572       // instead of complains in Resource_Manager
573       isResourceFound = false;
574       INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString());
575     }
576   } else
577     isResourceFound = true;
578
579   if (myResMgrUser.IsNull()) {
580     char * dir = getenv("GEOM_ENGINE_RESOURCES_DIR");
581     TCollection_AsciiString aNull;
582     if ( dir )
583     {
584       aUserResDir = dir;
585     }
586     else
587     {
588       aUserResDir = getenv("HOME");
589 #ifdef WIN32
590       aUserResDir += "\\.salome\\resources";
591 #else
592       aUserResDir += "/.salome/resources";
593 #endif
594     }
595
596     myResMgrUser = new Resource_Manager ("ImportExport", aNull, aUserResDir, Standard_False);
597
598     isResourceFoundUser = true;
599     
600     if (!myResMgrUser->Find("Import") && !myResMgrUser->Find("Export")) {
601       // instead of complains in Resource_Manager
602       isResourceFoundUser = false;
603     }
604       
605   } else
606     isResourceFoundUser = true;
607     
608   if(!isResourceFound && !isResourceFoundUser){
609     INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString());
610     INFOS("No valid file \"ImportExport\" found in " << aUserResDir.ToCString() );
611   }
612
613   return ( myResMgr->Find("Import") || myResMgr->Find("Export") ||
614            myResMgrUser->Find("Import") || myResMgrUser->Find("Export"));
615 }
616
617 //=============================================================================
618 /*!
619  *  RestoreShape
620  */
621 //=============================================================================
622 Handle(GEOM_Object) GEOMImpl_IInsertOperations::RestoreShape (std::istringstream& theStream)
623 {
624   SetErrorCode(KO);
625
626   //Add a new result object
627   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
628
629   //Add a Copy function
630   Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF);
631   if (aFunction.IsNull()) return NULL;
632
633   //Check if the function is set correctly
634   if (aFunction->GetDriverGUID() != GEOMImpl_CopyDriver::GetID()) return NULL;
635
636   //Read a shape from the stream
637   TopoDS_Shape aShape;
638   BRep_Builder B;
639   BRepTools::Read(aShape, theStream, B);
640   if (aShape.IsNull()) {
641     SetErrorCode("RestoreShape error: BREP reading failed");
642   }
643
644   //Set function value
645   aFunction->SetValue(aShape);
646
647   //Special dump to avoid restored shapes publication.
648   //See correcponding code in GEOM_Engine.cxx (method ProcessFunction)
649   //GEOM::TPythonDump(aFunction) << "#";
650
651   GEOM::TPythonDump(aFunction) << result
652     << " = geompy.RestoreShape(\"\") # the shape string has not been dump for performance reason";
653
654   SetErrorCode(OK);
655
656   return result;
657 }
658
659 int GEOMImpl_IInsertOperations::LoadTexture(const TCollection_AsciiString& theTextureFile)
660 {
661   SetErrorCode(KO);
662
663   if (theTextureFile.IsEmpty()) return 0;
664
665 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
666   Handle(TColStd_HArray1OfByte) aTexture;
667 #else
668   Handle(TDataStd_HArray1OfByte) aTexture;
669 #endif
670
671   FILE* fp = fopen(theTextureFile.ToCString(), "r");
672   if (!fp) return 0;
673
674   std::list<std::string> lines;
675   char buffer[4096];
676   int maxlen = 0;
677   while (!feof(fp)) {
678     if ((fgets(buffer, 4096, fp)) == NULL) break;
679     int aLen = strlen(buffer);
680     if (buffer[aLen-1] == '\n') buffer[aLen-1] = '\0';
681     lines.push_back(buffer);
682     maxlen = std::max(maxlen, (int)strlen(buffer));
683   }
684
685   fclose(fp);
686
687   int lenbytes = maxlen/8;
688   if (maxlen%8) lenbytes++;
689
690   if (lenbytes == 0 || lines.empty())
691     return 0;
692
693   std::list<unsigned char> bytedata;
694   std::list<std::string>::const_iterator it;
695   for (it = lines.begin(); it != lines.end(); ++it) {
696     std::string line = *it;
697     int lenline = (line.size()/8 + (line.size()%8 ? 1 : 0)) * 8;
698     for (int i = 0; i < lenline/8; i++) {
699       unsigned char byte = 0;
700       for (int j = 0; j < 8; j++)
701         byte = (byte << 1) + ( i*8+j < line.size() && line[i*8+j] != '0' ? 1 : 0 );
702       bytedata.push_back(byte);
703     }
704     for (int i = lenline/8; i < lenbytes; i++)
705       bytedata.push_back((unsigned char)0);
706   }
707
708   if (bytedata.empty() || bytedata.size() != lines.size()*lenbytes)
709     return 0;
710
711 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
712   aTexture = new TColStd_HArray1OfByte (1, lines.size()*lenbytes);
713 #else
714   aTexture = new TDataStd_HArray1OfByte (1, lines.size()*lenbytes);
715 #endif
716
717   std::list<unsigned char>::iterator bdit;
718   int i;
719   for (i = 1, bdit = bytedata.begin(); bdit != bytedata.end(); ++bdit, ++i)
720     aTexture->SetValue(i, (Standard_Byte)(*bdit));
721
722   int aTextureId = GetEngine()->addTexture(GetDocID(), lenbytes*8, lines.size(), aTexture, theTextureFile);
723   if (aTextureId > 0) SetErrorCode(OK);
724   return aTextureId;
725 }
726   
727 int GEOMImpl_IInsertOperations::AddTexture(int theWidth, int theHeight, 
728 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
729                                            const Handle(TColStd_HArray1OfByte)& theTexture)
730 #else
731                                            const Handle(TDataStd_HArray1OfByte)& theTexture)
732 #endif
733 {
734   SetErrorCode(KO);
735   int aTextureId = GetEngine()->addTexture(GetDocID(), theWidth, theHeight, theTexture);
736   if (aTextureId > 0) SetErrorCode(OK);
737   return aTextureId;
738 }
739
740 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
741 Handle(TColStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
742 #else
743 Handle(TDataStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
744 #endif
745                                                                       int& theWidth, int& theHeight)
746 {
747   SetErrorCode(KO);
748   
749 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
750   Handle(TColStd_HArray1OfByte) aTexture;
751 #else
752   Handle(TDataStd_HArray1OfByte) aTexture;
753 #endif
754
755   theWidth = theHeight = 0;
756   TCollection_AsciiString aFileName;
757
758   if (theTextureId <= 0)
759     return aTexture;
760
761   aTexture = GetEngine()->getTexture(GetDocID(), theTextureId, theWidth, theHeight, aFileName);
762
763   if (theWidth > 0 && theHeight > 0 && aTexture->Length() > 0) SetErrorCode(OK);
764
765   return aTexture;
766 }
767
768 std::list<int> GEOMImpl_IInsertOperations::GetAllTextures()
769 {
770   SetErrorCode(KO);
771   std::list<int> id_list = GetEngine()->getAllTextures(GetDocID());
772   SetErrorCode(OK);
773   return id_list;
774 }
775
776 TopAbs_ShapeEnum getGroupDimension(XAO::Group* group)
777 {
778   XAO::Dimension dim = group->getDimension();
779   TopAbs_ShapeEnum rdim;
780   switch ( dim )
781   {
782   case XAO::VERTEX:
783     rdim = TopAbs_VERTEX; break;
784   case XAO::EDGE:
785     rdim = TopAbs_EDGE; break;
786   case XAO::FACE:
787     rdim = TopAbs_FACE; break;
788   case XAO::SOLID:
789     rdim = TopAbs_SOLID; break;
790   default:
791     rdim = TopAbs_COMPOUND; break;
792   }
793   return rdim;
794 }
795
796 XAO::Dimension shapeEnumToDimension(const TopAbs_ShapeEnum& shape)
797 {
798   XAO::Dimension dim;
799   switch( shape ) {
800   case TopAbs_VERTEX:
801     dim = XAO::VERTEX; break;
802   case TopAbs_EDGE:
803     dim = XAO::EDGE; break;
804   case TopAbs_FACE:
805     dim = XAO::FACE; break;
806   case TopAbs_SOLID:
807     dim = XAO::SOLID; break;
808   default:
809     throw SALOME_Exception("Bad type"); // TODO
810   }
811   return dim;
812 }
813
814 void GEOMImpl_IInsertOperations::exportGroups(std::list<Handle(GEOM_Object)> groupList, XAO::Xao* xaoObject, XAO::BrepGeometry* geometry)
815 {
816   // add the groups
817   std::list<Handle(GEOM_Object)>::iterator groupIterator = groupList.begin();
818   while (groupIterator != groupList.end())
819   {
820     Handle(GEOM_Object) currGroup = (*groupIterator++);
821     Handle(TColStd_HArray1OfInteger) groupIds = myGroupOperations->GetObjects(currGroup);
822     
823     TopAbs_ShapeEnum shapeGroup = myGroupOperations->GetType(currGroup);
824     XAO::Dimension dim = shapeEnumToDimension(shapeGroup);
825     XAO::Group* group = xaoObject->addGroup(dim, currGroup->GetName().ToCString());
826     
827     switch (shapeGroup)
828     {
829     case TopAbs_VERTEX:
830       for (int i = 1; i <= groupIds->Length(); i++)
831       {
832         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
833         int index = geometry->getVertexIndexByReference(ref);
834         group->add(index);
835       }
836       break;
837     case TopAbs_EDGE:
838       for (int i = 1; i <= groupIds->Length(); i++)
839       {
840         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
841         int index = geometry->getEdgeIndexByReference(ref);
842         group->add(index);
843       }
844       break;
845     case TopAbs_FACE:
846       for (int i = 1; i <= groupIds->Length(); i++)
847       {
848         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
849         int index = geometry->getFaceIndexByReference(ref);
850         group->add(index);
851       }
852       break;
853     case TopAbs_SOLID:
854       for (int i = 1; i <= groupIds->Length(); i++)
855       {
856         std::string ref = XAO::XaoUtils::intToString(groupIds->Value(i));
857         int index = geometry->getSolidIndexByReference(ref);
858         group->add(index);
859       }
860       break;
861     }
862   }
863 }
864
865 void GEOMImpl_IInsertOperations::exportFields(std::list<Handle(GEOM_Object)> fieldList, XAO::Xao* xaoObject, XAO::BrepGeometry* geometry)
866 {
867   // TODO
868 }
869
870 void GEOMImpl_IInsertOperations::exportSubshapes(const Handle(GEOM_Object)& shape, XAO::BrepGeometry* geometry)
871 {
872   Handle(TColStd_HSequenceOfTransient) subObjects = myShapesOperations->GetExistingSubObjects(shape, false);
873   int nbSubObjects = subObjects->Length();
874   // set the names of the sub shapes
875   for (int i = 1; i <= nbSubObjects; i++)
876   {
877     Handle(Standard_Transient) transientSubObject = subObjects->Value(i);
878     if (transientSubObject.IsNull())
879       continue;
880     
881     Handle(GEOM_Object) subObject = Handle(GEOM_Object)::DownCast(transientSubObject);
882     if (subObject->GetType() != GEOM_GROUP)
883     {
884       int subIndex = myShapesOperations->GetSubShapeIndex(shape, subObject);
885       switch (subObject->GetValue().ShapeType())
886       {
887       case TopAbs_VERTEX:
888         geometry->changeVertexName(subIndex, subObject->GetName().ToCString());
889         break;
890       case TopAbs_EDGE:
891         geometry->changeEdgeName(subIndex, subObject->GetName().ToCString());
892         break;
893       case TopAbs_FACE:
894         geometry->changeFaceName(subIndex, subObject->GetName().ToCString());
895         break;
896       case TopAbs_SOLID:
897         geometry->changeSolidName(subIndex, subObject->GetName().ToCString());
898         break;
899       }
900     }
901   }
902 }
903
904 //=============================================================================
905 /*!
906  *  Export a shape to XAO format
907  *  \param shape The shape to export
908  *  \param groups The list of groups to export
909  *  \param fields The list of fields to export
910  *  \param fileName The name of the file to exported
911  *  \return boolean indicating if export was succeful.
912  */
913 //=============================================================================
914 bool GEOMImpl_IInsertOperations::ExportXAO(Handle(GEOM_Object) shape,
915                                            std::list<Handle(GEOM_Object)> groupList,
916                                            std::list<Handle(GEOM_Object)> fieldList,
917                                            const char* author,
918                                            const char* fileName)
919 {
920   SetErrorCode(KO);
921   
922   if (shape.IsNull()) return false;
923   
924   // add a new shape function with parameters
925   Handle(GEOM_Function) lastFunction = shape->GetLastFunction();
926   if (lastFunction.IsNull()) return false;
927   
928   // add a new result object
929   Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
930   
931   // add an Export function
932   Handle(GEOM_Function) exportFunction = result->AddFunction(GEOMImpl_XAODriver::GetID(), IMPORTEXPORT_EXPORTXAO);
933   if (exportFunction.IsNull()) return false;
934   if (exportFunction->GetDriverGUID() != GEOMImpl_XAODriver::GetID()) return false;
935   
936   // create the XAO object
937   XAO::Xao* xaoObject = new XAO::Xao();
938   xaoObject->setAuthor(author);
939   
940   // add the geometry
941   XAO::BrepGeometry* geometry = (XAO::BrepGeometry*)XAO::Geometry::createGeometry(XAO::BREP);
942   TopoDS_Shape topoShape = shape->GetValue();
943   exportFunction->SetValue(topoShape);
944   XAO::BrepGeometry* brep = (XAO::BrepGeometry*)geometry;
945   brep->setTopoDS_Shape(topoShape);
946   
947   geometry->setName(shape->GetName().ToCString());
948   exportSubshapes(shape, geometry);
949   xaoObject->setGeometry(geometry);
950   
951   exportGroups(groupList, xaoObject, geometry);
952   exportFields(fieldList, xaoObject, geometry);
953   
954   // export the XAO to the file
955   xaoObject->exportXAO(fileName);
956   
957   // make a Python command
958   GEOM::TPythonDump pd(exportFunction);
959   pd << "exported = geompy.ExportXAO(" << shape;
960   
961   // list of groups
962   pd << ", [";
963   if (groupList.size() > 0)
964   {
965     std::list<Handle(GEOM_Object)>::iterator itGroup = groupList.begin();
966     pd << (*itGroup++);
967     while (itGroup != groupList.end())
968     {
969       pd << ", " << (*itGroup++);
970     }
971   }
972   
973   // list of fields
974   pd << "], [";
975   if (fieldList.size() > 0)
976   {
977     std::list<Handle(GEOM_Object)>::iterator itField = fieldList.begin();
978     pd << (*itField++);
979     while (itField != fieldList.end())
980     {
981       pd << ", " << (*itField++);
982     }
983   }
984   pd << "], ";
985   pd << author << ", \"" << fileName << "\")";
986   
987   SetErrorCode(OK);
988   delete xaoObject;
989   
990   return true;
991 }
992
993 void GEOMImpl_IInsertOperations::importSubShapes(XAO::Geometry* xaoGeometry,
994                                                  Handle(GEOM_Function) function, int shapeType, int dim,
995                                                  Handle(TColStd_HSequenceOfTransient)& subShapeList)
996 {
997   Handle(GEOM_Object) subShape;
998   Handle(GEOM_Function) aFunction;
999   Handle(TColStd_HArray1OfInteger) anArray;
1000   
1001   XAO::GeometricElementList::iterator elementIterator = xaoGeometry->begin((XAO::Dimension)dim);
1002   for (; elementIterator != xaoGeometry->end((XAO::Dimension)dim); elementIterator++)
1003   {
1004     XAO::GeometricElement element = elementIterator->second;
1005     if (!element.hasName())
1006       continue;
1007     
1008     std::string name = element.getName();
1009     std::string ref = element.getReference();
1010     int iref = XAO::XaoUtils::stringToInt(ref);
1011     
1012     anArray = new TColStd_HArray1OfInteger(1, 1);
1013     anArray->SetValue(1, iref);
1014     
1015     subShape = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1016     Handle(GEOM_Function) aFunction = subShape->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1017     if (aFunction.IsNull())
1018       return;
1019     
1020     subShape->SetName(name.c_str());
1021     subShape->SetType(shapeType);
1022     
1023     GEOM_ISubShape aSSI(aFunction);
1024     aSSI.SetMainShape(function);
1025     aSSI.SetIndices(anArray);
1026     
1027     //aFunction->SetValue(aValue);
1028     subShapeList->Append(subShape);
1029     
1030     // Put this subshape in the list of sub-shapes of theMainShape
1031     function->AddSubShapeReference(aFunction);
1032   }
1033 }
1034
1035 //=============================================================================
1036 /*!
1037  *  Import a shape from XAO format
1038  *  \param fileName The name of the file to import
1039  *  \param shape The imported shape
1040  *  \param subShapes The list of imported groups
1041  *  \param groups The list of imported groups
1042  *  \param fields The list of imported fields
1043  *  \return boolean indicating if import was succeful.
1044  */
1045 //=============================================================================
1046 bool GEOMImpl_IInsertOperations::ImportXAO(const char* fileName,
1047                                            Handle(GEOM_Object)& shape,
1048                                            Handle(TColStd_HSequenceOfTransient)& subShapes,
1049                                            Handle(TColStd_HSequenceOfTransient)& groups,
1050                                            Handle(TColStd_HSequenceOfTransient)& fields)
1051 {
1052   SetErrorCode(KO);
1053   
1054   if (fileName == NULL || groups.IsNull() || fields.IsNull())
1055     return false;
1056   
1057   // Read the XAO
1058   XAO::Xao* xaoObject = new XAO::Xao();
1059   try
1060   {
1061     xaoObject->importXAO(fileName);
1062   }
1063   catch (XAO::XAO_Exception& exc)
1064   {
1065     delete xaoObject;
1066     SetErrorCode(exc.what());
1067     return false;
1068   }
1069   
1070   XAO::Geometry* xaoGeometry = xaoObject->getGeometry();
1071   if (xaoGeometry == NULL)
1072   {
1073     delete xaoObject;
1074     SetErrorCode("Cannot import XAO: geometry format not supported.");
1075     return false;
1076   }
1077   
1078   // create the shape
1079   shape = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
1080   Handle(GEOM_Function) function = shape->AddFunction(GEOMImpl_XAODriver::GetID(), IMPORTEXPORT_EXPORTXAO);
1081   if (function.IsNull()) return false;
1082   if (function->GetDriverGUID() != GEOMImpl_XAODriver::GetID()) return false;
1083   
1084   // set the geometry
1085   if (xaoGeometry->getFormat() == XAO::BREP)
1086   {
1087     XAO::BrepGeometry* brep = (XAO::BrepGeometry*)xaoGeometry;
1088     TopoDS_Shape geomShape = brep->getTopoDS_Shape();
1089     function->SetValue(geomShape);
1090     shape->SetName(xaoGeometry->getName().c_str());
1091   }
1092   else
1093   {
1094     delete xaoObject;
1095     SetErrorCode("Cannot import XAO: geometry format not supported.");
1096     return false;
1097   }
1098   
1099   // create sub shapes with names
1100   importSubShapes(xaoGeometry, function, GEOM_POINT, XAO::VERTEX, subShapes);
1101   importSubShapes(xaoGeometry, function, GEOM_EDGE, XAO::EDGE, subShapes);
1102   importSubShapes(xaoGeometry, function, GEOM_FACE, XAO::FACE, subShapes);
1103   importSubShapes(xaoGeometry, function, GEOM_SOLID, XAO::SOLID, subShapes);
1104   
1105   // create groups
1106   int nbGroups = xaoObject->countGroups();
1107   for (int i = 0; i < nbGroups; ++i)
1108   {
1109     XAO::Group* xaoGroup = xaoObject->getGroup(i);
1110     
1111     // build an array with the indexes of the sub shapes
1112     int nbElt = xaoGroup->count();
1113     Handle(TColStd_HArray1OfInteger) array = new TColStd_HArray1OfInteger(1, nbElt);
1114     int j = 0;
1115     for (std::set<int>::iterator it = xaoGroup->begin(); it != xaoGroup->end(); ++it)
1116     {
1117       int index = (*it);
1118       std::string ref = xaoGeometry->getElementReference(xaoGroup->getDimension(), index);
1119       array->SetValue(++j, XAO::XaoUtils::stringToInt(ref));
1120     }
1121     
1122     // create the group with the array of sub shapes indexes
1123     Handle(GEOM_Object) group = GetEngine()->AddSubShape(shape, array);
1124     group->SetType(GEOM_GROUP);
1125     group->SetName(xaoGroup->getName().c_str());
1126     
1127     // Set a sub-shape type
1128     TDF_Label freeLabel = group->GetFreeLabel();
1129     TDataStd_Integer::Set(freeLabel, (Standard_Integer) getGroupDimension(xaoGroup));
1130     groups->Append(group);
1131     
1132     function = group->GetLastFunction();
1133   }
1134   
1135   // TODO: create the fields
1136   
1137   // make a Python command
1138   GEOM::TPythonDump pd(function);
1139   pd << "(imported, " << shape << ", ";
1140   
1141   // list of sub shapes
1142   pd << "[";
1143   int nbSubshapes = subShapes->Length();
1144   std::cout << "Nb SubShapes = " << nbSubshapes << std::endl;
1145   if (nbSubshapes > 0)
1146   {
1147     for (int i = 1; i <= nbSubshapes; i++)
1148     {
1149       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(subShapes->Value(i));
1150       pd << obj << ((i < nbSubshapes) ? ", " : "");
1151     }
1152   }
1153   pd << "], [";
1154   
1155   // list of groups
1156   if (nbGroups > 0)
1157   {
1158     for (int i = 1; i <= nbGroups; i++)
1159     {
1160       Handle(GEOM_Object) obj = Handle(GEOM_Object)::DownCast(groups->Value(i));
1161       pd << obj << ((i < nbGroups) ? ", " : "");
1162     }
1163   }
1164   
1165   pd << "], [";
1166   
1167   // list of fields
1168   pd << "]";
1169   pd << ") = geompy.ImportXAO(\"" << fileName << "\")";
1170   
1171   delete xaoObject;
1172   SetErrorCode(OK);
1173   
1174   return true;
1175 }