1 // Copyright (C) 2007-2010 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
23 #include <Standard_Stream.hxx>
25 #include <GEOMImpl_IInsertOperations.hxx>
27 #include "utilities.h"
29 #include <Utils_ExceptHandlers.hxx>
31 #include <TFunction_DriverTable.hxx>
32 #include <TFunction_Driver.hxx>
33 #include <TFunction_Logbook.hxx>
34 #include <TDF_Tool.hxx>
36 #include <GEOM_Function.hxx>
37 #include <GEOM_PythonDump.hxx>
39 #include <GEOMImpl_CopyDriver.hxx>
40 #include <GEOMImpl_ExportDriver.hxx>
41 #include <GEOMImpl_ImportDriver.hxx>
43 #include <GEOMImpl_ICopy.hxx>
44 #include <GEOMImpl_IImportExport.hxx>
46 #include <GEOMImpl_Types.hxx>
49 #include <TopoDS_Vertex.hxx>
50 #include <BRep_Tool.hxx>
52 #include <TDataStd_HArray1OfByte.hxx>
54 #include <Standard_Failure.hxx>
55 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
57 //=============================================================================
61 //=============================================================================
63 GEOMImpl_IInsertOperations::GEOMImpl_IInsertOperations(GEOM_Engine* theEngine, int theDocID)
64 : GEOM_IOperations(theEngine, theDocID)
66 MESSAGE("GEOMImpl_IInsertOperations::GEOMImpl_IInsertOperations");
69 //=============================================================================
73 //=============================================================================
75 GEOMImpl_IInsertOperations::~GEOMImpl_IInsertOperations()
77 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_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
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 an Export function
150 Handle(GEOM_Function) aFunction = theOriginal->AddFunction(GEOMImpl_ExportDriver::GetID(), EXPORT_SHAPE);
151 if (aFunction.IsNull()) return;
153 //Check if the function is set correctly
154 if (aFunction->GetDriverGUID() != GEOMImpl_ExportDriver::GetID()) return;
156 Handle(TCollection_HAsciiString) aHLibName;
157 if (!IsSupported(Standard_False, theFormatName, aHLibName)) {
160 TCollection_AsciiString aLibName = aHLibName->String();
163 GEOMImpl_IImportExport aCI (aFunction);
164 aCI.SetOriginal(aRefFunction);
165 aCI.SetFileName(theFileName);
166 aCI.SetFormatName(theFormatName);
167 aCI.SetPluginName(aLibName);
171 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
174 if (!GetSolver()->ComputeFunction(aFunction)) {
175 SetErrorCode("Not enough space on disk, or you haven't permissions to write this directory");
179 catch (Standard_Failure) {
180 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
181 SetErrorCode(aFail->GetMessageString());
185 //Make a Python command
186 GEOM::TPythonDump(aFunction) << "geompy.Export(" << theOriginal << ", \""
187 << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")";
192 //=============================================================================
196 //=============================================================================
197 Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import
198 (const TCollection_AsciiString& theFileName,
199 const TCollection_AsciiString& theFormatName)
203 if (theFileName.IsEmpty() || theFormatName.IsEmpty()) return NULL;
205 //Add a new result object
206 Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT);
208 //Add an Import function
209 Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_ImportDriver::GetID(), IMPORT_SHAPE);
210 if (aFunction.IsNull()) return result;
212 //Check if the function is set correctly
213 if (aFunction->GetDriverGUID() != GEOMImpl_ImportDriver::GetID()) return result;
215 Handle(TCollection_HAsciiString) aHLibName;
216 if (!IsSupported(Standard_True, theFormatName.SubString(1,4), aHLibName)) {
219 TCollection_AsciiString aLibName = aHLibName->String();
222 GEOMImpl_IImportExport aCI (aFunction);
223 aCI.SetFileName(theFileName);
224 aCI.SetFormatName(theFormatName);
225 aCI.SetPluginName(aLibName);
226 //cout<<"IIO: theFormatName = "<<theFormatName.ToCString()<<endl;
230 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
233 if (!GetSolver()->ComputeFunction(aFunction)) {
234 SetErrorCode("Import driver failed");
238 catch (Standard_Failure) {
239 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
240 SetErrorCode(aFail->GetMessageString());
244 //Make a Python command
245 if( theFormatName != "IGES_UNIT" ) {
246 GEOM::TPythonDump(aFunction) << result << " = geompy.Import(\""
247 << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")";
252 if( theFormatName == "IGES_UNIT" ) {
253 TopoDS_Shape S = aFunction->GetValue();
254 TopoDS_Vertex V = TopoDS::Vertex(S);
255 gp_Pnt P = BRep_Tool::Pnt(V);
256 double scale = P.X();
257 TCollection_AsciiString aUnitName = "UNIT_M";
258 if( fabs(scale-0.01) < 1.e-6 )
259 aUnitName = "UNIT_CM";
260 else if( fabs(scale-0.001) < 1.e-6 )
261 aUnitName = "UNIT_MM";
262 //cout<<"IIO: aUnitName = "<<aUnitName.ToCString()<<endl;
263 SetErrorCode(aUnitName);
269 //=============================================================================
273 //=============================================================================
274 Standard_Boolean GEOMImpl_IInsertOperations::ImportTranslators
275 (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
276 Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
278 if (theFormats.IsNull())
279 theFormats = new TColStd_HSequenceOfAsciiString;
283 if (thePatterns.IsNull())
284 thePatterns = new TColStd_HSequenceOfAsciiString;
286 thePatterns->Clear();
288 if (!InitResMgr()) return Standard_False;
290 // Read Import formats list from install directory
291 if (myResMgr->Find("Import")) {
292 TCollection_AsciiString aFormats (myResMgr->Value("Import"));
293 TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
295 for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
296 theFormats->Append(aToken);
300 // Read Import formats from user directory
301 if (myResMgrUser->Find("Import")) {
302 TCollection_AsciiString aFormats (myResMgrUser->Value("Import"));
303 TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
305 for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
306 int aLenFormats = theFormats->Length();
307 bool isFound = false;
308 for(int aInd=1;aInd<=aLenFormats;aInd++){
309 if( theFormats->Value(aInd) == aToken){
315 theFormats->Append(aToken);
319 // Read Patterns for each supported format
320 int j = 1, len = theFormats->Length();
321 for (; j <= len; j++) {
322 TCollection_AsciiString aKey, aPattern;
323 aKey = theFormats->Value(j) + ".ImportPattern";
324 if (myResMgr->Find(aKey.ToCString()))
325 aPattern = myResMgr->Value(aKey.ToCString());
326 else if(myResMgrUser->Find(aKey.ToCString()))
327 aPattern = myResMgrUser->Value(aKey.ToCString());
329 aKey = theFormats->Value(j) + ".Pattern";
330 if (myResMgr->Find(aKey.ToCString()))
331 aPattern = myResMgr->Value(aKey.ToCString());
332 else if(myResMgrUser->Find(aKey.ToCString()))
333 aPattern = myResMgrUser->Value(aKey.ToCString());
335 aPattern = theFormats->Value(j);
336 aPattern += " Files ( *.* )";
339 thePatterns->Append(aPattern);
342 return (!theFormats->IsEmpty());
345 //=============================================================================
349 //=============================================================================
350 Standard_Boolean GEOMImpl_IInsertOperations::ExportTranslators
351 (Handle(TColStd_HSequenceOfAsciiString)& theFormats,
352 Handle(TColStd_HSequenceOfAsciiString)& thePatterns)
354 if (theFormats.IsNull())
355 theFormats = new TColStd_HSequenceOfAsciiString;
359 if (thePatterns.IsNull())
360 thePatterns = new TColStd_HSequenceOfAsciiString;
362 thePatterns->Clear();
364 if (!InitResMgr()) return Standard_False;
366 // Read Export formats list from install directory
367 if (myResMgr->Find("Export")) {
368 TCollection_AsciiString aFormats (myResMgr->Value("Export"));
369 TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
371 for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
372 theFormats->Append(aToken);
376 // Read Export formats list from user directory
377 if (myResMgrUser->Find("Export")) {
378 TCollection_AsciiString aFormats (myResMgrUser->Value("Export"));
379 TCollection_AsciiString aToken = aFormats.Token("| \t", 1);
381 for (; !aToken.IsEmpty(); aToken = aFormats.Token("| \t", ++i)) {
382 int aLenFormats = theFormats->Length();
383 bool isFound = false;
384 for(int aInd=1;aInd<=aLenFormats;aInd++){
385 if( theFormats->Value(aInd) == aToken){
391 theFormats->Append(aToken);
395 // Read Patterns for each supported format
396 int j = 1, len = theFormats->Length();
397 for (; j <= len; j++) {
398 TCollection_AsciiString aKey, aPattern;
399 aKey = theFormats->Value(j) + ".ExportPattern";
400 if (myResMgr->Find(aKey.ToCString()))
401 aPattern = myResMgr->Value(aKey.ToCString());
402 else if (myResMgrUser->Find(aKey.ToCString()))
403 aPattern = myResMgrUser->Value(aKey.ToCString());
405 aKey = theFormats->Value(j) + ".Pattern";
406 if (myResMgr->Find(aKey.ToCString()))
407 aPattern = myResMgr->Value(aKey.ToCString());
408 else if (myResMgrUser->Find(aKey.ToCString()))
409 aPattern = myResMgrUser->Value(aKey.ToCString());
411 aPattern = theFormats->Value(j);
412 aPattern += " Files ( *.* )";
415 thePatterns->Append(aPattern);
418 return (!theFormats->IsEmpty());
421 //=============================================================================
425 //=============================================================================
426 Standard_Boolean GEOMImpl_IInsertOperations::IsSupported
427 (const Standard_Boolean isImport,
428 const TCollection_AsciiString& theFormat,
429 Handle(TCollection_HAsciiString)& theLibName)
431 if (!InitResMgr()) return Standard_False;
433 // Import/Export mode
434 TCollection_AsciiString aMode;
435 //Standard_CString aMode;
436 if (isImport) aMode = "Import";
437 else aMode = "Export";
439 // Read supported formats for the certain mode from install directory
440 if (myResMgr->Find(aMode.ToCString())) {
441 TCollection_AsciiString aFormats (myResMgr->Value(aMode.ToCString()));
442 if (aFormats.Search(theFormat) > -1) {
443 // Read library name for the supported format
444 TCollection_AsciiString aKey (theFormat);
447 if (myResMgr->Find(aKey.ToCString())) {
448 TCollection_AsciiString aLibName (myResMgr->Value(aKey.ToCString()));
454 theLibName = new TCollection_HAsciiString (aLibName);
455 return Standard_True;
460 // Read supported formats for the certain mode from user directory
461 if (myResMgrUser->Find(aMode.ToCString())) {
462 TCollection_AsciiString aFormats (myResMgrUser->Value(aMode.ToCString()));
463 if (aFormats.Search(theFormat) > -1) {
464 // Read library name for the supported format
465 TCollection_AsciiString aKey (theFormat);
468 if (myResMgrUser->Find(aKey.ToCString())) {
469 TCollection_AsciiString aLibName (myResMgrUser->Value(aKey.ToCString()));
470 theLibName = new TCollection_HAsciiString (aLibName);
471 return Standard_True;
476 return Standard_False;
479 //=============================================================================
483 //=============================================================================
484 Standard_Boolean GEOMImpl_IInsertOperations::InitResMgr()
486 bool isResourceFound = false;
487 bool isResourceFoundUser = false;
488 TCollection_AsciiString aUserResDir,aResDir;
490 if (myResMgr.IsNull()) {
491 // Initialize the Resource Manager
492 TCollection_AsciiString aNull;
493 aResDir = TCollection_AsciiString(getenv("GEOM_ROOT_DIR"));
495 aResDir += "\\share\\salome\\resources\\geom";
497 aResDir += "/share/salome/resources/geom";
500 myResMgr = new Resource_Manager ("ImportExport", aResDir, aNull, Standard_False);
502 isResourceFound = true;
503 if (!myResMgr->Find("Import") && !myResMgr->Find("Export")) {
504 // instead of complains in Resource_Manager
505 isResourceFound = false;
506 INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString());
509 isResourceFound = true;
511 if (myResMgrUser.IsNull()) {
512 char * dir = getenv("GEOM_ENGINE_RESOURCES_DIR");
513 TCollection_AsciiString aNull;
520 aUserResDir = getenv("HOME");
522 aUserResDir += "\\.salome\\resources";
524 aUserResDir += "/.salome/resources";
528 myResMgrUser = new Resource_Manager ("ImportExport", aNull, aUserResDir, Standard_False);
530 isResourceFoundUser = true;
532 if (!myResMgrUser->Find("Import") && !myResMgrUser->Find("Export")) {
533 // instead of complains in Resource_Manager
534 isResourceFoundUser = false;
538 isResourceFoundUser = true;
540 if(!isResourceFound && !isResourceFoundUser){
541 INFOS("No valid file \"ImportExport\" found in " << aResDir.ToCString());
542 INFOS("No valid file \"ImportExport\" found in " << aUserResDir.ToCString() );
545 return ( myResMgr->Find("Import") || myResMgr->Find("Export") ||
546 myResMgrUser->Find("Import") || myResMgrUser->Find("Export"));
549 int GEOMImpl_IInsertOperations::LoadTexture(const TCollection_AsciiString& theTextureFile)
553 if (theTextureFile.IsEmpty()) return 0;
555 Handle(TDataStd_HArray1OfByte) aTexture;
557 FILE* fp = fopen(theTextureFile.ToCString(), "r");
560 std::list<std::string> lines;
564 if ((fgets(buffer, 4096, fp)) == NULL) break;
565 int aLen = strlen(buffer);
566 if (buffer[aLen-1] == '\n') buffer[aLen-1] = '\0';
567 lines.push_back(buffer);
568 maxlen = std::max(maxlen, (int)strlen(buffer));
573 int lenbytes = maxlen/8;
574 if (maxlen%8) lenbytes++;
576 if (lenbytes == 0 || lines.empty())
579 std::list<unsigned char> bytedata;
580 std::list<std::string>::const_iterator it;
581 for (it = lines.begin(); it != lines.end(); ++it) {
582 std::string line = *it;
583 int lenline = (line.size()/8 + (line.size()%8 ? 1 : 0)) * 8;
584 for (int i = 0; i < lenline/8; i++) {
585 unsigned char byte = 0;
586 for (int j = 0; j < 8; j++)
587 byte = (byte << 1) + ( i*8+j < line.size() && line[i*8+j] != '0' ? 1 : 0 );
588 bytedata.push_back(byte);
590 for (int i = lenline/8; i < lenbytes; i++)
591 bytedata.push_back((unsigned char)0);
594 if (bytedata.empty() || bytedata.size() != lines.size()*lenbytes)
597 aTexture = new TDataStd_HArray1OfByte(1, lines.size()*lenbytes);
598 std::list<unsigned char>::iterator bdit;
600 for (i = 1, bdit = bytedata.begin(); bdit != bytedata.end(); ++bdit, ++i)
601 aTexture->SetValue(i, (Standard_Byte)(*bdit));
603 int aTextureId = GetEngine()->addTexture(GetDocID(), lenbytes*8, lines.size(), aTexture, theTextureFile);
604 if (aTextureId > 0) SetErrorCode(OK);
608 int GEOMImpl_IInsertOperations::AddTexture(int theWidth, int theHeight,
609 const Handle(TDataStd_HArray1OfByte)& theTexture)
612 int aTextureId = GetEngine()->addTexture(GetDocID(), theWidth, theHeight, theTexture);
613 if (aTextureId > 0) SetErrorCode(OK);
617 Handle(TDataStd_HArray1OfByte) GEOMImpl_IInsertOperations::GetTexture(int theTextureId,
618 int& theWidth, int& theHeight)
622 Handle(TDataStd_HArray1OfByte) aTexture;
623 theWidth = theHeight = 0;
624 TCollection_AsciiString aFileName;
626 if (theTextureId <= 0)
629 aTexture = GetEngine()->getTexture(GetDocID(), theTextureId, theWidth, theHeight, aFileName);
631 if (theWidth > 0 && theHeight > 0 && aTexture->Length() > 0) SetErrorCode(OK);
636 std::list<int> GEOMImpl_IInsertOperations::GetAllTextures()
639 std::list<int> id_list = GetEngine()->getAllTextures(GetDocID());