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=a170d36d5e2b1f060a01efac948d781fae12ef32;hp=a5ed1ac3cc05f09eda82048861185dcef174f648;hb=30628bd54b2932ebfaae2ae2c24af7f173c4970e;hpb=63a442b2c3cbc5e2155d83e86dfdb77d6961fab3 diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index a5ed1ac3c..a170d36d5 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 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 @@ -79,6 +79,8 @@ #include #include +#include + // to pass CORBA exception through SMESH_TRY #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; } @@ -103,10 +105,9 @@ int SMESH_Mesh_i::_idGenerator = 0; SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, SMESH_Gen_i* gen_i, - CORBA::Long studyId ) + CORBA::Long studyId ) : SALOME::GenericObj_i( thePOA ) { - MESSAGE("SMESH_Mesh_i"); _impl = NULL; _gen_i = gen_i; _id = _idGenerator++; @@ -125,8 +126,6 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i::~SMESH_Mesh_i() { - MESSAGE("~SMESH_Mesh_i"); - // destroy groups map::iterator itGr; for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) @@ -159,6 +158,11 @@ SMESH_Mesh_i::~SMESH_Mesh_i() } _mapHypo.clear(); + // clear cashed shapes if no more meshes remain; (the cash is blame, + // together with publishing, of spent time increasing in issue 22874) + if ( _impl->NbMeshes() == 1 ) + _gen_i->GetShapeReader()->ClearClientBuffer(); + delete _editor; _editor = NULL; delete _previewEditor; _previewEditor = NULL; delete _impl; _impl = NULL; @@ -225,7 +229,25 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh() try { TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh(); if ( !S.IsNull() ) + { aShapeObj = _gen_i->ShapeToGeomObject( S ); + if ( aShapeObj->_is_nil() ) + { + // S was removed from GEOM_Client by newGroupShape() called by other mesh; + // find GEOM_Object by entry (IPAL52735) + list::iterator data = _geomGroupData.begin(); + for ( ; data != _geomGroupData.end(); ++data ) + if ( data->_smeshObject->_is_equivalent( _this() )) + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + if ( study->_is_nil() ) break; + SALOMEDS::SObject_wrap so = study->FindObjectID( data->_groupEntry.c_str() ); + CORBA::Object_var obj = _gen_i->SObjectToObject( so ); + aShapeObj = GEOM::GEOM_Object::_narrow( obj ); + break; + } + } + } } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); @@ -268,7 +290,7 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) - _preMeshInfo->ForgetAllData(); + _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh() try { _impl->Clear(); @@ -277,7 +299,6 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception) catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } - _impl->GetMeshDS()->Modified(); TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()"; } @@ -475,7 +496,13 @@ int SMESH_Mesh_i::ImportSTLFile( const char* theFileName ) SMESH_TRY; // Read mesh with name = into SMESH_Mesh - _impl->STLToMesh( theFileName ); + std::string name = _impl->STLToMesh( theFileName ); + if ( !name.empty() ) + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( study, _this() ); + _gen_i->SetName( meshSO, name.c_str() ); + } SMESH_CATCH( SMESH::throwCorbaException ); @@ -537,7 +564,7 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus switch (theStatus) { RETURNCASE( HYP_OK ); RETURNCASE( HYP_MISSING ); - RETURNCASE( HYP_CONCURENT ); + RETURNCASE( HYP_CONCURRENT ); RETURNCASE( HYP_BAD_PARAMETER ); RETURNCASE( HYP_HIDDEN_ALGO ); RETURNCASE( HYP_HIDING_ALGO ); @@ -1050,6 +1077,7 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) builder->RemoveObjectWithChildren( aGroupSO ); } } + aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion // Remove the group from SMESH data structures removeGroup( aGroup->GetLocalID() ); @@ -1073,13 +1101,37 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup if ( theGroup->_is_nil() ) return; + vector nodeIds; // to remove nodes becoming free + if ( !theGroup->IsEmpty() ) + { + CORBA::Long elemID = theGroup->GetID( 1 ); + int nbElemNodes = GetElemNbNodes( elemID ); + if ( nbElemNodes > 0 ) + nodeIds.reserve( theGroup->Size() * nbElemNodes ); + } + // Remove contents SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup ); SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() ); while ( elemIt->more() ) - _impl->GetMeshDS()->RemoveElement( elemIt->next() ); + { + const SMDS_MeshElement* e = elemIt->next(); - TPythonDump pyDump; // Supress dump from RemoveGroup() + SMDS_ElemIteratorPtr nIt = e->nodesIterator(); + while ( nIt->more() ) + nodeIds.push_back( nIt->next()->GetID() ); + + _impl->GetMeshDS()->RemoveElement( e ); + } + + // Remove free nodes + if ( theGroup->GetType() != SMESH::NODE ) + for ( size_t i = 0 ; i < nodeIds.size(); ++i ) + if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] )) + if ( n->NbInverseElements() == 0 ) + _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 ); + + TPythonDump pyDump; // Suppress dump from RemoveGroup() // Update Python script (theGroup must be alive for this) pyDump << SMESH::SMESH_Mesh_var(_this()) @@ -1561,25 +1613,52 @@ SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, return aResGrp._retn(); } +namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM +{ + bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners, + bool & toStopChecking ) + { + toStopChecking = ( nbCommon < nbChecked ); + return nbCommon == nbNodes; + } + bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners, + bool & toStopChecking ) + { + toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners ); + return nbCommon == nbCorners; + } + bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners, + bool & toStopChecking ) + { + return nbCommon > 0; + } + bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners, + bool & toStopChecking ) + { + return nbCommon >= (nbNodes+1) / 2; + } +} + //============================================================================= /*! - \brief Create groups of entities from existing groups of superior dimensions - System - 1) extract all nodes from each group, - 2) combine all elements of specified dimension laying on these nodes. - \param theGroups list of source groups - \param theElemType dimension of elements - \param theName name of new group - \return pointer on new group - * - IMP 19939 + * Create a group of entities basing on nodes of other groups. + * \param [in] theGroups - list of either groups, sub-meshes or filters. + * \param [in] anElemType - a type of elements to include to the new group. + * \param [in] theName - a name of the new group. + * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group. + * \param [in] theUnderlyingOnly - if \c True, an element is included to the + * new group provided that it is based on nodes of an element of \a aListOfGroups + * \return SMESH_Group - the created group */ +// IMP 19939, bug 22010, IMP 22635 //============================================================================= SMESH::SMESH_Group_ptr -SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, - SMESH::ElementType theElemType, - const char* theName ) +SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups, + SMESH::ElementType theElemType, + const char* theName, + SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes, + CORBA::Boolean theUnderlyingOnly) throw (SALOME::SALOME_Exception) { SMESH::SMESH_Group_var aResGrp; @@ -1595,6 +1674,17 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType; + bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop); + SMESH_Comment nbCoNoStr( "SMESH."); + switch ( theNbCommonNodes ) { + case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break; + case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break; + case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break; + case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break; + default: return aResGrp._retn(); + } + int nbChecked, nbCommon, nbNodes, nbCorners; + // Create a group TPythonDump pyDump; @@ -1607,14 +1697,19 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, SMESH::DownCast( aResGrp )->GetGroupDS(); SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup(); + vector isNodeInGroups; + for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups { - SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; + SMESH::SMESH_IDSource_var aGrp = theGroups[ g ]; if ( CORBA::is_nil( aGrp ) ) continue; + SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh(); + if ( mesh->_is_nil() || mesh->GetId() != this->GetId() ) + continue; - groupBaseDS = SMESH::DownCast( aGrp )->GetGroupDS(); - SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements(); + SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL ); + if ( !elIt ) continue; if ( theElemType == SMESH::NODE ) // get all nodes of elements { @@ -1625,30 +1720,93 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, resGroupCore.Add( nIt->next() ); } } - else // get elements of theElemType based on nodes of every element of group + // get elements of theElemType based on nodes of every element of group + else if ( theUnderlyingOnly ) { while ( elIt->more() ) { - const SMDS_MeshElement* el = elIt->next(); // an element of group + const SMDS_MeshElement* el = elIt->next(); // an element of ref group TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() ); TIDSortedElemSet checkedElems; - SMDS_ElemIteratorPtr nIt = el->nodesIterator(); + SMDS_NodeIteratorPtr nIt = el->nodeIterator(); while ( nIt->more() ) { - const SMDS_MeshNode* n = static_cast( nIt->next() ); + const SMDS_MeshNode* n = nIt->next(); SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType ); // check nodes of elements of theElemType around el while ( elOfTypeIt->more() ) { const SMDS_MeshElement* elOfType = elOfTypeIt->next(); if ( !checkedElems.insert( elOfType ).second ) continue; - + nbNodes = elOfType->NbNodes(); + nbCorners = elOfType->NbCornerNodes(); + nbCommon = 0; + bool toStopChecking = false; SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator(); - bool allNodesOK = true; - while ( nIt2->more() && allNodesOK ) - allNodesOK = elNodes.count( nIt2->next() ); - if ( allNodesOK ) - resGroupCore.Add( elOfType ); + for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked ) + if ( elNodes.count( nIt2->next() ) && + isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking )) + { + resGroupCore.Add( elOfType ); + break; + } + } + } + } + } + // get all nodes of elements of groups + else + { + while ( elIt->more() ) + { + const SMDS_MeshElement* el = elIt->next(); // an element of group + SMDS_NodeIteratorPtr nIt = el->nodeIterator(); + while ( nIt->more() ) + { + const SMDS_MeshNode* n = nIt->next(); + if ( n->GetID() >= (int) isNodeInGroups.size() ) + isNodeInGroups.resize( n->GetID() + 1, false ); + isNodeInGroups[ n->GetID() ] = true; + } + } + } + } + + // Get elements of theElemType based on a certain number of nodes of elements of groups + if ( !theUnderlyingOnly && !isNodeInGroups.empty() ) + { + const SMDS_MeshNode* n; + vector isElemChecked( aMeshDS->MaxElementID() + 1 ); + const int isNodeInGroupsSize = isNodeInGroups.size(); + for ( int iN = 0; iN < isNodeInGroupsSize; ++iN ) + { + if ( !isNodeInGroups[ iN ] || + !( n = aMeshDS->FindNode( iN ))) + continue; + + // check nodes of elements of theElemType around n + SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType ); + while ( elOfTypeIt->more() ) + { + const SMDS_MeshElement* elOfType = elOfTypeIt->next(); + vector::reference isChecked = isElemChecked[ elOfType->GetID() ]; + if ( isChecked ) + continue; + isChecked = true; + + nbNodes = elOfType->NbNodes(); + nbCorners = elOfType->NbCornerNodes(); + nbCommon = 0; + bool toStopChecking = false; + SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator(); + for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked ) + { + const int nID = nIt->next()->GetID(); + if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] && + isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking )) + { + resGroupCore.Add( elOfType ); + break; } } } @@ -1658,7 +1816,8 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, // Update Python script pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this()) << ".CreateDimGroup( " - << theGroups << ", " << theElemType << ", '" << theName << "' )"; + << theGroups << ", " << theElemType << ", '" << theName << "', " + << nbCoNoStr << ", " << theUnderlyingOnly << ")"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1694,7 +1853,7 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, CORBA::String_var entry = groupSO->GetID(); groupData._groupEntry = entry.in(); // indices - for ( int i = 0; i < ids->length(); ++i ) + for ( CORBA::ULong i = 0; i < ids->length(); ++i ) groupData._indices.insert( ids[i] ); // SMESH object groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj ); @@ -1747,7 +1906,7 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() ); GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup ); - for ( int i = 0; i < ids->length(); ++i ) + for ( CORBA::ULong i = 0; i < ids->length(); ++i ) curIndices.insert( ids[i] ); if ( groupData._indices == curIndices ) @@ -1814,15 +1973,21 @@ void SMESH_Mesh_i::CheckGeomModif() if ( study->_is_nil() ) return; GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() ); - if ( mainGO->_is_nil() ) return; + //if ( mainGO->_is_nil() ) return; - if ( mainGO->GetType() == GEOM_GROUP || + // 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 || mainGO->GetTick() == _mainShapeTick ) { CheckGeomGroupModif(); return; } + // Update after shape transformation like Translate + GEOM_Client* geomClient = _gen_i->GetShapeReader(); if ( !geomClient ) return; GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); @@ -2100,9 +2265,11 @@ void SMESH_Mesh_i::CheckGeomGroupModif() groupData.push_back ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType())); } - // set new shape to mesh -> DS of submeshes and geom groups is deleted + // set new shape to mesh -> DS of sub-meshes and geom groups are deleted + _impl->Clear(); + _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730 _impl->ShapeToMesh( newShape ); - + // reassign hypotheses TShapeHypList::iterator indS_hyps = assignedHyps.begin(); for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps ) @@ -2119,7 +2286,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() continue; for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt ) _impl->AddHypothesis( geom._shape, (*hypIt)->GetID()); - // care of submeshes + // care of sub-meshes SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape ); if ( newID != oldID ) { _mapSubMesh [ newID ] = newSubmesh; @@ -2782,7 +2949,7 @@ void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite) if ( !aFile.openForWriting() ) { msg << "You cannot create the file " << aFile.getName() - << ". Check the directory existance and access rights"; + << ". Check the directory existence and access rights"; } aFile.remove(); } @@ -2855,6 +3022,7 @@ void SMESH_Mesh_i::ExportToMEDX (const char* file, CORBA::Boolean autoDimension) throw(SALOME::SALOME_Exception) { + //MESSAGE("SMESH::MED_VERSION:"<< theVersion); SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -2881,6 +3049,7 @@ void SMESH_Mesh_i::ExportToMED (const char* file, SMESH::MED_VERSION theVersion) throw(SALOME::SALOME_Exception) { + //MESSAGE("SMESH::MED_VERSION:"<< theVersion); ExportToMEDX(file,auto_groups,theVersion,true); } @@ -2894,7 +3063,8 @@ void SMESH_Mesh_i::ExportMED (const char* file, CORBA::Boolean auto_groups) throw(SALOME::SALOME_Exception) { - ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true); + //MESSAGE("SMESH::MED_VERSION:"<< SMESH::MED_LATEST); + ExportToMEDX(file,auto_groups,SMESH::MED_LATEST,true); } //================================================================================ @@ -2983,9 +3153,15 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportSTL( r'" << file << "', " << isascii << " )"; + CORBA::String_var name; + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, _this() ); + if ( !so->_is_nil() ) + name = so->GetName(); + // Perform Export - PrepareForWriting(file); - _impl->ExportSTL(file, isascii); + PrepareForWriting( file ); + _impl->ExportSTL( file, isascii, name.in() ); } //================================================================================ @@ -3121,9 +3297,9 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, ( !geomAssocFields || !geomAssocFields[0] )) return; - std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 ); - std::vector< int > intVals( meshDS->MaxShapeIndex()+1 ); - std::vector< int > subIdsByDim[ 4 ]; + std::vector< std::vector< double > > dblVals; + std::vector< std::vector< int > > intVals; + std::vector< int > subIdsByDim[ 4 ]; const double noneDblValue = 0.; const double noneIntValue = 0; @@ -3163,6 +3339,9 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, for ( size_t iC = 0; iC < comps->length(); ++iC ) fieldWriter.SetCompName( iC, comps[ iC ].in() ); + dblVals.resize( comps->length() ); + intVals.resize( comps->length() ); + // find sub-shape IDs std::vector< int >& subIds = subIdsByDim[ dim ]; @@ -3188,6 +3367,17 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, fieldWriter.SetDtIt( int( stamp ), int( id )); // fill dblVals or intVals + for ( size_t iC = 0; iC < comps->length(); ++iC ) + if ( dataType == GEOM::FDT_Double ) + { + dblVals[ iC ].clear(); + dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 ); + } + else + { + intVals[ iC ].clear(); + intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 ); + } switch ( dataType ) { case GEOM::FDT_Double: @@ -3195,10 +3385,11 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step ); if ( dblStep->_is_nil() ) continue; GEOM::ListOfDouble_var vv = dblStep->GetValues(); - if ( vv->length() != subIds.size() ) + if ( vv->length() != subIds.size() * comps->length() ) THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); - for ( size_t i = 0; i < vv->length(); ++i ) - dblVals[ subIds[ i ]] = vv[ i ]; + for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ]; break; } case GEOM::FDT_Int: @@ -3206,10 +3397,11 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step ); if ( intStep->_is_nil() ) continue; GEOM::ListOfLong_var vv = intStep->GetValues(); - if ( vv->length() != subIds.size() ) + if ( vv->length() != subIds.size() * comps->length() ) THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); - for ( size_t i = 0; i < vv->length(); ++i ) - intVals[ subIds[ i ]] = (int) vv[ i ]; + for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ]; break; } case GEOM::FDT_Bool: @@ -3217,10 +3409,11 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step ); if ( boolStep->_is_nil() ) continue; GEOM::short_array_var vv = boolStep->GetValues(); - if ( vv->length() != subIds.size() ) + if ( vv->length() != subIds.size() * comps->length() ) THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); - for ( size_t i = 0; i < vv->length(); ++i ) - intVals[ subIds[ i ]] = (int) vv[ i ]; + for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ]; break; } default: continue; @@ -3233,20 +3426,24 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, { const SMDS_MeshElement* e = elemIt->next(); const int shapeID = e->getshapeId(); - if ( shapeID < 1 || shapeID >= dblVals.size() ) - fieldWriter.AddValue( noneDblValue ); + if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( noneDblValue ); else - fieldWriter.AddValue( dblVals[ shapeID ]); + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( dblVals[ iC ][ shapeID ]); } else while ( elemIt->more() ) { const SMDS_MeshElement* e = elemIt->next(); const int shapeID = e->getshapeId(); - if ( shapeID < 1 || shapeID >= intVals.size() ) - fieldWriter.AddValue( (double) noneIntValue ); + if ( shapeID < 1 || shapeID >= (int) intVals[0].size() ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( (double) noneIntValue ); else - fieldWriter.AddValue( (double) intVals[ shapeID ]); + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]); } // write a step @@ -3413,8 +3610,14 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart, PrepareForWriting(file); + CORBA::String_var name; + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart ); + if ( !so->_is_nil() ) + name = so->GetName(); + SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportSTL(file, isascii, &partDS); + _impl->ExportSTL( file, isascii, name.in(), &partDS ); TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( " << meshPart<< ", r'" << file << "', " << isascii << ")"; @@ -3428,7 +3631,8 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart, void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, const char* file, - CORBA::Boolean overwrite) + CORBA::Boolean overwrite, + CORBA::Boolean groupElemsByType) throw (SALOME::SALOME_Exception) { #ifdef WITH_CGNS @@ -3438,8 +3642,20 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, PrepareForWriting(file,overwrite); + std::string meshName(""); + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart ); + if ( !so->_is_nil() ) + { + CORBA::String_var name = so->GetName(); + meshName = name.in(); + } + SMESH_TRY; + SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportCGNS(file, &partDS); + _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType ); + + SMESH_CATCH( SMESH::throwCorbaException ); TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( " << meshPart<< ", r'" << file << "', " << overwrite << ")"; @@ -3592,7 +3808,7 @@ CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception) return _impl->NbBiQuadQuadrangles(); } -CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception) +CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) @@ -3601,6 +3817,15 @@ CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception) return _impl->NbPolygons(); } +CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order); + + return _impl->NbPolygons((SMDSAbs_ElementOrder)order); +} + CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { @@ -3897,7 +4122,7 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem ) throw (SALOME::SALOME_Exception) { - SMESH::ElementType type; + SMESH::ElementType type = SMESH::ALL; SMESH_TRY; if ( _preMeshInfo ) @@ -4045,7 +4270,7 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID) throw (SALOME::SALOME_Exception) { - SMESH::ElementType type; + SMESH::ElementType type = SMESH::ALL; SMESH_TRY; if ( _preMeshInfo ) @@ -4083,8 +4308,7 @@ CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() _preMeshInfo->FullLoadFromFile(); CORBA::LongLong pointeur = CORBA::LongLong(_impl); - if ( MYDEBUG ) - MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<length( vtool.NbFaceNodes( faceIndex )); const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex ); - for ( int i = 0; i < aResult->length(); ++i ) + for ( CORBA::ULong i = 0; i < aResult->length(); ++i ) aResult[ i ] = nn[ i ]->GetID(); } } @@ -4540,7 +4764,7 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes) if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) { vector< const SMDS_MeshNode * > nn( nodes.length() ); - for ( int i = 0; i < nodes.length(); ++i ) + for ( CORBA::ULong i = 0; i < nodes.length(); ++i ) if ( !( nn[i] = mesh->FindNode( nodes[i] ))) return elemID; @@ -4555,6 +4779,35 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes) return elemID; } +//================================================================================ +/*! + * \brief Return elements including all given nodes. + */ +//================================================================================ + +SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes, + SMESH::ElementType elemType) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH::long_array_var result = new SMESH::long_array(); + + if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) + { + vector< const SMDS_MeshNode * > nn( nodes.length() ); + for ( CORBA::ULong i = 0; i < nodes.length(); ++i ) + nn[i] = mesh->FindNode( nodes[i] ); + + std::vector elems; + mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType ); + result->length( elems.size() ); + for ( size_t i = 0; i < elems.size(); ++i ) + result[i] = elems[i]->GetID(); + } + return result._retn(); +} + //============================================================================= /*! * Returns true if given element is polygon @@ -4678,6 +4931,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM ); SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups; + ::SMESH_MeshEditor::ElemFeatures elemType; // submesh by subshape id if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1; @@ -4710,7 +4964,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, if ( elem ) { ::SMESH_MeshEditor editor( _impl ); - elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() ); + elem = editor.AddElement( nodes, elemType.Init( elem )); } } if ( elem ) @@ -4737,7 +4991,6 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, SALOMEDS::SObject_wrap aSO = _gen_i->PublishGroup( study, mesh, groups[ iG ], GEOM::GEOM_Object::_nil(), theGroupName); - aSO->_is_nil(); // avoid "unused variable" warning } SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]); if ( !grp_i ) continue; @@ -4929,11 +5182,11 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters() SALOMEDS::Study_var aStudy = gen->GetCurrentStudy(); if ( !aStudy->_is_nil()) { SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters); - if(aSections->length() > 0) { - SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1]; - aResult->length(aVars.length()); - for(int i = 0;i < aVars.length();i++) - aResult[i] = CORBA::string_dup( aVars[i]); + if ( aSections->length() > 0 ) { + SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ]; + aResult->length( aVars.length() ); + for ( CORBA::ULong i = 0;i < aVars.length(); i++ ) + aResult[i] = CORBA::string_dup( aVars[i] ); } } } @@ -4959,6 +5212,8 @@ SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes() if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME; if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D; if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL; + if (_impl->NbNodes() && + nbTypes == 0 ) types[nbTypes++] = SMESH::NODE; types->length( nbTypes ); return types._retn(); @@ -5048,6 +5303,37 @@ void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr, while (theItr->more()) theInfo[ theItr->next()->GetEntityType() ]++; } +//============================================================================= +/* + * Returns mesh unstructed grid information. + */ +//============================================================================= + +SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream() +{ + SALOMEDS::TMPFile_var SeqFile; + if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) { + SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid(); + if(aGrid) { + vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New(); + aWriter->WriteToOutputStringOn(); + aWriter->SetInputData(aGrid); + aWriter->SetFileTypeToBinary(); + aWriter->Write(); + char* str = aWriter->GetOutputString(); + int size = aWriter->GetOutputStringLength(); + + //Allocate octect buffer of required size + CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size); + //Copy ostrstream content to the octect buffer + memcpy(OctetBuf, str, size); + //Create and return TMPFile + SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1); + aWriter->Delete(); + } + } + return SeqFile._retn(); +} //============================================================================= namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj, @@ -5131,7 +5417,7 @@ namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_v _elem = _mesh->FindNode( *_idPtr++ ); } else if ((_elem = _mesh->FindElement( *_idPtr++ )) && - _elem->GetType() != _type ) + (_elem->GetType() != _type && _type != SMDSAbs_All )) { _elem = 0; } @@ -5164,7 +5450,7 @@ namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_v { const SMDS_MeshElement* res = _node; _node = 0; - while (( _elemIter->more() || _nodeIter->more() ) && !_node ) + while ( !_node && ( _elemIter->more() || _nodeIter->more() )) { if ( _nodeIter->more() ) { @@ -5192,7 +5478,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje SMESH::ElementType theType) { SMDS_ElemIteratorPtr elemIt; - bool typeOK = false; + bool typeOK = ( theType == SMESH::ALL ); SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType ); SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh(); @@ -5211,7 +5497,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje if ( sm ) { elemIt = sm->GetElements(); - if ( elemType != SMDSAbs_Node ) + if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All ) { typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType ); elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr(); @@ -5221,15 +5507,19 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast( theObject )) { SMESHDS_GroupBase* groupDS = group_i->GetGroupDS(); - if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node )) + if ( groupDS && ( elemType == groupDS->GetType() || + elemType == SMDSAbs_Node || + elemType == SMDSAbs_All )) { elemIt = groupDS->GetElements(); - typeOK = ( groupDS->GetType() == elemType ); + typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All ); } } else if ( SMESH::Filter_i* filter_i = SMESH::DownCast( theObject )) { - if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node ) + if ( filter_i->GetElementType() == theType || + elemType == SMDSAbs_Node || + elemType == SMDSAbs_All) { SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i(); if ( pred_i && pred_i->GetPredicate() ) @@ -5237,7 +5527,7 @@ 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 ); + typeOK = ( filterType == elemType || elemType == SMDSAbs_All ); } } } @@ -5245,7 +5535,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje { SMESH::array_of_ElementType_var types = theObject->GetTypes(); const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE ); - if ( isNodes && elemType != SMDSAbs_Node ) + if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All ) return elemIt; if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject )) { @@ -5258,7 +5548,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje SMESH::long_array_var ids = theObject->GetIDs(); elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType )); } - typeOK = ( isNodes == ( elemType == SMDSAbs_Node )); + typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All ); } if ( elemIt && elemIt->more() && !typeOK ) @@ -5298,10 +5588,10 @@ TopAbs_ShapeEnum shapeTypeByDim(const int theDim) //----------------------------------------------------------------------------- /*! - * \brief Internal structure used to find concurent submeshes + * \brief Internal structure used to find concurrent submeshes * - * It represents a pair < submesh, concurent dimension >, where - * 'concurrent dimension' is dimension of shape where the submesh can concurent + * It represents a pair < submesh, concurrent dimension >, where + * 'concurrent dimension' is dimension of shape where the submesh can concurrent * with another submesh. In other words, it is dimension of a hypothesis assigned * to submesh. */ @@ -5418,7 +5708,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 != theOther->_hypotheses.size() - 1; + return nbSame != (int)theOther->_hypotheses.size() - 1; } // Return true if algorithm of this SMESH_DimHyp is used if no @@ -5693,7 +5983,7 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() removeDimHyps(dimHypListArr); - // now, minimise the number of concurrent groups + // 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 // list with common submesh has to be united into one list @@ -5790,7 +6080,7 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, continue; if ( theIsDump ) aPythonDump << "[ "; - // convert shape indeces into interfaces + // convert shape indices into interfaces SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array(); aResSubSet->length(aSubOrder.size()); TListOfInt::const_iterator subIt = aSubOrder.begin(); @@ -5832,6 +6122,7 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh(); SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh ); + mesh_i->Load(); _meshDS = mesh_i->GetImpl().GetMeshDS(); SetPersistentId( _meshDS->GetPersistentId() ); @@ -5851,14 +6142,14 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): SMESH::array_of_ElementType_var types = meshPart->GetTypes(); if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes { - for (int i=0; i < anIDs->length(); i++) - if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i])) + for ( CORBA::ULong i=0; i < anIDs->length(); i++ ) + if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] )) if ( _elements[ SMDSAbs_Node ].insert( n ).second ) tmpInfo.Add( n ); } else { - for (int i=0; i < anIDs->length(); i++) + for ( CORBA::ULong i=0; i < anIDs->length(); i++ ) if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i])) if ( _elements[ e->GetType() ].insert( e ).second ) { @@ -5874,6 +6165,8 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): } myInfo = tmpInfo; + ShapeToMesh( _meshDS->ShapeToMesh() ); + _meshDS = 0; // to enforce iteration on _elements and _nodes } } @@ -5899,6 +6192,21 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & myInfo = tmpInfo; } // ------------------------------------------------------------------------------------- +const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const +{ + if ( _meshDS ) return _meshDS->FindElement( IDelem ); + + TElemID elem( IDelem ); + for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType ) + if ( !_elements[ iType ].empty() ) + { + TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem ); + if ( it != _elements[ iType ].end() ) + return *it; + } + return 0; +} +// ------------------------------------------------------------------------------------- SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const { if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );