Salome HOME
PR: doubleNodesOnGroupBoundaries in progress
authorprascle <prascle>
Wed, 9 Mar 2011 08:42:21 +0000 (08:42 +0000)
committerprascle <prascle>
Wed, 9 Mar 2011 08:42:21 +0000 (08:42 +0000)
src/OBJECT/SMESH_Object.cxx
src/SMDS/SMDS_Downward.cxx
src/SMDS/SMDS_UnstructuredGrid.cxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHDS/SMESHDS_Mesh.hxx

index ded63b7937367466310009048aa1a6f968a23a51..6e44e059defb5ea3af447f879556f1a9d0e3381a 100644 (file)
@@ -843,7 +843,7 @@ SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup,
 SMESH_GroupObj::~SMESH_GroupObj()
 {
   if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
-  myGroupServer->UnRegister();
+  myGroupServer->Destroy();
 }
 
 //=================================================================================
@@ -973,7 +973,7 @@ SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
 SMESH_subMeshObj::~SMESH_subMeshObj()
 {
   if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
-  mySubMeshServer->UnRegister();
+  mySubMeshServer->Destroy();
 }
 
 //=================================================================================
index ed6fc38988c1600ebe50fc0b785cb6fed0efc915..962321ed83d5a2912f7e60b6e9a9d5de85683d27 100644 (file)
@@ -27,6 +27,24 @@ vector<int> SMDS_Downward::_cellDimension;
  */
 int SMDS_Downward::getCellDimension(unsigned char cellType)
 {
+  if (_cellDimension.empty())
+    {
+      _cellDimension.resize(VTK_MAXTYPE + 1, 0);
+      _cellDimension[VTK_LINE] = 1;
+      _cellDimension[VTK_QUADRATIC_EDGE] = 1;
+      _cellDimension[VTK_TRIANGLE] = 2;
+      _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2;
+      _cellDimension[VTK_QUAD] = 2;
+      _cellDimension[VTK_QUADRATIC_QUAD] = 2;
+      _cellDimension[VTK_TETRA] = 3;
+      _cellDimension[VTK_QUADRATIC_TETRA] = 3;
+      _cellDimension[VTK_HEXAHEDRON] = 3;
+      _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3;
+      _cellDimension[VTK_WEDGE] = 3;
+      _cellDimension[VTK_QUADRATIC_WEDGE] = 3;
+      _cellDimension[VTK_PYRAMID] = 3;
+      _cellDimension[VTK_QUADRATIC_PYRAMID] = 3;
+    }
   return _cellDimension[cellType];
 }
 
index 8c394c8d7589e14174b8e10b296801d5a202a04d..65139c880e608f95881581e35746d1638ae9faea 100644 (file)
@@ -813,15 +813,15 @@ int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsi
 {
   int vtkType = this->GetCellType(vtkId);
   int cellDim = SMDS_Downward::getCellDimension(vtkType);
-  if (cellDim != 3)
-    return 0; // TODO voisins des faces ou edges
+  if (cellDim <2)
+    return 0; // TODO voisins des edges = edges connectees
   int cellId = this->_cellIdToDownId[vtkId];
 
   int nbCells = _downArray[vtkType]->getNumberOfDownCells(cellId);
   const int *downCells = _downArray[vtkType]->getDownCells(cellId);
   const unsigned char* downTyp = _downArray[vtkType]->getDownTypes(cellId);
 
-  // --- iteration on faces of the 3D cell.
+  // --- iteration on faces of the 3D cell (or edges on the 2D cell).
 
   int nb = 0;
   for (int i = 0; i < nbCells; i++)
@@ -832,7 +832,8 @@ int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsi
       const int *upCells = _downArray[cellType]->getUpCells(downId);
       const unsigned char* upTypes = _downArray[cellType]->getUpTypes(downId);
 
-      // --- max 2 upCells, one is this cell, the other is a neighbor
+      // ---for a volume, max 2 upCells, one is this cell, the other is a neighbor
+      //    for a face, number of neighbors (connected faces) not known
 
       for (int j = 0; j < nbUp; j++)
         {
@@ -884,11 +885,10 @@ void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map<int, int> loc
     }
 }
 
