mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-12-25 17:00:34 +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()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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(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);
|
||||
|
||||
// TODO update subshape list of elements and nodes
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user