Salome HOME
IMP20439 Create hole by element and nodes duplication
authorptv <ptv@opencascade.com>
Tue, 11 Aug 2009 12:01:49 +0000 (12:01 +0000)
committerptv <ptv@opencascade.com>
Tue, 11 Aug 2009 12:01:49 +0000 (12:01 +0000)
idl/SMESH_MeshEditor.idl
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx
src/SMESH_SWIG/smeshDC.py

index b1b36c257f1dd6384a435c088295d353263f57b6..198275ed8d8418d5b1c8eaebdcff39b4b580931d 100644 (file)
@@ -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 );
 
   };
 };
index cdf05341428618cd7260352e47280288f2e4d1e3..09bc9e4cb09faec258cfcbddba3373c2de1a74df 100644 (file)
@@ -47,6 +47,7 @@
 #include "utilities.h"
 
 #include <BRep_Tool.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
 #include <ElCLib.hxx>
 #include <Extrema_GenExtPS.hxx>
 #include <Extrema_POnSurf.hxx>
@@ -54,7 +55,9 @@
 #include <GeomAdaptor_Surface.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Surface.hxx>
+#include <Precision.hxx>
 #include <TColStd_ListOfInteger.hxx>
+#include <TopAbs_State.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
@@ -8188,89 +8191,166 @@ SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& 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<const SMDS_MeshNode*> > 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<const SMDS_MeshNode*> aNodeArr( anElem->NbNodes() );
-
+    bool isDuplicate = false;
+    // duplicate nodes to duplicate element
+    std::vector<const SMDS_MeshNode*> 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<const SMDS_MeshNode*> >::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<const SMDS_MeshNode*> 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<const SMDS_MeshNode*>(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 );
 }
index 82559eadfc03aa257e78ad38ae80c250fe9af09c..a0dec46dc3d39e2c8f08e42a312c008a5dba7a7b 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <list>
 #include <map>
+#include <set>
 
 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<double>& 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;
index 428aacbc94226da6a95b418ae3270d0fb4d239d8..f9a7ee08ff93623d7e9300a2a2fc69e811c0617a 100644 (file)
@@ -917,7 +917,9 @@ namespace
   { 
     for (int i=0; i<IDs.length(); i++) {
       CORBA::Long ind = IDs[i];
-      const SMDS_MeshElement * elem = aMesh->FindElement(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) ;
 
index 9943e74cb4ae300f6351543c75217838e4c2f2fb..73df0b465a49f20ae4eb6bd4673c69dc5f9e86d0 100644 (file)
@@ -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(); }
 
index 9bf05b3038c4fe49e64d701cdd29d892a86a17b5..1649840ccf64f6f17c23d6986b45f9c3cd412a00 100644 (file)
@@ -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.
 #