From 787fff00679978dcfe51335e456ae5c55fd6558a Mon Sep 17 00:00:00 2001 From: ptv Date: Tue, 11 Aug 2009 12:01:49 +0000 Subject: [PATCH] IMP20439 Create hole by element and nodes duplication --- idl/SMESH_MeshEditor.idl | 104 ++++++++---- src/SMESH/SMESH_MeshEditor.cxx | 188 +++++++++++++++------ src/SMESH/SMESH_MeshEditor.hxx | 17 +- src/SMESH_I/SMESH_MeshEditor_i.cxx | 255 +++++++++++++++++++++-------- src/SMESH_I/SMESH_MeshEditor_i.hxx | 93 ++++++++++- src/SMESH_SWIG/smeshDC.py | 70 +++++--- 6 files changed, 540 insertions(+), 187 deletions(-) diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl index b1b36c257..198275ed8 100644 --- a/idl/SMESH_MeshEditor.idl +++ b/idl/SMESH_MeshEditor.idl @@ -687,46 +687,90 @@ module SMESH /*! * \brief Creates a hole in a mesh by doubling the nodes of some particular elements - * \param theNodes - identifiers of nodes to be doubled - * \param theModifiedElems - identifiers of elements to be updated by the new (doubled) - * nodes. If list of element identifiers is empty then nodes are doubled but - * they not assigned to elements - * \return TRUE if operation has been completed successfully, FALSE otherwise - * \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups() + * \param theElems - the list of elements (edges or faces) to be replicated + * The nodes for duplication could be found from these elements + * \param theNodesNot - list of nodes to NOT replicate + * \param theAffectedElems - the list of elements (cells and edges) to which the + * replicated nodes should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroup(), DoubleNodeGroups() */ - boolean DoubleNodes( in long_array theNodes, in long_array theModifiedElems ); + boolean DoubleNodes( in long_array theElems, + in long_array theNodesNot, + in long_array theAffectedElems ); /*! - * \brief Creates a hole in a mesh by doubling the nodes of some particular elements - * This method provided for convenience works as DoubleNodes() described above. - * \param theNodeId - identifier of node to be doubled. - * \param theModifiedElems - identifiers of elements to be updated. - * \return TRUE if operation has been completed successfully, FALSE otherwise - * \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups() + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - the list of elements (edges or faces) to be replicated + * The nodes for duplication could be found from these elements + * \param theNodesNot - list of nodes to NOT replicate + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion() + */ + boolean DoubleNodesInRegion( in long_array theElems, + in long_array theNodesNot, + in GEOM::GEOM_Object theShape ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodes(), DoubleNodeGroups() */ - boolean DoubleNode( in long theNodeId, in long_array theModifiedElems ); + boolean DoubleNodeGroup( in SMESH_GroupBase theElems, + in SMESH_GroupBase theNodesNot, + in SMESH_GroupBase theAffectedElems ); /*! - * \brief Creates a hole in a mesh by doubling the nodes of some particular elements - * This method provided for convenience works as DoubleNodes() described above. - * \param theNodes - group of nodes to be doubled. - * \param theModifiedElems - group of elements to be updated. - * \return TRUE if operation has been completed successfully, FALSE otherwise - * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups() + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - group of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion() */ - boolean DoubleNodeGroup( in SMESH_GroupBase theNodes, - in SMESH_GroupBase theModifiedElems ); + boolean DoubleNodeGroupInRegion( in SMESH_GroupBase theElems, + in SMESH_GroupBase theNodesNot, + in GEOM::GEOM_Object theShape ); /*! - \brief Creates a hole in a mesh by doubling the nodes of some particular elements - This method provided for convenience works as DoubleNodes() described above. - \param theNodes - list of groups of nodes to be doubled - \param theModifiedElems - list of groups of elements to be updated. - \return TRUE if operation has been completed successfully, FALSE otherwise - \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes() + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroup(), DoubleNodes() + */ + boolean DoubleNodeGroups( in ListOfGroups theElems, + in ListOfGroups theNodesNot, + in ListOfGroups theAffectedElems ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion() */ - boolean DoubleNodeGroups( in ListOfGroups theNodes, - in ListOfGroups theModifiedElems ); + boolean DoubleNodeGroupsInRegion( in ListOfGroups theElems, + in ListOfGroups theNodesNot, + in GEOM::GEOM_Object theShape ); }; }; diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index cdf053414..09bc9e4cb 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -47,6 +47,7 @@ #include "utilities.h" #include +#include #include #include #include @@ -54,7 +55,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -8188,89 +8191,166 @@ SMESH_MeshEditor::FindMatchingNodes(set& theSide1, /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements - \param theNodes - identifiers of nodes to be doubled - \param theModifiedElems - identifiers of elements to be updated by the new (doubled) - nodes. If list of element identifiers is empty then nodes are doubled but - they not assigned to elements + \param theElems - the list of elements (edges or faces) to be replicated + The nodes for duplication could be found from these elements + \param theNodesNot - list of nodes to NOT replicate + \param theAffectedElems - the list of elements (cells and edges) to which the + replicated nodes should be associated to. \return TRUE if operation has been completed successfully, FALSE otherwise */ -bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, - const std::list< int >& theListOfModifiedElems ) +bool SMESH_MeshEditor::DoubleNodes( const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + const TIDSortedElemSet& theAffectedElems ) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - if ( theListOfNodes.size() == 0 ) + if ( theElems.size() == 0 ) return false; SMESHDS_Mesh* aMeshDS = GetMeshDS(); if ( !aMeshDS ) return false; - // iterate through nodes and duplicate them - + bool res = false; std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode; + // duplicate elements and nodes + res = doubleNodes( aMeshDS, theElems, theNodesNot, anOldNodeToNewNode, true ); + // replce nodes by duplications + res = doubleNodes( aMeshDS, theAffectedElems, theNodesNot, anOldNodeToNewNode, false ); + return res; +} - std::list< int >::const_iterator aNodeIter; - for ( aNodeIter = theListOfNodes.begin(); aNodeIter != theListOfNodes.end(); ++aNodeIter ) - { - int aCurr = *aNodeIter; - SMDS_MeshNode* aNode = (SMDS_MeshNode*)aMeshDS->FindNode( aCurr ); - if ( !aNode ) - continue; - - // duplicate node - - const SMDS_MeshNode* aNewNode = aMeshDS->AddNode( aNode->X(), aNode->Y(), aNode->Z() ); - if ( aNewNode ) - { - anOldNodeToNewNode[ aNode ] = aNewNode; - myLastCreatedNodes.Append( aNewNode ); - } - } - - // Create map of new nodes for modified elements - - std::map< SMDS_MeshElement*, vector > anElemToNodes; - - std::list< int >::const_iterator anElemIter; - for ( anElemIter = theListOfModifiedElems.begin(); - anElemIter != theListOfModifiedElems.end(); ++anElemIter ) +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theMeshDS - mesh instance + \param theElems - the elements replicated or modified (nodes should be changed) + \param theNodesNot - nodes to NOT replicate + \param theNodeNodeMap - relation of old node to new created node + \param theIsDoubleElem - flag os to replicate element or modify + \return TRUE if operation has been completed successfully, FALSE otherwise +*/ +bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS, + const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + std::map< const SMDS_MeshNode*, + const SMDS_MeshNode* >& theNodeNodeMap, + const bool theIsDoubleElem ) +{ + // iterate on through element and duplicate them (by nodes duplication) + bool res = false; + TIDSortedElemSet::iterator elemItr = theElems.begin(); + for ( ; elemItr != theElems.end(); ++elemItr ) { - int aCurr = *anElemIter; - SMDS_MeshElement* anElem = (SMDS_MeshElement*)aMeshDS->FindElement( aCurr ); - if ( !anElem ) + const SMDS_MeshElement* anElem = *elemItr; + if (!anElem) continue; - vector aNodeArr( anElem->NbNodes() ); - + bool isDuplicate = false; + // duplicate nodes to duplicate element + std::vector newNodes( anElem->NbNodes() ); SMDS_ElemIteratorPtr anIter = anElem->nodesIterator(); int ind = 0; while ( anIter->more() ) { + SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next(); - if ( aCurr && anOldNodeToNewNode.find( aCurrNode ) != anOldNodeToNewNode.end() ) + SMDS_MeshNode* aNewNode = aCurrNode; + if ( theNodeNodeMap.find( aCurrNode ) != theNodeNodeMap.end() ) + aNewNode = (SMDS_MeshNode*)theNodeNodeMap[ aCurrNode ]; + else if ( theIsDoubleElem && theNodesNot.find( aCurrNode ) == theNodesNot.end() ) { - const SMDS_MeshNode* aNewNode = anOldNodeToNewNode[ aCurrNode ]; - aNodeArr[ ind++ ] = aNewNode; + // duplicate node + aNewNode = theMeshDS->AddNode( aCurrNode->X(), aCurrNode->Y(), aCurrNode->Z() ); + theNodeNodeMap[ aCurrNode ] = aNewNode; + myLastCreatedNodes.Append( aNewNode ); } - else - aNodeArr[ ind++ ] = aCurrNode; + isDuplicate |= (aCurrNode == aNewNode); + newNodes[ ind++ ] = aNewNode; } - anElemToNodes[ anElem ] = aNodeArr; + if ( !isDuplicate ) + continue; + + if ( theIsDoubleElem ) + myLastCreatedElems.Append( AddElement(newNodes, anElem->GetType(), anElem->IsPoly()) ); + else + theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() ); + + res = true; } + return res; +} - // Change nodes of elements +/*! + \brief Check if element located inside shape + \return TRUE if IN or ON shape, FALSE otherwise +*/ - std::map< SMDS_MeshElement*, vector >::iterator - anElemToNodesIter = anElemToNodes.begin(); - for ( ; anElemToNodesIter != anElemToNodes.end(); ++anElemToNodesIter ) +static bool isInside(const SMDS_MeshElement* theElem, + BRepClass3d_SolidClassifier& theBsc3d, + const double theTol) +{ + gp_XYZ centerXYZ (0, 0, 0); + SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator(); + while (aNodeItr->more()) { - const SMDS_MeshElement* anElem = anElemToNodesIter->first; - vector aNodeArr = anElemToNodesIter->second; - if ( anElem ) - aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() ); + SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next(); + centerXYZ += gp_XYZ(aNode->X(), aNode->Y(), aNode->Z()); } + gp_Pnt aPnt(centerXYZ); + theBsc3d.Perform(aPnt, theTol); + TopAbs_State aState = theBsc3d.State(); + return (aState == TopAbs_IN || aState == TopAbs_ON ); +} - return true; +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + \param theElems - group of of elements (edges or faces) to be replicated + \param theNodesNot - group of nodes not to replicated + \param theShape - shape to detect affected elements (element which geometric center + located on or inside shape). + The replicated nodes should be associated to affected elements. + \return TRUE if operation has been completed successfully, FALSE otherwise +*/ + +bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + const TopoDS_Shape& theShape ) +{ + SMESHDS_Mesh* aMesh = GetMeshDS(); + if (!aMesh) + return false; + if ( theShape.IsNull() ) + return false; + + const double aTol = Precision::Confusion(); + BRepClass3d_SolidClassifier bsc3d(theShape); + bsc3d.PerformInfinitePoint(aTol); + + // iterates on indicated elements and get elements by back references from their nodes + TIDSortedElemSet anAffected; + TIDSortedElemSet::iterator elemItr = theElems.begin(); + for ( ; elemItr != theElems.end(); ++elemItr ) + { + SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr; + if (!anElem) + continue; + + SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator(); + while ( nodeItr->more() ) + { + const SMDS_MeshNode* aNode = static_cast(nodeItr->next()); + if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() ) + continue; + SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator(); + while ( backElemItr->more() ) + { + SMDS_MeshElement* curElem = (SMDS_MeshElement*)backElemItr->next(); + if ( curElem && theElems.find(curElem) == theElems.end() && + isInside( curElem, bsc3d, aTol ) ) + anAffected.insert( curElem ); + } + } + } + return DoubleNodes( theElems, theNodesNot, anAffected ); } diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index 82559eadf..a0dec46dc 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -41,6 +41,7 @@ #include #include +#include class SMDS_MeshFace; class SMDS_MeshNode; @@ -576,8 +577,13 @@ public: const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; } - bool DoubleNodes( const std::list< int >& theListOfNodes, - const std::list< int >& theListOfModifiedElems ); + bool DoubleNodes( const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + const TIDSortedElemSet& theAffectedElems ); + + bool DoubleNodesInRegion( const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + const TopoDS_Shape& theShape ); private: @@ -661,6 +667,13 @@ private: void LinearAngleVariation(const int NbSteps, list& theAngles); + bool doubleNodes( SMESHDS_Mesh* theMeshDS, + const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + std::map< const SMDS_MeshNode*, + const SMDS_MeshNode* >& theNodeNodeMap, + const bool theIsDoubleElem ); + private: SMESH_Mesh * myMesh; diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 428aacbc9..f9a7ee08f 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -917,7 +917,9 @@ namespace { for (int i=0; iFindElement(ind); + const SMDS_MeshElement * elem = + (aType == SMDSAbs_Node ? aMesh->FindNode(ind) + : aMesh->FindElement(ind)); if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType )) aMap.insert( elem ); } @@ -4137,31 +4139,32 @@ void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPytho //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements - \param theNodes - identifiers of nodes to be doubled - \param theModifiedElems - identifiers of elements to be updated by the new (doubled) - nodes. If list of element identifiers is empty then nodes are doubled but - they not assigned to elements + \param theElems - the list of elements (edges or faces) to be replicated + The nodes for duplication could be found from these elements + \param theNodesNot - list of nodes to NOT replicate + \param theAffectedElems - the list of elements (cells and edges) to which the + replicated nodes should be associated to. \return TRUE if operation has been completed successfully, FALSE otherwise - \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups() + \sa DoubleNodeGroup(), DoubleNodeGroups() */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes, - const SMESH::long_array& theModifiedElems ) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theElems, + const SMESH::long_array& theNodesNot, + const SMESH::long_array& theAffectedElems ) + { initData(); ::SMESH_MeshEditor aMeshEditor( myMesh ); - list< int > aListOfNodes; - int i, n; - for ( i = 0, n = theNodes.length(); i < n; i++ ) - aListOfNodes.push_back( theNodes[ i ] ); - list< int > aListOfElems; - for ( i = 0, n = theModifiedElems.length(); i < n; i++ ) - aListOfElems.push_back( theModifiedElems[ i ] ); + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All); + arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node); + arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All); - bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems ); + bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected ); storeResult( aMeshEditor) ; @@ -4171,99 +4174,207 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements - This method provided for convenience works as DoubleNodes() described above. - \param theNodeId - identifier of node to be doubled. - \param theModifiedElems - identifiers of elements to be updated. + \param theElems - the list of elements (edges or faces) to be replicated + The nodes for duplication could be found from these elements + \param theNodesNot - list of nodes to NOT replicate + \param theShape - shape to detect affected elements (element which geometric center + located on or inside shape). + The replicated nodes should be associated to affected elements. \return TRUE if operation has been completed successfully, FALSE otherwise - \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups() + \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion() */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId, - const SMESH::long_array& theModifiedElems ) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesInRegion + ( const SMESH::long_array& theElems, + const SMESH::long_array& theNodesNot, + GEOM::GEOM_Object_ptr theShape ) + { - SMESH::long_array_var aNodes = new SMESH::long_array; - aNodes->length( 1 ); - aNodes[ 0 ] = theNodeId; - return DoubleNodes( aNodes, theModifiedElems ); + initData(); + + ::SMESH_MeshEditor aMeshEditor( myMesh ); + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes; + arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All); + arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node); + + TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape ); + bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape ); + + storeResult( aMeshEditor) ; + + return aResult; } //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements - This method provided for convenience works as DoubleNodes() described above. - \param theNodes - group of nodes to be doubled. - \param theModifiedElems - group of elements to be updated. + \param theElems - group of of elements (edges or faces) to be replicated + \param theNodesNot - group of nodes not to replicated + \param theAffectedElems - group of elements to which the replicated nodes + should be associated to. \return TRUE if operation has been completed successfully, FALSE otherwise - \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups() + \sa DoubleNodes(), DoubleNodeGroups() */ //================================================================================ +static void groupToSet(SMESH::SMESH_GroupBase_ptr theGrp, + SMESHDS_Mesh* theMeshDS, + TIDSortedElemSet& theElemSet, + const SMDSAbs_ElementType theType) + +{ + if ( !CORBA::is_nil( theGrp ) ) + arrayToSet( *theGrp->GetListOfID(), theMeshDS, theElemSet, theType); +} + CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( - SMESH::SMESH_GroupBase_ptr theNodes, - SMESH::SMESH_GroupBase_ptr theModifiedElems ) + SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems ) + { - if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE ) + if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE ) return false; + + initData(); - SMESH::long_array_var aNodes = theNodes->GetListOfID(); - SMESH::long_array_var aModifiedElems; - if ( !CORBA::is_nil( theModifiedElems ) ) - aModifiedElems = theModifiedElems->GetListOfID(); - else - { - aModifiedElems = new SMESH::long_array; - aModifiedElems->length( 0 ); - } + ::SMESH_MeshEditor aMeshEditor( myMesh ); - return DoubleNodes( aNodes, aModifiedElems ); + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + groupToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); + groupToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); + groupToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All ); + + bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected ); + + storeResult( aMeshEditor) ; + + return aResult; } //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements - This method provided for convenience works as DoubleNodes() described above. - \param theNodes - list of groups of nodes to be doubled - \param theModifiedElems - list of groups of elements to be updated. + \param theElems - group of of elements (edges or faces) to be replicated + \param theNodesNot - group of nodes not to replicated + \param theShape - shape to detect affected elements (element which geometric center + located on or inside shape). + The replicated nodes should be associated to affected elements. \return TRUE if operation has been completed successfully, FALSE otherwise - \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes() + \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion() */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups( - const SMESH::ListOfGroups& theNodes, - const SMESH::ListOfGroups& theModifiedElems ) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroupInRegion( + SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + GEOM::GEOM_Object_ptr theShape ) + { + if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE ) + return false; + initData(); ::SMESH_MeshEditor aMeshEditor( myMesh ); - std::list< int > aNodes; - int i, n, j, m; - for ( i = 0, n = theNodes.length(); i < n; i++ ) - { - SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ]; - if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE ) - { - SMESH::long_array_var aCurr = aGrp->GetListOfID(); - for ( j = 0, m = aCurr->length(); j < m; j++ ) - aNodes.push_back( aCurr[ j ] ); - } - } + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + groupToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); + groupToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); + + TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape ); + bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape ); - std::list< int > anElems; - for ( i = 0, n = theModifiedElems.length(); i < n; i++ ) + storeResult( aMeshEditor) ; + + return aResult; +} + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + This method provided for convenience works as DoubleNodes() described above. + \param theElems - list of groups of elements (edges or faces) to be replicated + \param theNodesNot - list of groups of nodes not to replicated + \param theAffectedElems - group of elements to which the replicated nodes + should be associated to. + \return TRUE if operation has been completed successfully, FALSE otherwise + \sa DoubleNodeGroup(), DoubleNodes() +*/ +//================================================================================ + +static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList, + SMESHDS_Mesh* theMeshDS, + TIDSortedElemSet& theElemSet, + const bool theIsNodeGrp) +{ + for ( int i = 0, n = theGrpList.length(); i < n; i++ ) { - SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ]; - if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE ) - { - SMESH::long_array_var aCurr = aGrp->GetListOfID(); - for ( j = 0, m = aCurr->length(); j < m; j++ ) - anElems.push_back( aCurr[ j ] ); - } + SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ]; + if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE + : aGrp->GetType() != SMESH::NODE ) ) + arrayToSet( *aGrp->GetListOfID(), theMeshDS, theElemSet, + theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All ); } +} + +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups( + const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + const SMESH::ListOfGroups& theAffectedElems ) +{ + initData(); + + ::SMESH_MeshEditor aMeshEditor( myMesh ); + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + listOfGroupToSet(theElems, aMeshDS, anElems, false ); + listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true ); + listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false ); + + bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected ); + + storeResult( aMeshEditor) ; + + return aResult; +} + +//================================================================================ +/*! + \brief Creates a hole in a mesh by doubling the nodes of some particular elements + This method provided for convenience works as DoubleNodes() described above. + \param theElems - list of groups of elements (edges or faces) to be replicated + \param theNodesNot - list of groups of nodes not to replicated + \param theShape - shape to detect affected elements (element which geometric center + located on or inside shape). + The replicated nodes should be associated to affected elements. + \return TRUE if operation has been completed successfully, FALSE otherwise + \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion() +*/ +//================================================================================ + +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroupsInRegion( + const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + GEOM::GEOM_Object_ptr theShape ) +{ + initData(); + + ::SMESH_MeshEditor aMeshEditor( myMesh ); + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes; + listOfGroupToSet(theElems, aMeshDS, anElems,false ); + listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true ); - bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems ); + TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape ); + bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape ); storeResult( aMeshEditor) ; diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index 9943e74cb..73df0b465 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -500,19 +500,94 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor */ int GetMeshId() const { return myMesh->GetId(); } - CORBA::Boolean DoubleNodes( const SMESH::long_array& theNodes, - const SMESH::long_array& theModifiedElems ); - CORBA::Boolean DoubleNode( CORBA::Long theNodeId, - const SMESH::long_array& theModifiedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - the list of elements (edges or faces) to be replicated + * The nodes for duplication could be found from these elements + * \param theNodesNot - list of nodes to NOT replicate + * \param theAffectedElems - the list of elements (cells and edges) to which the + * replicated nodes should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroup(), DoubleNodeGroups() + */ + CORBA::Boolean DoubleNodes( const SMESH::long_array& theElems, + const SMESH::long_array& theNodesNot, + const SMESH::long_array& theAffectedElems ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - the list of elements (edges or faces) to be replicated + * The nodes for duplication could be found from these elements + * \param theNodesNot - list of nodes to NOT replicate + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion() + */ + CORBA::Boolean DoubleNodesInRegion( const SMESH::long_array& theElems, + const SMESH::long_array& theNodesNot, + GEOM::GEOM_Object_ptr theShape ); - CORBA::Boolean DoubleNodeGroup( SMESH::SMESH_GroupBase_ptr theNodes, - SMESH::SMESH_GroupBase_ptr theModifiedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodes(), DoubleNodeGroups() + */ + CORBA::Boolean DoubleNodeGroup( SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems ); - CORBA::Boolean DoubleNodeGroups( const SMESH::ListOfGroups& theNodes, - const SMESH::ListOfGroups& theModifiedElems); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion() + */ + CORBA::Boolean DoubleNodeGroupInRegion( SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + GEOM::GEOM_Object_ptr theShape ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroup(), DoubleNodes() + */ + CORBA::Boolean DoubleNodeGroups( const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + const SMESH::ListOfGroups& theAffectedElems ); + + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * This method provided for convenience works as DoubleNodes() described above. + * \param theElems - list of groups of elements (edges or faces) to be replicated + * \param theNodesNot - list of groups of nodes not to replicated + * \param theShape - shape to detect affected elements (element which geometric center + * located on or inside shape). + * The replicated nodes should be associated to affected elements. + * \return TRUE if operation has been completed successfully, FALSE otherwise + * \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion() + */ + CORBA::Boolean DoubleNodeGroupsInRegion( const SMESH::ListOfGroups& theElems, + const SMESH::ListOfGroups& theNodesNot, + GEOM::GEOM_Object_ptr theShape ); -private: //!< private methods + private: //!< private methods SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); } diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index 9bf05b303..1649840cc 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -3319,41 +3319,71 @@ class Mesh: return self.editor.GetLastCreatedElems() ## Creates a hole in a mesh by doubling the nodes of some particular elements - # @param theNodes identifiers of nodes to be doubled - # @param theModifiedElems identifiers of elements to be updated by the new (doubled) - # nodes. If list of element identifiers is empty then nodes are doubled but - # they not assigned to elements + # @param theElems - the list of elements (edges or faces) to be replicated + # The nodes for duplication could be found from these elements + # @param theNodesNot - list of nodes to NOT replicate + # @param theAffectedElems - the list of elements (cells and edges) to which the + # replicated nodes should be associated to. # @return TRUE if operation has been completed successfully, FALSE otherwise # @ingroup l2_modif_edit - def DoubleNodes(self, theNodes, theModifiedElems): - return self.editor.DoubleNodes(theNodes, theModifiedElems) + def DoubleNodes(self, theElems, theNodesNot, theAffectedElems): + return self.editor.DoubleNodes(theElems, theNodesNot) ## Creates a hole in a mesh by doubling the nodes of some particular elements - # This method provided for convenience works as DoubleNodes() described above. - # @param theNodes identifiers of node to be doubled - # @param theModifiedElems identifiers of elements to be updated + # @param theElems - the list of elements (edges or faces) to be replicated + # The nodes for duplication could be found from these elements + # @param theNodesNot - list of nodes to NOT replicate + # @param theShape - shape to detect affected elements (element which geometric center + # located on or inside shape). + # The replicated nodes should be associated to affected elements. # @return TRUE if operation has been completed successfully, FALSE otherwise # @ingroup l2_modif_edit - def DoubleNode(self, theNodeId, theModifiedElems): - return self.editor.DoubleNode(theNodeId, theModifiedElems) + def DoubleNodesInRegion( self theElems, theNodesNot, theShape ): + return self.editor.DoubleNodesInRegion(theElems, theNodesNot) + + ## Creates a hole in a mesh by doubling the nodes of some particular elements + # This method provided for convenience works as DoubleNodes() described above. + # @param theElems - group of of elements (edges or faces) to be replicated + # @param theNodesNot - group of nodes not to replicated + # @param theAffectedElems - group of elements to which the replicated nodes + # should be associated to. + # @ingroup l2_modif_edit + def DoubleNodeGroup(self, theElems, theNodesNot, theAffectedElems): + return self.editor.DoubleNodeGroup(theElems, theNodesNot, theAffectedElems) ## Creates a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. - # @param theNodes group of nodes to be doubled - # @param theModifiedElems group of elements to be updated. - # @return TRUE if operation has been completed successfully, FALSE otherwise + # @param theElems - group of of elements (edges or faces) to be replicated + # @param theNodesNot - group of nodes not to replicated + # @param theShape - shape to detect affected elements (element which geometric center + # located on or inside shape). + # The replicated nodes should be associated to affected elements. # @ingroup l2_modif_edit - def DoubleNodeGroup(self, theNodes, theModifiedElems): - return self.editor.DoubleNodeGroup(theNodes, theModifiedElems) + def DoubleNodeGroupInRegion(self, theElems, theNodesNot, theShape): + return self.editor.DoubleNodeGroup(theElems, theNodesNot, theShape) ## Creates a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. - # @param theNodes list of groups of nodes to be doubled - # @param theModifiedElems list of groups of elements to be updated. + # @param theElems - list of groups of elements (edges or faces) to be replicated + # @param theNodesNot - list of groups of nodes not to replicated + # @param theAffectedElems - group of elements to which the replicated nodes + # should be associated to. + # @return TRUE if operation has been completed successfully, FALSE otherwise + # @ingroup l2_modif_edit + def DoubleNodeGroups(self, theElems, theNodesNot, theAffectedElems): + return self.editor.DoubleNodeGroups(theElems, theNodesNot, theAffectedElems) + + ## Creates a hole in a mesh by doubling the nodes of some particular elements + # This method provided for convenience works as DoubleNodes() described above. + # @param theElems - list of groups of elements (edges or faces) to be replicated + # @param theNodesNot - list of groups of nodes not to replicated + # @param theShape - shape to detect affected elements (element which geometric center + # located on or inside shape). + # The replicated nodes should be associated to affected elements. # @return TRUE if operation has been completed successfully, FALSE otherwise # @ingroup l2_modif_edit - def DoubleNodeGroups(self, theNodes, theModifiedElems): - return self.editor.DoubleNodeGroups(theNodes, theModifiedElems) + def DoubleNodeGroupsInRegion(self, theElems, theNodesNot, theShape): + return self.editor.DoubleNodeGroupsInRegion(theElems, theNodesNot, theShape) ## The mother class to define algorithm, it is not recommended to use it directly. # -- 2.39.2