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=a9264306ce7a952c97db72620c208eb1b6db2cab;hp=74815a4ffb6da1be32aa5bdcee92258d80ab0ac6;hb=cc85955178440fffe36eef234d759e3c3590248f;hpb=3785fda32c59dfa7cf1ac7c680cc185be0bdcdfc diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 74815a4ff..a9264306c 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -96,6 +96,7 @@ static int MYDEBUG = 0; using namespace std; using SMESH::TPythonDump; +using SMESH::TVar; int SMESH_Mesh_i::_idGenerator = 0; @@ -239,7 +240,7 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh() for ( ; data != _geomGroupData.end(); ++data ) if ( data->_smeshObject->_is_equivalent( _this() )) { - SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() ); + SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() ); CORBA::Object_var obj = _gen_i->SObjectToObject( so ); aShapeObj = GEOM::GEOM_Object::_narrow( obj ); break; @@ -468,6 +469,23 @@ char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits) return CORBA::string_dup( ver.c_str() ); } +//================================================================================ +/*! + * Return the list of med versions compatibles for write/append, + * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) + */ +//================================================================================ +SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend() +{ + SMESH::long_array_var aResult = new SMESH::long_array(); + std::vector mvok = MED::GetMEDVersionsAppendCompatible(); + long nbver = mvok.size(); + aResult->length( nbver ); + for ( int i = 0; i < nbver; i++ ) + aResult[i] = mvok[i]; + return aResult._retn(); +} + //============================================================================= /*! * ImportUNVFile @@ -674,9 +692,9 @@ SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape, //use PseudoShape in case if mesh has no shape if(HasShapeToMesh()) myLocSubShape = _gen_i->GeomObjectToShape( aSubShape); - else + else myLocSubShape = _impl->GetShapeToMesh(); - + const int hypId = anHyp->GetId(); std::string error; status = _impl->AddHypothesis( myLocSubShape, hypId, &error ); @@ -754,6 +772,9 @@ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape, if (CORBA::is_nil( anHyp )) THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM); + if ( _preMeshInfo ) + _preMeshInfo->ForgetOrLoad(); + SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; try { @@ -937,7 +958,7 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617) // aSubShape = theSubMesh->GetSubShape(); - SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder(); + SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder(); builder->RemoveObjectWithChildren( anSO ); // Update Python script @@ -1001,8 +1022,8 @@ SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType, TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj ); if ( !aShape.IsNull() ) { - aNewGroup = - SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape )); + aNewGroup = + SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape )); if ( _gen_i->CanPublishInStudy( aNewGroup ) ) { @@ -1046,7 +1067,7 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM); SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow - ( createGroup( theElemType, theName, TopoDS_Shape(), predicate )); + ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate )); TPythonDump pd; if ( !aNewGroup->_is_nil() ) @@ -1393,7 +1414,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr //============================================================================= /*! - \brief Intersect list of groups. New group is created. All mesh elements that + \brief Intersect list of groups. New group is created. All mesh elements that are present in all initial groups simultaneously are added to the new one. \param theGroups list of groups \param theName name of group to be created @@ -1478,7 +1499,7 @@ SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups, } //============================================================================= -/*! +/*! * New group is created. All mesh elements that are present in * a main group but is not present in a tool group are added to the new one */ @@ -1541,7 +1562,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr //============================================================================= /*! - \brief Cut lists of groups. New group is created. All mesh elements that are + \brief Cut lists of groups. New group is created. All mesh elements that are present in main groups but do not present in tool groups are added to the new one \param theMainGroups list of main groups \param theToolGroups list of tool groups @@ -1550,8 +1571,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr */ //============================================================================= SMESH::SMESH_Group_ptr -SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, - const SMESH::ListOfGroups& theToolGroups, +SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, + const SMESH::ListOfGroups& theToolGroups, const char* theName ) throw (SALOME::SALOME_Exception) { @@ -1851,6 +1872,89 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups, return aResGrp._retn(); } +//================================================================================ +/*! + * \brief Distribute all faces of the mesh between groups using sharp edges and optionally + * existing 1D elements as group boundaries. + * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of + * adjacent faces is more than \a sharpAngle in degrees. + * \param [in] theCreateEdges - to create 1D elements for detected sharp edges. + * \param [in] theUseExistingEdges - to use existing edges as group boundaries + * \return ListOfGroups - the created groups + */ +//================================================================================ + +SMESH::ListOfGroups* +SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle, + CORBA::Boolean theCreateEdges, + CORBA::Boolean theUseExistingEdges ) + throw (SALOME::SALOME_Exception) +{ + if ( theSharpAngle < 0 || theSharpAngle > 180 ) + THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees", + SALOME::BAD_PARAM); + + SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups; + + TPythonDump pyDump; + + SMESH_TRY; + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESHDS_Mesh* meshDS = _impl->GetMeshDS(); + + std::vector< SMESH_MeshAlgos::Edge > edges = + SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges ); + + if ( theCreateEdges ) + { + std::vector nodes(2); + for ( size_t i = 0; i < edges.size(); ++i ) + { + nodes[0] = edges[i]._node1; + nodes[1] = edges[i]._node2; + if ( meshDS->FindElement( nodes, SMDSAbs_Edge )) + continue; + if ( edges[i]._medium ) + meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium ); + else + meshDS->AddEdge( edges[i]._node1, edges[i]._node2 ); + } + } + + std::vector< std::vector< const SMDS_MeshElement* > > faceGroups = + SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges ); + + SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor + + resultGroups->length( faceGroups.size() ); + for ( size_t iG = 0; iG < faceGroups.size(); ++iG ) + { + SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE, + _editor->GenerateGroupName("Group").c_str()); + resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group ); + + SMESHDS_GroupBase* groupBaseDS = + SMESH::DownCast( group )->GetGroupDS(); + SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup(); + + std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ]; + for ( size_t i = 0; i < faces.size(); ++i ) + groupCore.Add( faces[i] ); + } + + pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this()) + << ".FaceGroupsSeparatedByEdges( " + << TVar( theSharpAngle ) << ", " + << theCreateEdges << ", " + << theUseExistingEdges << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); + return resultGroups._retn(); + +} + //================================================================================ /*! * \brief Remember GEOM group data @@ -1974,11 +2078,66 @@ namespace struct TGroupOnGeomData { int _oldID; - int _shapeID; + TopoDS_Shape _shape; SMDSAbs_ElementType _type; std::string _name; Quantity_Color _color; + + TGroupOnGeomData( const SMESHDS_GroupOnGeom* group ) + { + _oldID = group->GetID(); + _type = group->GetType(); + _name = group->GetStoreName(); + _color = group->GetColor(); + } }; + + //----------------------------------------------------------------------------- + /*! + * \brief Check if a filter is still valid after geometry removal + */ + bool isValidGeomFilter( SMESH::Filter_var theFilter ) + { + if ( theFilter->_is_nil() ) + return false; + SMESH::Filter::Criteria_var criteria; + theFilter->GetCriteria( criteria.out() ); + + for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr ) + { + const char* thresholdID = criteria[ iCr ].ThresholdID.in(); + std::string entry; + switch ( criteria[ iCr ].Type ) + { + case SMESH::FT_BelongToGeom: + case SMESH::FT_BelongToPlane: + case SMESH::FT_BelongToCylinder: + case SMESH::FT_BelongToGenSurface: + case SMESH::FT_LyingOnGeom: + entry = thresholdID; + break; + case SMESH::FT_ConnectedElements: + if ( thresholdID ) + { + entry = thresholdID; + break; + } + default: + continue; + } + SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() ); + if ( so->_is_nil() ) + return false; + CORBA::Object_var obj = so->GetObject(); + GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj ); + if ( gen->GeomObjectToShape( geom ).IsNull() ) + return false; + + } // loop on criteria + + return true; + } } //============================================================================= @@ -1991,19 +2150,67 @@ namespace void SMESH_Mesh_i::CheckGeomModif() { + SMESH::SMESH_Mesh_var me = _this(); + GEOM::GEOM_Object_var mainGO = GetShapeToMesh(); + + //bool removedFromClient = false; + + if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636) + { + //removedFromClient = _impl->HasShapeToMesh(); + + // try to find geometry by study reference + SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me ); + SALOMEDS::SObject_wrap geomRefSO, geomSO; + if ( !meshSO->_is_nil() && + meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) && + geomRefSO->ReferencedObject( geomSO.inout() )) + { + CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO ); + mainGO = GEOM::GEOM_Object::_narrow( geomObj ); + } + + if ( mainGO->_is_nil() && // geometry removed ==> + !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc. + { + // convert geom dependent groups into standalone ones + CheckGeomGroupModif(); + + _impl->ShapeToMesh( TopoDS_Shape() ); + + // remove sub-meshes + std::map::iterator i_sm = _mapSubMeshIor.begin(); + while ( i_sm != _mapSubMeshIor.end() ) + { + SMESH::SMESH_subMesh_ptr sm = i_sm->second; + ++i_sm; + RemoveSubMesh( sm ); + } + // remove all children except groups in the study + SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder(); + SALOMEDS::SObject_wrap so; + for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag ) + if ( meshSO->FindSubObject( tag, so.inout() )) + builder->RemoveObjectWithChildren( so ); + + _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" ); + + return; + } + } + if ( !_impl->HasShapeToMesh() ) return; - GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() ); - //if ( mainGO->_is_nil() ) return; // Update after group modification - if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape() - called by other mesh (IPAL52735) */ - mainGO->GetType() == GEOM_GROUP || + if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified mainGO->GetTick() == _mainShapeTick ) { + int nb = NbNodes() + NbElements(); CheckGeomGroupModif(); + if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change + _gen_i->UpdateIcons( me ); return; } @@ -2030,23 +2237,35 @@ void SMESH_Mesh_i::CheckGeomModif() SMESHDS_Mesh * meshDS = _impl->GetMeshDS(); // store data of groups on geometry - vector< TGroupOnGeomData > groupsData; - const set& groups = meshDS->GetGroups(); + std::vector< TGroupOnGeomData > groupsData; + const std::set& groups = meshDS->GetGroups(); groupsData.reserve( groups.size() ); - set::const_iterator g = groups.begin(); + std::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 ); + groupsData.push_back( TGroupOnGeomData( group )); + + // get a new shape + SMESH::SMESH_GroupOnGeom_var gog; + std::map::iterator i_grp = _mapGroups.find( group->GetID() ); + if ( i_grp != _mapGroups.end() ) + gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second ); + + GEOM::GEOM_Object_var geom; + if ( !gog->_is_nil() ) + geom = gog->GetShape(); + if ( !geom->_is_nil() ) + { + CORBA::String_var ior = geomGen->GetStringFromIOR( geom ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + groupsData.back()._shape = _gen_i->GeomObjectToShape( geom ); + } } + } // store assigned hypotheses - vector< pair< int, THypList > > ids2Hyps; + std::vector< pair< int, THypList > > ids2Hyps; const ShapeToHypothesis & hyps = meshDS->GetHypotheses(); for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() ) { @@ -2061,7 +2280,7 @@ void SMESH_Mesh_i::CheckGeomModif() _impl->ShapeToMesh( newShape ); // re-add shapes of geom groups - list::iterator data = _geomGroupData.begin(); + std::list::iterator data = _geomGroupData.begin(); for ( ; data != _geomGroupData.end(); ++data ) { TopoDS_Shape newShape = newGroupShape( *data ); @@ -2091,36 +2310,28 @@ void SMESH_Mesh_i::CheckGeomModif() _impl->AddHypothesis( s, (*h)->GetID() ); } - // restore groups + // restore groups on geometry for ( size_t i = 0; i < groupsData.size(); ++i ) { const TGroupOnGeomData& data = groupsData[i]; + if ( data._shape.IsNull() ) + continue; - map::iterator i2g = _mapGroups.find( data._oldID ); + std::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 )); + SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape ); 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(); + std::map::iterator i_sm = _mapSubMesh.begin(); for ( ; i_sm != _mapSubMesh.end(); ++i_sm ) i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first )); @@ -2137,6 +2348,98 @@ void SMESH_Mesh_i::CheckGeomModif() void SMESH_Mesh_i::CheckGeomGroupModif() { + // remove sub-meshes referring a removed sub-shapes (if main shape still exists) + SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder(); + GEOM::GEOM_Object_var mainGO = GetShapeToMesh(); + SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() )); + if ( !mainGO->_is_nil() && !meshSO->_is_nil() ) + { + SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO; + for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag ) + if ( meshSO->FindSubObject( tag, rootSO.inout() )) + { + int nbValid = 0, nbRemoved = 0; + SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO ); + for ( ; chItr->More(); chItr->Next() ) + { + SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO + if ( !smSO->_is_nil() && + smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) && + geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference + { + CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO ); + GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj ); + if ( !geom->_non_existent() ) + { + ++nbValid; + continue; // keep the sub-mesh + } + } + CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO ); + SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj ); + if ( !sm->_is_nil() && !sm->_non_existent() ) + { + GEOM::GEOM_Object_var smGeom = sm->GetSubShape(); + if ( smGeom->_is_nil() ) + { + RemoveSubMesh( sm ); + ++nbRemoved; + } + } + else + { + if ( _preMeshInfo ) + _preMeshInfo->ForgetAllData(); // unknown hypothesis modified + builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH + ++nbRemoved; + } + } + if ( /*nbRemoved > 0 &&*/ nbValid == 0 ) + builder->RemoveObjectWithChildren( rootSO ); + } + } + + // check for removed sub-shapes and convert geom dependent groups into standalone ones + std::map::iterator i_gr = _mapGroups.begin(); + while ( i_gr != _mapGroups.end()) + { + SMESH::SMESH_GroupBase_ptr group = i_gr->second; + ++i_gr; + SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO; + SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group ); + SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group ); + bool isValidGeom = false; + if ( !onGeom->_is_nil() ) + { + isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); + } + else if ( !onFilt->_is_nil() ) + { + isValidGeom = isValidGeomFilter( onFilt->GetFilter() ); + } + else // standalone + { + isValidGeom = ( !groupSO->_is_nil() && + !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() )); + } + if ( !isValidGeom ) + { + if ( !IsLoaded() || group->IsEmpty() ) + { + RemoveGroup( group ); + } + else if ( !onGeom->_is_nil() || !onFilt->_is_nil() ) + { + SMESH::SMESH_Group_var ( ConvertToStandalone( group )); + } + else // is it possible? + { + builder->RemoveObjectWithChildren( refSO ); + } + } + } + + if ( !_impl->HasShapeToMesh() ) return; CORBA::Long nbEntities = NbNodes() + NbElements(); @@ -2283,7 +2586,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() groupData.push_back ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType())); } - // set new shape to mesh -> DS of sub-meshes and geom groups are deleted + // set new shape to mesh -> DS of sub-meshes and geom groups is deleted _impl->Clear(); _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730 _impl->ShapeToMesh( newShape ); @@ -2328,10 +2631,10 @@ void SMESH_Mesh_i::CheckGeomGroupModif() SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] ); CORBA::String_var name = groupSO->GetName(); // update - SMESH_GroupBase_i* group_i = SMESH::DownCast(_mapGroups[oldID] ); - int newID; - if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape )) - group_i->changeLocalId( newID ); + if ( SMESH_GroupBase_i* group_i = SMESH::DownCast(_mapGroups[oldID])) + if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(), + /*id=*/-1, geom._shape )) + group_i->changeLocalId( group->GetID() ); } break; // everything has been updated @@ -2409,9 +2712,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase // remove reference to geometry SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO); for ( ; chItr->More(); chItr->Next() ) + { // Remove group's child SObject - builder->RemoveObject( chItr->Value() ); - + SALOMEDS::SObject_wrap so = chItr->Value(); + builder->RemoveObject( so ); + } // Update Python script TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this()) << ".ConvertToStandalone( " << aGroupSO << " )"; @@ -2419,9 +2724,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase // change icon of Group on Filter if ( isOnFilter ) { - SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes(); - const int isEmpty = ( elemTypes->length() == 0 ); - if ( !isEmpty ) + // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes(); + // const int isEmpty = ( elemTypes->length() == 0 ); + // if ( !isEmpty ) { SALOMEDS::GenericAttribute_wrap anAttr = builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" ); @@ -2460,9 +2765,25 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theS if(MYDEBUG) MESSAGE( "createSubMesh" ); TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject); ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape); - const int subMeshId = mySubMesh->GetId(); + int subMeshId = 0; + + SMESH_subMesh_i * subMeshServant; + if ( mySubMesh ) + { + subMeshId = mySubMesh->GetId(); + subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId); + } + else // "invalid sub-mesh" + { + // The invalid sub-mesh is created for the case where a valid sub-shape not found + // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0. + if ( _mapSubMesh.empty() ) + subMeshId = -1; + else + subMeshId = _mapSubMesh.begin()->first - 1; + subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject); + } - SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId); SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this(); _mapSubMesh [subMeshId] = mySubMesh; @@ -2477,7 +2798,8 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theS else { nextId = 0; } // avoid "unused variable" warning // to track changes of GEOM groups - addGeomGroupData( theSubShapeObject, subMesh ); + if ( subMeshId > 0 ) + addGeomGroupData( theSubShapeObject, subMesh ); return subMesh._retn(); } @@ -2513,13 +2835,17 @@ bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617) { - if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end()) + SMESH_subMesh* sm; + if (( _mapSubMesh.count( subMeshId )) && + ( sm = _impl->GetSubMeshContaining( subMeshId ))) { - TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape(); + TopoDS_Shape S = sm->GetSubShape(); if ( !S.IsNull() ) { list hyps = _impl->GetHypothesisList( S ); isHypChanged = !hyps.empty(); + if ( isHypChanged && _preMeshInfo ) + _preMeshInfo->ForgetOrLoad(); list::const_iterator hyp = hyps.begin(); for ( ; hyp != hyps.end(); ++hyp ) _impl->RemoveHypothesis(S, (*hyp)->GetID()); @@ -2566,6 +2892,7 @@ bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType, const char* theName, + const int theID, const TopoDS_Shape& theShape, const SMESH_PredicatePtr& thePredicate ) { @@ -2584,10 +2911,11 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType } while ( !presentNames.insert( newName ).second ); theName = newName.c_str(); } - int anId; SMESH::SMESH_GroupBase_var aGroup; - if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate )) + if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, + theID, theShape, thePredicate )) { + int anId = g->GetID(); SMESH_GroupBase_i* aGroupImpl; if ( !theShape.IsNull() ) aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId ); @@ -2603,7 +2931,7 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType // register CORBA object for persistence int nextId = _gen_i->RegisterObject( aGroup ); if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); } - else { nextId = 0; } // avoid "unused variable" warning in release mode + else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode // to track changes of GEOM groups if ( !theShape.IsNull() ) { @@ -2735,7 +3063,7 @@ namespace SMESH_Mesh_i* _mesh; TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {} virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); } - virtual void HypothesisModified () { _mesh->onHypothesisModified(); } + virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); } virtual void Load () { _mesh->Load(); } }; } @@ -2746,13 +3074,30 @@ namespace */ //================================================================================ -void SMESH_Mesh_i::onHypothesisModified() +void SMESH_Mesh_i::onHypothesisModified(int theHypID) { if ( _preMeshInfo ) _preMeshInfo->ForgetOrLoad(); SMESH::SMESH_Mesh_var mesh = _this(); _gen_i->UpdateIcons( mesh ); + + // mark a hypothesis as valid after edition + SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent(); + SALOMEDS::SObject_wrap hypRoot; + if ( !smeshComp->_is_nil() && + smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() )) + { + SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot ); + for ( ; anIter->More(); anIter->Next() ) + { + SALOMEDS::SObject_wrap hypSO = anIter->Value(); + CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO ); + SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj ); + if ( !hyp->_is_nil() && hyp->GetId() == theHypID ) + _gen_i->HighLightInvalid( hyp, false ); + } + } } //============================================================================= @@ -3027,7 +3372,7 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, void SMESH_Mesh_i::ExportMED(const char* file, CORBA::Boolean auto_groups, - CORBA::Long minor, + CORBA::Long version, CORBA::Boolean overwrite, CORBA::Boolean autoDimension) throw(SALOME::SALOME_Exception) @@ -3038,12 +3383,12 @@ void SMESH_Mesh_i::ExportMED(const char* file, _preMeshInfo->FullLoadFromFile(); string aMeshName = prepareMeshNameAndGroups(file, overwrite); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor, 0, autoDimension ); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension ); TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'" << file << "', " << "auto_groups=" <FullLoadFromFile(); @@ -3210,8 +3556,9 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, SMESH::DownCast< SMESH_Mesh_i* >( meshPart )) { aMeshName = prepareMeshNameAndGroups(file, overwrite); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor, - 0, autoDimension, /*addODOnVertices=*/have0dField); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, + 0, autoDimension, /*addODOnVertices=*/have0dField, + ZTolerance); meshDS = _impl->GetMeshDS(); } else @@ -3228,8 +3575,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, } SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart ); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor, - partDS, autoDimension, /*addODOnVertices=*/have0dField); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, + partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance); meshDS = tmpDSDeleter._obj = partDS; } @@ -3253,15 +3600,17 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] ); goList[i] = gbo; } - TPythonDump() << _this() << ".ExportPartToMED( r'" + TPythonDump() << _this() << ".ExportPartToMED( " + << meshPart << ", r'" << file << "', " - << "auto_groups=" << auto_groups << ", " - << "minor=" << minor << ", " - << "overwrite=" << overwrite << ", " - << "meshPart=" << meshPart << ", " - << "autoDimension=" << autoDimension << ", " - << "fields=" << goList << ", geomAssocFields='" - << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )"; + << auto_groups << ", " + << version << ", " + << overwrite << ", " + << autoDimension << ", " + << goList << ", '" + << ( geomAssocFields ? geomAssocFields : "" ) << "'," + << TVar( ZTolerance ) + << " )"; SMESH_CATCH( SMESH::throwCorbaException ); } @@ -4244,7 +4593,7 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, return aResult._retn(); } - + //============================================================================= /*! * Returns type of elements for given submesh @@ -4276,9 +4625,9 @@ SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID SMESH_CATCH( SMESH::throwCorbaException ); - return type; + return type; } - + //============================================================================= /*! @@ -4335,7 +4684,8 @@ SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id) */ //============================================================================= -SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id) +SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id, + SMESH::ElementType elemType) { if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -4346,13 +4696,14 @@ SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id) return aResult._retn(); // find node - const SMDS_MeshNode* aNode = aMeshDS->FindNode(id); - if(!aNode) + const SMDS_MeshNode* aNode = aMeshDS->FindNode( id ); + if ( !aNode ) return aResult._retn(); // find inverse elements - SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator(); - aResult->length( aNode->NbInverseElements() ); + SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType ); + SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type ); + aResult->length( aNode->NbInverseElements( type )); for( int i = 0; eIt->more(); ++i ) { const SMDS_MeshElement* elem = eIt->next(); @@ -4488,7 +4839,7 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) //============================================================================= /*! - * For given element returns ID of result shape after + * For given element returns ID of result shape after * ::FindShape() from SMESH_MeshEditor * If there is not element for given ID - returns -1 */ @@ -4576,8 +4927,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id) if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) ) { aResult->length( elem->NbNodes() ); - for ( int i = 0; i < elem->NbNodes(); ++i ) - aResult[ i ] = elem->GetNode( i )->GetID(); + for ( CORBA::ULong i = 0; i < aResult->length(); ++i ) + if ( const SMDS_MeshNode* n = elem->GetNode( i )) + aResult[ i ] = n->GetID(); } } return aResult._retn(); @@ -4693,7 +5045,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, { if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) ) { - SMDS_VolumeTool vtool( elem ); + SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false ); if ( faceIndex < vtool.NbFaces() ) { aResult->length( vtool.NbFaceNodes( faceIndex )); @@ -5153,7 +5505,7 @@ void SMESH_Mesh_i::checkGroupNames() int nbGrp = NbGroups(); if ( !nbGrp ) return; - + SMESH::ListOfGroups* grpList = 0; // avoid dump of "GetGroups" { @@ -5349,10 +5701,10 @@ SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream() aWriter->Write(); char* str = aWriter->GetOutputString(); int size = aWriter->GetOutputStringLength(); - - //Allocate octect buffer of required size + + //Allocate octet buffer of required size CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size); - //Copy ostrstream content to the octect buffer + //Copy ostrstream content to the octet buffer memcpy(OctetBuf, str, size); //Create and return TMPFile SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1); @@ -5373,10 +5725,12 @@ namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_v SMDS_ElemIteratorPtr _elemIter; PredicatePtr _predicate; const SMDS_MeshElement* _elem; + SMDSAbs_ElementType _type; - PredicateIterator( SMDS_ElemIteratorPtr iterator, - PredicatePtr predicate): - _elemIter(iterator), _predicate(predicate) + PredicateIterator( SMDS_ElemIteratorPtr iterator, + PredicatePtr predicate, + SMDSAbs_ElementType type): + _elemIter(iterator), _predicate(predicate), _type(type) { next(); } @@ -5390,8 +5744,9 @@ namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_v _elem = 0; while ( _elemIter->more() && !_elem ) { - _elem = _elemIter->next(); - if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() ))) + if ((_elem = _elemIter->next()) && + (( _type != SMDSAbs_All && _type != _elem->GetType() ) || + ( !_predicate->IsSatisfy( _elem->GetID() )))) _elem = 0; } return res; @@ -5545,6 +5900,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje else if ( SMESH::Filter_i* filter_i = SMESH::DownCast( theObject )) { if ( filter_i->GetElementType() == theType || + filter_i->GetElementType() == SMESH::ALL || elemType == SMDSAbs_Node || elemType == SMDSAbs_All) { @@ -5553,8 +5909,10 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje { SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() ); SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType ); - elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() )); - typeOK = ( filterType == elemType || elemType == SMDSAbs_All ); + SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType; + elemIt = SMDS_ElemIteratorPtr + ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType )); + typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() ); } } } @@ -5564,16 +5922,17 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE ); if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All ) return elemIt; + SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType; if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject )) { int nbIds; if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds )) - elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType )); + elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType )); } else { SMESH::long_array_var ids = theObject->GetIDs(); - elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType )); + elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType )); } typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All ); } @@ -5683,7 +6042,7 @@ class SMESH_DimHyp } return isShared; } - + //----------------------------------------------------------------------------- //! check algorithms static bool checkAlgo(const SMESHDS_Hypothesis* theA1, @@ -5697,7 +6056,7 @@ class SMESH_DimHyp return strcmp( theA1->GetName(), theA2->GetName() ) == 0; } - + //----------------------------------------------------------------------------- //! Check if sub-shape hypotheses are concurrent bool IsConcurrent(const SMESH_DimHyp* theOther) const @@ -5749,7 +6108,7 @@ class SMESH_DimHyp return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() ); } - + }; // end of SMESH_DimHyp //----------------------------------------------------------------------------- @@ -5757,7 +6116,7 @@ typedef list TDimHypList; //----------------------------------------------------------------------------- -void addDimHypInstance(const int theDim, +void addDimHypInstance(const int theDim, const TopoDS_Shape& theShape, const SMESH_Algo* theAlgo, const SMESH_subMesh* theSubMesh, @@ -5770,7 +6129,7 @@ void addDimHypInstance(const int theDim, dimHyp->_hypotheses.push_front(theAlgo); listOfdimHyp.push_back( dimHyp ); } - + SMESH_DimHyp* dimHyp = const_cast( listOfdimHyp.back() ); dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(), theHypList.begin(), theHypList.end() ); @@ -5829,7 +6188,7 @@ void unionLists(TListOfInt& theListOfId, if ( find_first_of( theListOfId.begin(), theListOfId.end(), otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() ) continue; - + // union two lists (from source into target) TListOfInt::iterator it2 = otherListOfId.begin(); for ( ; it2 != otherListOfId.end(); it2++ ) { @@ -5982,7 +6341,7 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr ); } } // end iterations on submesh - + // iterate on created dimension-hypotheses and check for concurrents for ( int i = 0; i < 4; i++ ) { const TDimHypList& listOfDimHyp = dimHypListArr[i]; @@ -6007,9 +6366,9 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() } } } - + removeDimHyps(dimHypListArr); - + // now, minimize the number of concurrent groups // Here we assume that lists of submeshes can have same submesh // in case of multi-dimension algorithms, as result @@ -6078,7 +6437,7 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() mesh.SetMeshOrder( subMeshOrder ); res = true; - + SMESH::SMESH_Mesh_var me = _this(); _gen_i->UpdateIcons( me ); @@ -6327,5 +6686,3 @@ _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDS // END Implementation of SMESH_MeshPartDS // //================================================================================ - -