Salome HOME
0020427: EDF 868 SMESH : Be able to define the submeshing order BR_phase16
authorptv <ptv@opencascade.com>
Thu, 1 Oct 2009 06:47:15 +0000 (06:47 +0000)
committerptv <ptv@opencascade.com>
Thu, 1 Oct 2009 06:47:15 +0000 (06:47 +0000)
1. Add Store/Retrieve into/from HDF study
2. Clear submesh affected in submesh order modification
3. Set Modified flag in GUI object browser

src/SMESH/SMESH_subMesh.cxx
src/SMESH/SMESH_subMesh.hxx
src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Mesh_i.cxx

index 21d1675184e5ce3f911484c3b2308fab9430fe54..b8615dcc243759a86274b8332f1187ca9995985b 100644 (file)
@@ -2191,3 +2191,29 @@ SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeS
       ( new _Iterator( new SMDS_mapIterator<TMap>( DependsOn() ), prepend, append ));
   }
 }
+
+//================================================================================
+/*!
+ * \brief  Find common submeshes (based on shared subshapes with other
+  * \param theOther submesh to check
+  * \param theSetOfCommon set of common submesh
+ */
+//================================================================================
+
+bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther,
+                                     std::set<const SMESH_subMesh*>& theSetOfCommon ) const
+{
+  int oldNb = theSetOfCommon.size();
+  // check main submeshes
+  const map <int, SMESH_subMesh*>::const_iterator otherEnd = theOther->_mapDepend.end();
+  if ( theOther->_mapDepend.find(this->GetId()) != otherEnd )
+    theSetOfCommon.insert( this );
+  if ( _mapDepend.find(theOther->GetId()) != _mapDepend.end() )
+    theSetOfCommon.insert( theOther );
+  // check common submeshes
+  map <int, SMESH_subMesh*>::const_iterator mapIt = _mapDepend.begin();
+  for( ; mapIt != _mapDepend.end(); mapIt++ )
+    if ( theOther->_mapDepend.find((*mapIt).first) != otherEnd )
+      theSetOfCommon.insert( (*mapIt).second );
+  return oldNb < theSetOfCommon.size();
+}
index d4c0468f942dd8600297f5a9332a71dc435dd94a..bba5665fcdb04fd77f1fc360eef147bcc2f20128 100644 (file)
@@ -228,6 +228,15 @@ public:
   void SetIsAlwaysComputed(bool isAlCo);
   bool IsAlwaysComputed() { return _alwaysComputed; }
 
+  
+  /*!
+   * \brief  Find common submeshes (based on shared subshapes with other
+   * \param theOther submesh to check
+   * \param theCommonIds set of common submesh IDs
+   * NOTE: this method does not cleat set before collect common IDs
+   */
+  bool FindIntersection( const SMESH_subMesh *           theOther,
+                         std::set<const SMESH_subMesh*>& theSetOfCommon ) const;
 
 protected:
   // ==================================================================
index 5c26efc2ca363474dcb334db115bb8dca2b92e66..00b63da3a4e9f842cced423403be45c5e9124914 100644 (file)
@@ -299,6 +299,11 @@ bool SMESHGUI_MeshOrderMgr::SetMeshOrder( const  ListListId& theListListIds )
     }
   }
 
+  // is it enought to set modifid attribute on root mesh objects only?
+  //  it is seems that modifaction flag will be set on child submeshes 
+  //  automatically  (see SMESH::ModifiedMesh for details)
+  SMESH::ModifiedMesh( aMeshSObj, false, false );
+
   SMESH::submesh_array_array_var meshOrder = new SMESH::submesh_array_array();
   meshOrder->length(theListListIds.count() );
   ListListId::const_iterator it = theListListIds.constBegin();
@@ -313,6 +318,8 @@ bool SMESHGUI_MeshOrderMgr::SetMeshOrder( const  ListListId& theListListIds )
 
     meshOrder[ i++ ] = subMeshList;
   }
+  // update object browser
+  SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
 
   return myMesh->SetMeshOrder(meshOrder);
 }
index 514eb938067386d3522f896d2a2760b68083f3d3..f0faba9fd18573b7a4a16ba61948a81fde50a6d3 100644 (file)
@@ -2703,6 +2703,40 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             //if ( shapeRefFound )
             //myWriter.AddAllSubMeshes();
 
