X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_subMesh_i.cxx;h=02c2664f0807b56dfc86344d499473ab5a34c96d;hp=2e58af96a8531f35da589f13f8200b8c286f8cdd;hb=44cfe3f661cf16b7253c2635368807ea332a4cc5;hpb=c981fa08d90e8e8e91e24424701357141b8dda56 diff --git a/src/SMESH_I/SMESH_subMesh_i.cxx b/src/SMESH_I/SMESH_subMesh_i.cxx index 2e58af96a..02c2664f0 100644 --- a/src/SMESH_I/SMESH_subMesh_i.cxx +++ b/src/SMESH_I/SMESH_subMesh_i.cxx @@ -1,45 +1,46 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// Copyright (C) 2007-2015 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 +// +// 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, or (at your option) any later version. // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_subMesh_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ - -using namespace std; +// #include "SMESH_subMesh_i.hxx" #include "SMESH_Gen_i.hxx" #include "SMESH_Mesh_i.hxx" +#include "SMESH_PreMeshInfo.hxx" #include "Utils_CorbaException.hxx" #include "utilities.h" #include "OpUtil.hxx" #include "Utils_ExceptHandlers.hxx" -#include -#include +#include +#include #include +using namespace std; + //============================================================================= /*! * @@ -50,7 +51,7 @@ SMESH_subMesh_i::SMESH_subMesh_i() : SALOME::GenericObj_i( PortableServer::POA::_nil() ) { MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use"); - ASSERT(0); + ASSERT(0); } //============================================================================= @@ -60,17 +61,15 @@ SMESH_subMesh_i::SMESH_subMesh_i() //============================================================================= SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA, - SMESH_Gen_i* gen_i, - SMESH_Mesh_i* mesh_i, - int localId ) + SMESH_Gen_i* gen_i, + SMESH_Mesh_i* mesh_i, + int localId ) : SALOME::GenericObj_i( thePOA ) { - MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i"); _gen_i = gen_i; _mesh_i = mesh_i; _localId = localId; - thePOA->activate_object( this ); - // **** + _preMeshInfo = NULL; } //============================================================================= /*! @@ -81,7 +80,8 @@ SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA, SMESH_subMesh_i::~SMESH_subMesh_i() { MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i"); - // **** + if ( _preMeshInfo ) delete _preMeshInfo; + _preMeshInfo = NULL; } //======================================================================= @@ -100,53 +100,92 @@ bool getSubMeshes(::SMESH_subMesh* theSubMesh, SMESH_Mesh* aMesh = theSubMesh->GetFather(); SMESHDS_Mesh* aMeshDS = aMesh->GetMeshDS(); SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS(); + ::SMESH_subMesh* sm; // nodes can be bound to either vertex, edge, face or solid_or_shell - TopoDS_Shape aShape = theSubMesh->GetSubShape(); - switch ( aShape.ShapeType() ) + TopoDS_Shape aShape = theSubMesh->GetSubShape(); + TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); + + // IPAL18558: Wrong information of the created sub-mesh is shown. (Sub-mesh on a FACE + // with only 1D algo assigned + // Find dimension of sub-meshes to return as highest dimension of the assigned algorithm + if ( theSubMesh->IsEmpty() && !theSubMesh->GetAlgo() ) { - case TopAbs_SOLID: { - // add submesh of solid itself - aSubMeshDS = aMeshDS->MeshElements( aShape ); - if ( aSubMeshDS ) + // on father sub-meshes, check presence of an algo which will mesh this sub-mesh + // even if no algo is assigned to this sub-mesh + bool topAlgoPresent = false; + TopTools_ListIteratorOfListOfShape ancestors( aMesh->GetAncestors( aShape )); + for ( ; ancestors.More() && !topAlgoPresent; ancestors.Next() ) + if (( sm = aMesh->GetSubMeshContaining( ancestors.Value() ))) + topAlgoPresent = ( sm->GetAlgo() && !sm->GetAlgo()->NeedDiscreteBoundary() ); + + if ( !topAlgoPresent ) + { + // look for a sub-mesh with an algo + SMESH_subMeshIteratorPtr smIt = + theSubMesh->getDependsOnIterator(/*includeSelf=*/false, /*complexShapeFirst=*/true); + TopAbs_ShapeEnum algoShape = TopAbs_SHAPE; + while ( smIt->more() && algoShape == TopAbs_SHAPE ) + { + sm = smIt->next(); + if ( sm->GetAlgo() ) + algoShape = sm->GetSubShape().ShapeType(); + } + if ( algoShape != TopAbs_SHAPE ) + { + // return all sub-meshes on this shape type + smIt = theSubMesh->getDependsOnIterator(/*includeSelf=*/false, /*complexShapeFirst=*/true); + while ( smIt->more() ) + { + sm = smIt->next(); + if ( sm->GetSubShape().ShapeType() == algoShape && sm->GetSubMeshDS() ) + theSubMeshList.push_back( sm->GetSubMeshDS() ); + } + return size < theSubMeshList.size(); + } + } + } + + switch ( aShapeType ) + { + case TopAbs_SOLID: + { + // add sub-mesh of solid itself + if (( aSubMeshDS = aMeshDS->MeshElements( aShape ))) theSubMeshList.push_back( aSubMeshDS ); + // and of the first shell TopExp_Explorer exp( aShape, TopAbs_SHELL ); - if ( exp.More() ) { - aSubMeshDS = aMeshDS->MeshElements( exp.Current() ); - if ( aSubMeshDS ) + if ( exp.More() ) + if (( aSubMeshDS = aMeshDS->MeshElements( exp.Current() ))) theSubMeshList.push_back( aSubMeshDS ); - } break; } case TopAbs_WIRE: case TopAbs_COMPOUND: - case TopAbs_COMPSOLID: { + case TopAbs_COMPSOLID: + { // call getSubMeshes() for sub-shapes list shapeList; shapeList.push_back( aShape ); list::iterator sh = shapeList.begin(); for ( ; sh != shapeList.end(); ++sh ) { for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) { - ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() ); - if ( aSubMesh ) - getSubMeshes( aSubMesh, theSubMeshList ); + if (( sm = aMesh->GetSubMeshContaining( it.Value() ))) + getSubMeshes( sm, theSubMeshList ); // add found sub-mesh or explore deeper else // no submesh for a compound inside compound shapeList.push_back( it.Value() ); } } - // return only unique submeshes - set smSet; - TListOfSubMeshes::iterator sm = theSubMeshList.begin(); - while ( sm != theSubMeshList.end() ) { - if ( !smSet.insert( *sm ).second ) - sm = theSubMeshList.erase( sm ); - else - ++sm; - } + // return only unique sub-meshes + set smSet( theSubMeshList.begin(), theSubMeshList.end() ); + theSubMeshList.assign( smSet.begin(), smSet.end() ); break; } + default: + if ( aSubMeshDS ) + theSubMeshList.push_back( aSubMeshDS ); } return size < theSubMeshList.size(); } @@ -161,7 +200,10 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfElements() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetNumberOfElements"); + + if ( _preMeshInfo ) + return _preMeshInfo->NbElements(); + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return 0; @@ -191,48 +233,42 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all) throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetNumberOfNodes"); + if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return 0; + if ( _preMeshInfo ) + { + if ( all ) return _preMeshInfo->NbNodes(); + else _preMeshInfo->FullLoadFromFile(); + } ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); - set nodeIds; - - // nodes are bound to shell instead of solid - TListOfSubMeshes smList; - if ( all && getSubMeshes( aSubMesh, smList )) + if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() ) { - TListOfSubMeshes::iterator sm = smList.begin(); - for ( ; sm != smList.end(); ++sm ) + // sub-mesh on a geom group, always return all nodes + return aSubMeshDS->NbNodes(); + } + if ( aSubMeshDS && !all ) + { + // return anything we have + return aSubMeshDS->NbNodes(); + } + if ( all ) // get nodes from aSubMesh and all child sub-meshes + { + int nbNodes = 0; + SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator( /*includeSelf=*/true ); + while ( smIt->more() ) { - SMDS_ElemIteratorPtr eIt = (*sm)->GetElements(); - while ( eIt->more() ) { - const SMDS_MeshElement* anElem = eIt->next(); - SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); - while ( nIt->more() ) - nodeIds.insert( nIt->next()->GetID() ); - } + aSubMesh = smIt->next(); + if (( aSubMeshDS = aSubMesh->GetSubMeshDS() )) + nbNodes += aSubMeshDS->NbNodes(); } - return nodeIds.size(); + return nbNodes; } - if ( aSubMeshDS == NULL ) - return 0; - - if ( all ) { // all nodes of submesh elements - SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); - while ( eIt->more() ) { - const SMDS_MeshElement* anElem = eIt->next(); - SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); - while ( nIt->more() ) - nodeIds.insert( nIt->next()->GetID() ); - } - return nodeIds.size(); - } - - return aSubMeshDS->NbNodes(); + return aSubMeshDS ? aSubMeshDS->NbNodes() : 0; } //============================================================================= @@ -240,17 +276,20 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all) * */ //============================================================================= - + SMESH::long_array* SMESH_subMesh_i::GetElementsId() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetElementsId"); + SMESH::long_array_var aResult = new SMESH::long_array(); if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return aResult._retn(); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); @@ -274,7 +313,7 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsId() for ( int i = 0; sm != smList.end(); sm++ ) { SMDS_ElemIteratorPtr anIt = (*sm)->GetElements(); - for ( int n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ ) + for ( ; i < nbElems && anIt->more(); i++ ) aResult[i] = anIt->next()->GetID(); } } @@ -292,12 +331,15 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetElementsByType"); + SMESH::long_array_var aResult = new SMESH::long_array(); if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return aResult._retn(); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); @@ -315,9 +357,15 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle if ( theElemType == SMESH::NODE ) { SMDS_ElemIteratorPtr eIt = (*sm)->GetElements(); - while ( eIt->more() ) { - const SMDS_MeshElement* anElem = eIt->next(); - SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + if ( eIt->more() ) { + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + } else { + SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes(); while ( nIt->more() ) nodeIds.insert( nIt->next()->GetID() ); } @@ -338,9 +386,15 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle if ( theElemType == SMESH::NODE && aSubMeshDS ) { SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); - while ( eIt->more() ) { - const SMDS_MeshElement* anElem = eIt->next(); - SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + if ( eIt->more() ) { + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + } else { + SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes(); while ( nIt->more() ) nodeIds.insert( nIt->next()->GetID() ); } @@ -388,7 +442,7 @@ SMESH::long_array* SMESH_subMesh_i::GetNodesId() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetNodesId"); + SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE ); return aResult._retn(); } @@ -403,7 +457,6 @@ SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - MESSAGE("SMESH_subMesh_i::GetFather"); return _mesh_i->_this(); } @@ -415,7 +468,6 @@ SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather() CORBA::Long SMESH_subMesh_i::GetId() { - MESSAGE("SMESH_subMesh_i::GetId"); return _localId; } @@ -432,8 +484,14 @@ GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape() try { if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) { TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape(); - if ( !S.IsNull() ) + if ( !S.IsNull() ) { aShapeObj = _gen_i->ShapeToGeomObject( S ); + //mzn: N7PAL16232, N7PAL16233 + //In some cases it's possible that GEOM_Client contains the shape same to S, but + //with another orientation. + if (aShapeObj->_is_nil()) + aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() ); + } } } catch(SALOME_Exception & S_ex) { @@ -447,30 +505,154 @@ GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape() * */ //============================================================================= -SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily() - throw (SALOME::SALOME_Exception) +SMESH::long_array* SMESH_subMesh_i::GetIDs() { - Unexpect aCatch(SALOME_SalomeException); - SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh(); - - SALOME_MED::Family_array_var families = - MEDMesh->getFamilies(SALOME_MED::MED_NODE); - - for ( int i = 0; i < families->length(); i++ ) { - if ( families[i]->getIdentifier() == ( _localId ) ) - return families[i]; - } - - return SALOME_MED::FAMILY::_nil(); + return GetElementsId(); } //============================================================================= /*! - * + * */ //============================================================================= -SMESH::long_array* SMESH_subMesh_i::GetIDs() +SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem ) + throw (SALOME::SALOME_Exception) { - SMESH::long_array_var aResult = GetElementsId(); - return aResult._retn(); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + return GetFather()->GetElementType( id, iselem ); +} + +//============================================================================= +/* + * Returns number of mesh elements of each \a EntityType + * @return array of number of elements per \a EntityType + */ +//============================================================================= + +SMESH::long_array* SMESH_subMesh_i::GetMeshInfo() +{ + if ( _preMeshInfo ) + return _preMeshInfo->GetMeshInfo(); + + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::Entity_Last); + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = 0; + + // get number of nodes + aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true); + + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + + // get statistic from child sub-meshes + TListOfSubMeshes smList; + if ( getSubMeshes( aSubMesh, smList ) ) + for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm ) + SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes ); + + return aRes._retn(); +} + +//======================================================================= +/* + * Returns number of mesh elements of each \a ElementType + */ +//======================================================================= + +SMESH::long_array* SMESH_subMesh_i::GetNbElementsByType() +{ + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::NB_ELEMENT_TYPES); + for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++) + if ( _preMeshInfo ) + aRes[ i ] = _preMeshInfo->NbElements( SMDSAbs_ElementType( i )); + else + aRes[ i ] = 0; + + if ( !_preMeshInfo ) + { + aRes[ SMESH::NODE ] = GetNumberOfNodes(true); + + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() ) + { + SMDS_ElemIteratorPtr eIt = smDS->GetElements(); + if ( eIt->more() ) + aRes[ eIt->next()->GetType() ] = smDS->NbElements(); + } + } + return aRes._retn(); +} + + +//======================================================================= +//function : GetTypes +//purpose : Returns types of elements it contains +//======================================================================= + +SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes() +{ + if ( _preMeshInfo ) + return _preMeshInfo->GetTypes(); + + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() ) + { + SMDS_ElemIteratorPtr eIt = smDS->GetElements(); + if ( eIt->more() ) + { + types->length( 1 ); + types[0] = SMESH::ElementType( eIt->next()->GetType()); + } + else if ( smDS->GetNodes()->more() ) + { + TopoDS_Shape shape = aSubMesh->GetSubShape(); + while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND ) + { + TopoDS_Iterator it( shape ); + shape = it.More() ? it.Value() : TopoDS_Shape(); + } + if ( !shape.IsNull() && shape.ShapeType() == TopAbs_VERTEX ) + { + types->length( 1 ); + types[0] = SMESH::NODE; + } + } + } + return types._retn(); +} + +//======================================================================= +//function : GetMesh +//purpose : interface SMESH_IDSource +//======================================================================= + +SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh() +{ + return GetFather(); +} + +//======================================================================= +//function : IsMeshInfoCorrect +//purpose : * Returns false if GetMeshInfo() returns incorrect information that may +// * happen if mesh data is not yet fully loaded from the file of study. +//======================================================================= + +bool SMESH_subMesh_i::IsMeshInfoCorrect() +{ + return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true; +} + +//======================================================================= +//function : GetVtkUgStream +//purpose : Return data vtk unstructured grid (not implemented) +//======================================================================= + +SALOMEDS::TMPFile* SMESH_subMesh_i::GetVtkUgStream() +{ + SALOMEDS::TMPFile_var SeqFile; + return SeqFile._retn(); }