mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-14 02:30:33 +05:00
PR: doubleNodesOnGroupBoundaries in progress
This commit is contained in:
parent
044bc6d891
commit
293e2534c0
@ -843,7 +843,7 @@ SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup,
|
|||||||
SMESH_GroupObj::~SMESH_GroupObj()
|
SMESH_GroupObj::~SMESH_GroupObj()
|
||||||
{
|
{
|
||||||
if ( MYDEBUG ) MESSAGE("~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()
|
SMESH_subMeshObj::~SMESH_subMeshObj()
|
||||||
{
|
{
|
||||||
if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
|
if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
|
||||||
mySubMeshServer->UnRegister();
|
mySubMeshServer->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
//=================================================================================
|
//=================================================================================
|
||||||
|
@ -27,6 +27,24 @@ vector<int> SMDS_Downward::_cellDimension;
|
|||||||
*/
|
*/
|
||||||
int SMDS_Downward::getCellDimension(unsigned char cellType)
|
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];
|
return _cellDimension[cellType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,15 +813,15 @@ int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsi
|
|||||||
{
|
{
|
||||||
int vtkType = this->GetCellType(vtkId);
|
int vtkType = this->GetCellType(vtkId);
|
||||||
int cellDim = SMDS_Downward::getCellDimension(vtkType);
|
int cellDim = SMDS_Downward::getCellDimension(vtkType);
|
||||||
if (cellDim != 3)
|
if (cellDim <2)
|
||||||
return 0; // TODO voisins des faces ou edges
|
return 0; // TODO voisins des edges = edges connectees
|
||||||
int cellId = this->_cellIdToDownId[vtkId];
|
int cellId = this->_cellIdToDownId[vtkId];
|
||||||
|
|
||||||
int nbCells = _downArray[vtkType]->getNumberOfDownCells(cellId);
|
int nbCells = _downArray[vtkType]->getNumberOfDownCells(cellId);
|
||||||
const int *downCells = _downArray[vtkType]->getDownCells(cellId);
|
const int *downCells = _downArray[vtkType]->getDownCells(cellId);
|
||||||
const unsigned char* downTyp = _downArray[vtkType]->getDownTypes(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;
|
int nb = 0;
|
||||||
for (int i = 0; i < nbCells; i++)
|
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 int *upCells = _downArray[cellType]->getUpCells(downId);
|
||||||
const unsigned char* upTypes = _downArray[cellType]->getUpTypes(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++)
|
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.
|
/*! reorder the nodes 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 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.
|
* @param orderedNodes list of nodes to reorder (in out)
|
||||||
* @return vtk id of the new volume.
|
* @return size of the list
|
||||||
*/
|
*/
|
||||||
int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, std::vector<vtkIdType>& orderedNodes)
|
int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, std::vector<vtkIdType>& orderedNodes)
|
||||||
{
|
{
|
||||||
|
@ -10626,11 +10626,16 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
|||||||
SMDS_UnstructuredGrid *grid = meshDS->getGrid();
|
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 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
|
// 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<DownIdType, std::map<int,int>, DownIdCompare> faceDomains; // face --> (id domain --> id volume)
|
||||||
std::map<int, std::map<int,int> > nodeDomains; //oldId -> (domainId -> newId)
|
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();
|
faceDomains.clear();
|
||||||
|
celldom.clear();
|
||||||
|
cellDomains.clear();
|
||||||
nodeDomains.clear();
|
nodeDomains.clear();
|
||||||
std::map<int,int> emptyMap;
|
std::map<int,int> emptyMap;
|
||||||
emptyMap.clear();
|
emptyMap.clear();
|
||||||
@ -10667,6 +10672,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
|||||||
if (!faceDomains[face].count(idom))
|
if (!faceDomains[face].count(idom))
|
||||||
{
|
{
|
||||||
faceDomains[face][idom] = vtkId; // volume associated to face in this domain
|
faceDomains[face][idom] = vtkId; // volume associated to face in this domain
|
||||||
|
celldom[vtkId] = idom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10674,15 +10680,23 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
|||||||
}
|
}
|
||||||
|
|
||||||
MESSAGE("Number of shared faces " << faceDomains.size());
|
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,
|
||||||
// for each node, for each domain of the face, create a clone of the node
|
// 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)
|
||||||
|
|
||||||
std::map<DownIdType, std::map<int,int>, DownIdCompare>::iterator itface = faceDomains.begin();
|
for (int idomain = 0; idomain < theElems.size(); idomain++)
|
||||||
|
{
|
||||||
|
const TIDSortedElemSet& domain = theElems[idomain];
|
||||||
|
itface = faceDomains.begin();
|
||||||
for (; itface != faceDomains.end(); ++itface)
|
for (; itface != faceDomains.end(); ++itface)
|
||||||
{
|
{
|
||||||
DownIdType face = itface->first;
|
|
||||||
std::map<int, int> domvol = itface->second;
|
std::map<int, int> domvol = itface->second;
|
||||||
|
if (!domvol.count(idomain))
|
||||||
|
continue;
|
||||||
|
DownIdType face = itface->first;
|
||||||
|
//MESSAGE(" --- face " << face.cellId);
|
||||||
std::set<int> oldNodes;
|
std::set<int> oldNodes;
|
||||||
oldNodes.clear();
|
oldNodes.clear();
|
||||||
grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
|
grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
|
||||||
@ -10690,20 +10704,67 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
|||||||
for (; itn != oldNodes.end(); ++itn)
|
for (; itn != oldNodes.end(); ++itn)
|
||||||
{
|
{
|
||||||
int oldId = *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
|
||||||
|
|
||||||
|
for (int idomain = 0; idomain < theElems.size(); 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);
|
||||||
if (!nodeDomains.count(oldId))
|
if (!nodeDomains.count(oldId))
|
||||||
nodeDomains[oldId] = emptyMap; // create an empty entry for node
|
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();
|
std::map<int, int>::iterator itdom = domvol.begin();
|
||||||
for (; itdom != domvol.end(); ++itdom)
|
for (; itdom != domvol.end(); ++itdom)
|
||||||
{
|
{
|
||||||
int idom = itdom->first;
|
int idom = itdom->first;
|
||||||
if ( nodeDomains[oldId].empty() )
|
//MESSAGE(" domain " << idom);
|
||||||
nodeDomains[oldId][idom] = oldId; // keep the old node in the first domain
|
if (!nodeDomains[oldId].count(idom))
|
||||||
else
|
|
||||||
{
|
{
|
||||||
double *coords = grid->GetPoint(oldId);
|
double *coords = grid->GetPoint(oldId);
|
||||||
SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]);
|
SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]);
|
||||||
int newId = newNode->getVtkId();
|
int newId = newNode->getVtkId();
|
||||||
nodeDomains[oldId][idom] = newId; // cloned node for other domains
|
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;
|
std::set<int>::iterator itn;
|
||||||
oldNodes.clear();
|
oldNodes.clear();
|
||||||
grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
|
grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
|
||||||
std::map<int,int> localClonedNodeIds;
|
|
||||||
|
|
||||||
std::map<int,int> domvol = itface->second;
|
std::map<int,int> domvol = itface->second;
|
||||||
std::map<int,int>::iterator itdom = domvol.begin();
|
std::map<int,int>::iterator itdom = domvol.begin();
|
||||||
@ -10731,24 +10791,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
|||||||
int vtkVolId = itdom->second;
|
int vtkVolId = itdom->second;
|
||||||
itdom++;
|
itdom++;
|
||||||
int dom2 = itdom->first;
|
int dom2 = itdom->first;
|
||||||
|
meshDS->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10756,6 +10799,8 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
|
|||||||
// get node id's of the face
|
// get node id's of the face
|
||||||
// replace old nodes by new nodes in volumes, and update inverse connectivity
|
// 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();
|
itface = faceDomains.begin();
|
||||||
for( ; itface != faceDomains.end();++itface )
|
for( ; itface != faceDomains.end();++itface )
|
||||||
{
|
{
|
||||||
|
@ -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.
|
/*! Create a volume (prism or hexahedron) by duplication of a face.
|
||||||
* the nodes of the new face are already created.
|
* Designed for use in creation of flat elements separating volume domains.
|
||||||
* @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face.
|
* A face separating two domains is shared by two volume cells.
|
||||||
* @param localClonedNodeIds map old node id to new node id. The old nodes define the face in the volume.
|
* 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.
|
* @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);
|
//MESSAGE("extrudeVolumeFromFace " << vtkVolId);
|
||||||
vector<vtkIdType> orderedNodes;
|
vector<vtkIdType> orderedOriginals;
|
||||||
orderedNodes.clear();
|
orderedOriginals.clear();
|
||||||
map<int, int>::const_iterator it = localClonedNodeIds.begin();
|
set<int>::const_iterator it = originalNodes.begin();
|
||||||
for (; it != localClonedNodeIds.end(); ++it)
|
for (; it != originalNodes.end(); ++it)
|
||||||
orderedNodes.push_back(it->first);
|
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++)
|
for (int i=0; i<nbNodes; i++)
|
||||||
orderedNodes.push_back(localClonedNodeIds[orderedNodes[i]]);
|
orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]);
|
||||||
|
for (int i=0; i<nbNodes; i++)
|
||||||
|
orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
|
||||||
SMDS_MeshVolume *vol = this->AddVolumeFromVtkIds(orderedNodes);
|
SMDS_MeshVolume *vol = this->AddVolumeFromVtkIds(orderedNodes);
|
||||||
|
|
||||||
// TODO update subshape list of elements and nodes
|
// TODO update subshape list of elements and nodes
|
||||||
|
@ -401,7 +401,11 @@ public:
|
|||||||
std::vector<const SMDS_MeshNode*> nodes,
|
std::vector<const SMDS_MeshNode*> nodes,
|
||||||
std::vector<int> quantities);
|
std::vector<int> quantities);
|
||||||
bool ModifyCellNodes(int smdsVolId, std::map<int,int> localClonedNodeIds);
|
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 Renumber (const bool isNodes, const int startID=1, const int deltaID=1);
|
||||||
|
|
||||||
void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S);
|
void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S);
|
||||||
|
Loading…
Reference in New Issue
Block a user