-/*! Create a volume (prism or hexahedron) by duplication of a face.
- * the nodes of the new face are already created.
+/*! reorder the nodes of a face
  * @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face.
- * @param localClonedNodeIds map old node id to new node id.
- * @return vtk id of the new volume.
+ * @param orderedNodes list of nodes to reorder (in out)
+ * @return size of the list
  */
 int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, std::vector<vtkIdType>& orderedNodes)
 {
index 475b6df5d64a187abb59e44328cf9a0f02f0b860..37d6e26d90c4ad3923809179ce00bd742a7051b8 100644 (file)
@@ -10626,11 +10626,16 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
   SMDS_UnstructuredGrid *grid = meshDS->getGrid();
 
   // --- build the list of faces shared by 2 domains (group of elements), with their domain and volume indexes
+  //     build the list of cells with only a node or an edge on the border, with their domain and volume indexes
   //     build the list of nodes shared by 2 or more domains, with their domain indexes
 
-  std::map<DownIdType, std::map<int,int>, DownIdCompare> faceDomains; // 2x(id domain --> id volume)
-  std::map<int, std::map<int,int> > nodeDomains; //oldId ->  (domainId -> newId)
+  std::map<DownIdType, std::map<int,int>, DownIdCompare> faceDomains; // face --> (id domain --> id volume)
+  std::map<int,int>celldom; // cell vtkId --> domain
+  std::map<DownIdType, std::map<int,int>, DownIdCompare> cellDomains;  // oldNode --> (id domain --> id cell)
+  std::map<int, std::map<int,int> > nodeDomains; // oldId -->  (domainId --> newId)
   faceDomains.clear();
+  celldom.clear();
+  cellDomains.clear();
   nodeDomains.clear();
   std::map<int,int> emptyMap;
   emptyMap.clear();
@@ -10667,6 +10672,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
                   if (!faceDomains[face].count(idom))
                     {
                       faceDomains[face][idom] = vtkId; // volume associated to face in this domain
+                      celldom[vtkId] = idom;
                     }
                 }
             }
@@ -10674,36 +10680,91 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
     }
 
   MESSAGE("Number of shared faces " << faceDomains.size());
+  std::map<DownIdType, std::map<int, int>, DownIdCompare>::iterator itface;
 
-  // --- for each shared face, get the nodes
+  // --- explore the shared faces domain by domain,
+  //     explore the nodes of the face and see if they belong to a cell in the domain,
+  //     which has only a node or an edge on the border (not a shared face)
+
+  for (int idomain = 0; idomain < theElems.size(); idomain++)
+    {
+      const TIDSortedElemSet& domain = theElems[idomain];
+      itface = faceDomains.begin();
+      for (; itface != faceDomains.end(); ++itface)
+        {
+          std::map<int, int> domvol = itface->second;
+          if (!domvol.count(idomain))
+            continue;
+          DownIdType face = itface->first;
+          //MESSAGE(" --- face " << face.cellId);
+          std::set<int> oldNodes;
+          oldNodes.clear();
+          grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+          std::set<int>::iterator itn = oldNodes.begin();
+          for (; itn != oldNodes.end(); ++itn)
+            {
+              int oldId = *itn;
+              //MESSAGE("     node " << oldId);
+              std::set<int> cells;
+              cells.clear();
+              vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
+              for (int i=0; i<l.ncells; i++)
+                {
+                  int vtkId = l.cells[i];
+                  const SMDS_MeshElement* anElem = GetMeshDS()->FindElement(GetMeshDS()->fromVtkToSmds(vtkId));
+                  if (!domain.count(anElem))
+                    continue;
+                  int vtkType = grid->GetCellType(vtkId);
+                  int downId = grid->CellIdToDownId(vtkId);
+                  DownIdType aCell(downId, vtkType);
+                  if (celldom.count(vtkId))
+                    continue;
+                  cellDomains[aCell][idomain] = vtkId;
+                  celldom[vtkId] = idomain;
+                }
+            }
+        }
+    }
+
+  // --- explore the shared faces domain by domain, to duplicate the nodes in a coherent way
+  //     for each shared face, get the nodes
   //     for each node, for each domain of the face, create a clone of the node
 
