Salome HOME
[bos #32720] EDF 25230 - partition fails on small case
[modules/geom.git] / src / GEOM / GEOM_Engine.cxx
index 1293fd8ed24f81f6adf1059cf83ccb8b3f76a038..14a0c516d8411af592dbe4fd673cd8a4873aad67 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  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
 #include "GEOM_SubShapeDriver.hxx"
 #include "Sketcher_Profile.hxx"
 
-#include <Basics_OCCTVersion.hxx>
-
 #include "utilities.h"
 
 #include <Basics_Utils.hxx>
+#include <Basics_OCCTVersion.hxx>
 
 #include <TDF_Tool.hxx>
 #include <TDF_Data.hxx>
 
 #include <TColStd_DataMapIteratorOfDataMapOfIntegerTransient.hxx>
 
+#if OCC_VERSION_LARGE < 0x07050000
 #include <Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString.hxx>
+#endif
 
-#if OCC_VERSION_LARGE > 0x07000000
 #include <BinDrivers.hxx>
 #include <StdDrivers_DocumentRetrievalDriver.hxx>
 #include <PCDM_StorageDriver.hxx>
-#endif
 
 #include <set>
 
 #define C_SQR_BRACKET ']'
 #define PY_NULL "None"
 
-#ifdef _DEBUG_
-static int MYDEBUG = 0;
-#else
-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;
@@ -109,7 +110,7 @@ bool ProcessFunction(Handle(GEOM_Function)&             theFunction,
                      TCollection_AsciiString&           theScript,
                      TCollection_AsciiString&           theAfterScript,
                      const TVariablesList&              theVariables,
-                     const bool                         theIsPublished,
+                     const bool                         /*theIsPublished*/,
                      TDF_LabelMap&                      theProcessed,
                      std::set<TCollection_AsciiString>& theIgnoreObjs,
                      bool&                              theIsDumpCollected);
@@ -149,6 +150,8 @@ static TCollection_AsciiString GetPublishCommands
                     const TIntToListIntMap                         &theMapRefs,
                           std::set< int >                          &thePublished);
 
