+
+//=============================================================================
+/*!
+ * 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";
+ aScript += "import SALOMEDS\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()) {
+ MESSAGE ( "Null function !!!!" );
+ 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 (aLen && aSeq->Value(aLen) < aScriptLength)
+ anUpdatedScript += aScript.SubString(aSeq->Value(aLen)+1, aScriptLength); // mkr : IPAL11865
+
+ // ouv : NPAL12872
+ for (anEntryToNameIt.Initialize( theObjectNames );
+ anEntryToNameIt.More();
+ anEntryToNameIt.Next())
+ {
+ const TCollection_AsciiString& aEntry = anEntryToNameIt.Key();
+ const TCollection_AsciiString& aName = anEntryToNameIt.Value();
+
+ TDF_Label L;
+ TDF_Tool::Label( aDoc->GetData(), aEntry, L );
+ if ( L.IsNull() )
+ continue;
+
+ Handle(GEOM_Object) obj = GEOM_Object::GetObject( L );
+ if ( obj.IsNull() )
+ continue;
+
+ bool anAutoColor = obj->GetAutoColor();
+ if ( anAutoColor )
+ {
+ TCollection_AsciiString aCommand( "\n\t" );
+ aCommand += aName + ".SetAutoColor(1)";
+ anUpdatedScript += aCommand.ToCString();
+ }
+
+ SALOMEDS::Color aColor = obj->GetColor();
+ if ( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 )
+ {
+ TCollection_AsciiString aCommand( "\n\t" );
+ aCommand += aName + ".SetColor(SALOMEDS.Color(" + aColor.R + "," + aColor.G + "," + aColor.B + "))";
+ anUpdatedScript += aCommand.ToCString();
+ }
+ }
+
+ // Make script to publish in study
+ if ( isPublished )
+ {
+ std::map< int, std::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( std::make_pair( tag, aCommand.ToCString() ));
+ }
+
+ // add publishing commands to the script
+ std::map< int, std::string >::iterator anEntryToCommand = anEntryToCommandMap.begin();
+ for ( ; anEntryToCommand != anEntryToCommandMap.end(); ++anEntryToCommand ) {
+ anUpdatedScript += (char*)anEntryToCommand->second.c_str();
+ }
+ }
+
+ //anUpdatedScript += "\n\tpass\n";
+ anUpdatedScript += "\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;
+
+ const 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;
+}