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=082f2914ad400880c7910dc29c7e6c5c973fd6de;hp=26fcc1e97c84907a03107b53f48f3487c4b4e775;hb=db6f1785f59eaa5f2d813dc89a83f9739fcf60ef;hpb=a63fc78c25199b018fae4f5b182e6a348be0abf2 diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 26fcc1e97..082f2914a 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2019 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 @@ -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; @@ -691,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 ); @@ -771,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 { @@ -954,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 @@ -1018,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 ) ) { @@ -1063,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() ) @@ -1100,6 +1104,10 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) if ( !aGroup ) return; + if ( aGroup->GetMeshServant() != this ) + THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh", + SALOME::BAD_PARAM ); + SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup ); if ( !aGroupSO->_is_nil() ) { @@ -1134,6 +1142,11 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup if ( theGroup->_is_nil() ) return; + SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup ); + if ( !groupImpl || groupImpl->GetMeshServant() != this ) + THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh", + SALOME::BAD_PARAM); + vector nodeIds; // to remove nodes becoming free bool isNodal = ( theGroup->GetType() == SMESH::NODE ); if ( !isNodal && !theGroup->IsEmpty() ) @@ -1410,7 +1423,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 @@ -1495,7 +1508,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 */ @@ -1558,7 +1571,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 @@ -1567,8 +1580,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) { @@ -1868,6 +1881,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 @@ -1991,11 +2087,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; + } } //============================================================================= @@ -2008,19 +2159,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; } @@ -2047,23 +2246,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() ) { @@ -2078,7 +2289,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 ); @@ -2108,36 +2319,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 )); @@ -2154,6 +2357,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(); @@ -2300,7 +2595,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 ); @@ -2345,10 +2640,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 @@ -2426,9 +2721,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 << " )"; @@ -2436,9 +2733,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" ); @@ -2547,14 +2844,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() && - _mapSubMesh[ subMeshId ]) + 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()); @@ -2601,6 +2901,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 ) { @@ -2619,10 +2920,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 ); @@ -2638,7 +2940,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() ) { @@ -2990,9 +3292,9 @@ CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED() void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite) { - SMESH_File aFile( file ); + SMESH_File aFile( file, false ); SMESH_Comment msg; - if (aFile.exists()) { + if ( aFile.exists() ) { // existing filesystem node if ( !aFile.isDirectory() ) { if ( aFile.openForWriting() ) { @@ -3212,7 +3514,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, CORBA::Boolean overwrite, CORBA::Boolean autoDimension, const GEOM::ListOfFields& fields, - const char* geomAssocFields) + const char* geomAssocFields, + CORBA::Double ZTolerance) throw (SALOME::SALOME_Exception) { MESSAGE("MED version: "<< version); @@ -3263,7 +3566,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, { aMeshName = prepareMeshNameAndGroups(file, overwrite); _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, - 0, autoDimension, /*addODOnVertices=*/have0dField); + 0, autoDimension, /*addODOnVertices=*/have0dField, + ZTolerance); meshDS = _impl->GetMeshDS(); } else @@ -3281,7 +3585,7 @@ 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, version, - partDS, autoDimension, /*addODOnVertices=*/have0dField); + partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance); meshDS = tmpDSDeleter._obj = partDS; } @@ -3313,7 +3617,9 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, << overwrite << ", " << autoDimension << ", " << goList << ", '" - << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )"; + << ( geomAssocFields ? geomAssocFields : "" ) << "'," + << TVar( ZTolerance ) + << " )"; SMESH_CATCH( SMESH::throwCorbaException ); } @@ -4296,7 +4602,7 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, return aResult._retn(); } - + //============================================================================= /*! * Returns type of elements for given submesh @@ -4328,9 +4634,9 @@ SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID SMESH_CATCH( SMESH::throwCorbaException ); - return type; + return type; } - + //============================================================================= /*! @@ -4387,7 +4693,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(); @@ -4398,13 +4705,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(); @@ -4540,7 +4848,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 */ @@ -4628,8 +4936,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(); @@ -4745,7 +5054,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 )); @@ -4759,7 +5068,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, } //======================================================================= -//function : GetElemFaceNodes +//function : GetFaceNormal //purpose : Returns three components of normal of given mesh face. //======================================================================= @@ -5056,7 +5365,7 @@ void SMESH_Mesh_i::CreateGroupServants() while ( groupIt->more() ) { ::SMESH_Group* group = groupIt->next(); - int anId = group->GetGroupDS()->GetID(); + int anId = group->GetID(); map::iterator it = _mapGroups.find(anId); if ( it != _mapGroups.end() && !CORBA::is_nil( it->second )) @@ -5205,7 +5514,7 @@ void SMESH_Mesh_i::checkGroupNames() int nbGrp = NbGroups(); if ( !nbGrp ) return; - + SMESH::ListOfGroups* grpList = 0; // avoid dump of "GetGroups" { @@ -5401,10 +5710,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); @@ -5425,10 +5734,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(); } @@ -5442,8 +5753,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; @@ -5597,6 +5909,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) { @@ -5605,8 +5918,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() ); } } } @@ -5616,16 +5931,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 ); } @@ -5735,7 +6051,7 @@ class SMESH_DimHyp } return isShared; } - + //----------------------------------------------------------------------------- //! check algorithms static bool checkAlgo(const SMESHDS_Hypothesis* theA1, @@ -5749,7 +6065,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 @@ -5767,19 +6083,23 @@ class SMESH_DimHyp if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound)) return false; -// bool checkSubShape = ( _dim >= theOther->_dim ) -// ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) ) -// : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ; bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim)); if ( !checkSubShape ) - return false; + return false; // check algorithms to be same - if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() )) - return true; // different algorithms -> concurrency ! + const SMESH_Algo* a1 = this->GetAlgo(); + const SMESH_Algo* a2 = theOther->GetAlgo(); + bool isSame = checkAlgo( a1, a2 ); + if ( !isSame ) + { + if ( !a1 || !a2 ) + return false; // pb? + return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency ! + } // check hypothesises for concurrence (skip first as algorithm) - int nbSame = 0; + size_t nbSame = 0; // pointers should be same, because it is referened from mesh hypothesis partition list ::const_iterator hypIt = _hypotheses.begin(); list ::const_iterator otheEndIt = theOther->_hypotheses.end(); @@ -5787,7 +6107,7 @@ class SMESH_DimHyp if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt ) nbSame++; // the submeshes are concurrent if their algorithms has different parameters - return nbSame != (int)theOther->_hypotheses.size() - 1; + return nbSame != theOther->_hypotheses.size() - 1; } // Return true if algorithm of this SMESH_DimHyp is used if no @@ -5801,7 +6121,7 @@ class SMESH_DimHyp return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() ); } - + }; // end of SMESH_DimHyp //----------------------------------------------------------------------------- @@ -5809,7 +6129,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, @@ -5822,7 +6142,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() ); @@ -5881,7 +6201,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++ ) { @@ -6034,7 +6354,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]; @@ -6059,9 +6379,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 @@ -6120,17 +6440,21 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() aPythonDump << " ]"; subMeshOrder.push_back( subMeshIds ); - // clear collected submeshes + // clear collected sub-meshes set::iterator clrIt = subMeshToClear.begin(); for ( ; clrIt != subMeshToClear.end(); clrIt++ ) if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt ) + { sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); + if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748 + sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo + } } aPythonDump << " ])"; mesh.SetMeshOrder( subMeshOrder ); res = true; - + SMESH::SMESH_Mesh_var me = _this(); _gen_i->UpdateIcons( me ); @@ -6379,5 +6703,3 @@ _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDS // END Implementation of SMESH_MeshPartDS // //================================================================================ - -