+void Prettify(TCollection_AsciiString& theScript);
+
 //================================================================================
 /*!
  * \brief Fix up the name of python variable
@@ -215,11 +218,9 @@ GEOM_Engine::GEOM_Engine()
   TFunction_DriverTable::Get()->AddDriver(GEOM_Object::GetSubShapeID(), new GEOM_SubShapeDriver());
   
   _OCAFApp = new GEOM_Application();
-#if OCC_VERSION_LARGE > 0x07000000
   _OCAFApp->DefineFormat("SALOME_GEOM", "GEOM Document Version 1.0", "sgd",
                          new StdDrivers_DocumentRetrievalDriver, 0);
   BinDrivers::DefineFormat(_OCAFApp);
-#endif
   _UndoLimit = 0;
 }
 
@@ -253,11 +254,7 @@ Handle(TDocStd_Document) GEOM_Engine::GetDocument(bool force)
     aDoc = _document;
   }
   else if (force) {
-#if OCC_VERSION_MAJOR > 6
     _OCAFApp->NewDocument("BinOcaf", aDoc);
-#else
-    _OCAFApp->NewDocument("SALOME_GEOM", aDoc);
-#endif
     aDoc->SetUndoLimit(_UndoLimit);
     _document = aDoc;
   }
@@ -393,9 +390,8 @@ Handle(GEOM_Object) GEOM_Engine::AddSubShape(Handle(GEOM_Object)              th
       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;
   }
 
@@ -435,6 +431,10 @@ bool GEOM_Engine::RemoveObject(Handle(GEOM_BaseObject)& theObject)
   if(!_document)
     return false;  // document is closed...
 
+  TDF_Label aLabel = theObject->GetEntry();
+  if ( aLabel == aLabel.Root() )
+    return false; // already removed object
+
   //Remove an object from the map of available objects
   TCollection_AsciiString anID = BuildIDFromObject(theObject);
   if (_objects.IsBound(anID)) {
@@ -463,14 +463,13 @@ bool GEOM_Engine::RemoveObject(Handle(GEOM_BaseObject)& theObject)
       aNode->Remove();
   }
 
-  TDF_Label aLabel = theObject->GetEntry();
   aLabel.ForgetAllAttributes(Standard_True);
 
   // Remember the label to reuse it then
   if ( _freeLabels.empty() || _freeLabels.back() != aLabel )
     _freeLabels.push_back(aLabel);
 
-  // we can't explicitely delete theObject. At least prevent its functioning
+  // we can't explicitly 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();
@@ -510,9 +509,13 @@ bool GEOM_Engine::Save(const char* theFileName)
 {
   if(!_document) return false;
 
-  _OCAFApp->SaveAs(_document, theFileName);
+#if defined(WIN32) && defined(UNICODE)
+  std::wstring aFileName = Kernel_Utils::utf8_decode_s(theFileName);
+#else
+  std::string aFileName = theFileName;
+#endif
 
-  return true;
+  return _OCAFApp->SaveAs( _document, aFileName.c_str() ) == PCDM_SS_OK;
 }
 
 //=============================================================================
@@ -522,17 +525,20 @@ bool GEOM_Engine::Save(const char* theFileName)
 //=============================================================================
 bool GEOM_Engine::Load(const char* theFileName)
 {
+#if defined(WIN32) && defined(UNICODE)
+       std::wstring aFileName = Kernel_Utils::utf8_decode_s(theFileName);
+#else
+       std::string aFileName = theFileName;
+#endif
   Handle(TDocStd_Document) aDoc;
-  if (_OCAFApp->Open(theFileName, aDoc) != PCDM_RS_OK) {
+  if (_OCAFApp->Open(aFileName.c_str(), aDoc) != PCDM_RS_OK) {
     return false;
   }
 
-#if OCC_VERSION_MAJOR > 6
   // Replace old document format by the new one.
   if (aDoc->StorageFormat().IsEqual("SALOME_GEOM")) {
     aDoc->ChangeStorageFormat("BinOcaf");
   }
-#endif
 
   aDoc->SetUndoLimit(_UndoLimit);
 
@@ -611,7 +617,7 @@ TCollection_AsciiString GEOM_Engine::DumpPython(std::vector<TObjectData>& theObj
   // a map containing copies of TObjectData from theObjectData
   TSting2ObjDataMap    aEntry2ObjData;
   // contains pointers to TObjectData of either aEntry2ObjData or theObjectData; the latter
-  // occures when several StudyEntries correspond to one Entry
+  // occurs when several StudyEntries correspond to one Entry
   TSting2ObjDataPtrMap aStEntry2ObjDataPtr;
 
   //Resource_DataMapOfAsciiStringAsciiString aEntry2StEntry, aStEntry2Entry, theObjectNames;
@@ -811,6 +817,11 @@ TCollection_AsciiString GEOM_Engine::DumpPython(std::vector<TObjectData>& theObj
     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;
 }
 
@@ -1263,7 +1274,7 @@ Handle(TColStd_HSequenceOfInteger) FindEntries(TCollection_AsciiString& theStrin
         if(c == 58) isFound = Standard_True;
       }
 
-      if(isFound && arr[j-2] != 58) { // last char should be a diggit
+      if(isFound && arr[j-2] != 58) { // last char should be a digit
         aSeq->Append(i+1); // +1 because AsciiString starts from 1
         aSeq->Append(j-1);
       }
@@ -1284,14 +1295,14 @@ Handle(TColStd_HSequenceOfInteger) FindEntries(TCollection_AsciiString& theStrin
 void ReplaceVariables(TCollection_AsciiString& theCommand,
                       const TVariablesList&    theVariables)
 {
-  if (MYDEBUG)
-    cout<<"Command : "<<theCommand<<endl;
+  if (SALOME::VerbosityActivated())
+    std::cout<<"Command : "<<theCommand<<std::endl;
 
-  if (MYDEBUG) {
-    cout<<"All Entries:"<<endl;
+  if (SALOME::VerbosityActivated()) {
+    std::cout<<"All Entries:"<<std::endl;
     TVariablesList::const_iterator it = theVariables.begin();
     for(;it != theVariables.end();it++)
-      cout<<"\t'"<<(*it).first<<"'"<<endl;
+      std::cout<<"\t'"<<(*it).first<<"'"<<std::endl;
   }
 
   //Additional case - multi-row commands
@@ -1301,8 +1312,8 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
     if( aCommand.Length() == 0 )
       break;
 
-    if (MYDEBUG)
-      cout<<"Sub-command : "<<aCommand<<endl;
+    if (SALOME::VerbosityActivated())
+      std::cout<<"Sub-command : "<<aCommand<<std::endl;
 
     Standard_Integer aStartCommandPos = theCommand.Location(aCommand,1,theCommand.Length());
     Standard_Integer aEndCommandPos = aStartCommandPos + aCommand.Length();
@@ -1319,8 +1330,8 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
     //Remove white spaces
     anEntry.RightAdjust();
     anEntry.LeftAdjust();
-    if(MYDEBUG)
-      cout<<"Result entry : '" <<anEntry<<"'"<<endl;
+    if(SALOME::VerbosityActivated())
+      std::cout<<"Result entry : '" <<anEntry<<"'"<<std::endl;
 
     if ( anEntry.IsEmpty() ) {
       aCommandIndex++;
@@ -1337,8 +1348,8 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
       anEntry.Remove( 1, 1 );
       anEntry.RightAdjust();
       anEntry.LeftAdjust();
-      if(MYDEBUG)
-        cout<<"Sub-entry : '" <<anEntry<<"'"<<endl;
+      if(SALOME::VerbosityActivated())
+                   std::cout<<"Sub-entry : '" <<anEntry<<"'"<<std::endl;
     }
 
     //Find variables used for object construction
@@ -1348,18 +1359,18 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
       aStates = (*it).second;
 
     if(!aStates) {
-      if(MYDEBUG)
-        cout<<"Valiables list empty!!!"<<endl;
+      if(SALOME::VerbosityActivated())
+                   std::cout<<"Valiables list empty!!!"<<std::endl;
       aCommandIndex++;
       continue;
     }
 
     TState aVariables = aStates->GetCurrectState();
 
-    if(MYDEBUG) {
-      cout<<"Variables from SObject:"<<endl;
-      for (int i = 0; i < aVariables.size();i++)
-        cout<<"\t Variable["<<i<<"] = "<<aVariables[i].myVariable<<endl;
+    if(SALOME::VerbosityActivated()) {
+          std::cout<<"Variables from SObject:"<<std::endl;
+      for (size_t i = 0; i < aVariables.size();i++)
+        std::cout<<"\t Variable["<<i<<"] = "<<aVariables[i].myVariable<<std::endl;
     }
 
     //Calculate total number of parameters
@@ -1367,15 +1378,15 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
     while(aCommand.Location(aTotalNbParams,COMMA,1,aCommand.Length()))
       aTotalNbParams++;
 
-    if(MYDEBUG)
-      cout<<"aTotalNbParams = "<<aTotalNbParams<<endl;
+    if(SALOME::VerbosityActivated())
+           std::cout<<"aTotalNbParams = "<<aTotalNbParams<<std::endl;
 
     Standard_Integer aFirstParam = aNbEntries;
 
     //Replace parameters by variables
     Standard_Integer aStartPos = 0;
     Standard_Integer aEndPos = 0;
-    int iVar = 0;
+    size_t iVar = 0;
     TCollection_AsciiString aVar, aReplacedVar;
     for(Standard_Integer i=aFirstParam;i <= aTotalNbParams;i++) {
       //Replace first parameter (bettwen '(' character and first ',' character)
@@ -1399,6 +1410,8 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
         aStartPos = aCommand.Location(i-1, COMMA, 1, aCommand.Length()) + 2;
         aEndPos = aCommand.Location(i, COMMA, 1, aCommand.Length());
       }
+      if (aStartPos == 0 || aEndPos == 0)
+        continue;
 
       if( aCommand.Value( aStartPos ) == O_SQR_BRACKET )
         aStartPos++;
@@ -1407,15 +1420,15 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
       if ( aStartPos == aEndPos )
         continue; // PAL20889: for "[]"
 
-      if(MYDEBUG)
-        cout<<"aStartPos = "<<aStartPos<<", aEndPos = "<<aEndPos<<endl;
+      if(SALOME::VerbosityActivated())
+        std::cout<<"aStartPos = "<<aStartPos<<", aEndPos = "<<aEndPos<<std::endl;
 
       aVar = aCommand.SubString(aStartPos, aEndPos-1);
       aVar.RightAdjust();
       aVar.LeftAdjust();
 
-      if(MYDEBUG)
-        cout<<"Variable: '"<< aVar <<"'"<<endl;
+      if(SALOME::VerbosityActivated())
+        std::cout<<"Variable: '"<< aVar <<"'"<<std::endl;
 
       // specific case for sketcher
       if(aVar.Location( TCollection_AsciiString("Sketcher:"), 1, aVar.Length() ) != 0) {
@@ -1434,8 +1447,8 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
             aEndSectionPos = aVar.Length();
 
           aSection = aVar.SubString(aStartSectionPos, aEndSectionPos-1);
-          if(MYDEBUG)
-            cout<<"aSection: "<<aSection<<endl;
+          if(SALOME::VerbosityActivated())
+                             std::cout<<"aSection: "<<aSection<<std::endl;
 
           Standard_Integer aNbParams = 1;
           while( aSection.Location( aNbParams, ' ', 1, aSection.Length() ) )
@@ -1451,15 +1464,15 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
             else
               aEndParamPos = aSection.Length() + 1;
 
-            if(MYDEBUG)
-              cout<<"aParamIndex: "<<aParamIndex<<" aStartParamPos: " <<aStartParamPos<<" aEndParamPos: "<<aEndParamPos<<endl;
+            if(SALOME::VerbosityActivated())
+              std::cout<<"aParamIndex: "<<aParamIndex<<" aStartParamPos: " <<aStartParamPos<<" aEndParamPos: "<<aEndParamPos<<std::endl;
 
             if ( aStartParamPos == aEndParamPos)
               continue;
 
             aParameter = aSection.SubString(aStartParamPos, aEndParamPos-1);
-            if(MYDEBUG)
-              cout<<"aParameter: "<<aParameter<<endl;
+            if(SALOME::VerbosityActivated())
+                               std::cout<<"aParameter: "<<aParameter<<std::endl;
 
             if(iVar >= aVariables.size())
               continue;
@@ -1475,28 +1488,31 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
               aReplacedParameter.InsertAfter(aReplacedParameter.Length(),"'");
             }
 
-            if(MYDEBUG)
-              cout<<"aSection before : "<<aSection<<endl;
+            if(SALOME::VerbosityActivated())
+                               std::cout<<"aSection before : "<<aSection<< std::endl;
             aSection.Remove(aStartParamPos, aEndParamPos - aStartParamPos);
             aSection.Insert(aStartParamPos, aReplacedParameter);
-            if(MYDEBUG)
-              cout<<"aSection after  : "<<aSection<<endl<<endl;
+            if(SALOME::VerbosityActivated())
+              std::cout<<"aSection after  : "<<aSection<<std::endl<<std::endl;
             iVar++;
           }
-          if(MYDEBUG)
-            cout<<"aVar before : "<<aVar<<endl;
+
+          if(SALOME::VerbosityActivated())
+            std::cout<<"aVar before : "<<aVar<<std::endl;
+
           aVar.Remove(aStartSectionPos, aEndSectionPos - aStartSectionPos);
           aVar.Insert(aStartSectionPos, aSection);
-          if(MYDEBUG)
-            cout<<"aVar after  : "<<aVar<<endl<<endl;
+
+          if(SALOME::VerbosityActivated())
+            std::cout<<"aVar after  : "<<aVar<<std::endl<<std::endl;
         }
 
-        if(MYDEBUG)
-          cout<<"aCommand before : "<<aCommand<<endl;
+        if(SALOME::VerbosityActivated())
+          std::cout<<"aCommand before : "<<aCommand<<std::endl;
         aCommand.Remove(aStartPos, aEndPos - aStartPos);
         aCommand.Insert(aStartPos, aVar);
-        if(MYDEBUG)
-          cout<<"aCommand after  : "<<aCommand<<endl;
+        if(SALOME::VerbosityActivated())
+          std::cout<<"aCommand after  : "<<aCommand<<std::endl;
 
         break;
       } // end of specific case for sketcher
@@ -1532,8 +1548,8 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
     aStates->IncrementState();
   }
 
-  if (MYDEBUG)
-    cout<<"Command : "<<theCommand<<endl;
+  if (SALOME::VerbosityActivated())
+    std::cout<<"Command : "<<theCommand<<std::endl;
 }
 
 //=============================================================================
@@ -1543,7 +1559,7 @@ void ReplaceVariables(TCollection_AsciiString& theCommand,
 //=============================================================================
 void ReplaceEntriesByNames (TCollection_AsciiString&                  theScript,
                             TSting2ObjDataMap&                        aEntry2ObjData,
-                            const bool                                theIsPublished,
+                            const bool                                /*theIsPublished*/,
                             TColStd_SequenceOfAsciiString&            theObjListToPublish,
                             Standard_Integer&                         objectCounter,
                             Resource_DataMapOfAsciiStringAsciiString& aNameToEntry)
