X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FGEOM%2FGEOM_Engine.cxx;h=90faf13feca75632a95730280e45cb12ef2e8fb5;hb=8af6f2a74ecd53c356e81e728d91af4d865b8261;hp=32d3e97c284ab764724d4ac44f6fb2496ef9e01c;hpb=8180539548a5038e52445454e88c1a170ee64e56;p=modules%2Fgeom.git diff --git a/src/GEOM/GEOM_Engine.cxx b/src/GEOM/GEOM_Engine.cxx index 32d3e97c2..90faf13fe 100644 --- a/src/GEOM/GEOM_Engine.cxx +++ b/src/GEOM/GEOM_Engine.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -20,20 +20,19 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifdef WNT +#ifdef WIN32 #pragma warning( disable:4786 ) #endif #include "GEOM_Engine.hxx" -#include "GEOM_Solver.hxx" +#include "GEOM_Field.hxx" #include "GEOM_Function.hxx" #include "GEOM_ISubShape.hxx" -#include "GEOM_SubShapeDriver.hxx" -#include "GEOM_DataMapIteratorOfDataMapOfAsciiStringTransient.hxx" #include "GEOM_PythonDump.hxx" - -#include +#include "GEOM_Solver.hxx" +#include "GEOM_SubShapeDriver.hxx" +#include "Sketcher_Profile.hxx" #include "utilities.h" @@ -61,16 +60,14 @@ #include #include -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 -#include #include -#else -#include -#include -#endif #include +#include +#include +#include + #include #include @@ -89,14 +86,23 @@ static int MYDEBUG = 0; static int MYDEBUG = 0; #endif +// VSR 29/08/2017: 0023327, 0023428: eliminate unnecessary lines in Python dump +// Next macro, when defined, causes appearing of SubShapeAllIDs(), SubShapeAllSortedIDs(), GetSameIDs() +// and other such commands in Python dump. +// See also GEOMImpl_IShapesOperations.cxx. +// --------------------------------------- +// #define DUMP_SUBSHAPE_IDS +// --------------------------------------- + typedef std::map< TCollection_AsciiString, TCollection_AsciiString > TSting2StringMap; typedef std::map< TCollection_AsciiString, TObjectData > TSting2ObjDataMap; typedef std::map< TCollection_AsciiString, TObjectData* > TSting2ObjDataPtrMap; +typedef std::map< int, std::list < int > > TIntToListIntMap; static GEOM_Engine* TheEngine = NULL; -static TCollection_AsciiString BuildIDFromObject(Handle(GEOM_Object)& theObject) +static TCollection_AsciiString BuildIDFromObject(Handle(GEOM_BaseObject)& theObject) { TCollection_AsciiString anID(theObject->GetDocID()), anEntry; TDF_Tool::Entry(theObject->GetEntry(), anEntry); @@ -104,7 +110,7 @@ static TCollection_AsciiString BuildIDFromObject(Handle(GEOM_Object)& theObject) return anID; } -static TCollection_AsciiString BuildID(Standard_Integer theDocID, char* theEntry) +static TCollection_AsciiString BuildID(Standard_Integer theDocID, const char* theEntry) { TCollection_AsciiString anID(theDocID); anID+=(TCollection_AsciiString("_")+theEntry); @@ -127,6 +133,11 @@ bool ProcessFunction(Handle(GEOM_Function)& theFunction, std::set& theIgnoreObjs, bool& theIsDumpCollected); +static int GetTag(const TCollection_AsciiString &theEntry); + +static void FillMapOfRef(const Handle(GEOM_Function) &theFunction, + TIntToListIntMap &theRefMap); + void ReplaceVariables(TCollection_AsciiString& theCommand, const TVariablesList& theVariables); @@ -152,30 +163,36 @@ void PublishObject (TObjectData& theObjectData, std::map< int, TCollection_AsciiString >& theEntryToCmdMap, std::set& theMapOfPublished); -namespace +static TCollection_AsciiString GetPublishCommands + (const int theTag, + const std::map< int, TCollection_AsciiString > &theEntryToCmdMap, + const TIntToListIntMap &theMapRefs, + std::set< int > &thePublished); + +void Prettify(TCollection_AsciiString& theScript); + +//================================================================================ +/*! + * \brief Fix up the name of python variable + */ +//================================================================================ + +void GEOM_Engine::healPyName( TCollection_AsciiString& pyName, + const TCollection_AsciiString& anEntry, + Resource_DataMapOfAsciiStringAsciiString& aNameToEntry) { - //================================================================================ - /*! - * \brief Fix up the name of python variable - */ - //================================================================================ - - void healPyName( TCollection_AsciiString& pyName, - const TCollection_AsciiString& anEntry, - Resource_DataMapOfAsciiStringAsciiString& aNameToEntry) - { - const TCollection_AsciiString allowedChars - ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_"); + const TCollection_AsciiString allowedChars + ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_"); - if ( pyName.IsIntegerValue() ) { // pyName must not start with a digit - pyName.Insert( 1, 'a' ); - } - int p, p2=1; // replace not allowed chars - while ((p = pyName.FirstLocationNotInSet(allowedChars, p2, pyName.Length()))) { - pyName.SetValue(p, '_'); - p2=p; - } - if ( aNameToEntry.IsBound( pyName ) && anEntry != aNameToEntry( pyName )) + if ( pyName.IsIntegerValue() ) { // pyName must not start with a digit + pyName.Insert( 1, 'a' ); + } + int p, p2=1; // replace not allowed chars + while ((p = pyName.FirstLocationNotInSet(allowedChars, p2, pyName.Length()))) { + pyName.SetValue(p, '_'); + p2=p; + } + if ( aNameToEntry.IsBound( pyName ) && anEntry != aNameToEntry( pyName )) { // diff objects have same name - make a new name by appending a digit TCollection_AsciiString aName2; Standard_Integer i = 0; @@ -184,7 +201,6 @@ namespace } while ( aNameToEntry.IsBound( aName2 ) && anEntry != aNameToEntry( aName2 )); pyName = aName2; } - } } //======================================================================= @@ -221,7 +237,10 @@ GEOM_Engine::GEOM_Engine() TFunction_DriverTable::Get()->AddDriver(GEOM_Object::GetSubShapeID(), new GEOM_SubShapeDriver()); _OCAFApp = new GEOM_Application(); - _UndoLimit = 10; + _OCAFApp->DefineFormat("SALOME_GEOM", "GEOM Document Version 1.0", "sgd", + new StdDrivers_DocumentRetrievalDriver, 0); + BinDrivers::DefineFormat(_OCAFApp); + _UndoLimit = 0; } /*! @@ -238,11 +257,7 @@ GEOM_Engine::~GEOM_Engine() RemoveObject(*objit); //Close all documents not closed -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 TColStd_DataMapIteratorOfDataMapOfIntegerTransient anItr (_mapIDDocument); -#else - Interface_DataMapIteratorOfDataMapOfIntegerTransient anItr (_mapIDDocument); -#endif for (; anItr.More(); anItr.Next()) { Close(anItr.Key()); @@ -264,7 +279,7 @@ Handle(TDocStd_Document) GEOM_Engine::GetDocument(int theDocID, bool force) aDoc = Handle(TDocStd_Document)::DownCast(_mapIDDocument(theDocID)); } else if (force) { - _OCAFApp->NewDocument("SALOME_GEOM", aDoc); + _OCAFApp->NewDocument("BinOcaf", aDoc); aDoc->SetUndoLimit(_UndoLimit); _mapIDDocument.Bind(theDocID, aDoc); TDataStd_Integer::Set(aDoc->Main(), theDocID); @@ -280,11 +295,7 @@ Handle(TDocStd_Document) GEOM_Engine::GetDocument(int theDocID, bool force) int GEOM_Engine::GetDocID(Handle(TDocStd_Document) theDocument) { if (theDocument.IsNull()) return -1; -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 TColStd_DataMapIteratorOfDataMapOfIntegerTransient anItr (_mapIDDocument); -#else - Interface_DataMapIteratorOfDataMapOfIntegerTransient anItr (_mapIDDocument); -#endif for (; anItr.More(); anItr.Next()) if (anItr.Value() == theDocument) return anItr.Key(); @@ -296,22 +307,30 @@ int GEOM_Engine::GetDocID(Handle(TDocStd_Document) theDocument) * GetObject */ //============================================================================= -Handle(GEOM_Object) GEOM_Engine::GetObject(int theDocID, char* theEntry, bool force) + +Handle(GEOM_BaseObject) GEOM_Engine::GetObject(int theDocID, const char* theEntry, bool force) { - Handle(GEOM_Object) anObject; + Handle(GEOM_BaseObject) anObject; TCollection_AsciiString anID = BuildID(theDocID, theEntry); if (_objects.IsBound(anID)) { - anObject = Handle(GEOM_Object)::DownCast(_objects(anID)); + anObject = Handle(GEOM_BaseObject)::DownCast(_objects(anID)); } else if (force) { Handle(TDocStd_Document) aDoc = GetDocument(theDocID, force); if ( !aDoc.IsNull()) { TDF_Label aLabel; TDF_Tool::Label(aDoc->Main().Data(), theEntry, aLabel, Standard_True); - anObject = new GEOM_Object(aLabel); - _objects.Bind(anID, anObject); + if ( !aLabel.IsNull() ) { + int objType = GEOM_BaseObject::GetType( aLabel ); + switch ( objType ) { + case GEOM_FIELD_OBJTYPE: anObject = new GEOM_Field (aLabel); break; + case GEOM_FIELD_STEP_OBJTYPE: anObject = new GEOM_FieldStep(aLabel); break; + default: anObject = new GEOM_Object (aLabel); + } + _objects.Bind(anID, anObject); + } } } @@ -320,10 +339,11 @@ Handle(GEOM_Object) GEOM_Engine::GetObject(int theDocID, char* theEntry, bool fo //============================================================================= /*! - * AddObject + * AddBaseObject */ //============================================================================= -Handle(GEOM_Object) GEOM_Engine::AddObject(int theDocID, int theType) + +Handle(GEOM_BaseObject) GEOM_Engine::AddBaseObject(int theDocID, int theType) { Handle(TDocStd_Document) aDoc = GetDocument(theDocID); Handle(TDataStd_TreeNode) aRoot = TDataStd_TreeNode::Set(aDoc->Main()); @@ -345,7 +365,12 @@ Handle(GEOM_Object) GEOM_Engine::AddObject(int theDocID, int theType) aChild = TDF_TagSource::NewChild(aDoc->Main()); } - Handle(GEOM_Object) anObject = new GEOM_Object(aChild, theType); + Handle(GEOM_BaseObject) anObject; + switch ( theType ) { + case GEOM_FIELD_OBJTYPE: anObject = new GEOM_Field (aChild, theType); break; + case GEOM_FIELD_STEP_OBJTYPE: anObject = new GEOM_FieldStep(aChild, theType); break; + default: anObject = new GEOM_Object (aChild, theType); + } //Put an object in the map of created objects TCollection_AsciiString anID = BuildIDFromObject(anObject); @@ -355,12 +380,24 @@ Handle(GEOM_Object) GEOM_Engine::AddObject(int theDocID, int theType) return anObject; } +//================================================================================ +/*! + * \brief Adds a new object of the type theType in the OCAF document + */ +//================================================================================ + +Handle(GEOM_Object) GEOM_Engine::AddObject(int theDocID, int theType) +{ + return Handle(GEOM_Object)::DownCast( AddBaseObject(theDocID, theType) ); +} + //============================================================================= /*! * AddSubShape */ //============================================================================= -Handle(GEOM_Object) GEOM_Engine::AddSubShape(Handle(GEOM_Object) theMainShape, + +Handle(GEOM_Object) GEOM_Engine::AddSubShape(Handle(GEOM_Object) theMainShape, Handle(TColStd_HArray1OfInteger) theIndices, bool isStandaloneOperation) { @@ -396,18 +433,15 @@ Handle(GEOM_Object) GEOM_Engine::AddSubShape(Handle(GEOM_Object) theMainShape, aSSI.SetIndices(theIndices); try { -#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; -#endif GEOM_Solver aSolver (GEOM_Engine::GetEngine()); if (!aSolver.ComputeFunction(aFunction)) { MESSAGE("GEOM_Engine::AddSubShape Error: Can't build a sub shape"); return NULL; } } - catch (Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - MESSAGE("GEOM_Engine::AddSubShape Error: " << aFail->GetMessageString()); + catch (Standard_Failure& aFail) { + MESSAGE("GEOM_Engine::AddSubShape Error: " << aFail.GetMessageString()); return NULL; } @@ -440,7 +474,7 @@ Handle(GEOM_Object) GEOM_Engine::AddSubShape(Handle(GEOM_Object) theMainShape, * RemoveObject */ //============================================================================= -bool GEOM_Engine::RemoveObject(Handle(GEOM_Object) theObject) +bool GEOM_Engine::RemoveObject(Handle(GEOM_BaseObject)& theObject) { if (theObject.IsNull()) return false; @@ -450,10 +484,16 @@ bool GEOM_Engine::RemoveObject(Handle(GEOM_Object) theObject) //Remove an object from the map of available objects TCollection_AsciiString anID = BuildIDFromObject(theObject); - if (_objects.IsBound(anID)) _objects.UnBind(anID); + if (_objects.IsBound(anID)) { + Handle(GEOM_BaseObject) anObject = Handle(GEOM_BaseObject)::DownCast(_objects(anID)); + if ( anObject != theObject ) + anObject->_label = anObject->_label.Root(); + _objects.UnBind(anID); + } // If sub-shape, remove it from the list of sub-shapes of its main shape - if (!theObject->IsMainShape()) { + Handle(GEOM_Object) aGO = Handle(GEOM_Object)::DownCast( theObject ); + if ( !aGO.IsNull() && !aGO->IsMainShape()) { Handle(GEOM_Function) aFunction = theObject->GetFunction(1); GEOM_ISubShape aSSI (aFunction); Handle(GEOM_Function) aMainShape = aSSI.GetMainShape(); @@ -475,7 +515,15 @@ bool GEOM_Engine::RemoveObject(Handle(GEOM_Object) theObject) // Remember the label to reuse it then std::list& aFreeLabels = _freeLabels[aDocID]; - aFreeLabels.push_back(aLabel); + if ( aFreeLabels.empty() || aFreeLabels.back() != aLabel ) + aFreeLabels.push_back(aLabel); + + // we can't explicitely delete theObject. At least prevent its functioning + // as an alive object when aLabel is reused for a new object + theObject->_label = aLabel.Root(); + theObject->_ior.Clear(); + theObject->_parameters.Clear(); + theObject->_docID = -1; theObject.Nullify(); @@ -507,7 +555,7 @@ void GEOM_Engine::Redo(int theDocID) * Save */ //============================================================================= -bool GEOM_Engine::Save(int theDocID, char* theFileName) +bool GEOM_Engine::Save(int theDocID, const char* theFileName) { if(!_mapIDDocument.IsBound(theDocID)) return false; Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast(_mapIDDocument(theDocID)); @@ -522,17 +570,18 @@ bool GEOM_Engine::Save(int theDocID, char* theFileName) * Load */ //============================================================================= -bool GEOM_Engine::Load(int theDocID, char* theFileName) +bool GEOM_Engine::Load(int theDocID, const char* theFileName) { Handle(TDocStd_Document) aDoc; -#if OCC_VERSION_LARGE > 0x06050100 // For OCCT6.5.2 and higher if (_OCAFApp->Open(theFileName, aDoc) != PCDM_RS_OK) { -#else - if (_OCAFApp->Open(theFileName, aDoc) != CDF_RS_OK) { -#endif return false; } + // Replace old document format by the new one. + if (aDoc->StorageFormat().IsEqual("SALOME_GEOM")) { + aDoc->ChangeStorageFormat("BinOcaf"); + } + aDoc->SetUndoLimit(_UndoLimit); if(_mapIDDocument.IsBound(theDocID)) _mapIDDocument.UnBind(theDocID); @@ -602,13 +651,13 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, } aScript = "import GEOM\n"; - aScript += "import geompy\n"; + aScript += "from salome.geom import geomBuilder\n"; aScript += "import math\n"; aScript += "import SALOMEDS\n\n"; if( isMultiFile ) aScript += "def RebuildData(theStudy):"; - aScript += "\n\tgeompy.init_geom(theStudy)\n"; + aScript += "\n\tgeompy = geomBuilder.New(theStudy)\n"; AddTextures(theDocID, aScript); @@ -628,7 +677,7 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, TDF_Label L; TDF_Tool::Label( aDoc->GetData(), data._entry, L ); if ( L.IsNull() ) continue; - Handle(GEOM_Object) obj = GEOM_Object::GetObject( L ); + Handle(GEOM_BaseObject) obj = GEOM_BaseObject::GetObject( L ); // fill maps if ( !obj.IsNull() ) { TSting2ObjDataMap::iterator ent2Data = @@ -655,6 +704,7 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, // Mantis issue 0020768 Standard_Integer objectCounter = 0; Resource_DataMapOfAsciiStringAsciiString aNameToEntry; + TIntToListIntMap aRefMap; if (aDoc->Main().FindAttribute(GEOM_Function::GetFunctionTreeID(), aRoot)) { TDataStd_ChildNodeIterator Itr(aRoot); @@ -683,6 +733,10 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, continue; // aCurScript is already at the end of aFuncScript aFuncScript += aCurScript; } + + // Fill the map of references. + FillMapOfRef(aFunction, aRefMap); + if (isDumpCollected ) { // Replace entries by the names ReplaceEntriesByNames( aFuncScript, aEntry2ObjData, isPublished, @@ -698,9 +752,16 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, aNameToEntry, anEntryToCmdMap, anIgnoreObjMap ); } // add publishing commands to the script + std::set< int > aPublished; std::map< int, TCollection_AsciiString >::iterator anEntryToCmd = anEntryToCmdMap.begin(); - for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd ) - aFuncScript += anEntryToCmd->second; + + for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd ) { + const TCollection_AsciiString aPublishCmds = + GetPublishCommands(anEntryToCmd->first, anEntryToCmdMap, + aRefMap, aPublished); + + aFuncScript += aPublishCmds; + } // PTv, 0020001 add result objects from RestoreGivenSubShapes into ignore list, // because they will be published during command execution @@ -753,9 +814,16 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, aNameToEntry, anEntryToCmdMap, anIgnoreObjMap ); } // add publishing commands to the script + std::set< int > aPublished; std::map< int, TCollection_AsciiString >::iterator anEntryToCmd = anEntryToCmdMap.begin(); - for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd ) - aScript += anEntryToCmd->second; + + for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd ) { + const TCollection_AsciiString aPublishCmds = + GetPublishCommands(anEntryToCmd->first, anEntryToCmdMap, + aRefMap, aPublished); + + aScript += aPublishCmds; + } } //RNV: issue 16219: EDF PAL 469: "RemoveFromStudy" Function @@ -771,7 +839,7 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, { TObjectData* data = aStEntry2ObjDataPtrIt->second; if ( data->_unpublished && !data->_pyName.IsEmpty() ) { - aScript += unpublishCmd + data->_pyName + ")"; + aScript += unpublishCmd + data->_pyName + ")"; } } @@ -798,6 +866,11 @@ TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, aScript.Insert( posToInsertGlobalVars, globalVars ); } + // VSR 29/08/2017: 0023327, 0023428: eliminate unnecessary lines in Python dump +#ifndef DUMP_SUBSHAPE_IDS + Prettify(aScript); +#endif + return aScript; } @@ -838,11 +911,7 @@ Handle(TColStd_HSequenceOfAsciiString) GEOM_Engine::GetAllDumpNames() const #define TEXTURE_LABEL_DATA 5 int GEOM_Engine::addTexture(int theDocID, int theWidth, int theHeight, -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 const Handle(TColStd_HArray1OfByte)& theTexture, -#else - const Handle(TDataStd_HArray1OfByte)& theTexture, -#endif const TCollection_AsciiString& theFileName) { Handle(TDocStd_Document) aDoc = GetDocument(theDocID); @@ -887,19 +956,11 @@ int GEOM_Engine::addTexture(int theDocID, int theWidth, int theHeight, return aTextureID; } -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 Handle(TColStd_HArray1OfByte) GEOM_Engine::getTexture(int theDocID, int theTextureID, -#else -Handle(TDataStd_HArray1OfByte) GEOM_Engine::getTexture(int theDocID, int theTextureID, -#endif int& theWidth, int& theHeight, TCollection_AsciiString& theFileName) { -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 Handle(TColStd_HArray1OfByte) anArray; -#else - Handle(TDataStd_HArray1OfByte) anArray; -#endif theWidth = theHeight = 0; Handle(TDocStd_Document) aDoc = GetDocument(theDocID); @@ -955,10 +1016,122 @@ std::list GEOM_Engine::getAllTextures(int theDocID) return id_list; } +void GEOM_Engine::DocumentModified(const int theDocId, const bool isModified) +{ + if (isModified) _mapModifiedDocs.Add(theDocId); + else _mapModifiedDocs.Remove(theDocId); +} + +bool GEOM_Engine::DocumentModified(const int theDocId) +{ + return _mapModifiedDocs.Contains(theDocId); +} + //=========================================================================== // Internal functions //=========================================================================== +//============================================================================= +/*! + * MakeCommandfor3DSketcher: Make new command for 3DSketcher + */ +//============================================================================= +TCollection_AsciiString MakeCommandfor3DSketcher (const TCollection_AsciiString& theDescr ) +{ + TCollection_AsciiString aNewDescr; + int i = 1; + TCollection_AsciiString aSubStr = theDescr.Token("\n\t", i); + for (; !aSubStr.IsEmpty(); aSubStr = theDescr.Token("\n\t", i)) { + if (aSubStr.Search( "Make3DSketcherCommand" ) != -1) { + TCollection_AsciiString aResult = aSubStr.Token(" ", 1); + // "3DSketcher:CMD[:CMD[:CMD...]]" + TCollection_AsciiString aCommand = aSubStr.Token("\"", 2); + + // Split the command string to separate CMDs + int icmd = 2; + TColStd_SequenceOfAsciiString aSequence; + if (aCommand.Length()) { + TCollection_AsciiString aToken = aCommand.Token(":", icmd); + while (aToken.Length() > 0) { + aSequence.Append(aToken); + aToken = aCommand.Token(":", ++icmd); + } + } + + if (aSequence.Length() > 0) { + if (i > 1) + aNewDescr += "\n\t"; + + aNewDescr += "\nsk = geompy.Sketcher3D()"; + int nbCMDs = aSequence.Length(); + for (icmd = 1; icmd <= nbCMDs; icmd++) { + aNewDescr += "\n\t"; + + TCollection_AsciiString aCMD = aSequence.Value(icmd); + + // Split the CMD into string values + TColStd_SequenceOfAsciiString aStrVals; + int ival = 1; + TCollection_AsciiString aToken = aCMD.Token(" ", ival); + while (aToken.Length() > 0) { + aStrVals.Append(aToken); + aToken = aCMD.Token(" ", ++ival); + } + + TCollection_AsciiString aCMDpref = aStrVals.Value(1); + if (aCMDpref == "TT") { + aNewDescr += "sk.addPointsAbsolute("; + aNewDescr += aStrVals.Value(2) + ", " + aStrVals.Value(3) + ", " + aStrVals.Value(4) + ")"; + } + else if (aCMDpref == "T") { + aNewDescr += "sk.addPointsRelative("; + aNewDescr += aStrVals.Value(2) + ", " + aStrVals.Value(3) + ", " + aStrVals.Value(4) + ")"; + } + else if (aCMDpref == "WW") { + aNewDescr += "sk.close()"; + } + else if (aCMDpref.Value(1) == 'O'){ + TCollection_AsciiString aCMDtrunc = aStrVals.Value(1); + aCMDtrunc.Trunc(3); + if (aCMDpref.Value(4) == 'C') + aNewDescr += "sk.addPointRadiusAngleH"; + else + aNewDescr += "sk.addPointRadiusAngles"; + if (aCMDpref.Value(5) == 'A') + aNewDescr += "Absolute("; + else + aNewDescr += "Relative("; + aNewDescr += aStrVals.Value(4) + ", " + + aStrVals.Value(2) + ", " + aStrVals.Value(3) + ", " + "\""+aCMDtrunc+"\"" + ")"; + } + } + aNewDescr += "\n\t"; + aNewDescr += aResult + " = sk.wire()"; + } + } // Make3DSketcherCommand + else if (aSubStr.Search( "Make3DSketcher" ) != -1) { + TCollection_AsciiString aResult = aSubStr.Token(" ", 1); + TCollection_AsciiString aCommand = aSubStr.Token("[", 2); + aCommand = aCommand.Token("]", 1); + if (i > 1) + aNewDescr += "\n\t"; + aNewDescr += "\nsk = geompy.Sketcher3D()"; + aNewDescr += "\n\t"; + aNewDescr += "sk.addPointsAbsolute("; + aNewDescr += aCommand + ")"; + aNewDescr += "\n\t"; + aNewDescr += aResult + " = sk.wire()"; + } + else { + if (i > 1) + aNewDescr += "\n\t"; + aNewDescr += aSubStr; + } + i++; + } + return aNewDescr; +} + //============================================================================= /*! * ProcessFunction: Dump function description into script @@ -1048,91 +1221,13 @@ bool ProcessFunction(Handle(GEOM_Function)& theFunction, ReplaceVariables(aDescr,theVariables); //Process sketcher functions, replacing string command by calls to Sketcher interface + if ( ( aDescr.Search( "MakeSketcherOnPlane" ) != -1 ) || ( aDescr.Search( "MakeSketcher" ) != -1 ) ) { + Sketcher_Profile aProfile( aDescr.ToCString()); + // Make new command for SketcherOnPlane and for Sketcher + aDescr = aProfile.GetDump(); + } if (aDescr.Search( "Make3DSketcher" ) != -1) { - TCollection_AsciiString aNewDescr; - int i = 1; - TCollection_AsciiString aSubStr = aDescr.Token("\n\t", i); - for (; !aSubStr.IsEmpty(); aSubStr = aDescr.Token("\n\t", i)) { - if (aSubStr.Search( "Make3DSketcherCommand" ) != -1) { - TCollection_AsciiString aResult = aSubStr.Token(" ", 1); - // "3DSketcher:CMD[:CMD[:CMD...]]" - TCollection_AsciiString aCommand = aSubStr.Token("\"", 2); - - // Split the command string to separate CMDs - int icmd = 2; - TColStd_SequenceOfAsciiString aSequence; - if (aCommand.Length()) { - TCollection_AsciiString aToken = aCommand.Token(":", icmd); - while (aToken.Length() > 0) { - aSequence.Append(aToken); - aToken = aCommand.Token(":", ++icmd); - } - } - - if (aSequence.Length() > 0) { - if (i > 1) - aNewDescr += "\n\t"; - - aNewDescr += "sk = geompy.Sketcher3D()"; - int nbCMDs = aSequence.Length(); - for (icmd = 1; icmd <= nbCMDs; icmd++) { - aNewDescr += "\n\t"; - - TCollection_AsciiString aCMD = aSequence.Value(icmd); - - // Split the CMD into string values - TColStd_SequenceOfAsciiString aStrVals; - int ival = 1; - TCollection_AsciiString aToken = aCMD.Token(" ", ival); - while (aToken.Length() > 0) { - aStrVals.Append(aToken); - aToken = aCMD.Token(" ", ++ival); - } - - TCollection_AsciiString aCMDpref = aStrVals.Value(1); - if (aCMDpref == "TT") { - aNewDescr += "sk.addPointsAbsolute("; - aNewDescr += aStrVals.Value(2) + ", " + aStrVals.Value(3) + ", " + aStrVals.Value(4) + ")"; - } - else if (aCMDpref == "T") { - aNewDescr += "sk.addPointsRelative("; - aNewDescr += aStrVals.Value(2) + ", " + aStrVals.Value(3) + ", " + aStrVals.Value(4) + ")"; - } - else if (aCMDpref == "WW") { - aNewDescr += "sk.close()"; - } - else { - aNewDescr += "sk.addPointAnglesLength(\""; - aNewDescr += aCMDpref + "\", " + - aStrVals.Value(2) + ", " + aStrVals.Value(3) + ", " + aStrVals.Value(4) + ")"; - } - } - aNewDescr += "\n\t"; - aNewDescr += aResult + " = sk.wire()"; - } - } // Make3DSketcherCommand - else if (aSubStr.Search( "Make3DSketcher" ) != -1) { - TCollection_AsciiString aResult = aSubStr.Token(" ", 1); - TCollection_AsciiString aCommand = aSubStr.Token("[", 2); - aCommand = aCommand.Token("]", 1); - if (i > 1) - aNewDescr += "\n\t"; - aNewDescr += "sk = geompy.Sketcher3D()"; - aNewDescr += "\n\t"; - aNewDescr += "sk.addPointsAbsolute("; - aNewDescr += aCommand + ")"; - aNewDescr += "\n\t"; - aNewDescr += aResult + " = sk.wire()"; - } - else { - if (i > 1) - aNewDescr += "\n\t"; - aNewDescr += aSubStr; - } - - i++; - } - aDescr = aNewDescr; + aDescr = MakeCommandfor3DSketcher ( aDescr ); } if ( theIsDumpCollected ) { @@ -1156,6 +1251,67 @@ bool ProcessFunction(Handle(GEOM_Function)& theFunction, return true; } +//============================================================================= +/*! + * GetTag: Returns the tag from entry + */ +//============================================================================= +int GetTag(const TCollection_AsciiString &theEntry) +{ + const int aGeomObjDepth = 3; + const int aTag = theEntry.Token(":", aGeomObjDepth).IntegerValue(); + + return aTag; +} + +//============================================================================= +/*! + * FillMapOfRef: Fill the map of references + */ +//============================================================================= +void FillMapOfRef(const Handle(GEOM_Function) &theFunction, + TIntToListIntMap &theRefMap) +{ + TDF_LabelSequence aSeq; + TCollection_AsciiString anObjEntry; + int anObjTag; + + TDF_Tool::Entry(theFunction->GetOwnerEntry(), anObjEntry); + anObjTag = GetTag(anObjEntry); + theFunction->GetDependency(aSeq); + + const Standard_Integer aLen = aSeq.Length(); + Standard_Integer i; + + for (i = 1; i <= aLen; i++) { + TDF_Label aRefLabel = aSeq.Value(i); + Handle(TDF_Reference) aRef; + + if (aRefLabel.FindAttribute(TDF_Reference::GetID(), aRef)) { + if (!aRef.IsNull() && !aRef->Get().IsNull()) { + Handle(TDataStd_TreeNode) aT; + + if (TDataStd_TreeNode::Find(aRef->Get(), aT)) { + TDF_Label aDepLabel = aT->Label(); + Handle(GEOM_Function) aRefFunct = GEOM_Function::GetFunction(aDepLabel); + + if (!aRefFunct.IsNull()) { + // Get entry of the referenced object. + TDF_Tool::Entry(aRefFunct->GetOwnerEntry(), anObjEntry); + + const int aRefTag = GetTag(anObjEntry); + + if (anObjTag != aRefTag) { + // Avoid making references for operations without copy. + theRefMap[anObjTag].push_back(aRefTag); + } + } + } + } + } + } +} + //============================================================================= /*! * FindEntries: Returns a sequence of start/end positions of entries in the string @@ -1372,8 +1528,8 @@ void ReplaceVariables(TCollection_AsciiString& theCommand, if(MYDEBUG) cout<<"aParamIndex: "<Length(), aStart = 1, aScriptLength = theScript.Length(); @@ -1483,7 +1640,7 @@ void ReplaceEntriesByNames (TCollection_AsciiString& theScript, if ( data._pyName.IsEmpty() ) { // encounted for the 1st time if ( !data._name.IsEmpty() ) { // published object data._pyName = data._name; - healPyName( data._pyName, anEntry, aNameToEntry); + engine->healPyName( data._pyName, anEntry, aNameToEntry); } else { do { @@ -1558,16 +1715,16 @@ void AddObjectColors (int theDocID, case Aspect_TOM_POINT: aCommand += "GEOM.MT_POINT"; break; case Aspect_TOM_PLUS: aCommand += "GEOM.MT_PLUS"; break; case Aspect_TOM_STAR: aCommand += "GEOM.MT_STAR"; break; - case Aspect_TOM_O: aCommand += "GEOM.MT_O"; break; case Aspect_TOM_X: aCommand += "GEOM.MT_X"; break; + case Aspect_TOM_O: aCommand += "GEOM.MT_O"; break; case Aspect_TOM_O_POINT: aCommand += "GEOM.MT_O_POINT"; break; case Aspect_TOM_O_PLUS: aCommand += "GEOM.MT_O_PLUS"; break; case Aspect_TOM_O_STAR: aCommand += "GEOM.MT_O_STAR"; break; case Aspect_TOM_O_X: aCommand += "GEOM.MT_O_X"; break; - case Aspect_TOM_BALL: aCommand += "GEOM.MT_BALL"; break; case Aspect_TOM_RING1: aCommand += "GEOM.MT_RING1"; break; case Aspect_TOM_RING2: aCommand += "GEOM.MT_RING2"; break; case Aspect_TOM_RING3: aCommand += "GEOM.MT_RING3"; break; + case Aspect_TOM_BALL: aCommand += "GEOM.MT_BALL"; break; default: aCommand += "GEOM.MT_NONE"; break; // just for completeness, should not get here } aCommand += ", "; @@ -1604,11 +1761,7 @@ void AddObjectColors (int theDocID, } } -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 static TCollection_AsciiString pack_data (const Handle(TColStd_HArray1OfByte)& aData) -#else -static TCollection_AsciiString pack_data (const Handle(TDataStd_HArray1OfByte)& aData) -#endif { TCollection_AsciiString stream; if (!aData.IsNull()) { @@ -1636,11 +1789,7 @@ void AddTextures (int theDocID, TCollection_AsciiString& theScript) if (*it <= 0) continue; Standard_Integer aWidth, aHeight; TCollection_AsciiString aFileName; -#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 Handle(TColStd_HArray1OfByte) aTexture = -#else - Handle(TDataStd_HArray1OfByte) aTexture = -#endif engine->getTexture(theDocID, *it, aWidth, aHeight, aFileName); if (aWidth > 0 && aHeight > 0 && !aTexture.IsNull() && aTexture->Length() > 0 ) { TCollection_AsciiString aCommand = "\n\t"; @@ -1675,6 +1824,7 @@ void PublishObject (TObjectData& theObjectData, std::map< int, TCollection_AsciiString >& theEntryToCmdMap, std::set< TCollection_AsciiString>& theIgnoreMap) { + GEOM_Engine* engine = GEOM_Engine::GetEngine(); if ( theObjectData._studyEntry.IsEmpty() ) return; // was not published if ( theIgnoreMap.count( theObjectData._entry ) ) @@ -1691,8 +1841,6 @@ void PublishObject (TObjectData& theObjectData, if ( stEntry2DataPtr != theStEntry2ObjDataPtr.end() ) aFatherData = stEntry2DataPtr->second; - const int geomObjDepth = 3; - // treat multiply published object if ( theObjectData._pyName.IsEmpty() ) { @@ -1700,14 +1848,14 @@ void PublishObject (TObjectData& theObjectData, if ( data0._pyName.IsEmpty() ) return; // something wrong theObjectData._pyName = theObjectData._name; - healPyName( theObjectData._pyName, theObjectData._entry, theNameToEntry); + engine->healPyName( theObjectData._pyName, theObjectData._entry, theNameToEntry); TCollection_AsciiString aCreationCommand("\n\t"); aCreationCommand += theObjectData._pyName + " = " + data0._pyName; // store aCreationCommand before publishing commands - int tag = theObjectData._entry.Token( ":", geomObjDepth ).IntegerValue(); - theEntryToCmdMap.insert( std::make_pair( tag + 2*theEntry2ObjData.size(), aCreationCommand )); + int tag = GetTag(theObjectData._entry); + theEntryToCmdMap.insert( std::make_pair( tag + -2*theEntry2ObjData.size(), aCreationCommand )); } // make a command @@ -1721,12 +1869,94 @@ void PublishObject (TObjectData& theObjectData, aCommand += theObjectData._pyName + ", '" + theObjectData._name + "' )"; // bind a command to the study entry - int tag = theObjectData._entry.Token( ":", geomObjDepth ).IntegerValue(); + int tag = GetTag(theObjectData._entry); theEntryToCmdMap.insert( std::make_pair( tag, aCommand )); theObjectData._studyEntry.Clear(); // not to publish any more } +//================================================================================ +/*! + * \brief Returns the string of publishing commands. Take into account that + * references should be published prior to the objects refer to them. + */ +//================================================================================ +TCollection_AsciiString GetPublishCommands + (const int theTag, + const std::map< int, TCollection_AsciiString > &theEntryToCmdMap, + const TIntToListIntMap &theMapRefs, + std::set< int > &thePublished) +{ + TCollection_AsciiString aResult; + + if (!thePublished.count(theTag)) { + // This object is not published yet. + std::map< int, TCollection_AsciiString >::const_iterator anIt = + theEntryToCmdMap.find(theTag); + + if (anIt != theEntryToCmdMap.end()) { + // There is a pubish cmd. + TIntToListIntMap::const_iterator aRefIt = theMapRefs.find(theTag); + + if (aRefIt != theMapRefs.end()) { + // Recursively publish all references. + std::list< int >::const_iterator aRefTagIt = aRefIt->second.begin(); + + for(; aRefTagIt != aRefIt->second.end(); ++aRefTagIt) { + const TCollection_AsciiString aRefCmd = GetPublishCommands + (*aRefTagIt, theEntryToCmdMap, theMapRefs, thePublished); + + aResult += aRefCmd; + } + } + + // Add the object command. + aResult += anIt->second; + } + + thePublished.insert(theTag); + } + + return aResult; +} + +void Prettify(TCollection_AsciiString& theScript) +{ + TCollection_AsciiString output; + static std::list ToRemove; + if (ToRemove.empty()) { + ToRemove.push_back("geompy.SubShapeAllIDs"); + ToRemove.push_back("geompy.SubShapeAllSortedCentresIDs"); + ToRemove.push_back("geompy.SubShapeAllSortedIDs"); + ToRemove.push_back("geompy.GetFreeFacesIDs"); + ToRemove.push_back("geompy.GetShapesOnBoxIDs"); + ToRemove.push_back("geompy.GetShapesOnShapeIDs"); + ToRemove.push_back("geompy.GetShapesOnPlaneIDs"); + ToRemove.push_back("geompy.GetShapesOnPlaneWithLocationIDs"); + ToRemove.push_back("geompy.GetShapesOnCylinderIDs"); + ToRemove.push_back("geompy.GetShapesOnCylinderWithLocationIDs"); + ToRemove.push_back("geompy.GetShapesOnSphereIDs"); + ToRemove.push_back("geompy.GetShapesOnQuadrangleIDs"); + ToRemove.push_back("geompy.GetSameIDs"); + } + + int start = 1; + while (start <= theScript.Length()) { + int end = theScript.Location("\n", start, theScript.Length()); + if (end == -1) end = theScript.Length(); + TCollection_AsciiString line = theScript.SubString(start, end); + bool found = false; + for (std::list::const_iterator it = ToRemove.begin(); it != ToRemove.end() && !found; ++it) + found = line.Search( *it ) != -1; + if (!found) + output += line; + start = end + 1; + } + theScript = output; + + //OK @@@@@@@@@@@@@@@@@@@@@@@@@@@ +} + //================================================================================ /*! * \brief Constructor