-  std::map<DownIdType, std::map<int,int>, DownIdCompare>::iterator itface = faceDomains.begin();
-  for( ; itface != faceDomains.end();++itface )
+  for (int idomain = 0; idomain < theElems.size(); idomain++)
     {
-      DownIdType face = itface->first;
-      std::map<int,int> domvol = itface->second;
-      std::set<int> oldNodes;
-      oldNodes.clear();
-      grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
-      std::set<int>::iterator itn = oldNodes.begin();
-      for (;itn != oldNodes.end(); ++itn)
+      itface = faceDomains.begin();
+      for (; itface != faceDomains.end(); ++itface)
         {
-          int oldId = *itn;
-          if (!nodeDomains.count(oldId))
-            nodeDomains[oldId] = emptyMap; // create an empty entry for node
-          std::map<int,int>::iterator itdom = domvol.begin();
-          for(; itdom != domvol.end(); ++itdom)
+          std::map<int, int> domvol = itface->second;
+          if (!domvol.count(idomain))
+            continue;
+          DownIdType face = itface->first;
+          //MESSAGE(" --- face " << face.cellId);
+          std::set<int> oldNodes;
+          oldNodes.clear();
+          grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+          std::set<int>::iterator itn = oldNodes.begin();
+          for (; itn != oldNodes.end(); ++itn)
             {
-              int idom = itdom->first;
-              if ( nodeDomains[oldId].empty() )
-                nodeDomains[oldId][idom] = oldId; // keep the old node in the first domain
-              else
+              int oldId = *itn;
+              //MESSAGE("     node " << oldId);
+              if (!nodeDomains.count(oldId))
+                nodeDomains[oldId] = emptyMap; // create an empty entry for node
+              if (nodeDomains[oldId].empty())
+                nodeDomains[oldId][idomain] = oldId; // keep the old node in the first domain
+              std::map<int, int>::iterator itdom = domvol.begin();
+              for (; itdom != domvol.end(); ++itdom)
                 {
-                  double *coords = grid->GetPoint(oldId);
-                  SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]);
-                  int newId = newNode->getVtkId();
-                  nodeDomains[oldId][idom] = newId; // cloned node for other domains
+                  int idom = itdom->first;
+                  //MESSAGE("         domain " << idom);
+                  if (!nodeDomains[oldId].count(idom))
+                    {
+                      double *coords = grid->GetPoint(oldId);
+                      SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]);
+                      int newId = newNode->getVtkId();
+                      nodeDomains[oldId][idom] = newId; // cloned node for other domains
+                      //MESSAGE("         newNode " << newId);
+                    }
                 }
             }
         }
@@ -10723,7 +10784,6 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
           std::set<int>::iterator itn;
           oldNodes.clear();
           grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
-          std::map<int,int> localClonedNodeIds;
 
           std::map<int,int> domvol = itface->second;
           std::map<int,int>::iterator itdom = domvol.begin();
@@ -10731,24 +10791,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
           int vtkVolId = itdom->second;
           itdom++;
           int dom2 = itdom->first;
-
-          localClonedNodeIds.clear();
-          for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn)
-            {
-              int oldId = *itn;
-              int refid = oldId;
-              if (nodeDomains[oldId].count(dom1))
-                refid = nodeDomains[oldId][dom1];
-              else
-                MESSAGE("--- problem domain node " << dom1 << " " << oldId);
-              int newid = oldId;
-              if (nodeDomains[oldId].count(dom2))
-                newid = nodeDomains[oldId][dom2];
-              else
-                MESSAGE("--- problem domain node " << dom2 << " " << oldId);
-              localClonedNodeIds[oldId] = newid;
-            }
-          meshDS->extrudeVolumeFromFace(vtkVolId, localClonedNodeIds);
+          meshDS->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains);
         }
     }
 
