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;
// 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;
}
//================================================================================
#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;
// 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
//
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;
}
// 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();
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)
}
}
}
- 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:
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
}
else
{
- meshedFaces.push_back( prism.myBottom );
+ suspectSourceFaces.push_back( prism.myBottom );
if ( prism.myAlgoSM && prism.myAlgoSM->GetAlgo() )
meshedFace2AlgoSM.Bind( prism.myBottom, prism.myAlgoSM );
}
//=============================================================================
/*!
- *
+ * Compute the mesh on the given shape
*/
//=============================================================================
//=============================================================================
/*!
- *
+ * Return FaceQuadStruct where sides ordered CCW, top and left sides
+ * reversed to be co-directed with bottom and right sides
*/
//=============================================================================