X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_MeshEditor_i.cxx;h=9de57c975706a25fbf79216219c01df44de7816e;hp=d88c81400cbf295a0d4f148f3b95e1c8e7fb104b;hb=b3da9e90b47c443a8457f5b0e4ffd64910a17345;hpb=7aebb99e42c6b0c3c056a5eecb0f29033db2231a diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index d88c81400..9de57c975 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,10 +23,15 @@ // Author : Nicolas REJNERI // Module : SMESH -#ifdef WNT +#ifdef WIN32 #define NOMINMAX #endif +// A macro used in SMESH_TryCatch.hxx, +// it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH +#define SMY_OWN_CATCH \ + catch ( SALOME::SALOME_Exception & e ) { throw e; } + #include "SMESH_MeshEditor_i.hxx" #include "SMDS_EdgePosition.hxx" @@ -47,6 +52,7 @@ #include "SMESH_Gen_i.hxx" #include "SMESH_Group.hxx" #include "SMESH_Group_i.hxx" +#include "SMESH_MeshAlgos.hxx" #include "SMESH_MeshPartDS.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_PythonDump.hxx" @@ -57,6 +63,7 @@ #include #include #include +#include #include #include @@ -170,6 +177,10 @@ namespace MeshEditor_I { return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), anElemNode->GetID()); } + void RemoveAll() + { + GetMeshDS()->ClearMesh(); + } };// struct TPreviewMesh static SMESH_NodeSearcher * theNodeSearcher = 0; @@ -216,22 +227,22 @@ namespace MeshEditor_I { } myMesh = mesh; myMeshPartIOR = meshPartIOR; - if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) { - const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn(); - TDependsOnMap::const_iterator sm; - for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++) - sm->second->SetEventListener( this, 0, sm->second ); + SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() ); + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true ); + while ( smIt->more() ) + { + sm = smIt->next(); + sm->SetEventListener( this, 0, sm ); } } } //!< delete self from all submeshes void Unset(SMESH_Mesh* mesh) { - if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) { - const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn(); - TDependsOnMap::const_iterator sm; - for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++) - sm->second->DeleteEventListener( this ); + if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) { + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true ); + while ( smIt->more() ) + smIt->next()->DeleteEventListener( this ); } myMesh = 0; } @@ -266,15 +277,29 @@ namespace MeshEditor_I { void arrayToSet(const SMESH::long_array & IDs, const SMESHDS_Mesh* aMesh, TIDSortedElemSet& aMap, - const SMDSAbs_ElementType aType = SMDSAbs_All ) + const SMDSAbs_ElementType aType = SMDSAbs_All, + SMDS_MeshElement::Filter* aFilter = NULL) { - for (int i=0; iFindNode(ind) : aMesh->FindElement(ind)); - if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType )) - aMap.insert( aMap.end(), elem ); - } + SMDS_MeshElement::NonNullFilter filter1; + SMDS_MeshElement::TypeFilter filter2( aType ); + + if ( aFilter == NULL ) + aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2; + + SMDS_MeshElement::Filter & filter = *aFilter; + + if ( aType == SMDSAbs_Node ) + for (int i=0; iFindNode( IDs[i] ); + if ( filter( elem )) + aMap.insert( aMap.end(), elem ); + } + else + for (int i=0; iFindElement( IDs[i] ); + if ( filter( elem )) + aMap.insert( aMap.end(), elem ); + } } //================================================================================ /*! @@ -437,7 +462,11 @@ SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview): SMESH_MeshEditor_i::~SMESH_MeshEditor_i() { - deleteAuxIDSources(); + PortableServer::POA_var poa = SMESH_Gen_i::GetPOA(); + PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this); + poa->deactivate_object(anObjectId.in()); + + //deleteAuxIDSources(); delete myPreviewMesh; myPreviewMesh = 0; delete myPreviewEditor; myPreviewEditor = 0; } @@ -451,7 +480,7 @@ SMESH_MeshEditor_i::~SMESH_MeshEditor_i() void SMESH_MeshEditor_i::initData(bool deleteSearchers) { if ( myIsPreviewMode ) { - if ( myPreviewMesh ) myPreviewMesh->Clear(); + if ( myPreviewMesh ) myPreviewMesh->RemoveAll(); } else { if ( deleteSearchers ) @@ -565,10 +594,9 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() while ( itMeshElems->more() ) { const SMDS_MeshElement* aMeshElem = itMeshElems->next(); - SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator(); + SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator(); while ( itElemNodes->more() ) { - const SMDS_MeshNode* aMeshNode = - static_cast( itElemNodes->next() ); + const SMDS_MeshNode* aMeshNode = itElemNodes->next(); int aNodeID = aMeshNode->GetID(); TNodesMap::iterator anIter = nodesMap.find(aNodeID); if ( anIter == nodesMap.end() ) { @@ -585,12 +613,10 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() // filling the elements types SMDSAbs_ElementType aType = aMeshElem->GetType(); bool isPoly = aMeshElem->IsPoly(); - myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType; - myPreviewData->elementTypes[i].isPoly = isPoly; + myPreviewData->elementTypes[i].isPoly = isPoly; myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes(); i++; - } myPreviewData->nodesXYZ.length( j ); @@ -600,8 +626,8 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ ) myPreviewData->elementConnectivities[i] = *aConnIter; } - return myPreviewData._retn(); + SMESH_CATCH( SMESH::throwCorbaException ); return 0; } @@ -652,9 +678,22 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems() return 0; } +//======================================================================= +//function : ClearLastCreated +//purpose : Clears sequences of last created elements and nodes +//======================================================================= + +void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception) +{ + SMESH_TRY; + getEditor().CrearLastCreated(); + SMESH_CATCH( SMESH::throwCorbaException ); +} + //======================================================================= /* * Returns description of an error/warning occured during the last operation + * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API */ //======================================================================= @@ -685,16 +724,26 @@ SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError() //======================================================================= //function : MakeIDSource -//purpose : Wrap a sequence of ids in a SMESH_IDSource +//purpose : Wrap a sequence of ids in a SMESH_IDSource. +// Call UnRegister() as you fininsh using it!! //======================================================================= -struct SMESH_MeshEditor_i::_IDSource : public POA_SMESH::SMESH_IDSource +struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource, + public virtual SALOME::GenericObj_i { SMESH::long_array _ids; SMESH::ElementType _type; SMESH::SMESH_Mesh_ptr _mesh; SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); } SMESH::long_array* GetMeshInfo() { return 0; } + SMESH::long_array* 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++) + aRes[ i ] = ( i == _type ) ? _ids.length() : 0; + return aRes._retn(); + } SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); } bool IsMeshInfoCorrect() { return true; } SMESH::array_of_ElementType* GetTypes() @@ -711,14 +760,16 @@ struct SMESH_MeshEditor_i::_IDSource : public POA_SMESH::SMESH_IDSource SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids, SMESH::ElementType type) { - if ( myAuxIDSources.size() > 10 ) - deleteAuxIDSources(); + // if ( myAuxIDSources.size() > 10 ) { + // delete myAuxIDSources.front(); + // myAuxIDSources.pop_front(); + // } _IDSource* idSrc = new _IDSource; idSrc->_mesh = myMesh_i->_this(); idSrc->_ids = ids; idSrc->_type = type; - myAuxIDSources.push_back( idSrc ); + //myAuxIDSources.push_back( idSrc ); SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this(); @@ -730,14 +781,26 @@ bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSourc return SMESH::DownCast( idSource ); } -void SMESH_MeshEditor_i::deleteAuxIDSources() +CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource, + int& nbIds) { - std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin(); - for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt ) - delete *idSrcIt; - myAuxIDSources.clear(); + if ( _IDSource* tmpIdSource = SMESH::DownCast( idSource )) + { + nbIds = (int) tmpIdSource->_ids.length(); + return & tmpIdSource->_ids[0]; + } + nbIds = 0; + return 0; } +// void SMESH_MeshEditor_i::deleteAuxIDSources() +// { +// std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin(); +// for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt ) +// delete *idSrcIt; +// myAuxIDSources.clear(); +// } + //============================================================================= /*! * @@ -981,26 +1044,19 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]); SMDS_MeshElement* elem = 0; - if (NbNodes == 3) { - elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); - } - else if (NbNodes == 4) { - elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); - } - else if (NbNodes == 6) { - elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], - nodes[4], nodes[5]); - } - else if (NbNodes == 8) { - elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], - nodes[4], nodes[5], nodes[6], nodes[7]); - } - else if (NbNodes == 9) { - elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], - nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] ); - } - else if (NbNodes > 2) { - elem = getMeshDS()->AddPolygonalFace(nodes); + switch (NbNodes) { + case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break; + case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break; + case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5]); break; + case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6]); break; + case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7]); break; + case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7], + nodes[8] ); break; + default: elem = getMeshDS()->AddPolygonalFace(nodes); } // Update Python script @@ -1202,6 +1258,7 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje TPythonDump pyDump; TIDSortedElemSet elements, elems0D; + prepareIdSource( theObject ); if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) getEditor().Create0DElementsOnAllNodes( elements, elems0D ); @@ -1413,7 +1470,6 @@ void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID * \brief Bind an element to a shape * \param ElementID - element ID * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0] - * \retval boolean - false if ElementID or ShapeID is invalid */ //============================================================================= @@ -1427,7 +1483,7 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID, if ( !elem ) THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM); - if ( mesh->MaxShapeIndex() < ShapeID ) + if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 ) THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM); TopoDS_Shape shape = mesh->IndexToShape( ShapeID ); @@ -1551,6 +1607,8 @@ CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theO TPythonDump aTPythonDump; // suppress dump in Reorient() + prepareIdSource( theObject ); + SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = Reorient(anElementsId); @@ -1585,6 +1643,7 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, initData(/*deleteSearchers=*/false); TIDSortedElemSet elements; + prepareIdSource( the2Dgroup ); if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1)) THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM); @@ -1609,14 +1668,14 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, if ( myMesh->NbFaces() == 0 ) THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM); - theElementSearcher = myEditor.GetElementSearcher(); + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() ); } else { typedef SMDS_SetIterator TIter; SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() )); - theElementSearcher = myEditor.GetElementSearcher(elemsIt); + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt); } } // find a face @@ -1653,7 +1712,7 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, //============================================================================= /*! - * + * \brief Fuse neighbour triangles into quadrangles. */ //============================================================================= @@ -1666,8 +1725,16 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE initData(); SMESHDS_Mesh* aMesh = getMeshDS(); - TIDSortedElemSet faces; - arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face); + TIDSortedElemSet faces,copyFaces; + SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE); + arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter); + TIDSortedElemSet* workElements = & faces; + + if ( myIsPreviewMode ) { + SMDSAbs_ElementType select = SMDSAbs_Face; + getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select ); + workElements = & copyFaces; + } SMESH::NumericalFunctor_i* aNumericalFunctor = dynamic_cast( SMESH_Gen_i::GetServant( Criterion ).in() ); @@ -1677,12 +1744,13 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE else aCrit = aNumericalFunctor->GetNumericalFunctor(); - // Update Python script - TPythonDump() << "isDone = " << this << ".TriToQuad( " - << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )"; - + if ( !myIsPreviewMode ) { + // Update Python script + TPythonDump() << "isDone = " << this << ".TriToQuad( " + << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )"; + } - bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle ); + bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle ); declareMeshModified( /*isReComputeSafe=*/!stat ); return stat; @@ -1693,7 +1761,7 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfE //============================================================================= /*! - * + * \brief Fuse neighbour triangles into quadrangles. */ //============================================================================= @@ -1706,15 +1774,19 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr initData(); TPythonDump aTPythonDump; // suppress dump in TriToQuad() + + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle); - SMESH::NumericalFunctor_i* aNumericalFunctor = - SMESH::DownCast( Criterion ); + if ( !myIsPreviewMode ) { + SMESH::NumericalFunctor_i* aNumericalFunctor = + SMESH::DownCast( Criterion ); - // Update Python script - aTPythonDump << "isDone = " << this << ".TriToQuadObject(" - << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )"; + // Update Python script + aTPythonDump << "isDone = " << this << ".TriToQuadObject(" + << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )"; + } return isDone; @@ -1724,7 +1796,7 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr //============================================================================= /*! - * + * \brief Split quadrangles into triangles. */ //============================================================================= @@ -1760,12 +1832,12 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfE return 0; } - //============================================================================= /*! - * + * \brief Split quadrangles into triangles. */ //============================================================================= + CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject, SMESH::NumericalFunctor_ptr Criterion) throw (SALOME::SALOME_Exception) @@ -1775,6 +1847,7 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr TPythonDump aTPythonDump; // suppress dump in QuadToTri() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion); @@ -1791,12 +1864,37 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr return 0; } +//================================================================================ +/*! + * \brief Split each of quadrangles into 4 triangles. + * \param [in] theObject - theQuads Container of quadrangles to split. + */ +//================================================================================ + +void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject) + throw (SALOME::SALOME_Exception) +{ + SMESH_TRY; + initData(); + + TIDSortedElemSet faces; + prepareIdSource( theObject ); + if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) && + faces.empty() ) + THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM); + + getEditor().QuadTo4Tri( faces ); + TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); +} //============================================================================= /*! - * + * \brief Split quadrangles into triangles. */ //============================================================================= + CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements, CORBA::Boolean Diag13) throw (SALOME::SALOME_Exception) @@ -1821,12 +1919,12 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle return 0; } - //============================================================================= /*! - * + * \brief Split quadrangles into triangles. */ //============================================================================= + CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject, CORBA::Boolean Diag13) throw (SALOME::SALOME_Exception) @@ -1836,6 +1934,7 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th TPythonDump aTPythonDump; // suppress dump in SplitQuad() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13); @@ -1853,7 +1952,11 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th //============================================================================= /*! - * BestSplit + * Find better splitting of the given quadrangle. + * \param IDOfQuad ID of the quadrangle to be splitted. + * \param Criterion A criterion to choose a diagonal for splitting. + * \return 1 if 1-3 diagonal is better, 2 if 2-4 + * diagonal is better, 0 if error occurs. */ //============================================================================= @@ -1877,6 +1980,7 @@ CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad, int id = getEditor().BestSplit(quad, aCrit); declareMeshModified( /*isReComputeSafe=*/ id < 1 ); + return id; } SMESH_CATCH( SMESH::throwCorbaException ); @@ -1895,12 +1999,15 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, { SMESH_TRY; initData(); + prepareIdSource( elems ); - SMESH::long_array_var anElementsId = elems->GetIDs(); - TIDSortedElemSet elemSet; - arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume ); + ::SMESH_MeshEditor::TFacetOfElem elemSet; + const int noneFacet = -1; + SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME ); + while( volIt->more() ) + elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet )); - getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags )); + getEditor().SplitVolumes( elemSet, int( methodFlags )); declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute() TPythonDump() << this << ".SplitVolumesIntoTetra( " @@ -1909,6 +2016,70 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, SMESH_CATCH( SMESH::throwCorbaException ); } +//================================================================================ +/*! + * \brief Split hexahedra into triangular prisms + * \param elems - elements to split + * \param facetToSplitNormal - normal used to find a facet of hexahedron + * to split into triangles + * \param methodFlags - flags passing splitting method: + * 1 - split the hexahedron into 2 prisms + * 2 - split the hexahedron into 4 prisms + */ +//================================================================================ + +void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems, + const SMESH::PointStruct & startHexPoint, + const SMESH::DirStruct& facetToSplitNormal, + CORBA::Short methodFlags, + CORBA::Boolean allDomains) + throw (SALOME::SALOME_Exception) +{ + SMESH_TRY; + initData(); + prepareIdSource( elems ); + + gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x, + startHexPoint.y, + startHexPoint.z ), + gp_Dir( facetToSplitNormal.PS.x, + facetToSplitNormal.PS.y, + facetToSplitNormal.PS.z )); + TIDSortedElemSet elemSet; + SMESH::long_array_var anElementsId = elems->GetIDs(); + SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA ); + arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter ); + + ::SMESH_MeshEditor::TFacetOfElem elemFacets; + while ( !elemSet.empty() ) + { + getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets ); + if ( !allDomains ) + break; + + ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin(); + for ( ; ef != elemFacets.end(); ++ef ) + elemSet.erase( ef->first ); + } + + if ( methodFlags == 2 ) + methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS ); + else + methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS ); + + getEditor().SplitVolumes( elemFacets, int( methodFlags )); + declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute() + + TPythonDump() << this << ".SplitHexahedraIntoPrisms( " + << elems << ", " + << startHexPoint << ", " + << facetToSplitNormal<< ", " + << methodFlags<< ", " + << allDomains << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); +} + //======================================================================= //function : Smooth //purpose : @@ -2035,7 +2206,6 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements, return 0; } - //============================================================================= /*! * @@ -2056,6 +2226,7 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObjec TPythonDump aTPythonDump; // suppress dump in smooth() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method, IsParametric); @@ -2075,7 +2246,6 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObjec return 0; } - //============================================================================= /*! * @@ -2258,6 +2428,7 @@ void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject << theNbOfSteps << ", " << theTolerance << " )"; } + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); rotationSweep(anElementsId, theAxis, @@ -2287,6 +2458,7 @@ void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObje << TVar( theNbOfSteps ) << ", " << TVar( theTolerance ) << " )"; } + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); rotationSweep(anElementsId, theAxis, @@ -2317,6 +2489,7 @@ void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObje << TVar( theNbOfSteps ) << ", " << TVar( theTolerance ) << " )"; } + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); rotationSweep(anElementsId, theAxis, @@ -2342,6 +2515,7 @@ SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theO { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, theAxis, @@ -2376,6 +2550,7 @@ SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr th { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, theAxis, @@ -2411,6 +2586,7 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, theAxis, @@ -2468,7 +2644,7 @@ SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements, theMakeGroups = false; } - TElemOfElemListMap aHystory; + ::SMESH_MeshEditor::TTElemOfElemListMap aHystory; ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups); @@ -2524,6 +2700,7 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObjec CORBA::Long theNbOfSteps) throw (SALOME::SALOME_Exception) { + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false ); if (!myIsPreviewMode) { @@ -2542,6 +2719,7 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObj CORBA::Long theNbOfSteps) throw (SALOME::SALOME_Exception) { + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node ); if ( !myIsPreviewMode ) { @@ -2560,6 +2738,7 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObj CORBA::Long theNbOfSteps) throw (SALOME::SALOME_Exception) { + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge ); if ( !myIsPreviewMode ) { @@ -2578,6 +2757,7 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObj CORBA::Long theNbOfSteps) throw (SALOME::SALOME_Exception) { + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face ); if ( !myIsPreviewMode ) { @@ -2645,6 +2825,7 @@ SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr the { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true); @@ -2669,6 +2850,7 @@ SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr t { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Node); @@ -2693,6 +2875,7 @@ SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr t { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Edge); @@ -2717,6 +2900,7 @@ SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr t { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Face); @@ -2752,7 +2936,7 @@ SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements const SMESH::PointStruct * P = &theStepVector.PS; gp_Vec stepVec( P->x, P->y, P->z ); - TElemOfElemListMap aHystory; + ::SMESH_MeshEditor::TTElemOfElemListMap aHystory; ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, theMakeGroups, theExtrFlags, theSewTolerance); @@ -3115,6 +3299,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObje << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; } SMESH::SMESH_MeshEditor::Extrusion_Error anError; + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); extrusionAlongPath( anElementsId, thePathMesh, @@ -3160,6 +3345,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theOb << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; } SMESH::SMESH_MeshEditor::Extrusion_Error anError; + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); extrusionAlongPath( anElementsId, thePathMesh, @@ -3206,6 +3392,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theOb << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; } SMESH::SMESH_MeshEditor::Extrusion_Error anError; + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); extrusionAlongPath( anElementsId, thePathMesh, @@ -3293,6 +3480,7 @@ ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, thePathMesh, @@ -3347,6 +3535,7 @@ ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, thePathMesh, @@ -3402,6 +3591,7 @@ ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( theObject ); SMESH::long_array_var anElementsId = theObject->GetIDs(); SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, thePathMesh, @@ -3459,6 +3649,7 @@ ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object, { TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + prepareIdSource( Object ); SMESH::long_array_var anElementsId = Object->GetIDs(); SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId, Path, @@ -3747,6 +3938,7 @@ void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObj bool emptyIfIsMesh = myIsPreviewMode ? false : true; + prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) mirror(elements, theAxis, theMirrorType, theCopy, false); } @@ -3796,6 +3988,7 @@ SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr t SMESH::ListOfGroups * aGroups = 0; TIDSortedElemSet elements; + prepareIdSource( theObject ); if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) aGroups = mirror(elements, theMirror, theMirrorType, true, true); @@ -3881,6 +4074,7 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr the mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); TIDSortedElemSet elements; + prepareIdSource( theObject ); if ( mesh_i && idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) { @@ -4009,6 +4203,7 @@ void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject, bool emptyIfIsMesh = myIsPreviewMode ? false : true; + prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) translate(elements, theVector, theCopy, false); } @@ -4054,6 +4249,7 @@ SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObjec SMESH::ListOfGroups * aGroups = 0; TIDSortedElemSet elements; + prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) aGroups = translate(elements, theVector, true, true); @@ -4136,6 +4332,7 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, mesh_i = SMESH::DownCast( mesh ); TIDSortedElemSet elements; + prepareIdSource( theObject ); if ( mesh_i && idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) { @@ -4263,6 +4460,7 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject, } TIDSortedElemSet elements; bool emptyIfIsMesh = myIsPreviewMode ? false : true; + prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) rotate(elements,theAxis,theAngle,theCopy,false); } @@ -4312,6 +4510,7 @@ SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, SMESH::ListOfGroups * aGroups = 0; TIDSortedElemSet elements; + prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) aGroups = rotate(elements, theAxis, theAngle, true, true); @@ -4403,6 +4602,7 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, mesh_i = SMESH::DownCast( mesh ); TIDSortedElemSet elements; + prepareIdSource( theObject ); if (mesh_i && idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) { @@ -4455,6 +4655,7 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, theCopy = false; TIDSortedElemSet elements; + prepareIdSource( theObject ); bool emptyIfIsMesh = myIsPreviewMode ? false : true; if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) return 0; @@ -4638,6 +4839,7 @@ void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr initData(); TIDSortedNodeSet nodes; + prepareIdSource( theObject ); idSourceToNodeSet( theObject, getMeshDS(), nodes ); ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; @@ -4681,6 +4883,7 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject, initData(); TIDSortedNodeSet nodes; + prepareIdSource( theObject ); idSourceToNodeSet( theObject, getMeshDS(), nodes ); for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i ) @@ -4774,6 +4977,7 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObj if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) ) { TIDSortedElemSet elems; + prepareIdSource( theObject ); idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true); ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID; @@ -4933,7 +5137,7 @@ CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x, theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other if ( !theNodeSearcher ) { - theNodeSearcher = myEditor.GetNodeSearcher(); + theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() ); } gp_Pnt p( x,y,z ); if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p )) @@ -4970,7 +5174,7 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x, if ( !node ) // preview moving node { if ( !theNodeSearcher ) { - theNodeSearcher = myEditor.GetNodeSearcher(); + theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() ); } gp_Pnt p( x,y,z ); node = theNodeSearcher->FindClosestTo( p ); @@ -5040,7 +5244,7 @@ SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x, theSearchersDeleter.Set( myMesh ); if ( !theElementSearcher ) { - theElementSearcher = myEditor.GetElementSearcher(); + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() ); } theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ), SMDSAbs_ElementType( type ), @@ -5049,13 +5253,6 @@ SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x, for ( int i = 0; i < foundElems.size(); ++i ) res[i] = foundElems[i]->GetID(); - if ( !myIsPreviewMode ) // call from tui - TPythonDump() << "res = " << this << ".FindElementsByPoint( " - << x << ", " - << y << ", " - << z << ", " - << type << " )"; - return res._retn(); SMESH_CATCH( SMESH::throwCorbaException ); @@ -5105,7 +5302,7 @@ SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementID typedef SMDS_SetIterator TIter; SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() )); - theElementSearcher = myEditor.GetElementSearcher(elemsIt); + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt ); } vector< const SMDS_MeshElement* > foundElems; @@ -5117,14 +5314,6 @@ SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementID for ( int i = 0; i < foundElems.size(); ++i ) res[i] = foundElems[i]->GetID(); - if ( !myIsPreviewMode ) // call from tui - TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( " - << elementIDs << ", " - << x << ", " - << y << ", " - << z << ", " - << type << " )"; - return res._retn(); SMESH_CATCH( SMESH::throwCorbaException ); @@ -5145,7 +5334,7 @@ CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x, SMESH_TRY; theSearchersDeleter.Set( myMesh ); if ( !theElementSearcher ) { - theElementSearcher = myEditor.GetElementSearcher(); + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() ); } return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z ))); @@ -5481,8 +5670,11 @@ void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d TIDSortedElemSet elems; bool elemsOK; if ( !( elemsOK = CORBA::is_nil( theObject ))) + { + prepareIdSource( theObject ); elemsOK = idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ); + } if ( elemsOK ) { if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node ) @@ -5561,8 +5753,11 @@ void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr th throw (SALOME::SALOME_Exception) { SMESH_TRY; - TPythonDump pyDump; + + TPythonDump pyDump; + TIDSortedElemSet elems; + prepareIdSource( theObject ); if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true )) { if ( elems.empty() ) @@ -5643,11 +5838,99 @@ string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix) int index = 0; while (!groupNames.insert(name).second) - name = SMESH_Comment( thePrefix ) << "_" << index; + name = SMESH_Comment( thePrefix ) << "_" << index++; return name; } +//================================================================================ +/*! + * \brief Prepare SMESH_IDSource for work + */ +//================================================================================ + +void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject) +{ + if ( SMESH::Filter_i* filter = SMESH::DownCast( theObject )) + { + SMESH::SMESH_Mesh_var mesh = myMesh_i->_this(); + filter->SetMesh( mesh ); + } +} + +//================================================================================ +/*! + * \brief Duplicates given elements, i.e. creates new elements based on the + * same nodes as the given ones. + * \param theElements - container of elements to duplicate. + * \param theGroupName - a name of group to contain the generated elements. + * If a group with such a name already exists, the new elements + * are added to the existng group, else a new group is created. + * If \a theGroupName is empty, new elements are not added + * in any group. + * \return a group where the new elements are added. NULL if theGroupName == "". + * \sa DoubleNode() + */ +//================================================================================ + +SMESH::SMESH_Group_ptr +SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements, + const char* theGroupName) + throw (SALOME::SALOME_Exception) +{ + SMESH::SMESH_Group_var newGroup; + + SMESH_TRY; + initData(); + + TPythonDump pyDump; + + TIDSortedElemSet elems; + prepareIdSource( theElements ); + if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true)) + { + getEditor().DoubleElements( elems ); + + if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() ) + { + // group type + SMESH::ElementType type = + SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() ); + // find existing group + SMESH::ListOfGroups_var groups = myMesh_i->GetGroups(); + for ( size_t i = 0; i < groups->length(); ++i ) + if ( groups[i]->GetType() == type ) + { + CORBA::String_var name = groups[i]->GetName(); + if ( strcmp( name, theGroupName ) == 0 ) { + newGroup = SMESH::SMESH_Group::_narrow( groups[i] ); + break; + } + } + // create a new group + if ( newGroup->_is_nil() ) + newGroup = myMesh_i->CreateGroup( type, theGroupName ); + // fill newGroup + if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup )) + { + SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() ); + const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems(); + for ( int i = 1; i <= aSeq.Length(); i++ ) + groupDS->SMDSGroup().Add( aSeq(i) ); + } + } + } + // python dump + if ( !newGroup->_is_nil() ) + pyDump << newGroup << " = "; + pyDump << this << ".DoubleElements( " + << theElements << ", " << "'" << theGroupName <<"')"; + + SMESH_CATCH( SMESH::throwCorbaException ); + + return newGroup._retn(); +} + //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements @@ -6580,33 +6863,45 @@ CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D() //================================================================================ /*! - * \brief Double nodes on shared faces between groups of volumes and create flat - * elements on demand. - * The list of groups must describe a partition of the mesh volumes. + * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand. + * The list of groups must contain at least two groups. The groups have to be disjoint: + * no common element into two different groups. * The nodes of the internal faces at the boundaries of the groups are doubled. - * In option, the internal faces are replaced by flat elements. - * Triangles are transformed in prisms, and quadrangles in hexahedrons. + * Optionally, the internal faces are replaced by flat elements. + * Triangles are transformed into prisms, and quadrangles into hexahedrons. * The flat elements are stored in groups of volumes. - * @param theDomains - list of groups of volumes - * @param createJointElems - if TRUE, create the elements - * @return TRUE if operation has been completed successfully, FALSE otherwise + * These groups are named according to the position of the group in the list: + * the group j_n_p is the group of the flat elements that are built between the group #n and the group #p in the list. + * If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created. + * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation). + * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples". + * \param theDomains - list of groups of volumes + * \param createJointElems - if TRUE, create the elements + * \param onAllBoundaries - if TRUE, the nodes and elements are also created on + * the boundary between \a theDomains and the rest mesh + * \return TRUE if operation has been completed successfully, FALSE otherwise */ //================================================================================ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains, - CORBA::Boolean createJointElems ) + CORBA::Boolean createJointElems, + CORBA::Boolean onAllBoundaries ) throw (SALOME::SALOME_Exception) { - bool aResult = false; + bool isOK = false; SMESH_TRY; initData(); SMESHDS_Mesh* aMeshDS = getMeshDS(); + // MESSAGE("theDomains.length = "< domains; - domains.clear(); + domains.resize( theDomains.length() ); for ( int i = 0, n = theDomains.length(); i < n; i++ ) { @@ -6615,26 +6910,25 @@ SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& the { // if ( aGrp->GetType() != SMESH::VOLUME ) // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM); - TIDSortedElemSet domain; - domain.clear(); - domains.push_back(domain); SMESH::long_array_var anIDs = aGrp->GetIDs(); arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All ); } } - aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems ); + isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries ); // TODO publish the groups of flat elements in study - declareMeshModified( /*isReComputeSafe=*/ !aResult ); + declareMeshModified( /*isReComputeSafe=*/ !isOK ); // Update Python script TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains - << ", " << createJointElems << " )"; + << ", " << createJointElems << ", " << onAllBoundaries << " )"; SMESH_CATCH( SMESH::throwCorbaException ); - return aResult; + myMesh_i->CreateGroupServants(); // publish created groups if any + + return isOK; } //================================================================================ @@ -6714,7 +7008,7 @@ void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius, theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other if ( !theNodeSearcher ) - theNodeSearcher = aMeshEditor.GetNodeSearcher(); + theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() ); vector nodesCoords; for (int i = 0; i < theNodesCoords.length(); i++) @@ -6789,6 +7083,7 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource, TIDSortedElemSet elements; SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume; + prepareIdSource( idSource ); if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true )) { // mesh to fill in