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