Salome HOME
bos #20282 EDF 22320 - general compute fails
authoreap <eap@opencascade.com>
Wed, 2 Dec 2020 08:51:19 +0000 (11:51 +0300)
committereap <eap@opencascade.com>
Wed, 2 Dec 2020 08:51:19 +0000 (11:51 +0300)
1) Compute sub-meshes with prescribed order before the rest ones
2) Save sub-mesh order not as ids but as entries, because ids of groups
   within SMESHDS_Mesh can change at study loading if some group is no
   longer used as a base of sub-mesh of group on geometry

src/SMESH/SMESH_Mesh.cxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx

index e71853f0f646711e99def985c04d1b5fcde15f82..e35195d3368dbf6697eaa76069f83c403414ec22 100644 (file)
@@ -2414,18 +2414,19 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
 
 bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) const
 {
-  if ( !_mySubMeshOrder.size() || theListToSort.size() < 2)
+  if ( _mySubMeshOrder.empty() || theListToSort.size() < 2 )
     return true;
-  
-  bool res = false;
-  std::vector<SMESH_subMesh*> onlyOrderedList, smVec;
 
-  // collect all ordered submeshes in one list as pointers
+
+  // collect all ordered sub-meshes in smVec as pointers
   // and get their positions within theListToSort
+
+  std::vector<SMESH_subMesh*> smVec;
   typedef std::vector<SMESH_subMesh*>::iterator TPosInList;
-  std::map< int, TPosInList > sortedPos;
+  std::map< size_t, size_t > sortedPos; // index in theListToSort to order
   TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end();
   TListOfListOfInt::const_iterator      listIdsIt = _mySubMeshOrder.begin();
+  bool needSort = false;
   for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++)
   {
     const TListOfInt& listOfId = *listIdsIt;
@@ -2452,27 +2453,46 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) con
     // find smVec items in theListToSort
     for ( size_t i = 0; i < smVec.size(); ++i )
     {
-      TPosInList smPos = find( smBeg, smEnd, smVec[i] );
-      if ( smPos != smEnd ) {
-        sortedPos[ std::distance( smBeg, smPos )] = smPos;
-        if ( sortedPos.size() > onlyOrderedList.size() )
-          onlyOrderedList.push_back( smVec[i] );
+      TPosInList smPos = find( smBeg, smEnd, smVec[i] ); // position in theListToSort
+      if ( smPos != smEnd )
+      {
+        size_t posInList = std::distance( smBeg, smPos );
+        size_t     order = sortedPos.size();
+        sortedPos.insert( std::make_pair( posInList, order ));
+        if ( posInList != order )
+          needSort = true;
       }
     }
   }
-  if (onlyOrderedList.size() < 2)
-    return res;
-  res = true;
+  if ( ! needSort )
+    return false;
 
-  std::vector<SMESH_subMesh*>::iterator onlyBIt = onlyOrderedList.begin();
-  std::vector<SMESH_subMesh*>::iterator onlyEIt = onlyOrderedList.end();
+  // set sm of sortedPos from theListToSort to front of orderedSM
+  // and the rest of theListToSort to orderedSM end
 
-  // iterate on ordered sub-meshes and insert them in detected positions
-  std::map< int, TPosInList >::iterator i_pos = sortedPos.begin();
-  for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos )
-    *(i_pos->second) = *onlyBIt;
+  std::vector<SMESH_subMesh*> orderedSM;
+  orderedSM.reserve( theListToSort.size() );
+  orderedSM.resize( sortedPos.size() );
 
-  return res;
+  size_t iPrev = 0;
+  sortedPos.insert( std::make_pair( theListToSort.size(), sortedPos.size() ));
+  for ( const auto & pos_order : sortedPos )
+  {
+    const size_t& posInList = pos_order.first;
+    const size_t&     order = pos_order.second;
+    if ( order < sortedPos.size() - 1 )
+      orderedSM[ order ] = theListToSort[ posInList ];
+
+    if ( iPrev < posInList )
+      orderedSM.insert( orderedSM.end(),
+                        theListToSort.begin() + iPrev,
+                        theListToSort.begin() + posInList );
+    iPrev = posInList + 1;
+  }
+
+  theListToSort.swap( orderedSM );
+
+  return true;
 }
 
 //================================================================================
index 701de05a84ed019316a6715d8302079d3b49ff0f..28957d7febbc79b3e4b26445234e769b4e64fd6b 100644 (file)
 #include <cstdlib>
 #include <memory>
 
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/serialization/list.hpp>
+#include <boost/serialization/string.hpp>
+
 using namespace std;
 using SMESH::TPythonDump;
 using SMESH::TVar;
@@ -4790,7 +4795,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
 
             // store submesh order if any
             const TListOfListOfInt& theOrderIds = myLocMesh.GetMeshOrder();