@@ -1563,7 +1579,7 @@ void ReplaceEntriesByNames (TCollection_AsciiString&                  theScript,
     theObjListToPublish.Append( anEntry );
     
     TObjectData& data = aEntry2ObjData[ anEntry ];
-    if ( data._pyName.IsEmpty() ) { // encounted for the 1st time
+    if ( data._pyName.IsEmpty() ) { // encountered for the 1st time
       if ( !data._name.IsEmpty() ) { // published object
         data._pyName = data._name;
         engine->healPyName( data._pyName, anEntry, aNameToEntry);
@@ -1780,7 +1796,7 @@ void PublishObject (TObjectData&                              theObjectData,
 
     // store aCreationCommand before publishing commands
     int tag = GetTag(theObjectData._entry);
-    theEntryToCmdMap.insert( std::make_pair( tag + 2*theEntry2ObjData.size(), aCreationCommand ));
+    theEntryToCmdMap.insert( std::make_pair( tag + -2*theEntry2ObjData.size(), aCreationCommand ));
   }
 
   // make a command
@@ -1816,6 +1832,8 @@ TCollection_AsciiString GetPublishCommands
 
   if (!thePublished.count(theTag)) {
     // This object is not published yet.
+    thePublished.insert(theTag);
+
     std::map< int, TCollection_AsciiString >::const_iterator anIt =
       theEntryToCmdMap.find(theTag);
 
@@ -1824,7 +1842,7 @@ TCollection_AsciiString GetPublishCommands
       TIntToListIntMap::const_iterator aRefIt = theMapRefs.find(theTag);
 
       if (aRefIt != theMapRefs.end()) {
-        // Recursively publish all references.
+        // Recursively publish all references.         
         std::list< int >::const_iterator aRefTagIt = aRefIt->second.begin();
 
         for(; aRefTagIt != aRefIt->second.end(); ++aRefTagIt) {
@@ -1838,13 +1856,48 @@ TCollection_AsciiString GetPublishCommands
       // Add the object command.
       aResult += anIt->second;
     }
-
-    thePublished.insert(theTag);
   }
 
   return aResult;
 }
 
+void Prettify(TCollection_AsciiString& theScript)
+{
+  TCollection_AsciiString output;
+  static std::list<TCollection_AsciiString> 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<TCollection_AsciiString>::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
@@ -1872,7 +1925,7 @@ ObjectStates::~ObjectStates()
 //================================================================================
 TState ObjectStates::GetCurrectState() const
 {
-  if(_states.size() > _dumpstate)
+  if((int)_states.size() > _dumpstate)
     return _states[_dumpstate];
   return TState();
 }