@@ -10756,6 +10799,8 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
   //     get node id's of the face
   //     replace old nodes by new nodes in volumes, and update inverse connectivity
 
+  MESSAGE("cellDomains " << cellDomains.size());
+  faceDomains.insert(cellDomains.begin(), cellDomains.end());
   itface = faceDomains.begin();
   for( ; itface != faceDomains.end();++itface )
     {
index 9727f5fc68709cb205aa6ac22824c797101db8b9..8d1d41b7861872fc7652cdd885a0af6483ef0fe4 100644 (file)
@@ -1977,23 +1977,38 @@ bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNo
 }
 
 /*! Create a volume (prism or hexahedron) by duplication of a face.
- * the nodes of the new face are already created.
- * @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face.
- * @param localClonedNodeIds map old node id to new node id. The old nodes define the face in the volume.
+ * Designed for use in creation of flat elements separating volume domains.
+ * A face separating two domains is shared by two volume cells.
+ * All the nodes are already created (for the two faces).
+ * Each original Node is associated to corresponding nodes in the domains.
+ * Some nodes may be duplicated for more than two domains, when domain separations intersect.
+ * In that case, even some of the nodes to use for the original face may be changed.
+ * @param vtkVolId: vtk id of a volume containing the face, to get an orientation for the face.
+ * @param domain1: domain of the original face
+ * @param domain2: domain of the duplicated face
+ * @param originalNodes: the vtk node ids of the original face
+ * @param nodeDomains: map(original id --> map(domain --> duplicated node id))
  * @return ok if success.
  */
-bool SMESHDS_Mesh::extrudeVolumeFromFace(int vtkVolId, std::map<int,int>& localClonedNodeIds)
+bool SMESHDS_Mesh::extrudeVolumeFromFace(int vtkVolId,
+                                         int domain1,
+                                         int domain2,
+                                         std::set<int>& originalNodes,
+                                         std::map<int,std::map<int,int> >& nodeDomains)
 {
   //MESSAGE("extrudeVolumeFromFace " << vtkVolId);
-  vector<vtkIdType> orderedNodes;
-  orderedNodes.clear();
-  map<int, int>::const_iterator it = localClonedNodeIds.begin();
-  for (; it != localClonedNodeIds.end(); ++it)
-    orderedNodes.push_back(it->first);
+  vector<vtkIdType> orderedOriginals;
+  orderedOriginals.clear();
+  set<int>::const_iterator it = originalNodes.begin();
+  for (; it != originalNodes.end(); ++it)
+    orderedOriginals.push_back(*it);
 
-  int nbNodes = myGrid->getOrderedNodesOfFace(vtkVolId, orderedNodes);
+  int nbNodes = myGrid->getOrderedNodesOfFace(vtkVolId, orderedOriginals);
+  vector<vtkIdType> orderedNodes;
+  for (int i=0; i<nbNodes; i++)
+    orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]);
   for (int i=0; i<nbNodes; i++)
-    orderedNodes.push_back(localClonedNodeIds[orderedNodes[i]]);
+    orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
   SMDS_MeshVolume *vol = this->AddVolumeFromVtkIds(orderedNodes);
 
   // TODO update subshape list of elements and nodes
index af0ba92ae35b647e6605b4779cd1941744486ad3..6d1e63fb0a0c692d9d332c26b85e6c6aac7b590c 100644 (file)
@@ -401,7 +401,11 @@ public:
                              std::vector<const SMDS_MeshNode*> nodes,
                              std::vector<int>                  quantities);
   bool ModifyCellNodes(int smdsVolId, std::map<int,int> localClonedNodeIds);
-  bool extrudeVolumeFromFace(int vtkVolId, std::map<int,int>& localClonedNodeIds);
+  bool extrudeVolumeFromFace(int vtkVolId,
+                             int domain1,
+                             int domain2,
+                             std::set<int>& originalNodes,
+                             std::map<int,std::map<int,int> >& nodeDomains);
   void Renumber (const bool isNodes, const int startID=1, const int deltaID=1);
 
   void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S);