-            if ( theOrderIds.size() ) {
+            const bool isNewOrederVersion = true; // old version saves ids, new one, entries
+            if ( !theOrderIds.empty() && !isNewOrederVersion ) { // keep old version for reference
               char order_list[ 30 ];
               strcpy( order_list, "Mesh Order" );
               // count number of submesh ids
@@ -4821,6 +4827,38 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
               //
               delete[] smIDs;
             }
+            if ( !theOrderIds.empty() && isNewOrederVersion )
+            {
+              // convert ids to entries
+              std::list< std::list< std::string > > orderEntryLists;
+              for ( const TListOfInt& idList : theOrderIds )
+              {
+                orderEntryLists.emplace_back();
+                std::list< std::string > & entryList = orderEntryLists.back();
+                for ( const int& id : idList )
+                {
+                  const TopoDS_Shape& shape = mySMESHDSMesh->IndexToShape( id );
+                  GEOM::GEOM_Object_var  go = ShapeToGeomObject( shape );
+                  SALOMEDS::SObject_var  so = ObjectToSObject( go );
+                  if ( !so->_is_nil() )
+                  {
+                    CORBA::String_var entry = so->GetID();
+                    entryList.emplace_back( entry.in() );
+                  }
+                }
+              }
+              // convert orderEntryLists to string
+              std::ostringstream ostream;
+              boost::archive::text_oarchive( ostream ) << orderEntryLists;
+              std::string orderEntryString = ostream.str();
+
+              // write HDF group
+              aSize[ 0 ] = orderEntryString.size() + 1;
+              aDataset = new HDFdataset( "MeshOrder_new", aTopGroup, HDF_STRING, aSize, 1 );
+              aDataset->CreateOnDisk();
+              aDataset->WriteOnDisk((char*) orderEntryString.data() );
+              aDataset->CloseOnDisk();
+            }
 
             // groups root sub-branch
             SALOMEDS::SObject_wrap myGroupsBranch;
@@ -5968,7 +6006,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       }
 
       // read Sub-Mesh ORDER if any
-      if ( aTopGroup->ExistInternalObject( "Mesh Order" )) {
+      if ( aTopGroup->ExistInternalObject( "Mesh Order" )) { // old version keeps ids
         aDataset = new HDFdataset( "Mesh Order", aTopGroup );
         aDataset->OpenOnDisk();
         size = aDataset->GetSize();
@@ -5986,6 +6024,37 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds );
         delete [] smIDs;
       }
+      if ( aTopGroup->ExistInternalObject( "MeshOrder_new" )) // new version keeps entries
+      {
+        aDataset = new HDFdataset( "MeshOrder_new", aTopGroup );
+        aDataset->OpenOnDisk();
+        size = aDataset->GetSize();
+        std::string dataString; dataString.resize( size );
+        aDataset->ReadFromDisk((char*) dataString.data() );
+        aDataset->CloseOnDisk();
+
+        std::istringstream istream( dataString.data() );
+        boost::archive::text_iarchive archive( istream );
+        std::list< std::list< std::string > > orderEntryLists;
+        try {
+          archive >> orderEntryLists;
+        }
+        catch (...) {}
+
+        TListOfListOfInt anOrderIds;
+        for ( const std::list< std::string >& entryList : orderEntryLists )
+        {
+          anOrderIds.emplace_back();
+          for ( const std::string & entry : entryList )
+          {
+            GEOM::GEOM_Object_var go = GetGeomObjectByEntry( entry );
+            TopoDS_Shape       shape = GeomObjectToShape( go );
+            if ( SMESH_subMesh*   sm = myNewMeshImpl->GetImpl().GetSubMesh( shape ))
+              anOrderIds.back().emplace_back( sm->GetId() );
+          }
+        }
+        myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds );
+      }
     } // loop on meshes
 
     // update hyps needing full mesh data restored (issue 20918)
@@ -6045,7 +6114,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       }
     }
   }
-  pd << ""; // prevent optimizing pd out
 
   // creation of tree nodes for all data objects in the study
   // to support tree representation customization and drag-n-drop:
index 8455f6b4681a3886ab21329db943221ea44f882f..fe179f9a1a7682d215403772ceec9c3bffc637c7 100644 (file)
@@ -6493,7 +6493,7 @@ class SMESH_DimHyp
     TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
     for (; !isShared && anItr.More(); anItr.Next() )
     {
-      const TopoDS_Shape aSubSh = anItr.Key();
+      const TopoDS_Shape& aSubSh = anItr.Key();
       // check for case when concurrent dimensions are same
       isShared = theToFind.Contains( aSubSh );
       // check for sub-shape with concurrent dimension
index b35e76ae357ce433a4196246835d0aa49dbcf82b..78ed7f603885102dfc986ea92e9c915ccbd2e58f 100644 (file)
@@ -984,7 +984,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
                 }
                 else
                 {
-                  meshedFaces.push_back( prism.myBottom );
+                  suspectSourceFaces.push_back( prism.myBottom );
                   if ( prism.myAlgoSM && prism.myAlgoSM->GetAlgo() )
                     meshedFace2AlgoSM.Bind( prism.myBottom, prism.myAlgoSM );
                 }
index dca028078f63483d7d82d324cc6763d584987283..8ecdfa8c5c340ff41b49cccc23421951545818a3 100644 (file)
@@ -204,7 +204,7 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis
 
 //=============================================================================
 /*!
- *
+ * Compute the mesh on the given shape
  */
 //=============================================================================
 
@@ -1606,7 +1606,8 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
 
 //=============================================================================
 /*!
- *
+ * Return FaceQuadStruct where sides ordered CCW, top and left sides
+ *        reversed to be co-directed with bottom and right sides
  */
 //=============================================================================