1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include <Standard_Stream.hxx>
24 #include <GEOMImpl_IInsertOperations.hxx>
26 #include <GEOMImpl_CopyDriver.hxx>
27 #include <GEOMImpl_ExportDriver.hxx>
28 #include <GEOMImpl_ImportDriver.hxx>
29 #include <GEOMImpl_ICopy.hxx>
30 #include <GEOMImpl_IImportExport.hxx>
31 #include <GEOMImpl_Types.hxx>
33 #include <GEOM_Function.hxx>
34 #include <GEOM_PythonDump.hxx>
36 #include <Basics_OCCTVersion.hxx>
38 #include "utilities.h"
40 #include <Utils_ExceptHandlers.hxx>
42 #include <TFunction_DriverTable.hxx>
43 #include <TFunction_Driver.hxx>
44 #include <TFunction_Logbook.hxx>
45 #include <TDF_Tool.hxx>
48 #include <TopoDS_Vertex.hxx>
49 #include <BRep_Tool.hxx>
52 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
53 #include <TColStd_HArray1OfByte.hxx>
55 #include <TDataStd_HArray1OfByte.hxx>
58 #include <Standard_Failure.hxx>
59 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
61 //=============================================================================
65 //=============================================================================
66 GEOMImpl_IInsertOperations::GEOMImpl_IInsertOperations(GEOM_Engine* theEngine, int theDocID)
67 : GEOM_IOperations(theEngine, theDocID)
69 MESSAGE("GEOMImpl_IInsertOperations::GEOMImpl_IInsertOperations");
72 //=============================================================================
76 //=============================================================================
77 GEOMImpl_IInsertOperations::~GEOMImpl_IInsertOperations()
79 MESSAGE("GEOMImpl_IInsertOperations::~GEOMImpl_IInsertOperations");
82 //=============================================================================
86 //=============================================================================
87 Handle(GEOM_Object) GEOMImpl_IInsertOperations::MakeCopy (Handle(GEOM_Object) theOriginal)
91 if (theOriginal.IsNull()) return NULL;
93 //Add a new Copy object
94 Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
96 //Add a Copy function for creation a copy object
97 Handle(GEOM_Function) aFunction = aCopy->AddFunction(GEOMImpl_CopyDriver::GetID(), COPY_WITH_REF);
99 //Check if the function is set correctly
100 if(aFunction->GetDriverGUID() != GEOMImpl_CopyDriver::GetID()) return NULL;
102 GEOMImpl_ICopy aCI(aFunction);
104 Handle(GEOM_Function) aRefFunction = theOriginal->GetLastFunction();
105 if (aRefFunction.IsNull()) return NULL;
107 aCI.SetOriginal(aRefFunction);
109 //Compute the Copy value
111 #if OCC_VERSION_LARGE > 0x06010000
114 if (!GetSolver()->ComputeFunction(aFunction)) {
115 SetErrorCode("Copy driver failed");
119 catch (Standard_Failure) {
120 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
121 SetErrorCode(aFail->GetMessageString());
125 //Make a Python command
126 GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeCopy(" << theOriginal << ")";
132 //=============================================================================
136 //=============================================================================
137 void GEOMImpl_IInsertOperations::Export
138 (const Handle(GEOM_Object) theOriginal,
139 const TCollection_AsciiString& theFileName,
140 const TCollection_AsciiString& theFormatName)
144 if (theOriginal.IsNull()) return;
146 Handle(GEOM_Function) aRefFunction = theOriginal->GetLastFunction();
147 if (aRefFunction.IsNull()) return; //There is no function which creates an object to be exported
149 //Add a new result object
150 Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
152 //Add an Export function
153 Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_ExportDriver::GetID(), EXPORT_SHAPE);
154 if (aFunction.IsNull()) return;
156 //Check if the function is set correctly
157 if (aFunction->GetDriverGUID() != GEOMImpl_ExportDriver::GetID()) return;
159 Handle(TCollection_HAsciiString) aHLibName;
160 if (!IsSupported(Standard_False, theFormatName, aHLibName)) {
163 TCollection_AsciiString aLibName = aHLibName->String();
166 GEOMImpl_IImportExport aCI (aFunction);
167 aCI.SetOriginal(aRefFunction);
168 aCI.SetFileName(theFileName);
169 aCI.SetFormatName(theFormatName);
170 aCI.SetPluginName(aLibName);
174 #if OCC_VERSION_LARGE > 0x06010000
177 if (!GetSolver()->ComputeFunction(aFunction)) {
178 SetErrorCode("Not enough space on disk, or you haven't permissions to write this directory");
182 catch (Standard_Failure) {
183 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
184 SetErrorCode(aFail->GetMessageString());
188 //Make a Python command
189 GEOM::TPythonDump(aFunction) << "geompy.Export(" << theOriginal << ", \""
190 << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")";
195 //=============================================================================
199 //=============================================================================
200 Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import
201 (const TCollection_AsciiString& theFileName,
202 const TCollection_AsciiString& theFormatName)
206 if (theFileName.IsEmpty() || theFormatName.IsEmpty()) return NULL;
208 //Add a new result object
209 Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
211 //Add an Import function
212 Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_ImportDriver::GetID(), IMPORT_SHAPE);
213 if (aFunction.IsNull()) return result;
215 //Check if the function is set correctly
216 if (aFunction->GetDriverGUID() != GEOMImpl_ImportDriver::GetID()) return result;
218 Handle(TCollection_HAsciiString) aHLibName;
219 if (!IsSupported(Standard_True, theFormatName.SubString(1,4), aHLibName)) {
222 TCollection_AsciiString aLibName = aHLibName->String();
225 GEOMImpl_IImportExport aCI (aFunction);
226 aCI.SetFileName(theFileName);
227 aCI.SetFormatName(theFormatName);
228 aCI.SetPluginName(aLibName);
232 #if OCC_VERSION_LARGE > 0x06010000
235 if (!GetSolver()->ComputeFunction(aFunction)) {
236 SetErrorCode("Import driver failed");
240 catch (Standard_Failure) {
241 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
242 SetErrorCode(aFail->GetMessageString());
246 //Make a Python command
247 if( theFormatName != "IGES_UNIT" ) {
248 GEOM::TPythonDump(aFunction) << result << " = geompy.ImportFile(\""
249 << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")";
255 if (theFormatName == "IGES_UNIT") {
256 TopoDS_Shape S = aFunction->GetValue();
257 TopoDS_Vertex V = TopoDS::Vertex(S);
258 gp_Pnt P = BRep_Tool::Pnt(V);
259 double scale = P.X();
260 TCollection_AsciiString aUnitName = "UNIT_M";
261 if( fabs(scale-0.01) < 1.e-6 )
262 aUnitName = "UNIT_CM";
263 else if( fabs(scale-0.001) < 1.e-6 )
264 aUnitName = "UNIT_MM";
265 //cout<<"IIO: aUnitName = "<<aUnitName.ToCString()<<endl;
266 SetErrorCode(aUnitName);
273 //=============================================================================
277 //=============================================================================
278 TCollection_AsciiString GEOMImpl_IInsertOperations::ReadValue
279 (const TCollection_AsciiString& theFileName,
280 const TCollection_AsciiString& theFormatName,
281 const TCollection_AsciiString& theParameterName)
285 TCollection_AsciiString aValue, anError;
287 if (theFileName.IsEmpty() || theFormatName.IsEmpty() || theParameterName.IsEmpty()) return aValue;
289 Handle(TCollection_HAsciiString) aHLibName;
290 if (!IsSupported(Standard_True, theFormatName.SubString(1,4), aHLibName)) {
293 TCollection_AsciiString aLibName = aHLibName->String();
295 aValue = GEOMImpl_ImportDriver::ReadValue(theFileName, aLibName, theParameterName, anError);
296 if (anError.IsEmpty())
299 SetErrorCode(anError.ToCString());
304 //=============================================================================
308 //=============================================================================
309 Standard_Boolean GEOMImpl_IInsertOperations::ImportTranslators
310 (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
311 Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
313 if (theFormats.IsNull())
314 theFormats = new TColStd_HSequenceOfAsciiString;
318 if (thePatterns.IsNull())
319 thePatterns = new TColStd_HSequenceOfAsciiString;
321 thePatterns->Clear();
323 if (!InitResMgr()) return Standard_False;
325 // Read Import formats list from install directory
326 if (myResMgr->Find("Import")) {
327 TCollection_AsciiString aFormats (myResMgr->Value("Import"));
328 TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
330 for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
331 theFormats->Append(aToken);
335 // Read Import formats from user directory
336 if (myResMgrUser->Find("Import")) {
337 TCollection_AsciiString aFormats (myResMgrUser->Value("Import"));
338 TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
340 for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
341 int aLenFormats = theFormats->Length();
342 bool isFound = false;
343 for(int aInd=1;aInd<=aLenFormats;aInd++){
344 if( theFormats->Value(aInd) == aToken){
350 theFormats->Append(aToken);
354 // Read Patterns for each supported format
355 int j = 1, len = theFormats->Length();
356 for (; j <= len; j++) {
357 TCollection_AsciiString aKey, aPattern;
358 aKey = theFormats->Value(j) + ".ImportPattern";
359 if (myResMgr->Find(aKey.ToCString()))
360 aPattern = myResMgr->Value(aKey.ToCString());
361 else if(myResMgrUser->Find(aKey.ToCString()))
362 aPattern = myResMgrUser->Value(aKey.ToCString());
364 aKey = theFormats->Value(j) + ".Pattern";
365 if (myResMgr->Find(aKey.ToCString()))
366 aPattern = myResMgr->Value(aKey.ToCString());
367 else if(myResMgrUser->Find(aKey.ToCString()))
368 aPattern = myResMgrUser->Value(aKey.ToCString());
370 aPattern = theFormats->Value(j);
371 aPattern += " Files ( *.* )";
374 thePatterns->Append(aPattern);
377 return (!theFormats->IsEmpty());
380 //=============================================================================
384 //=============================================================================
385 Standard_Boolean GEOMImpl_IInsertOperations::ExportTranslators
386 (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
387 Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
389 if (theFormats.IsNull())
390 theFormats = new TColStd_HSequenceOfAsciiString;
394 if (thePatterns.IsNull())
395 thePatterns = new TColStd_HSequenceOfAsciiString;
397 thePatterns->Clear();
399 if (!InitResMgr()) return Standard_False;
401 // Read Export formats list from install directory
402 if (myResMgr->Find("Export")) {
403 TCollection_AsciiString aFormats (myResMgr->Value("Export"));
404 TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
406 for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
407 theFormats->Append(aToken);
411 // Read Export formats list from user directory
412 if (myResMgrUser->Find("Export")) {
413 TCollection_AsciiString aFormats (myResMgrUser->Value("Export"));
414 TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
416 for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
417 int aLenFormats = theFormats->Length();
418 bool isFound = false;
419 for(int aInd=1;aInd<=aLenFormats;aInd++){
420 if( theFormats->Value(aInd) == aToken){
426 theFormats->Append(aToken);
430 // Read Patterns for each supported format
431 int j = 1, len = theFormats->Length();
432 for (; j <= len; j++) {
433 TCollection_AsciiString aKey, aPattern;
434 aKey = theFormats->Value(j) + ".ExportPattern";
435 if (myResMgr->Find(aKey.ToCString()))
436 aPattern = myResMgr->Value(aKey.ToCString());
437 else if (myResMgrUser->Find(aKey.ToCString()))
438 aPattern = myResMgrUser->Value(aKey.ToCString());
440 aKey = theFormats->Value(j) + ".Pattern";
441 if (myResMgr->Find(aKey.ToCString()))
442 aPattern = myResMgr->Value(aKey.ToCString());
443 else if (myResMgrUser->Find(aKey.ToCString()))
444 aPattern = myResMgrUser->Value(aKey.ToCString());
446 aPattern = theFormats->Value(j);
447 aPattern += " Files ( *.* )";
450 thePatterns->Append(aPattern);
453 return (!theFormats->IsEmpty());
456 //=============================================================================
460 //=============================================================================
461 Standard_Boolean GEOMImpl_IInsertOperations::IsSupported
462 (const Standard_Boolean isImport,
463 const TCollection_AsciiString& theFormat,
464 Handle(TCollection_HAsciiString)& theLibName)
466 if (!InitResMgr()) return Standard_False;
468 // Import/Export mode
469 TCollection_AsciiString aMode;
470 //Standard_CString aMode;
471 if (isImport) aMode = "Import";
472 else aMode = "Export";
474 // Read supported formats for the certain mode from install directory
475 if (myResMgr->Find(aMode.ToCString())) {
476 TCollection_AsciiString aFormats (myResMgr->Value(aMode.ToCString()));
477 if (aFormats.Search(theFormat) > -1) {
478 // Read library name for the supported format
479 TCollection_AsciiString aKey (theFormat);
482 if (myResMgr->Find(aKey.ToCString())) {
483 TCollection_AsciiString aLibName (myResMgr->Value(aKey.ToCString()));
489 theLibName = new TCollection_HAsciiString (aLibName);
490 return Standard_True;
495 // Read supported formats for the certain mode from user directory
496 if (myResMgrUser->Find(aMode.ToCString())) {
497 TCollection_AsciiString aFormats (myResMgrUser->Value(aMode.ToCString()));
498 if (aFormats.Search(theFormat) > -1) {
499 // Read library name for the supported format
500 TCollection_AsciiString aKey (theFormat);
503 if (myResMgrUser->Find(aKey.ToCString())) {
504 TCollection_AsciiString aLibName (myResMgrUser->Value(aKey.ToCString()));
505 theLibName = new TCollection_HAsciiString (aLibName);
506 return Standard_True;
511 return Standard_False;
514 //=============================================================================
518 //=============================================================================
519 Standard_Boolean GEOMImpl_IInsertOperations::InitResMgr()
521 bool isResourceFound = false;
522 bool isResourceFoundUser = false;
523 TCollection_AsciiString aUserResDir,aResDir;
525 if (myResMgr.IsNull()) {
526 // Initialize the Resource Manager
527 TCollection_AsciiString aNull;
528 aResDir = TCollection_AsciiString(getenv("GEOM_ROOT_DIR"));
530 aResDir += "\\share\\salome\\resources\\geom";
532 aResDir += "/share/salome/resources/geom";
535 myResMgr = new Resource_Manager ("ImportExport", aResDir, aNull, Standard_False);
537 isResourceFound = true;
538 if (!myResMgr->Find("Import") && !myResMgr->Find("Export")) {
539 // instead of complains in Resource_Manager
540 isResourceFound = false;
541 INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString());
544 isResourceFound = true;
546 if (myResMgrUser.IsNull()) {
547 char * dir = getenv("GEOM_ENGINE_RESOURCES_DIR");
548 TCollection_AsciiString aNull;
555 aUserResDir = getenv("HOME");
557 aUserResDir += "\\.salome\\resources";
559 aUserResDir += "/.salome/resources";
563 myResMgrUser = new Resource_Manager ("ImportExport", aNull, aUserResDir, Standard_False);
565 isResourceFoundUser = true;
567 if (!myResMgrUser->Find("Import") && !myResMgrUser->Find("Export")) {
568 // instead of complains in Resource_Manager
569 isResourceFoundUser = false;
573 isResourceFoundUser = true;
575 if(!isResourceFound && !isResourceFoundUser){
576 INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString());
577 INFOS("No valid file \"ImportExport\" found in " << aUserResDir.ToCString() );
580 return ( myResMgr->Find("Import") || myResMgr->Find("Export") ||
581 myResMgrUser->Find("Import") || myResMgrUser->Find("Export"));
584 int GEOMImpl_IInsertOperations::LoadTexture(const TCollection_AsciiString& theTextureFile)
588 if (theTextureFile.IsEmpty()) return 0;
590 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
591 Handle(TColStd_HArray1OfByte) aTexture;
593 Handle(TDataStd_HArray1OfByte) aTexture;
596 FILE* fp = fopen(theTextureFile.ToCString(), "r");
599 std::list<std::string> lines;
603 if ((fgets(buffer, 4096, fp)) == NULL) break;
604 int aLen = strlen(buffer);
605 if (buffer[aLen-1] == '\n') buffer[aLen-1] = '\0';
606 lines.push_back(buffer);
607 maxlen = std::max(maxlen, (int)strlen(buffer));
612 int lenbytes = maxlen/8;
613 if (maxlen%8) lenbytes++;
615 if (lenbytes == 0 || lines.empty())
618 std::list<unsigned char> bytedata;
619 std::list<std::string>::const_iterator it;
620 for (it = lines.begin(); it != lines.end(); ++it) {
621 std::string line = *it;
622 int lenline = (line.size()/8 + (line.size()%8 ? 1 : 0)) * 8;
623 for (int i = 0; i < lenline/8; i++) {
624 unsigned char byte = 0;
625 for (int j = 0; j < 8; j++)
626 byte = (byte << 1) + ( i*8+j < line.size() && line[i*8+j] != '0' ? 1 : 0 );
627 bytedata.push_back(byte);
629 for (int i = lenline/8; i < lenbytes; i++)
630 bytedata.push_back((unsigned char)0);
633 if (bytedata.empty() || bytedata.size() != lines.size()*lenbytes)
636 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
637 aTexture = new TColStd_HArray1OfByte (1, lines.size()*lenbytes);
639 aTexture = new TDataStd_HArray1OfByte (1, lines.size()*lenbytes);
642 std::list<unsigned char>::iterator bdit;
644 for (i = 1, bdit = bytedata.begin(); bdit != bytedata.end(); ++bdit, ++i)
645 aTexture->SetValue(i, (Standard_Byte)(*bdit));
647 int aTextureId = GetEngine()->addTexture(GetDocID(), lenbytes*8, lines.size(), aTexture, theTextureFile);
648 if (aTextureId > 0) SetErrorCode(OK);
652 int GEOMImpl_IInsertOperations::AddTexture(int theWidth, int theHeight,
653 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
654 const Handle(TColStd_HArray1OfByte)& theTexture)
656 const Handle(TDataStd_HArray1OfByte)& theTexture)
660 int aTextureId = GetEngine()->addTexture(GetDocID(), theWidth, theHeight, theTexture);
661 if (aTextureId > 0) SetErrorCode(OK);
665 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
666 Handle(TColStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
668 Handle(TDataStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
670 int& theWidth, int& theHeight)
674 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
675 Handle(TColStd_HArray1OfByte) aTexture;
677 Handle(TDataStd_HArray1OfByte) aTexture;
680 theWidth = theHeight = 0;
681 TCollection_AsciiString aFileName;
683 if (theTextureId <= 0)
686 aTexture = GetEngine()->getTexture(GetDocID(), theTextureId, theWidth, theHeight, aFileName);
688 if (theWidth > 0 && theHeight > 0 && aTexture->Length() > 0) SetErrorCode(OK);
693 std::list<int> GEOMImpl_IInsertOperations::GetAllTextures()
696 std::list<int> id_list = GetEngine()->getAllTextures(GetDocID());