X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOM%2FGEOM_Engine.cxx;h=705f9c0e6660c2555c5724f84fddd0eb7be7ef64;hb=732211808796539fcf1de34e06038e7fb015ece9;hp=46726dceae50e4fe1aa259f96269528c3c775f30;hpb=0213ec66495d08807c5d4e2e98cd15cfb994d154;p=modules%2Fgeom.git diff --git a/src/GEOM/GEOM_Engine.cxx b/src/GEOM/GEOM_Engine.cxx index 46726dcea..705f9c0e6 100644 --- a/src/GEOM/GEOM_Engine.cxx +++ b/src/GEOM/GEOM_Engine.cxx @@ -5,13 +5,13 @@ #include "GEOM_ISubShape.hxx" #include "GEOM_SubShapeDriver.hxx" #include "GEOM_DataMapIteratorOfDataMapOfAsciiStringTransient.hxx" +#include "GEOM_PythonDump.hxx" #include "utilities.h" -#include - #include #include +#include #include #include #include @@ -23,6 +23,14 @@ #include #include #include +#include +#include + +#include +#include + +#include +#include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC @@ -50,6 +58,12 @@ static Standard_Integer ExtractDocID(TCollection_AsciiString& theID) return aDocID.IntegerValue(); } +void ProcessFunction(Handle(GEOM_Function)& theFunction, + TCollection_AsciiString& theScript, + TColStd_MapOfTransient& theProcessed); + +Handle(TColStd_HSequenceOfInteger) FindEntries(TCollection_AsciiString& theString); + //============================================================================= /*! * GetEngine @@ -157,7 +171,9 @@ Handle(GEOM_Object) GEOM_Engine::AddObject(int theDocID, int theType) * AddSubShape */ //============================================================================= -Handle(GEOM_Object) GEOM_Engine::AddSubShape(Handle(GEOM_Object) theMainShape, Handle(TColStd_HArray1OfInteger) theIndices) +Handle(GEOM_Object) GEOM_Engine::AddSubShape(Handle(GEOM_Object) theMainShape, + Handle(TColStd_HArray1OfInteger) theIndices, + bool isStandaloneOperation) { if(theMainShape.IsNull() || theIndices.IsNull()) return NULL; @@ -192,19 +208,18 @@ Handle(GEOM_Object) GEOM_Engine::AddSubShape(Handle(GEOM_Object) theMainShape, H if(_objects.IsBound(anID)) _objects.UnBind(anID); _objects.Bind(anID, anObject); - TCollection_AsciiString anEntry, aDescr(""); - TDF_Tool::Entry(anObject->GetEntry(), anEntry); - aDescr += anEntry; - aDescr += " = geom.AddSubShape("; - TDF_Tool::Entry(theMainShape->GetEntry(), anEntry); - aDescr += (anEntry+", "); - aDescr += (", ["); - for(Standard_Integer i=theIndices->Lower(); i<=theIndices->Upper(); i++) { - aDescr += (TCollection_AsciiString(theIndices->Value(i))+", "); + GEOM::TPythonDump pd (aFunction); + + if (isStandaloneOperation) { + pd << anObject << " = geompy.GetSubShape(" << theMainShape << ", ["; + Standard_Integer i = theIndices->Lower(), up = theIndices->Upper(); + for (; i <= up - 1; i++) { + pd << theIndices->Value(i) << ", "; + } + pd << theIndices->Value(up) << "])"; } - aDescr.Trunc(aDescr.Length()-1); - aDescr += "])"; - aFunction->SetDescription(aDescr); + else + pd << "None"; return anObject; } @@ -222,6 +237,14 @@ bool GEOM_Engine::RemoveObject(Handle(GEOM_Object) theObject) TCollection_AsciiString anID = BuildIDFromObject(theObject); if(_objects.IsBound(anID)) _objects.UnBind(anID); + int nb = theObject->GetNbFunctions(); + Handle(TDataStd_TreeNode) aNode; + for(int i = 1; i<=nb; i++) { + Handle(GEOM_Function) aFunction = theObject->GetFunction(i); + if(aFunction->GetEntry().FindAttribute(GEOM_Function::GetFunctionTreeID(), aNode)) + aNode->Remove(); + } + TDF_Label aLabel = theObject->GetEntry(); aLabel.ForgetAllAttributes(Standard_True); @@ -273,7 +296,9 @@ bool GEOM_Engine::Save(int theDocID, char* theFileName) bool GEOM_Engine::Load(int theDocID, char* theFileName) { Handle(TDocStd_Document) aDoc; - if(_OCAFApp->Open(theFileName, aDoc) != CDF_RS_OK) return false; + if(_OCAFApp->Open(theFileName, aDoc) != CDF_RS_OK) { + return false; + } aDoc->SetUndoLimit(_UndoLimit); @@ -282,6 +307,8 @@ bool GEOM_Engine::Load(int theDocID, char* theFileName) TDataStd_Integer::Set(aDoc->Main(), theDocID); + _OCAFApp->SaveAs(aDoc, "/dn05/salome/srn/Test.sdg"); + return true; } @@ -310,3 +337,294 @@ void GEOM_Engine::Close(int theDocID) aDoc.Nullify(); } } + +//============================================================================= +/*! + * DumpPython + */ +//============================================================================= +TCollection_AsciiString GEOM_Engine::DumpPython(int theDocID, + Resource_DataMapOfAsciiStringAsciiString& theObjectNames, + bool isPublished, + bool& aValidScript) +{ + TCollection_AsciiString aScript; + Handle(TDocStd_Document) aDoc = GetDocument(theDocID); + + if(aDoc.IsNull()) return TCollection_AsciiString("def RebuildData(theStudy): pass\n"); + + aScript = "import geompy\n"; + aScript += "import math\n\n"; + aScript += "def RebuildData(theStudy):"; + aScript += "\n\tgeompy.init_geom(theStudy)"; + + Standard_Integer posToInertGlobalVars = aScript.Length() + 1; + + Handle(TDataStd_TreeNode) aNode, aRoot; + Handle(GEOM_Function) aFunction; + TColStd_MapOfTransient aMap; + + if(aDoc->Main().FindAttribute(GEOM_Function::GetFunctionTreeID(), aRoot)) { + TDataStd_ChildNodeIterator Itr(aRoot); + for(; Itr.More(); Itr.Next()) { + aNode = Itr.Value(); + aFunction = GEOM_Function::GetFunction(aNode->Label()); + if(aFunction.IsNull()) { + cout << "Null function !!!!" << endl; + continue; + } + ProcessFunction(aFunction, aScript, aMap); + } + } + + Resource_DataMapOfAsciiStringAsciiString aEntry2StEntry, aStEntry2Entry; + Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString anEntryToNameIt; + // build maps entry <-> studyEntry + for (anEntryToNameIt.Initialize( theObjectNames ); + anEntryToNameIt.More(); + anEntryToNameIt.Next()) + { + const TCollection_AsciiString& aEntry = anEntryToNameIt.Key(); + // look for an object by entry + TDF_Label L; + TDF_Tool::Label( aDoc->GetData(), aEntry, L ); + if ( L.IsNull() ) continue; + Handle(GEOM_Object) obj = GEOM_Object::GetObject( L ); + // fill maps + if ( !obj.IsNull() ) { + TCollection_AsciiString aStudyEntry (obj->GetAuxData()); + aEntry2StEntry.Bind( aEntry, aStudyEntry); + aStEntry2Entry.Bind( aStudyEntry, aEntry ); + } + } + + Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(aScript); + Standard_Integer aLen = aSeq->Length(), objectCounter = 0, aStart = 1, aScriptLength = aScript.Length(); + Resource_DataMapOfAsciiStringAsciiString aNameToEntry, anEntryToBadName; + + //Replace entries by the names + TCollection_AsciiString anUpdatedScript, anEntry, aName, aBaseName("geomObj_"), + allowedChars ("qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_"); + if(aLen == 0) anUpdatedScript = aScript; + + for(Standard_Integer i = 1; i <= aLen; i+=2) { + anUpdatedScript += aScript.SubString(aStart, aSeq->Value(i)-1); + anEntry = aScript.SubString(aSeq->Value(i), aSeq->Value(i+1)); + if(theObjectNames.IsBound(anEntry)) { + aName = theObjectNames.Find(anEntry); + // check validity of aName + bool isValidName = true; + if ( aName.IsIntegerValue() ) { // aName must not start with a digit + aName.Insert( 1, 'a' ); + isValidName = false; + } + int p, p2=1; // replace not allowed chars + while ((p = aName.FirstLocationNotInSet(allowedChars, p2, aName.Length()))) { + aName.SetValue(p, '_'); + p2=p; + isValidName = false; + } + if ( aNameToEntry.IsBound( aName ) && anEntry != aNameToEntry( aName )) + { // diff objects have same name - make a new name by appending a digit + TCollection_AsciiString aName2; + Standard_Integer i = 0; + do { + aName2 = aName + "_" + ++i; + } while ( aNameToEntry.IsBound( aName2 ) && anEntry != aNameToEntry( aName2 )); + aName = aName2; + isValidName = false; + } + if ( !isValidName ) { + if ( isPublished ) + anEntryToBadName.Bind( anEntry, theObjectNames.Find(anEntry) ); + theObjectNames( anEntry ) = aName; + } + } + else { + do { + aName = aBaseName + TCollection_AsciiString(++objectCounter); + } while(aNameToEntry.IsBound(aName)); + theObjectNames.Bind(anEntry, aName); + } + aNameToEntry.Bind(aName, anEntry); // to detect same name of diff objects + + anUpdatedScript += aName; + aStart = aSeq->Value(i+1) + 1; + } + + //Add final part of the script + if(aSeq->Value(aLen) < aScriptLength) anUpdatedScript += aScript.SubString(aSeq->Value(aLen)+1, aScriptLength); + + // Make script to publish in study + if ( isPublished ) + { + map< int, string > anEntryToCommandMap; // sort publishing commands by object entry + for (anEntryToNameIt.Initialize( theObjectNames ); + anEntryToNameIt.More(); + anEntryToNameIt.Next()) + { + const TCollection_AsciiString& aEntry = anEntryToNameIt.Key(); + const TCollection_AsciiString& aName = anEntryToNameIt.Value(); + if ( !aEntry2StEntry.IsBound( aEntry )) + continue; // was not published + TCollection_AsciiString aCommand("\n\tgeompy."), aFatherEntry; + + // find a father entry + const TCollection_AsciiString& aStudyEntry = aEntry2StEntry( aEntry ); + TCollection_AsciiString aFatherStudyEntry = + aStudyEntry.SubString( 1, aStudyEntry.SearchFromEnd(":") - 1 ); + if ( aStEntry2Entry.IsBound( aFatherStudyEntry )) + aFatherEntry = aStEntry2Entry( aFatherStudyEntry ); + + // make a command + if ( !aFatherEntry.IsEmpty() && theObjectNames.IsBound( aFatherEntry )) { + aCommand += "addToStudyInFather( "; + aCommand += theObjectNames( aFatherEntry ) + ", "; + } + else + aCommand += "addToStudy( "; + if ( anEntryToBadName.IsBound( aEntry )) + aCommand += aName + ", \"" + anEntryToBadName( aEntry ) + "\" )"; + else + aCommand += aName + ", \"" + aName + "\" )"; + + // bind a command to the last digit of the entry + int tag = + aEntry.SubString( aEntry.SearchFromEnd(":")+1, aEntry.Length() ).IntegerValue(); + anEntryToCommandMap.insert( make_pair( tag, aCommand.ToCString() )); + } + + // add publishing commands to the script + map< int, string >::iterator anEntryToCommand = anEntryToCommandMap.begin(); + for ( ; anEntryToCommand != anEntryToCommandMap.end(); ++anEntryToCommand ) { + anUpdatedScript += (char*)anEntryToCommand->second.c_str(); + } + } + + anUpdatedScript += "\n\tpass\n"; + aValidScript = true; + + // fill _studyEntry2NameMap and build globalVars + TCollection_AsciiString globalVars; + _studyEntry2NameMap.Clear(); + Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString aStEntryToEntryIt; + for (aStEntryToEntryIt.Initialize( aStEntry2Entry ); + aStEntryToEntryIt.More(); + aStEntryToEntryIt.Next() ) + { + const TCollection_AsciiString & name = theObjectNames( aStEntryToEntryIt.Value() ); + _studyEntry2NameMap.Bind (aStEntryToEntryIt.Key(), name ); + if ( !globalVars.IsEmpty() ) + globalVars += ", "; + globalVars += name; + } + if ( !globalVars.IsEmpty() ) { + globalVars.Insert( 1, "\n\tglobal " ); + anUpdatedScript.Insert( posToInertGlobalVars, globalVars ); + } + + return anUpdatedScript; +} + +//======================================================================= +//function : GetDumpName +//purpose : +//======================================================================= + +const char* GEOM_Engine::GetDumpName (const char* theStudyEntry) const +{ + if ( _studyEntry2NameMap.IsBound( (char*)theStudyEntry )) + return _studyEntry2NameMap( (char*)theStudyEntry ).ToCString(); + + return NULL; +} + +//======================================================================= +//function : GetAllDumpNames +//purpose : +//======================================================================= + +Handle(TColStd_HSequenceOfAsciiString) GEOM_Engine::GetAllDumpNames() const +{ + Handle(TColStd_HSequenceOfAsciiString) aRetSeq = new TColStd_HSequenceOfAsciiString; + + Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString it (_studyEntry2NameMap); + for (; it.More(); it.Next()) { + aRetSeq->Append(it.Value()); + } + + return aRetSeq; +} + + +//=========================================================================== +// Internal functions +//=========================================================================== +void ProcessFunction(Handle(GEOM_Function)& theFunction, + TCollection_AsciiString& theScript, + TColStd_MapOfTransient& theProcessed) +{ + if(theFunction.IsNull() || theProcessed.Contains(theFunction)) return; + +/* + TDF_LabelSequence aSeq; + theFunction->GetDependency(aSeq); + Standard_Integer aLen = aSeq.Length(); + for(Standard_Integer i = 1; i<= aLen; i++) { + Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(aSeq.Value(i)); + if(aFunction.IsNull()) continue; + ProcessFunction(aFunction, theScript, theProcessed); + } +*/ + + TCollection_AsciiString aDescr = theFunction->GetDescription(); + if(aDescr.Length() == 0) { + //cout << "Warning: the function has no description" << endl; + return; + } + //Check if its internal function which doesn't requires dumping + if(aDescr == "None") return; + + theScript += "\n\t"; + theScript += aDescr; + + theProcessed.Add(theFunction); + return; +} + +//============================================================================= +/*! + * FindEntries: Returns a sequence of start/end positions of entries in the string + */ +//============================================================================= +Handle(TColStd_HSequenceOfInteger) FindEntries(TCollection_AsciiString& theString) +{ + Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger; + Standard_Integer aLen = theString.Length(); + Standard_Boolean isFound = Standard_False; + + char* arr = theString.ToCString(); + Standard_Integer i = 0, j; + + while(i < aLen) { + int c = (int)arr[i]; + j = i+1; + if(c >= 48 && c <= 57) { //Is digit? + + isFound = Standard_False; + while((j < aLen) && ((c >= 48 && c <= 57) || c == 58) ) { //Check if it is an entry + c = (int)arr[j++]; + if(c == 58) isFound = Standard_True; + } + + if(isFound && arr[j-2] != 58) { // last char should be a diggit + aSeq->Append(i+1); // +1 because AsciiString starts from 1 + aSeq->Append(j-1); + } + } + + i = j; + } + + return aSeq; +}