+            // store submesh order if any
+            const TListOfListOfInt& theOrderIds = myLocMesh.GetMeshOrder();
+            if ( theOrderIds.size() ) {
+              char order_list[ 30 ];
+              strcpy( order_list, "Mesh Order" );
+              // count number of submesh ids
+              int nbIDs = 0;
+              TListOfListOfInt::const_iterator idIt = theOrderIds.begin();
+              for ( ; idIt != theOrderIds.end(); idIt++ )
+                nbIDs += (*idIt).size();
+              // number of values = number of IDs +
+              //                    number of lists (for separators) - 1
+              int* smIDs = new int [ nbIDs + theOrderIds.size() - 1 ];
+              idIt = theOrderIds.begin();
+              for ( int i = 0; idIt != theOrderIds.end(); idIt++ ) {
+                const TListOfInt& idList = *idIt;
+                if (idIt != theOrderIds.begin()) // not first list
+                  smIDs[ i++ ] = -1/* *idList.size()*/; // separator between lists
+                // dump submesh ids from current list
+                TListOfInt::const_iterator id_smId = idList.begin();
+                for( ; id_smId != idList.end(); id_smId++ )
+                  smIDs[ i++ ] = *id_smId;
+              }
+              // write HDF group
+              aSize[ 0 ] = nbIDs + theOrderIds.size() - 1;
+
+              aDataset = new HDFdataset( order_list, aTopGroup, HDF_INT32, aSize, 1 );
+              aDataset->CreateOnDisk();
+              aDataset->WriteOnDisk( smIDs );
+              aDataset->CloseOnDisk();
+              //
+              delete[] smIDs;
+            }
+
             // groups root sub-branch
             SALOMEDS::SObject_var myGroupsBranch;
             for ( int i = GetNodeGroupsTag(); i <= GetVolumeGroupsTag(); i++ ) {
@@ -2887,7 +2921,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                   aDataset->WriteOnDisk( smIDs );
                   aDataset->CloseOnDisk();
                   //
-                  delete smIDs;
+                  delete[] smIDs;
                 }
                 
                 // Store node positions on sub-shapes (SMDS_Position):
@@ -3475,7 +3509,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               }
             }
           }
-
         }
       }
     }
@@ -4098,6 +4131,24 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
           aGroup->CloseOnDisk();
         }
       }
+      // read submeh order if any
+      if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) {
+        aDataset = new HDFdataset( "Mesh Order", aTopGroup );
+        aDataset->OpenOnDisk();
+        size = aDataset->GetSize();
+        int* smIDs = new int[ size ];
+        aDataset->ReadFromDisk( smIDs );
+        aDataset->CloseOnDisk();
+        TListOfListOfInt anOrderIds;
+        anOrderIds.push_back( TListOfInt() );
+        for ( int i = 0; i < size; i++ )
+          if ( smIDs[ i ] < 0 ) // is separator
+            anOrderIds.push_back( TListOfInt() );
+          else
+            anOrderIds.back().push_back(smIDs[ i ]);
+        
+        myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds );
+      }
     }
     // close mesh group
     if(aTopGroup)
index 63a39472cc0e83216595f4c60c561f8504320951..cb38dc54705de301c56dc641adff4beba80ecab0 100644 (file)
@@ -3728,6 +3728,29 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
   return aResult._retn();
 }
 
+//=============================================================================
+/*!
+ * \brief find common submeshes with given submesh
+ * \param theSubMeshList list of already collected submesh to check
+ * \param theSubMesh given submesh to intersect with other
+ * \param theCommonSubMeshes collected common submeshes
+ */
+//=============================================================================
+
+static void findCommonSubMesh
+ (std::list<const SMESH_subMesh*>& theSubMeshList,
+  const SMESH_subMesh*             theSubMesh,
+  std::set<const SMESH_subMesh*>&  theCommon )
+{
+  if ( !theSubMesh )
+    return;
+  std::list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
+  for ( ; it != theSubMeshList.end(); it++ )
+    theSubMesh->FindIntersection( *it, theCommon );
+  theSubMeshList.push_back( theSubMesh );
+  //theCommon.insert( theSubMesh );
+}
+
 //=============================================================================
 /*!
  * \brief Set submesh object order
@@ -3749,6 +3772,11 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
     const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
     TListOfInt subMeshIds;
     aPythonDump << "[ ";
+    // Collect subMeshes which should be clear
+    //  do it list-by-list, because modification of submesh order
+    //  take effect between concurrent submeshes only
+    std::set<const SMESH_subMesh*> subMeshToClear;
+    std::list<const SMESH_subMesh*> subMeshList;
     for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
     {
       const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
@@ -3756,9 +3784,21 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
         aPythonDump << ", ";
       aPythonDump << subMesh;
       subMeshIds.push_back( subMesh->GetId() );
+      // detech common parts of submeshes
+      if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
+        findCommonSubMesh( subMeshList, (*_mapSubMesh.find(subMesh->GetId())).second, subMeshToClear );
     }
     aPythonDump << " ]";
     subMeshOrder.push_back( subMeshIds );
+
+    // clear collected submeshes
+    std::set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
+    for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
+      SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
+        if ( sm )
+          sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+        // ClearSubMesh( *clrIt );
+      }
   }
   aPythonDump << " ])";
 
@@ -3799,6 +3839,8 @@ void SMESH_Mesh_i::convertMeshOrder
     aResSubSet->length(aSubOrder.size());
     TListOfInt::const_iterator subIt = aSubOrder.begin();
     for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
+      if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
+        continue;
       SMESH::SMESH_subMesh_var subMesh =
         SMESH::SMESH_subMesh::_duplicate( (*_mapSubMeshIor.find(*subIt)).second );
       if ( theIsDump ) {