From: prascle Date: Wed, 9 Mar 2011 08:42:21 +0000 (+0000) Subject: PR: doubleNodesOnGroupBoundaries in progress X-Git-Tag: StartingPortingMED3~32 X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=commitdiff_plain;h=293e2534c037c652f037bd800f5e83d2f94a38a0 PR: doubleNodesOnGroupBoundaries in progress --- diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx index ded63b793..6e44e059d 100644 --- a/src/OBJECT/SMESH_Object.cxx +++ b/src/OBJECT/SMESH_Object.cxx @@ -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(); } //================================================================================= diff --git a/src/SMDS/SMDS_Downward.cxx b/src/SMDS/SMDS_Downward.cxx index ed6fc3898..962321ed8 100644 --- a/src/SMDS/SMDS_Downward.cxx +++ b/src/SMDS/SMDS_Downward.cxx @@ -27,6 +27,24 @@ vector 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]; } diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx index 8c394c8d7..65139c880 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.cxx +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -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 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& orderedNodes) { diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 475b6df5d..37d6e26d9 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -10626,11 +10626,16 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorgetGrid(); // --- 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, DownIdCompare> faceDomains; // 2x(id domain --> id volume) - std::map > nodeDomains; //oldId -> (domainId -> newId) + std::map, DownIdCompare> faceDomains; // face --> (id domain --> id volume) + std::mapcelldom; // cell vtkId --> domain + std::map, DownIdCompare> cellDomains; // oldNode --> (id domain --> id cell) + std::map > nodeDomains; // oldId --> (domainId --> newId) faceDomains.clear(); + celldom.clear(); + cellDomains.clear(); nodeDomains.clear(); std::map emptyMap; emptyMap.clear(); @@ -10667,6 +10672,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector, 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 domvol = itface->second; + if (!domvol.count(idomain)) + continue; + DownIdType face = itface->first; + //MESSAGE(" --- face " << face.cellId); + std::set oldNodes; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + std::set::iterator itn = oldNodes.begin(); + for (; itn != oldNodes.end(); ++itn) + { + int oldId = *itn; + //MESSAGE(" node " << oldId); + std::set cells; + cells.clear(); + vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId); + for (int i=0; iFindElement(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, DownIdCompare>::iterator itface = faceDomains.begin(); - for( ; itface != faceDomains.end();++itface ) + for (int idomain = 0; idomain < theElems.size(); idomain++) { - DownIdType face = itface->first; - std::map domvol = itface->second; - std::set oldNodes; - oldNodes.clear(); - grid->GetNodeIds(oldNodes, face.cellId, face.cellType); - std::set::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::iterator itdom = domvol.begin(); - for(; itdom != domvol.end(); ++itdom) + std::map domvol = itface->second; + if (!domvol.count(idomain)) + continue; + DownIdType face = itface->first; + //MESSAGE(" --- face " << face.cellId); + std::set oldNodes; + oldNodes.clear(); + grid->GetNodeIds(oldNodes, face.cellId, face.cellType); + std::set::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::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::iterator itn; oldNodes.clear(); grid->GetNodeIds(oldNodes, face.cellId, face.cellType); - std::map localClonedNodeIds; std::map domvol = itface->second; std::map::iterator itdom = domvol.begin(); @@ -10731,24 +10791,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorsecond; 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 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& localClonedNodeIds) +bool SMESHDS_Mesh::extrudeVolumeFromFace(int vtkVolId, + int domain1, + int domain2, + std::set& originalNodes, + std::map >& nodeDomains) { //MESSAGE("extrudeVolumeFromFace " << vtkVolId); - vector orderedNodes; - orderedNodes.clear(); - map::const_iterator it = localClonedNodeIds.begin(); - for (; it != localClonedNodeIds.end(); ++it) - orderedNodes.push_back(it->first); + vector orderedOriginals; + orderedOriginals.clear(); + set::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 orderedNodes; + for (int i=0; iAddVolumeFromVtkIds(orderedNodes); // TODO update subshape list of elements and nodes diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index af0ba92ae..6d1e63fb0 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -401,7 +401,11 @@ public: std::vector nodes, std::vector quantities); bool ModifyCellNodes(int smdsVolId, std::map localClonedNodeIds); - bool extrudeVolumeFromFace(int vtkVolId, std::map& localClonedNodeIds); + bool extrudeVolumeFromFace(int vtkVolId, + int domain1, + int domain2, + std::set& originalNodes, + std::map >& nodeDomains); void Renumber (const bool isNodes, const int startID=1, const int deltaID=1); void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S);