// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
//
//
#include "SMDS_EdgePosition.hxx"
#include "SMDS_FacePosition.hxx"
+#include "SMDS_VertexPosition.hxx"
+#include "SMDS_SpacePosition.hxx"
#include CORBA_SERVER_HEADER(SMESH_Group)
#include CORBA_SERVER_HEADER(SMESH_Filter)
myShapeReader = NULL; // shape reader
mySMESHGen = this;
- OSD::SetSignal( true );
+ // set it in standalone mode only
+ //OSD::SetSignal( true );
}
//=============================================================================
void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode )
{
myIsEmbeddedMode = theMode;
+
+ if ( !myIsEmbeddedMode ) {
+ //PAL10867: disable signals catching with "noexcepthandler" option
+ char* envNoCatchSignals = getenv("NOT_INTERCEPT_SIGNALS");
+ if (!envNoCatchSignals || !atoi(envNoCatchSignals))
+ {
+ bool raiseFPE;
+#ifdef _DEBUG_
+ raiseFPE = true;
+ char* envDisableFPE = getenv("DISABLE_FPE");
+ if (envDisableFPE && atoi(envDisableFPE))
+ raiseFPE = false;
+#else
+ raiseFPE = false;
+#endif
+ OSD::SetSignal( raiseFPE );
+ }
+ // else OSD::SetSignal() is called in GUI
+ }
}
//=============================================================================
myStudyContextMap[ studyId ] = new StudyContext;
}
- SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
- if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() )
- aStudyBuilder->LoadWith( myCurrentStudy->FindComponent( "GEOM" ), GetGeomEngine() );
+ // myCurrentStudy may be nil
+ if ( !CORBA::is_nil( myCurrentStudy ) ) {
+ SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+ if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() )
+ aStudyBuilder->LoadWith( myCurrentStudy->FindComponent( "GEOM" ), GetGeomEngine() );
// set current study for geom engine
//if ( !CORBA::is_nil( GetGeomEngine() ) )
// GetGeomEngine()->GetCurrentStudy( myCurrentStudy->StudyId() );
+ }
}
//=============================================================================
return mesh._retn();
}
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateEmptyMesh
+ *
+ * Create empty mesh
+ */
+//=============================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh()
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMesh" );
+ // create mesh
+ SMESH::SMESH_Mesh_var mesh = this->createMesh();
+
+ // publish mesh in the study
+ if ( CanPublishInStudy( mesh ) ) {
+ SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+ aStudyBuilder->NewCommand(); // There is a transaction
+ SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, mesh.in() );
+ aStudyBuilder->CommitCommand();
+ if ( !aSO->_is_nil() ) {
+ // Update Python script
+ TPythonDump() << aSO << " = " << this << ".CreateEmptyMesh()";
+ }
+ }
+
+ return mesh._retn();
+}
+
//=============================================================================
/*!
* SMESH_Gen_i::CreateMeshFromUNV
SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
ASSERT( aServant );
aServant->ImportUNVFile( theFileName );
+
+ // Dump creation of groups
+ aServant->GetGroups();
+
return aMesh._retn();
}
Unexpect aCatch(SALOME_SalomeException);
if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" );
- // Python Dump
- TPythonDump aPythonDump;
- aPythonDump << "([";
- //TCollection_AsciiString aStr ("([");
-
// Retrieve mesh names from the file
DriverMED_R_SMESHDS_Mesh myReader;
myReader.SetFile( theFileName );
list<string> aNames = myReader.GetMeshNames(aStatus);
SMESH::mesh_array_var aResult = new SMESH::mesh_array();
theStatus = (SMESH::DriverMED_ReadStatus)aStatus;
+
+ { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups()
+
+ // Python Dump
+ TPythonDump aPythonDump;
+ aPythonDump << "([";
+ //TCollection_AsciiString aStr ("([");
+
if (theStatus == SMESH::DRS_OK) {
SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
aStudyBuilder->NewCommand(); // There is a transaction
// Update Python script
aPythonDump << "], status) = " << this << ".CreateMeshesFromMED('" << theFileName << "')";
+ }
+ // Dump creation of groups
+ for ( int i = 0; i < aResult->length(); ++i )
+ aResult[ i ]->GetGroups();
return aResult._retn();
}
return myGen.Compute( myLocMesh, myLocShape);
}
}
+ catch ( std::bad_alloc& exc ) {
+ THROW_SALOME_CORBA_EXCEPTION( "Memory allocation problem",
+ SALOME::INTERNAL_ERROR );
+ }
catch ( SALOME_Exception& S_ex ) {
INFOS( "Compute(): catch exception "<< S_ex.what() );
}
throw ( SALOME::SALOME_Exception )
{
Unexpect aCatch(SALOME_SalomeException);
+
+ GEOM::GEOM_Object_var geom = FindGeometryByMeshElement(theMesh, theElementID);
+ if ( !geom->_is_nil() ) {
+ GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh();
+ GEOM::GEOM_Gen_var geomGen = GetGeomEngine();
+
+ // try to find the corresponding SObject
+ GeomObjectToShape( geom ); // geom client remembers the found shape
+ SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() );
+ if ( SObj->_is_nil() )
+ // publish a new subshape
+ SObj = geomGen->AddInStudy( myCurrentStudy, geom, theGeomName, mainShape );
+ // return only published geometry
+ if ( !SObj->_is_nil() )
+ return geom._retn();
+ }
+ return GEOM::GEOM_Object::_nil();
+}
+
+
+//================================================================================
+/*!
+ * \brief Return geometrical object the given element is built on.
+ * \param theMesh - the mesh the element is in
+ * \param theElementID - the element ID
+ * \retval GEOM::GEOM_Object_ptr - the found geom object
+ */
+//================================================================================
+
+GEOM::GEOM_Object_ptr
+SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh,
+ CORBA::Long theElementID)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
if ( CORBA::is_nil( theMesh ) )
THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", SALOME::BAD_PARAM );
if ( !op->_is_nil() )
geom = op->GetSubShape( mainShape, shapeID );
}
- if ( !geom->_is_nil() ) {
- // try to find the corresponding SObject
- GeomObjectToShape( geom ); // geom client remembers the found shape
- SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() );
- if ( SObj->_is_nil() )
- // publish a new subshape
- SObj = geomGen->AddInStudy( myCurrentStudy, geom, theGeomName, mainShape );
- // return only published geometry
- if ( !SObj->_is_nil() )
- return geom._retn();
- }
+ if ( !geom->_is_nil() )
+ return geom._retn();
}
}
return GEOM::GEOM_Object::_nil();
}
}
// All sub-meshes will be stored in MED file
- if ( shapeRefFound )
- myWriter.AddAllSubMeshes();
+ // .. will NOT (PAL 12992)
+ //if ( shapeRefFound )
+ //myWriter.AddAllSubMeshes();
// groups root sub-branch
SALOMEDS::SObject_var myGroupsBranch;
myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data
}
- // Store node positions on sub-shapes (SMDS_Position):
-
if ( !mySMESHDSMesh->SubMeshes().empty() )
{
+ // Store submeshes
+ // ----------------
+ aGroup = new HDFgroup( "Submeshes", aTopGroup );
+ aGroup->CreateOnDisk();
+
+ // each element belongs to one or none submesh,
+ // so for each node/element, we store a submesh ID
+
+ // Make maps of submesh IDs of elements sorted by element IDs
+ typedef int TElemID;
+ typedef int TSubMID;
+ map< TElemID, TSubMID > eId2smId, nId2smId;
+ map< TElemID, TSubMID >::iterator hint; // insertion to map is done before hint
+ const map<int,SMESHDS_SubMesh*>& aSubMeshes = mySMESHDSMesh->SubMeshes();
+ map<int,SMESHDS_SubMesh*>::const_iterator itSubM ( aSubMeshes.begin() );
+ SMDS_NodeIteratorPtr itNode;
+ SMDS_ElemIteratorPtr itElem;
+ for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ )
+ {
+ TSubMID aSubMeID = itSubM->first;
+ SMESHDS_SubMesh* aSubMesh = itSubM->second;
+ if ( aSubMesh->IsComplexSubmesh() )
+ continue; // submesh containing other submeshs
+ // nodes
+ hint = nId2smId.begin(); // optimize insertion basing on increasing order of elem Ids in submesh
+ for ( itNode = aSubMesh->GetNodes(); itNode->more(); ++hint)
+ hint = nId2smId.insert( hint, make_pair( itNode->next()->GetID(), aSubMeID ));
+ // elements
+ hint = eId2smId.begin();
+ for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint)
+ hint = eId2smId.insert( hint, make_pair( itElem->next()->GetID(), aSubMeID ));
+ }
+
+ // Care of elements that are not on submeshes
+ if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) {
+ for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); )
+ /* --- stl_map.h says : */
+ /* A %map relies on unique keys and thus a %pair is only inserted if its */
+ /* first element (the key) is not already present in the %map. */
+ nId2smId.insert( make_pair( itNode->next()->GetID(), 0 ));
+ }
+ int nbElems = mySMESHDSMesh->NbEdges() + mySMESHDSMesh->NbFaces() + mySMESHDSMesh->NbVolumes();
+ if ( nbElems != eId2smId.size() ) {
+ for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); )
+ eId2smId.insert( make_pair( itElem->next()->GetID(), 0 ));
+ }
+
+ // Store submesh IDs
+ for ( int isNode = 0; isNode < 2; ++isNode )
+ {
+ map< TElemID, TSubMID >& id2smId = isNode ? nId2smId : eId2smId;
+ if ( id2smId.empty() ) continue;
+ map< TElemID, TSubMID >::const_iterator id_smId = id2smId.begin();
+ // make and fill array of submesh IDs
+ int* smIDs = new int [ id2smId.size() ];
+ for ( int i = 0; id_smId != id2smId.end(); ++id_smId, ++i )
+ smIDs[ i ] = id_smId->second;
+ // write HDF group
+ aSize[ 0 ] = id2smId.size();
+ string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
+ aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 );
+ aDataset->CreateOnDisk();
+ aDataset->WriteOnDisk( smIDs );
+ aDataset->CloseOnDisk();
+ //
+ delete smIDs;
+ }
+
+ // Store node positions on sub-shapes (SMDS_Position):
+ // ----------------------------------------------------
+
aGroup = new HDFgroup( "Node Positions", aTopGroup );
aGroup->CreateOnDisk();
int nbEdgeNodes = 0, nbFaceNodes = 0;
list<SMESHDS_SubMesh*> aEdgeSM, aFaceSM;
// loop on SMESHDS_SubMesh'es
- const map<int,SMESHDS_SubMesh*>& aSubMeshes = mySMESHDSMesh->SubMeshes();
- map<int,SMESHDS_SubMesh*>::const_iterator itSubM ( aSubMeshes.begin() );
- for ( ; itSubM != aSubMeshes.end() ; itSubM++ )
+ for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ )
{
SMESHDS_SubMesh* aSubMesh = (*itSubM).second;
if ( aSubMesh->IsComplexSubmesh() )
for ( ; itSM != pListSM->end(); itSM++ )
{
SMESHDS_SubMesh* aSubMesh = (*itSM);
- if ( aSubMesh->IsComplexSubmesh() )
- continue; // submesh containing other submeshs
SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes();
// loop on nodes in aSubMesh
SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() );
}
+//=============================================================================
+/*!
+ * \brief Creates SMDS_Position according to shape type
+ */
+//=============================================================================
+
+class PositionCreator {
+public:
+ SMDS_PositionPtr MakePosition(const TopAbs_ShapeEnum type) {
+ return (this->*myFuncTable[ type ])();
+ }
+ PositionCreator() {
+ myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition );
+ myFuncTable[ TopAbs_FACE ] = & PositionCreator::facePosition;
+ myFuncTable[ TopAbs_EDGE ] = & PositionCreator::edgePosition;
+ myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition;
+ }
+private:
+ SMDS_PositionPtr edgePosition() const { return SMDS_PositionPtr( new SMDS_EdgePosition ); }
+ SMDS_PositionPtr facePosition() const { return SMDS_PositionPtr( new SMDS_FacePosition ); }
+ SMDS_PositionPtr vertexPosition() const { return SMDS_PositionPtr( new SMDS_VertexPosition); }
+ SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition(); }
+ typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const;
+ vector<FmakePos> myFuncTable;
+};
//=============================================================================
/*!
}
if(hasData) {
+
// Read sub-meshes from MED
+ // -------------------------
if(MYDEBUG) MESSAGE("Create all sub-meshes");
- myReader.CreateAllSubMeshes();
+ bool submeshesInFamilies = ( ! aTopGroup->ExistInternalObject( "Submeshes" ));
+ if ( submeshesInFamilies )
+ {
+ // old way working before fix of PAL 12992
+ myReader.CreateAllSubMeshes();
+ }
+ else
+ {
+ // open a group
+ aGroup = new HDFgroup( "Submeshes", aTopGroup );
+ aGroup->OpenOnDisk();
+ int maxID = mySMESHDSMesh->MaxShapeIndex();
+ vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 );
+ vector< TopAbs_ShapeEnum > smType ( maxID + 1, TopAbs_SHAPE );
+
+ PositionCreator aPositionCreator;
+
+ SMDS_NodeIteratorPtr nIt = mySMESHDSMesh->nodesIterator();
+ SMDS_ElemIteratorPtr eIt = mySMESHDSMesh->elementsIterator();
+ for ( int isNode = 0; isNode < 2; ++isNode )
+ {
+ string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
+ if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() ))
+ {
+ aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup );
+ aDataset->OpenOnDisk();
+ // read submesh IDs for all elements sorted by ID
+ int nbElems = aDataset->GetSize();
+ int* smIDs = new int [ nbElems ];
+ aDataset->ReadFromDisk( smIDs );
+ aDataset->CloseOnDisk();
+
+ // get elements sorted by ID
+ ::SMESH_MeshEditor::TIDSortedElemSet elemSet;
+ if ( isNode )
+ while ( nIt->more() ) elemSet.insert( nIt->next() );
+ else
+ while ( eIt->more() ) elemSet.insert( eIt->next() );
+ ASSERT( elemSet.size() == nbElems );
+
+ // add elements to submeshes
+ ::SMESH_MeshEditor::TIDSortedElemSet::iterator iE = elemSet.begin();
+ for ( int i = 0; i < nbElems; ++i, ++iE )
+ {
+ int smID = smIDs[ i ];
+ if ( smID == 0 ) continue;
+ ASSERT( smID <= maxID );
+ const SMDS_MeshElement* elem = *iE;
+ // get or create submesh
+ SMESHDS_SubMesh* & sm = subMeshes[ smID ];
+ if ( ! sm ) {
+ sm = mySMESHDSMesh->NewSubMesh( smID );
+ smType[ smID ] = mySMESHDSMesh->IndexToShape( smID ).ShapeType();
+ }
+ // add
+ if ( isNode ) {
+ SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]);
+ pos->SetShapeId( smID );
+ SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( static_cast<const SMDS_MeshNode*>( elem ));
+ node->SetPosition( pos );
+ sm->AddNode( node );
+ } else {
+ sm->AddElement( elem );
+ }
+ }
+ delete smIDs;
+ }
+ }
+ } // end reading submeshes
// Read node positions on sub-shapes (SMDS_Position)
nbFids = aSize;
}
}
+ aDataset->CloseOnDisk();
} // loop on 5 datasets
// Set node positions on edges or faces