X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_Mesh_i.cxx;h=f9ec3b9c7020efe065c731515876a9d1e110693f;hp=b47ae9b19e261cd1c7ae03d6f169e51d68bbb774;hb=460317455ef0ba4015ca5cb0620cc9aa46f13078;hpb=ffa52542822b49458a812f75afed40e95fcb4b51 diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index b47ae9b19..f9ec3b9c7 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2014 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 @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -26,6 +26,7 @@ #include "SMESH_Mesh_i.hxx" #include "DriverMED_R_SMESHDS_Mesh.h" +#include "DriverMED_W_Field.h" #include "DriverMED_W_SMESHDS_Mesh.h" #include "MED_Factory.hxx" #include "SMDS_EdgePosition.hxx" @@ -81,8 +82,6 @@ #include #include -#include "SMESH_TryCatch.hxx" // include after OCCT headers! - // STL Includes #include #include @@ -91,6 +90,11 @@ #include +// to pass CORBA exception through SMESH_TRY +#define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; } + +#include "SMESH_TryCatch.hxx" // include after OCCT headers! + #ifdef _DEBUG_ static int MYDEBUG = 0; #else @@ -121,6 +125,7 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, _editor = NULL; _previewEditor = NULL; _preMeshInfo = NULL; + _mainShapeTick = 0; } //============================================================================= @@ -194,6 +199,7 @@ void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject ) // to track changes of GEOM groups SMESH::SMESH_Mesh_var mesh = _this(); addGeomGroupData( theShapeObject, mesh ); + _mainShapeTick = theShapeObject->GetTick(); } //================================================================================ @@ -276,7 +282,7 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception) try { _impl->Clear(); - CheckGeomGroupModif(); // issue 20145 + //CheckGeomGroupModif(); // issue 20145 } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); @@ -1504,7 +1510,7 @@ SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, if ( aType == SMESH::ALL ) aType = aGrp->GetType(); else if ( aType != aGrp->GetType() ) - THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types", + THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types", SALOME::BAD_PARAM); if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) @@ -1522,7 +1528,7 @@ SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, if ( CORBA::is_nil( aGrp ) ) continue; if ( aType != aGrp->GetType() ) - THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types", + THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types", SALOME::BAD_PARAM); if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) @@ -1703,6 +1709,9 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, groupData._indices.insert( ids[i] ); // SMESH object groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj ); + // shape index in SMESHDS + // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj ); + // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId(); } //================================================================================ @@ -1776,22 +1785,176 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) namespace { - //============================================================================= + //----------------------------------------------------------------------------- /*! * \brief Storage of shape and index used in CheckGeomGroupModif() */ - //============================================================================= struct TIndexedShape { int _index; TopoDS_Shape _shape; TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {} }; + //----------------------------------------------------------------------------- + /*! + * \brief Data to re-create a group on geometry + */ + struct TGroupOnGeomData + { + int _oldID; + int _shapeID; + SMDSAbs_ElementType _type; + std::string _name; + Quantity_Color _color; + }; +} + +//============================================================================= +/*! + * \brief Update data if geometry changes + * + * Issue 0022501 + */ +//============================================================================= + +void SMESH_Mesh_i::CheckGeomModif() +{ + if ( !_impl->HasShapeToMesh() ) return; + + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + if ( study->_is_nil() ) return; + + GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() ); + if ( mainGO->_is_nil() ) return; + + if ( mainGO->GetType() == GEOM_GROUP || + mainGO->GetTick() == _mainShapeTick ) + { + CheckGeomGroupModif(); + return; + } + + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + if ( !geomClient ) return; + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); + if ( geomGen->_is_nil() ) return; + + CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + + // Update data taking into account that + // all sub-shapes change but IDs of sub-shapes remain (except for geom groups) + + _impl->Clear(); + TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO ); + if ( newShape.IsNull() ) + return; + + _mainShapeTick = mainGO->GetTick(); + + SMESHDS_Mesh * meshDS = _impl->GetMeshDS(); + + // store data of groups on geometry + vector< TGroupOnGeomData > groupsData; + const set& groups = meshDS->GetGroups(); + groupsData.reserve( groups.size() ); + set::const_iterator g = groups.begin(); + for ( ; g != groups.end(); ++g ) + if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g )) + { + TGroupOnGeomData data; + data._oldID = group->GetID(); + data._shapeID = meshDS->ShapeToIndex( group->GetShape() ); + data._type = group->GetType(); + data._name = group->GetStoreName(); + data._color = group->GetColor(); + groupsData.push_back( data ); + } + // store assigned hypotheses + vector< pair< int, THypList > > ids2Hyps; + const ShapeToHypothesis & hyps = meshDS->GetHypotheses(); + for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() ) + { + const TopoDS_Shape& s = s2hyps.Key(); + const THypList& hyps = s2hyps.ChangeValue(); + ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps )); + } + + // change shape to mesh + int oldNbSubShapes = meshDS->MaxShapeIndex(); + _impl->ShapeToMesh( TopoDS_Shape() ); + _impl->ShapeToMesh( newShape ); + + // re-add shapes of geom groups + list::iterator data = _geomGroupData.begin(); + for ( ; data != _geomGroupData.end(); ++data ) + { + TopoDS_Shape newShape = newGroupShape( *data ); + if ( !newShape.IsNull() ) + { + if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape + { + TopoDS_Compound compound; + BRep_Builder().MakeCompound( compound ); + BRep_Builder().Add( compound, newShape ); + newShape = compound; + } + _impl->GetSubMesh( newShape ); + } + } + if ( oldNbSubShapes != meshDS->MaxShapeIndex() ) + THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug", + SALOME::INTERNAL_ERROR ); + + // re-assign hypotheses + for ( size_t i = 0; i < ids2Hyps.size(); ++i ) + { + const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first ); + const THypList& hyps = ids2Hyps[i].second; + THypList::const_iterator h = hyps.begin(); + for ( ; h != hyps.end(); ++h ) + _impl->AddHypothesis( s, (*h)->GetID() ); + } + + // restore groups + for ( size_t i = 0; i < groupsData.size(); ++i ) + { + const TGroupOnGeomData& data = groupsData[i]; + + map::iterator i2g = _mapGroups.find( data._oldID ); + if ( i2g == _mapGroups.end() ) continue; + + SMESH_GroupBase_i* gr_i = SMESH::DownCast( i2g->second ); + if ( !gr_i ) continue; + + int id; + SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id, + meshDS->IndexToShape( data._shapeID )); + if ( !g ) + { + _mapGroups.erase( i2g ); + } + else + { + g->GetGroupDS()->SetColor( data._color ); + gr_i->changeLocalId( id ); + _mapGroups[ id ] = i2g->second; + if ( data._oldID != id ) + _mapGroups.erase( i2g ); + } + } + + // update _mapSubMesh + map::iterator i_sm = _mapSubMesh.begin(); + for ( ; i_sm != _mapSubMesh.end(); ++i_sm ) + i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first )); + } + //============================================================================= /*! * \brief Update objects depending on changed geom groups - * + * * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation * issue 0020210: Update of a smesh group after modification of the associated geom group */ @@ -2716,13 +2879,13 @@ void SMESH_Mesh_i::ExportToMEDX (const char* file, _preMeshInfo->FullLoadFromFile(); string aMeshName = prepareMeshNameAndGroups(file, overwrite); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension ); + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'" << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << ", " << autoDimension << " )"; - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension ); - SMESH_CATCH( SMESH::throwCorbaException ); } @@ -2850,20 +3013,65 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) */ //================================================================================ -void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart, - const char* file, - CORBA::Boolean auto_groups, - ::SMESH::MED_VERSION version, - ::CORBA::Boolean overwrite, - ::CORBA::Boolean autoDimension) +void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean auto_groups, + SMESH::MED_VERSION version, + CORBA::Boolean overwrite, + CORBA::Boolean autoDimension, + const GEOM::ListOfFields& fields, + const char* geomAssocFields) throw (SALOME::SALOME_Exception) { - Unexpect aCatch(SALOME_SalomeException); - TPythonDump pyDump; + SMESH_TRY; + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); - if ( SMESH_Mesh_i * mesh = SMESH::DownCast< SMESH_Mesh_i* >( meshPart )) + // check fields + bool have0dField = false; + if ( fields.length() > 0 ) { - mesh->ExportToMEDX( file, auto_groups, version, autoDimension ); + GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh(); + if ( shapeToMesh->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR ); + + for ( size_t i = 0; i < fields.length(); ++i ) + { + if ( fields[i]->GetDataType() == GEOM::FDT_String ) + THROW_SALOME_CORBA_EXCEPTION + ( "Export of string fields is not supported", SALOME::BAD_PARAM); + GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape(); + if ( fieldShape->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR ); + if ( !fieldShape->IsSame( shapeToMesh ) ) + THROW_SALOME_CORBA_EXCEPTION + ( "Field defined not on shape", SALOME::BAD_PARAM); + if ( fields[i]->GetDimension() == 0 ) + have0dField = true; + } + if ( geomAssocFields ) + for ( int i = 0; geomAssocFields[i]; ++i ) + switch ( geomAssocFields[i] ) { + case 'v':case 'e':case 'f':case 's': break; + case 'V':case 'E':case 'F':case 'S': break; + default: THROW_SALOME_CORBA_EXCEPTION + ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM); + } + } + + SMESHDS_Mesh* meshDS = _impl->GetMeshDS(); + + // write mesh + + string aMeshName = "Mesh"; + SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0); + if ( CORBA::is_nil( meshPart ) || + SMESH::DownCast< SMESH_Mesh_i* >( meshPart )) + { + aMeshName = prepareMeshNameAndGroups(file, overwrite); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, + version, 0, autoDimension, have0dField); + meshDS = _impl->GetMeshDS(); } else { @@ -2872,7 +3080,6 @@ void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart, PrepareForWriting(file, overwrite); - string aMeshName = "Mesh"; SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); if ( !aStudy->_is_nil() ) { SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart ); @@ -2881,13 +3088,287 @@ void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart, aMeshName = name; } } - SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS, autoDimension ); + SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart ); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, + version, partDS, autoDimension, have0dField); + meshDS = tmpDSDeleter._obj = partDS; } - pyDump << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToMED( " - << meshPart << ", r'" << file << "', " - << auto_groups << ", " << version << ", " << overwrite << ", " - << autoDimension << " )"; + + // write fields + + if ( _impl->HasShapeToMesh() ) + { + DriverMED_W_Field fieldWriter; + fieldWriter.SetFile( file ); + fieldWriter.SetMeshName( aMeshName ); + fieldWriter.AddODOnVertices( have0dField ); + + exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields ); + } + + // dump + GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO; + goList->length( fields.length() ); + for ( size_t i = 0; i < fields.length(); ++i ) + { + GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] ); + goList[i] = gbo; + } + TPythonDump() << _this() << ".ExportPartToMED( " + << meshPart << ", r'" << file << "', " + << auto_groups << ", " << version << ", " << overwrite << ", " + << autoDimension << ", " << goList + << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); +} + +//================================================================================ +/*! + * Write GEOM fields to MED file + */ +//================================================================================ + +void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, + SMESHDS_Mesh* meshDS, + const GEOM::ListOfFields& fields, + const char* geomAssocFields) +{ +#define METH "SMESH_Mesh_i::exportMEDFields() " + + if (( fields.length() < 1 ) && + ( !geomAssocFields || !geomAssocFields[0] )) + return; + + std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 ); + std::vector< int > intVals( meshDS->MaxShapeIndex()+1 ); + std::vector< int > subIdsByDim[ 4 ]; + const double noneDblValue = 0.; + const double noneIntValue = 0; + + for ( size_t iF = 0; iF < fields.length(); ++iF ) + { + // set field data + + int dim = fields[ iF ]->GetDimension(); + SMDSAbs_ElementType elemType; + TopAbs_ShapeEnum shapeType; + switch ( dim ) { + case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break; + case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break; + case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break; + case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break; + default: + continue; // skip fields on whole shape + } + GEOM::field_data_type dataType = fields[ iF ]->GetDataType(); + if ( dataType == GEOM::FDT_String ) + continue; + GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps(); + if ( stepIDs->length() < 1 ) + continue; + GEOM::string_array_var comps = fields[ iF ]->GetComponents(); + if ( comps->length() < 1 ) + continue; + CORBA::String_var name = fields[ iF ]->GetName(); + + if ( !fieldWriter.Set( meshDS, + name.in(), + elemType, + comps->length(), + ( dataType == GEOM::FDT_Int ))) + continue; + + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.SetCompName( iC, comps[ iC ].in() ); + + // find sub-shape IDs + + std::vector< int >& subIds = subIdsByDim[ dim ]; + if ( subIds.empty() ) + for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id ) + if ( meshDS->IndexToShape( id ).ShapeType() == shapeType ) + subIds.push_back( id ); + + // write steps + + SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems(); + if ( !elemIt ) + continue; + + for ( size_t iS = 0; iS < stepIDs->length(); ++iS ) + { + GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]); + if ( step->_is_nil() ) + continue; + + CORBA::Long stamp = step->GetStamp(); + CORBA::Long id = step->GetID(); + fieldWriter.SetDtIt( int( stamp ), int( id )); + + // fill dblVals or intVals + switch ( dataType ) + { + case GEOM::FDT_Double: + { + GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step ); + if ( dblStep->_is_nil() ) continue; + GEOM::ListOfDouble_var vv = dblStep->GetValues(); + if ( vv->length() != subIds.size() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t i = 0; i < vv->length(); ++i ) + dblVals[ subIds[ i ]] = vv[ i ]; + break; + } + case GEOM::FDT_Int: + { + GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step ); + if ( intStep->_is_nil() ) continue; + GEOM::ListOfLong_var vv = intStep->GetValues(); + if ( vv->length() != subIds.size() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t i = 0; i < vv->length(); ++i ) + intVals[ subIds[ i ]] = (int) vv[ i ]; + break; + } + case GEOM::FDT_Bool: + { + GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step ); + if ( boolStep->_is_nil() ) continue; + GEOM::short_array_var vv = boolStep->GetValues(); + if ( vv->length() != subIds.size() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t i = 0; i < vv->length(); ++i ) + intVals[ subIds[ i ]] = (int) vv[ i ]; + break; + } + default: continue; + } + + // pass values to fieldWriter + elemIt = fieldWriter.GetOrderedElems(); + if ( dataType == GEOM::FDT_Double ) + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 || shapeID >= dblVals.size() ) + fieldWriter.AddValue( noneDblValue ); + else + fieldWriter.AddValue( dblVals[ shapeID ]); + } + else + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 || shapeID >= intVals.size() ) + fieldWriter.AddValue( noneIntValue ); + else + fieldWriter.AddValue( intVals[ shapeID ]); + } + + // write a step + fieldWriter.Perform(); + SMESH_ComputeErrorPtr res = fieldWriter.GetError(); + if ( res && res->IsKO() ) + { + if ( res->myComment.empty() ) + { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); } + else + { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); } + } + + } // loop on steps + } // loop on fields + + if ( !geomAssocFields || !geomAssocFields[0] ) + return; + + // write geomAssocFields + + std::vector< int > shapeDim( TopAbs_SHAPE + 1 ); + shapeDim[ TopAbs_COMPOUND ] = 3; + shapeDim[ TopAbs_COMPSOLID ] = 3; + shapeDim[ TopAbs_SOLID ] = 3; + shapeDim[ TopAbs_SHELL ] = 2; + shapeDim[ TopAbs_FACE ] = 2; + shapeDim[ TopAbs_WIRE ] = 1; + shapeDim[ TopAbs_EDGE ] = 1; + shapeDim[ TopAbs_VERTEX ] = 0; + shapeDim[ TopAbs_SHAPE ] = 3; + + for ( int iF = 0; geomAssocFields[ iF ]; ++iF ) + { + std::vector< std::string > compNames; + switch ( geomAssocFields[ iF ]) { + case 'v': case 'V': + fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/true ); + compNames.push_back( "dim" ); + break; + case 'e': case 'E': + fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/true ); + break; + case 'f': case 'F': + fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/true ); + break; + case 's': case 'S': + fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/true ); + break; + default: continue; + } + compNames.push_back( "id" ); + for ( size_t iC = 0; iC < compNames.size(); ++iC ) + fieldWriter.SetCompName( iC, compNames[ iC ].c_str() ); + + fieldWriter.SetDtIt( -1, -1 ); + + SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems(); + if ( !elemIt ) + continue; + + if ( compNames.size() == 2 ) // _vertices_ + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 ) + { + fieldWriter.AddValue( -1 ); + fieldWriter.AddValue( -1 ); + } + else + { + const TopoDS_Shape& S = meshDS->IndexToShape( shapeID ); + fieldWriter.AddValue( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]); + fieldWriter.AddValue( shapeID ); + } + } + else + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 ) + fieldWriter.AddValue( -1 ); + else + fieldWriter.AddValue( shapeID ); + } + + // write a step + fieldWriter.Perform(); + SMESH_ComputeErrorPtr res = fieldWriter.GetError(); + if ( res && res->IsKO() ) + { + if ( res->myComment.empty() ) + { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); } + else + { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); } + } + + } // loop on geomAssocFields + +#undef METH } //================================================================================ @@ -4048,7 +4529,8 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, //purpose : Returns three components of normal of given mesh face. //======================================================================= -SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId) +SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId, + CORBA::Boolean normalized) { if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -4058,7 +4540,7 @@ SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId) if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) { gp_XYZ normal; - if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, /*normalized=*/true )) + if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized )) { aResult->length( 3 ); aResult[ 0 ] = normal.X(); @@ -5099,8 +5581,37 @@ void findCommonSubMesh (list& theSubMeshList, //theCommon.insert( theSubMesh ); } +//----------------------------------------------------------------------------- +bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists ) +{ + TListOfListOfInt::const_iterator listsIt = smLists.begin(); + for ( ; listsIt != smLists.end(); ++listsIt ) + { + const TListOfInt& smIDs = *listsIt; + if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() ) + return true; + } + return false; +} + } // namespace +//============================================================================= +/*! + * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh + */ +//============================================================================= + +CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID) +{ + TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order + if ( isSubMeshInList( submeshID, anOrder )) + return false; + + TListOfListOfInt allConurrent = findConcurrentSubMeshes(); + return isSubMeshInList( submeshID, allConurrent ); +} + //============================================================================= /*! * \brief Return submesh objects list in meshing order @@ -5114,14 +5625,37 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); if ( !aMeshDS ) return aResult._retn(); - - ::SMESH_Mesh& mesh = GetImpl(); - TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order? - if ( !anOrder.size() ) { + TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order + TListOfListOfInt allConurrent = findConcurrentSubMeshes(); + anOrder.splice( anOrder.end(), allConurrent ); + + int listIndx = 0; + TListOfListOfInt::iterator listIt = anOrder.begin(); + for(; listIt != anOrder.end(); listIt++, listIndx++ ) + unionLists( *listIt, anOrder, listIndx + 1 ); + + // convert submesh ids into interface instances + // and dump command into python + convertMeshOrder( anOrder, aResult, false ); + + return aResult._retn(); +} + +//============================================================================= +/*! + * \brief Finds concurrent sub-meshes + */ +//============================================================================= + +TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() +{ + TListOfListOfInt anOrder; + ::SMESH_Mesh& mesh = GetImpl(); + { // collect submeshes and detect concurrent algorithms and hypothesises TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension - + map::iterator i_sm = _mapSubMesh.begin(); for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) { ::SMESH_subMesh* sm = (*i_sm).second; @@ -5193,11 +5727,8 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() for(; listIt != anOrder.end(); listIt++, listIndx++ ) unionLists( *listIt, anOrder, listIndx + 1 ); } - // convert submesh ids into interface instances - // and dump command into python - convertMeshOrder( anOrder, aResult, false ); - return aResult._retn(); + return anOrder; } //============================================================================= @@ -5286,7 +5817,8 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array(); aResSubSet->length(aSubOrder.size()); TListOfInt::const_iterator subIt = aSubOrder.begin(); - for( int j = 0; subIt != aSubOrder.end(); subIt++ ) { + int j; + for( j = 0; subIt != aSubOrder.end(); subIt++ ) { if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() ) continue; SMESH::SMESH_subMesh_var subMesh = @@ -5300,7 +5832,8 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, } if ( theIsDump ) aPythonDump << " ]"; - theResOrder[ listIndx++ ] = aResSubSet; + if ( j > 1 ) + theResOrder[ listIndx++ ] = aResSubSet; } // correct number of lists theResOrder.length( listIndx );