mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-28 05:10:32 +05:00
23256: [CEA 1796] Merge nodes suppresses some elements
This commit is contained in:
parent
0dc08969ad
commit
1ea4e6ee79
@ -7215,76 +7215,52 @@ int SMESH_MeshEditor::SimplifyFace (const vector<const SMDS_MeshNode *>& faceNod
|
|||||||
vector<int>& quantities) const
|
vector<int>& quantities) const
|
||||||
{
|
{
|
||||||
int nbNodes = faceNodes.size();
|
int nbNodes = faceNodes.size();
|
||||||
|
while ( faceNodes[ 0 ] == faceNodes[ nbNodes-1 ] && nbNodes > 2 )
|
||||||
|
--nbNodes;
|
||||||
if ( nbNodes < 3 )
|
if ( nbNodes < 3 )
|
||||||
return 0;
|
return 0;
|
||||||
|
size_t prevNbQuant = quantities.size();
|
||||||
|
|
||||||
set<const SMDS_MeshNode*> nodeSet;
|
vector< const SMDS_MeshNode* > simpleNodes; simpleNodes.reserve( nbNodes );
|
||||||
|
map< const SMDS_MeshNode*, int > nodeIndices; // indices within simpleNodes
|
||||||
|
map< const SMDS_MeshNode*, int >::iterator nInd;
|
||||||
|
|
||||||
// get simple seq of nodes
|
nodeIndices.insert( make_pair( faceNodes[0], 0 ));
|
||||||
vector<const SMDS_MeshNode*> simpleNodes( nbNodes );
|
simpleNodes.push_back( faceNodes[0] );
|
||||||
int iSimple = 0;
|
for ( int iCur = 1; iCur < nbNodes; iCur++ )
|
||||||
|
{
|
||||||
simpleNodes[iSimple++] = faceNodes[0];
|
if ( faceNodes[ iCur ] != simpleNodes.back() )
|
||||||
for (int iCur = 1; iCur < nbNodes; iCur++) {
|
{
|
||||||
if (faceNodes[iCur] != simpleNodes[iSimple - 1]) {
|
int index = simpleNodes.size();
|
||||||
simpleNodes[iSimple++] = faceNodes[iCur];
|
nInd = nodeIndices.insert( make_pair( faceNodes[ iCur ], index )).first;
|
||||||
nodeSet.insert( faceNodes[iCur] );
|
int prevIndex = nInd->second;
|
||||||
}
|
if ( prevIndex < index )
|
||||||
}
|
{
|
||||||
int nbUnique = nodeSet.size();
|
// a sub-loop found
|
||||||
int nbSimple = iSimple;
|
int loopLen = index - prevIndex;
|
||||||
if (simpleNodes[nbSimple - 1] == simpleNodes[0]) {
|
if ( loopLen > 2 )
|
||||||
nbSimple--;
|
{
|
||||||
iSimple--;
|
// store the sub-loop
|
||||||
}
|
|
||||||
|
|
||||||
if (nbUnique < 3)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// separate loops
|
|
||||||
int nbNew = 0;
|
|
||||||
bool foundLoop = (nbSimple > nbUnique);
|
|
||||||
while (foundLoop) {
|
|
||||||
foundLoop = false;
|
|
||||||
set<const SMDS_MeshNode*> loopSet;
|
|
||||||
for (iSimple = 0; iSimple < nbSimple && !foundLoop; iSimple++) {
|
|
||||||
const SMDS_MeshNode* n = simpleNodes[iSimple];
|
|
||||||
if (!loopSet.insert( n ).second) {
|
|
||||||
foundLoop = true;
|
|
||||||
|
|
||||||
// separate loop
|
|
||||||
int iC = 0, curLast = iSimple;
|
|
||||||
for (; iC < curLast; iC++) {
|
|
||||||
if (simpleNodes[iC] == n) break;
|
|
||||||
}
|
|
||||||
int loopLen = curLast - iC;
|
|
||||||
if (loopLen > 2) {
|
|
||||||
// create sub-element
|
|
||||||
nbNew++;
|
|
||||||
quantities.push_back( loopLen );
|
quantities.push_back( loopLen );
|
||||||
for (; iC < curLast; iC++) {
|
for ( int i = prevIndex; i < index; i++ )
|
||||||
poly_nodes.push_back(simpleNodes[iC]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// shift the rest nodes (place from the first loop position)
|
|
||||||
for (iC = curLast + 1; iC < nbSimple; iC++) {
|
|
||||||
simpleNodes[iC - loopLen] = simpleNodes[iC];
|
|
||||||
}
|
|
||||||
nbSimple -= loopLen;
|
|
||||||
iSimple -= loopLen;
|
|
||||||
}
|
|
||||||
} // for (iSimple = 0; iSimple < nbSimple; iSimple++)
|
|
||||||
} // while (foundLoop)
|
|
||||||
|
|
||||||
if (iSimple > 2) {
|
|
||||||
nbNew++;
|
|
||||||
quantities.push_back(iSimple);
|
|
||||||
for (int i = 0; i < iSimple; i++)
|
|
||||||
poly_nodes.push_back( simpleNodes[ i ]);
|
poly_nodes.push_back( simpleNodes[ i ]);
|
||||||
}
|
}
|
||||||
|
simpleNodes.resize( prevIndex+1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
simpleNodes.push_back( faceNodes[ iCur ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nbNew;
|
if ( simpleNodes.size() > 2 )
|
||||||
|
{
|
||||||
|
quantities.push_back( simpleNodes.size() );
|
||||||
|
poly_nodes.insert ( poly_nodes.end(), simpleNodes.begin(), simpleNodes.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return quantities.size() - prevNbQuant;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -7348,6 +7324,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
|||||||
const SMDS_MeshElement* elem = *eIt;
|
const SMDS_MeshElement* elem = *eIt;
|
||||||
const int nbNodes = elem->NbNodes();
|
const int nbNodes = elem->NbNodes();
|
||||||
const int aShapeId = FindShape( elem );
|
const int aShapeId = FindShape( elem );
|
||||||
|
SMDSAbs_EntityType entity = elem->GetEntityType();
|
||||||
|
|
||||||
nodeSet.clear();
|
nodeSet.clear();
|
||||||
curNodes.resize( nbNodes );
|
curNodes.resize( nbNodes );
|
||||||
@ -7373,7 +7350,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
|||||||
if ( nnIt_i != nodeNodeMap.end() ) { // n sticks
|
if ( nnIt_i != nodeNodeMap.end() ) { // n sticks
|
||||||
n = (*nnIt_i).second;
|
n = (*nnIt_i).second;
|
||||||
if (!nodesRecur.insert(n).second) {
|
if (!nodesRecur.insert(n).second) {
|
||||||
// error: recursive dependancy
|
// error: recursive dependency
|
||||||
stopRecur = true;
|
stopRecur = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7434,7 +7411,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
|||||||
}
|
}
|
||||||
elemType.SetPoly(( nbNewNodes / ( elemType.myIsQuad + 1 ) > 4 ));
|
elemType.SetPoly(( nbNewNodes / ( elemType.myIsQuad + 1 ) > 4 ));
|
||||||
|
|
||||||
SMDS_MeshElement* newElem = AddElement( face_nodes, elemType );
|
SMDS_MeshElement* newElem = AddElement( face_nodes, elemType.SetID(-1));
|
||||||
if ( aShapeId )
|
if ( aShapeId )
|
||||||
aMesh->SetMeshElementOnShape(newElem, aShapeId);
|
aMesh->SetMeshElementOnShape(newElem, aShapeId);
|
||||||
}
|
}
|
||||||
@ -7457,25 +7434,25 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
|||||||
|
|
||||||
vector<const SMDS_MeshNode *> poly_nodes;
|
vector<const SMDS_MeshNode *> poly_nodes;
|
||||||
vector<int> quantities;
|
vector<int> quantities;
|
||||||
|
vector<const SMDS_MeshNode *> faceNodes;
|
||||||
|
|
||||||
for (int iface = 1; iface <= nbFaces; iface++) {
|
for (int iface = 1; iface <= nbFaces; iface++)
|
||||||
|
{
|
||||||
int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
|
int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
|
||||||
vector<const SMDS_MeshNode *> faceNodes (nbFaceNodes);
|
faceNodes.resize( nbFaceNodes );
|
||||||
|
for (int inode = 1; inode <= nbFaceNodes; inode++)
|
||||||
for (int inode = 1; inode <= nbFaceNodes; inode++) {
|
{
|
||||||
const SMDS_MeshNode * faceNode = aPolyedre->GetFaceNode(iface, inode);
|
const SMDS_MeshNode * faceNode = aPolyedre->GetFaceNode(iface, inode);
|
||||||
TNodeNodeMap::iterator nnIt = nodeNodeMap.find(faceNode);
|
TNodeNodeMap::iterator nnIt = nodeNodeMap.find(faceNode);
|
||||||
if (nnIt != nodeNodeMap.end()) { // faceNode sticks
|
if ( nnIt != nodeNodeMap.end() ) // faceNode sticks
|
||||||
faceNode = (*nnIt).second;
|
faceNode = (*nnIt).second;
|
||||||
}
|
|
||||||
faceNodes[inode - 1] = faceNode;
|
faceNodes[inode - 1] = faceNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimplifyFace(faceNodes, poly_nodes, quantities);
|
SimplifyFace(faceNodes, poly_nodes, quantities);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( quantities.size() > 3 ) {
|
if ( quantities.size() > 3 ) {
|
||||||
// to be done: remove coincident faces
|
// TODO: remove coincident faces
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( quantities.size() > 3 )
|
if ( quantities.size() > 3 )
|
||||||
@ -7501,195 +7478,154 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
|||||||
|
|
||||||
// Regular elements
|
// Regular elements
|
||||||
// TODO not all the possible cases are solved. Find something more generic?
|
// TODO not all the possible cases are solved. Find something more generic?
|
||||||
switch ( nbNodes ) {
|
switch ( entity ) {
|
||||||
case 2: ///////////////////////////////////// EDGE
|
case SMDSEntity_Edge: //////// EDGE
|
||||||
isOk = false; break;
|
case SMDSEntity_Triangle: //// TRIANGLE
|
||||||
case 3: ///////////////////////////////////// TRIANGLE
|
case SMDSEntity_Quad_Triangle:
|
||||||
isOk = false; break;
|
case SMDSEntity_Tetra:
|
||||||
case 4:
|
case SMDSEntity_Quad_Tetra: // TETRAHEDRON
|
||||||
if ( elem->GetType() == SMDSAbs_Volume ) // TETRAHEDRON
|
{
|
||||||
isOk = false;
|
isOk = false;
|
||||||
else { //////////////////////////////////// QUADRANGLE
|
break;
|
||||||
|
}
|
||||||
|
case SMDSEntity_Quad_Edge:
|
||||||
|
{
|
||||||
|
isOk = false; // to linear EDGE ???????
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMDSEntity_Quadrangle: //////////////////////////////////// QUADRANGLE
|
||||||
|
{
|
||||||
if ( nbUniqueNodes < 3 )
|
if ( nbUniqueNodes < 3 )
|
||||||
isOk = false;
|
isOk = false;
|
||||||
else if ( nbRepl == 2 && iRepl[ 1 ] - iRepl[ 0 ] == 2 )
|
else if ( nbRepl == 1 && curNodes[ iRepl[0]] == curNodes[( iRepl[0]+2 )%4 ])
|
||||||
isOk = false; // opposite nodes stick
|
isOk = false; // opposite nodes stick
|
||||||
//MESSAGE("isOk " << isOk);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 6: ///////////////////////////////////// PENTAHEDRON
|
|
||||||
if ( nbUniqueNodes == 4 ) {
|
|
||||||
// ---------------------------------> tetrahedron
|
|
||||||
if (nbRepl == 3 &&
|
|
||||||
iRepl[ 0 ] > 2 && iRepl[ 1 ] > 2 && iRepl[ 2 ] > 2 ) {
|
|
||||||
// all top nodes stick: reverse a bottom
|
|
||||||
uniqueNodes[ 0 ] = curNodes [ 1 ];
|
|
||||||
uniqueNodes[ 1 ] = curNodes [ 0 ];
|
|
||||||
}
|
}
|
||||||
else if (nbRepl == 3 &&
|
case SMDSEntity_Quad_Quadrangle: // Quadratic QUADRANGLE
|
||||||
iRepl[ 0 ] < 3 && iRepl[ 1 ] < 3 && iRepl[ 2 ] < 3 ) {
|
{
|
||||||
// all bottom nodes stick: set a top before
|
|
||||||
uniqueNodes[ 3 ] = uniqueNodes [ 0 ];
|
|
||||||
uniqueNodes[ 0 ] = curNodes [ 3 ];
|
|
||||||
uniqueNodes[ 1 ] = curNodes [ 4 ];
|
|
||||||
uniqueNodes[ 2 ] = curNodes [ 5 ];
|
|
||||||
}
|
|
||||||
else if (nbRepl == 4 &&
|
|
||||||
iRepl[ 2 ] - iRepl [ 0 ] == 3 && iRepl[ 3 ] - iRepl [ 1 ] == 3 ) {
|
|
||||||
// a lateral face turns into a line: reverse a bottom
|
|
||||||
uniqueNodes[ 0 ] = curNodes [ 1 ];
|
|
||||||
uniqueNodes[ 1 ] = curNodes [ 0 ];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
isOk = false;
|
|
||||||
}
|
|
||||||
else if ( nbUniqueNodes == 5 ) {
|
|
||||||
// PENTAHEDRON --------------------> 2 tetrahedrons
|
|
||||||
if ( nbRepl == 2 && iRepl[ 1 ] - iRepl [ 0 ] == 3 ) {
|
|
||||||
// a bottom node sticks with a linked top one
|
|
||||||
// 1.
|
|
||||||
SMDS_MeshElement* newElem =
|
|
||||||
aMesh->AddVolume(curNodes[ 3 ],
|
|
||||||
curNodes[ 4 ],
|
|
||||||
curNodes[ 5 ],
|
|
||||||
curNodes[ iRepl[ 0 ] == 2 ? 1 : 2 ]);
|
|
||||||
myLastCreatedElems.Append(newElem);
|
|
||||||
if ( aShapeId )
|
|
||||||
aMesh->SetMeshElementOnShape( newElem, aShapeId );
|
|
||||||
// 2. : reverse a bottom
|
|
||||||
uniqueNodes[ 0 ] = curNodes [ 1 ];
|
|
||||||
uniqueNodes[ 1 ] = curNodes [ 0 ];
|
|
||||||
nbUniqueNodes = 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
isOk = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
isOk = false;
|
|
||||||
break;
|
|
||||||
case 8: {
|
|
||||||
if(elem->IsQuadratic()) { // Quadratic quadrangle
|
|
||||||
// 1 5 2
|
// 1 5 2
|
||||||
// +---+---+
|
// +---+---+
|
||||||
// | |
|
// | |
|
||||||
// | |
|
|
||||||
// 4+ +6
|
// 4+ +6
|
||||||
// | |
|
// | |
|
||||||
// | |
|
|
||||||
// +---+---+
|
// +---+---+
|
||||||
// 0 7 3
|
// 0 7 3
|
||||||
isOk = false;
|
if (( nbUniqueNodes == 6 && nbRepl == 2 ) &&
|
||||||
if(nbRepl==2) {
|
(( iRepl[0] == 1 && iRepl[1] == 4 && curNodes[1] == curNodes[0] ) ||
|
||||||
MESSAGE("nbRepl=2: " << iRepl[0] << " " << iRepl[1]);
|
( iRepl[0] == 2 && iRepl[1] == 5 && curNodes[2] == curNodes[1] ) ||
|
||||||
}
|
( iRepl[0] == 3 && iRepl[1] == 6 && curNodes[3] == curNodes[2] ) ||
|
||||||
if(nbRepl==3) {
|
( iRepl[0] == 3 && iRepl[1] == 7 && curNodes[3] == curNodes[0] )))
|
||||||
MESSAGE("nbRepl=3: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2]);
|
{
|
||||||
nbUniqueNodes = 6;
|
|
||||||
if( iRepl[0]==0 && iRepl[1]==1 && iRepl[2]==4 ) {
|
|
||||||
uniqueNodes[0] = curNodes[0];
|
|
||||||
uniqueNodes[1] = curNodes[2];
|
|
||||||
uniqueNodes[2] = curNodes[3];
|
|
||||||
uniqueNodes[3] = curNodes[5];
|
|
||||||
uniqueNodes[4] = curNodes[6];
|
|
||||||
uniqueNodes[5] = curNodes[7];
|
|
||||||
isOk = true;
|
isOk = true;
|
||||||
}
|
}
|
||||||
if( iRepl[0]==0 && iRepl[1]==3 && iRepl[2]==7 ) {
|
|
||||||
uniqueNodes[0] = curNodes[0];
|
|
||||||
uniqueNodes[1] = curNodes[1];
|
|
||||||
uniqueNodes[2] = curNodes[2];
|
|
||||||
uniqueNodes[3] = curNodes[4];
|
|
||||||
uniqueNodes[4] = curNodes[5];
|
|
||||||
uniqueNodes[5] = curNodes[6];
|
|
||||||
isOk = true;
|
|
||||||
}
|
|
||||||
if( iRepl[0]==0 && iRepl[1]==4 && iRepl[2]==7 ) {
|
|
||||||
uniqueNodes[0] = curNodes[1];
|
|
||||||
uniqueNodes[1] = curNodes[2];
|
|
||||||
uniqueNodes[2] = curNodes[3];
|
|
||||||
uniqueNodes[3] = curNodes[5];
|
|
||||||
uniqueNodes[4] = curNodes[6];
|
|
||||||
uniqueNodes[5] = curNodes[0];
|
|
||||||
isOk = true;
|
|
||||||
}
|
|
||||||
if( iRepl[0]==1 && iRepl[1]==2 && iRepl[2]==5 ) {
|
|
||||||
uniqueNodes[0] = curNodes[0];
|
|
||||||
uniqueNodes[1] = curNodes[1];
|
|
||||||
uniqueNodes[2] = curNodes[3];
|
|
||||||
uniqueNodes[3] = curNodes[4];
|
|
||||||
uniqueNodes[4] = curNodes[6];
|
|
||||||
uniqueNodes[5] = curNodes[7];
|
|
||||||
isOk = true;
|
|
||||||
}
|
|
||||||
if( iRepl[0]==1 && iRepl[1]==4 && iRepl[2]==5 ) {
|
|
||||||
uniqueNodes[0] = curNodes[0];
|
|
||||||
uniqueNodes[1] = curNodes[2];
|
|
||||||
uniqueNodes[2] = curNodes[3];
|
|
||||||
uniqueNodes[3] = curNodes[1];
|
|
||||||
uniqueNodes[4] = curNodes[6];
|
|
||||||
uniqueNodes[5] = curNodes[7];
|
|
||||||
isOk = true;
|
|
||||||
}
|
|
||||||
if( iRepl[0]==2 && iRepl[1]==3 && iRepl[2]==6 ) {
|
|
||||||
uniqueNodes[0] = curNodes[0];
|
|
||||||
uniqueNodes[1] = curNodes[1];
|
|
||||||
uniqueNodes[2] = curNodes[2];
|
|
||||||
uniqueNodes[3] = curNodes[4];
|
|
||||||
uniqueNodes[4] = curNodes[5];
|
|
||||||
uniqueNodes[5] = curNodes[7];
|
|
||||||
isOk = true;
|
|
||||||
}
|
|
||||||
if( iRepl[0]==2 && iRepl[1]==5 && iRepl[2]==6 ) {
|
|
||||||
uniqueNodes[0] = curNodes[0];
|
|
||||||
uniqueNodes[1] = curNodes[1];
|
|
||||||
uniqueNodes[2] = curNodes[3];
|
|
||||||
uniqueNodes[3] = curNodes[4];
|
|
||||||
uniqueNodes[4] = curNodes[2];
|
|
||||||
uniqueNodes[5] = curNodes[7];
|
|
||||||
isOk = true;
|
|
||||||
}
|
|
||||||
if( iRepl[0]==3 && iRepl[1]==6 && iRepl[2]==7 ) {
|
|
||||||
uniqueNodes[0] = curNodes[0];
|
|
||||||
uniqueNodes[1] = curNodes[1];
|
|
||||||
uniqueNodes[2] = curNodes[2];
|
|
||||||
uniqueNodes[3] = curNodes[4];
|
|
||||||
uniqueNodes[4] = curNodes[5];
|
|
||||||
uniqueNodes[5] = curNodes[3];
|
|
||||||
isOk = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(nbRepl==4) {
|
|
||||||
MESSAGE("nbRepl=4: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2] << " " << iRepl[3]);
|
|
||||||
}
|
|
||||||
if(nbRepl==5) {
|
|
||||||
MESSAGE("nbRepl=5: " << iRepl[0] << " " << iRepl[1] << " " << iRepl[2] << " " << iRepl[3] << " " << iRepl[4]);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SMDSEntity_BiQuad_Quadrangle: // Bi-Quadratic QUADRANGLE
|
||||||
|
{
|
||||||
|
// 1 5 2
|
||||||
|
// +---+---+
|
||||||
|
// | |
|
||||||
|
// 4+ 8+ +6
|
||||||
|
// | |
|
||||||
|
// +---+---+
|
||||||
|
// 0 7 3
|
||||||
|
if (( nbUniqueNodes == 7 && nbRepl == 2 && iRepl[1] != 8 ) &&
|
||||||
|
(( iRepl[0] == 1 && iRepl[1] == 4 && curNodes[1] == curNodes[0] ) ||
|
||||||
|
( iRepl[0] == 2 && iRepl[1] == 5 && curNodes[2] == curNodes[1] ) ||
|
||||||
|
( iRepl[0] == 3 && iRepl[1] == 6 && curNodes[3] == curNodes[2] ) ||
|
||||||
|
( iRepl[0] == 3 && iRepl[1] == 7 && curNodes[3] == curNodes[0] )))
|
||||||
|
{
|
||||||
|
isOk = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMDSEntity_Penta: ///////////////////////////////////// PENTAHEDRON
|
||||||
|
{
|
||||||
|
isOk = false;
|
||||||
|
if ( nbUniqueNodes == 4 ) {
|
||||||
|
// ---------------------------------> tetrahedron
|
||||||
|
if ( curNodes[3] == curNodes[4] &&
|
||||||
|
curNodes[3] == curNodes[5] ) {
|
||||||
|
// top nodes stick
|
||||||
|
isOk = true;
|
||||||
|
}
|
||||||
|
else if ( curNodes[0] == curNodes[1] &&
|
||||||
|
curNodes[0] == curNodes[2] ) {
|
||||||
|
// bottom nodes stick: set a top before
|
||||||
|
uniqueNodes[ 3 ] = uniqueNodes [ 0 ];
|
||||||
|
uniqueNodes[ 0 ] = curNodes [ 5 ];
|
||||||
|
uniqueNodes[ 1 ] = curNodes [ 4 ];
|
||||||
|
uniqueNodes[ 2 ] = curNodes [ 3 ];
|
||||||
|
isOk = true;
|
||||||
|
}
|
||||||
|
else if (( curNodes[0] == curNodes[3] ) +
|
||||||
|
( curNodes[1] == curNodes[4] ) +
|
||||||
|
( curNodes[2] == curNodes[5] ) == 2 ) {
|
||||||
|
// a lateral face turns into a line
|
||||||
|
isOk = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( nbUniqueNodes == 5 ) {
|
||||||
|
// PENTAHEDRON --------------------> pyramid
|
||||||
|
if ( curNodes[0] == curNodes[3] )
|
||||||
|
{
|
||||||
|
uniqueNodes[ 0 ] = curNodes[ 1 ];
|
||||||
|
uniqueNodes[ 1 ] = curNodes[ 4 ];
|
||||||
|
uniqueNodes[ 2 ] = curNodes[ 5 ];
|
||||||
|
uniqueNodes[ 3 ] = curNodes[ 2 ];
|
||||||
|
uniqueNodes[ 4 ] = curNodes[ 0 ];
|
||||||
|
isOk = true;
|
||||||
|
}
|
||||||
|
if ( curNodes[1] == curNodes[4] )
|
||||||
|
{
|
||||||
|
uniqueNodes[ 0 ] = curNodes[ 0 ];
|
||||||
|
uniqueNodes[ 1 ] = curNodes[ 2 ];
|
||||||
|
uniqueNodes[ 2 ] = curNodes[ 5 ];
|
||||||
|
uniqueNodes[ 3 ] = curNodes[ 3 ];
|
||||||
|
uniqueNodes[ 4 ] = curNodes[ 1 ];
|
||||||
|
isOk = true;
|
||||||
|
}
|
||||||
|
if ( curNodes[2] == curNodes[5] )
|
||||||
|
{
|
||||||
|
uniqueNodes[ 0 ] = curNodes[ 0 ];
|
||||||
|
uniqueNodes[ 1 ] = curNodes[ 3 ];
|
||||||
|
uniqueNodes[ 2 ] = curNodes[ 4 ];
|
||||||
|
uniqueNodes[ 3 ] = curNodes[ 1 ];
|
||||||
|
uniqueNodes[ 4 ] = curNodes[ 2 ];
|
||||||
|
isOk = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMDSEntity_Hexa:
|
||||||
|
{
|
||||||
//////////////////////////////////// HEXAHEDRON
|
//////////////////////////////////// HEXAHEDRON
|
||||||
isOk = false;
|
isOk = false;
|
||||||
SMDS_VolumeTool hexa (elem);
|
SMDS_VolumeTool hexa (elem);
|
||||||
hexa.SetExternalNormal();
|
hexa.SetExternalNormal();
|
||||||
if ( nbUniqueNodes == 4 && nbRepl == 4 ) {
|
if ( nbUniqueNodes == 4 && nbRepl == 4 ) {
|
||||||
//////////////////////// HEX ---> 1 tetrahedron
|
//////////////////////// HEX ---> tetrahedron
|
||||||
for ( int iFace = 0; iFace < 6; iFace++ ) {
|
for ( int iFace = 0; iFace < 6; iFace++ ) {
|
||||||
const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes
|
const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes
|
||||||
if (curNodes[ind[ 0 ]] == curNodes[ind[ 1 ]] &&
|
if (curNodes[ind[ 0 ]] == curNodes[ind[ 1 ]] &&
|
||||||
curNodes[ind[ 0 ]] == curNodes[ind[ 2 ]] &&
|
curNodes[ind[ 0 ]] == curNodes[ind[ 2 ]] &&
|
||||||
curNodes[ind[ 0 ]] == curNodes[ind[ 3 ]] ) {
|
curNodes[ind[ 0 ]] == curNodes[ind[ 3 ]] ) {
|
||||||
// one face turns into a point ...
|
// one face turns into a point ...
|
||||||
|
int pickInd = ind[ 0 ];
|
||||||
int iOppFace = hexa.GetOppFaceIndex( iFace );
|
int iOppFace = hexa.GetOppFaceIndex( iFace );
|
||||||
ind = hexa.GetFaceNodesIndices( iOppFace );
|
ind = hexa.GetFaceNodesIndices( iOppFace );
|
||||||
int nbStick = 0;
|
int nbStick = 0;
|
||||||
|
uniqueNodes.clear();
|
||||||
for ( iCur = 0; iCur < 4 && nbStick < 2; iCur++ ) {
|
for ( iCur = 0; iCur < 4 && nbStick < 2; iCur++ ) {
|
||||||
if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] )
|
if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] )
|
||||||
nbStick++;
|
nbStick++;
|
||||||
|
else
|
||||||
|
uniqueNodes.push_back( curNodes[ind[ iCur ]]);
|
||||||
}
|
}
|
||||||
if ( nbStick == 1 ) {
|
if ( nbStick == 1 ) {
|
||||||
// ... and the opposite one - into a triangle.
|
// ... and the opposite one - into a triangle.
|
||||||
// set a top node
|
// set a top node
|
||||||
ind = hexa.GetFaceNodesIndices( iFace );
|
uniqueNodes.push_back( curNodes[ pickInd ]);
|
||||||
uniqueNodes[ 3 ] = curNodes[ind[ 0 ]];
|
|
||||||
isOk = true;
|
isOk = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -7697,7 +7633,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( nbUniqueNodes == 6 && nbRepl == 2 ) {
|
else if ( nbUniqueNodes == 6 && nbRepl == 2 ) {
|
||||||
//////////////////////// HEX ---> 1 prism
|
//////////////////////// HEX ---> prism
|
||||||
int nbTria = 0, iTria[3];
|
int nbTria = 0, iTria[3];
|
||||||
const int *ind; // indices of face nodes
|
const int *ind; // indices of face nodes
|
||||||
// look for triangular faces
|
// look for triangular faces
|
||||||
@ -7712,7 +7648,6 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
|||||||
// check if triangles are opposite
|
// check if triangles are opposite
|
||||||
if ( nbTria == 2 && iTria[0] == hexa.GetOppFaceIndex( iTria[1] ))
|
if ( nbTria == 2 && iTria[0] == hexa.GetOppFaceIndex( iTria[1] ))
|
||||||
{
|
{
|
||||||
isOk = true;
|
|
||||||
// set nodes of the bottom triangle
|
// set nodes of the bottom triangle
|
||||||
ind = hexa.GetFaceNodesIndices( iTria[ 0 ]);
|
ind = hexa.GetFaceNodesIndices( iTria[ 0 ]);
|
||||||
vector<int> indB;
|
vector<int> indB;
|
||||||
@ -7732,11 +7667,12 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
|||||||
uniqueNodes[ iCur + 3 ] = curNodes[ indT[ j ]];
|
uniqueNodes[ iCur + 3 ] = curNodes[ indT[ j ]];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
isOk = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (nbUniqueNodes == 5 && nbRepl == 4 ) {
|
}
|
||||||
//////////////////// HEXAHEDRON ---> 2 tetrahedrons
|
else if (nbUniqueNodes == 5 && nbRepl == 3 ) {
|
||||||
|
//////////////////// HEXAHEDRON ---> pyramid
|
||||||
for ( int iFace = 0; iFace < 6; iFace++ ) {
|
for ( int iFace = 0; iFace < 6; iFace++ ) {
|
||||||
const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes
|
const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes
|
||||||
if (curNodes[ind[ 0 ]] == curNodes[ind[ 1 ]] &&
|
if (curNodes[ind[ 0 ]] == curNodes[ind[ 1 ]] &&
|
||||||
@ -7745,139 +7681,61 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
|||||||
// one face turns into a point ...
|
// one face turns into a point ...
|
||||||
int iOppFace = hexa.GetOppFaceIndex( iFace );
|
int iOppFace = hexa.GetOppFaceIndex( iFace );
|
||||||
ind = hexa.GetFaceNodesIndices( iOppFace );
|
ind = hexa.GetFaceNodesIndices( iOppFace );
|
||||||
int nbStick = 0;
|
uniqueNodes.clear();
|
||||||
iUnique = 2; // reverse a tetrahedron 1 bottom
|
for ( iCur = 0; iCur < 4; iCur++ ) {
|
||||||
for ( iCur = 0; iCur < 4 && nbStick == 0; iCur++ ) {
|
|
||||||
if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] )
|
if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] )
|
||||||
nbStick++;
|
break;
|
||||||
else if ( iUnique >= 0 )
|
else
|
||||||
uniqueNodes[ iUnique-- ] = curNodes[ind[ iCur ]];
|
uniqueNodes.push_back( curNodes[ind[ iCur ]]);
|
||||||
}
|
}
|
||||||
if ( nbStick == 0 ) {
|
if ( uniqueNodes.size() == 4 ) {
|
||||||
// ... and the opposite one is a quadrangle
|
// ... and the opposite one is a quadrangle
|
||||||
// set a top node
|
// set a top node
|
||||||
const int* indTop = hexa.GetFaceNodesIndices( iFace );
|
const int* indTop = hexa.GetFaceNodesIndices( iFace );
|
||||||
uniqueNodes[ 3 ] = curNodes[indTop[ 0 ]];
|
uniqueNodes.push_back( curNodes[indTop[ 0 ]]);
|
||||||
nbUniqueNodes = 4;
|
|
||||||
// tetrahedron 2
|
|
||||||
SMDS_MeshElement* newElem =
|
|
||||||
aMesh->AddVolume(curNodes[ind[ 0 ]],
|
|
||||||
curNodes[ind[ 3 ]],
|
|
||||||
curNodes[ind[ 2 ]],
|
|
||||||
curNodes[indTop[ 0 ]]);
|
|
||||||
myLastCreatedElems.Append(newElem);
|
|
||||||
if ( aShapeId )
|
|
||||||
aMesh->SetMeshElementOnShape( newElem, aShapeId );
|
|
||||||
isOk = true;
|
isOk = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( nbUniqueNodes == 6 && nbRepl == 4 ) {
|
|
||||||
////////////////// HEXAHEDRON ---> 2 tetrahedrons or 1 prism
|
if ( !isOk && nbUniqueNodes > 4 ) {
|
||||||
// find indices of quad and tri faces
|
////////////////// HEXAHEDRON ---> polyhedron
|
||||||
int iQuadFace[ 6 ], iTriFace[ 6 ], nbQuad = 0, nbTri = 0, iFace;
|
hexa.SetExternalNormal();
|
||||||
for ( iFace = 0; iFace < 6; iFace++ ) {
|
vector<const SMDS_MeshNode *> poly_nodes; poly_nodes.reserve( 6 * 4 );
|
||||||
|
vector<int> quantities; quantities.reserve( 6 );
|
||||||
|
for ( int iFace = 0; iFace < 6; iFace++ )
|
||||||
|
{
|
||||||
const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes
|
const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes
|
||||||
|
if ( curNodes[ind[0]] == curNodes[ind[2]] ||
|
||||||
|
curNodes[ind[1]] == curNodes[ind[3]] )
|
||||||
|
{
|
||||||
|
quantities.clear();
|
||||||
|
break; // opposite nodes stick
|
||||||
|
}
|
||||||
nodeSet.clear();
|
nodeSet.clear();
|
||||||
for ( iCur = 0; iCur < 4; iCur++ )
|
for ( iCur = 0; iCur < 4; iCur++ )
|
||||||
nodeSet.insert( curNodes[ind[ iCur ]] );
|
|
||||||
nbUniqueNodes = nodeSet.size();
|
|
||||||
if ( nbUniqueNodes == 3 )
|
|
||||||
iTriFace[ nbTri++ ] = iFace;
|
|
||||||
else if ( nbUniqueNodes == 4 )
|
|
||||||
iQuadFace[ nbQuad++ ] = iFace;
|
|
||||||
}
|
|
||||||
if (nbQuad == 2 && nbTri == 4 &&
|
|
||||||
hexa.GetOppFaceIndex( iQuadFace[ 0 ] ) == iQuadFace[ 1 ]) {
|
|
||||||
// 2 opposite quadrangles stuck with a diagonal;
|
|
||||||
// sample groups of merged indices: (0-4)(2-6)
|
|
||||||
// --------------------------------------------> 2 tetrahedrons
|
|
||||||
const int *ind1 = hexa.GetFaceNodesIndices( iQuadFace[ 0 ]); // indices of quad1 nodes
|
|
||||||
const int *ind2 = hexa.GetFaceNodesIndices( iQuadFace[ 1 ]);
|
|
||||||
int i0, i1d, i2, i3d, i0t, i2t; // d-daigonal, t-top
|
|
||||||
if (curNodes[ind1[ 0 ]] == curNodes[ind2[ 0 ]] &&
|
|
||||||
curNodes[ind1[ 2 ]] == curNodes[ind2[ 2 ]]) {
|
|
||||||
// stuck with 0-2 diagonal
|
|
||||||
i0 = ind1[ 3 ];
|
|
||||||
i1d = ind1[ 0 ];
|
|
||||||
i2 = ind1[ 1 ];
|
|
||||||
i3d = ind1[ 2 ];
|
|
||||||
i0t = ind2[ 1 ];
|
|
||||||
i2t = ind2[ 3 ];
|
|
||||||
}
|
|
||||||
else if (curNodes[ind1[ 1 ]] == curNodes[ind2[ 3 ]] &&
|
|
||||||
curNodes[ind1[ 3 ]] == curNodes[ind2[ 1 ]]) {
|
|
||||||
// stuck with 1-3 diagonal
|
|
||||||
i0 = ind1[ 0 ];
|
|
||||||
i1d = ind1[ 1 ];
|
|
||||||
i2 = ind1[ 2 ];
|
|
||||||
i3d = ind1[ 3 ];
|
|
||||||
i0t = ind2[ 0 ];
|
|
||||||
i2t = ind2[ 1 ];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
// tetrahedron 1
|
|
||||||
uniqueNodes[ 0 ] = curNodes [ i0 ];
|
|
||||||
uniqueNodes[ 1 ] = curNodes [ i1d ];
|
|
||||||
uniqueNodes[ 2 ] = curNodes [ i3d ];
|
|
||||||
uniqueNodes[ 3 ] = curNodes [ i0t ];
|
|
||||||
nbUniqueNodes = 4;
|
|
||||||
// tetrahedron 2
|
|
||||||
SMDS_MeshElement* newElem = aMesh->AddVolume(curNodes[ i1d ],
|
|
||||||
curNodes[ i2 ],
|
|
||||||
curNodes[ i3d ],
|
|
||||||
curNodes[ i2t ]);
|
|
||||||
myLastCreatedElems.Append(newElem);
|
|
||||||
if ( aShapeId )
|
|
||||||
aMesh->SetMeshElementOnShape( newElem, aShapeId );
|
|
||||||
isOk = true;
|
|
||||||
}
|
|
||||||
else if (( nbTri == 2 && nbQuad == 3 ) || // merged (0-4)(1-5)
|
|
||||||
( nbTri == 4 && nbQuad == 2 )) { // merged (7-4)(1-5)
|
|
||||||
// --------------------------------------------> prism
|
|
||||||
// find 2 opposite triangles
|
|
||||||
nbUniqueNodes = 6;
|
|
||||||
for ( iFace = 0; iFace + 1 < nbTri; iFace++ ) {
|
|
||||||
if ( hexa.GetOppFaceIndex( iTriFace[ iFace ] ) == iTriFace[ iFace + 1 ]) {
|
|
||||||
// find indices of kept and replaced nodes
|
|
||||||
// and fill unique nodes of 2 opposite triangles
|
|
||||||
const int *ind1 = hexa.GetFaceNodesIndices( iTriFace[ iFace ]);
|
|
||||||
const int *ind2 = hexa.GetFaceNodesIndices( iTriFace[ iFace + 1 ]);
|
|
||||||
const SMDS_MeshNode** hexanodes = hexa.GetNodes();
|
|
||||||
// fill unique nodes
|
|
||||||
iUnique = 0;
|
|
||||||
isOk = true;
|
|
||||||
for ( iCur = 0; iCur < 4 && isOk; iCur++ ) {
|
|
||||||
const SMDS_MeshNode* n = curNodes[ind1[ iCur ]];
|
|
||||||
const SMDS_MeshNode* nInit = hexanodes[ind1[ iCur ]];
|
|
||||||
if ( n == nInit ) {
|
|
||||||
// iCur of a linked node of the opposite face (make normals co-directed):
|
|
||||||
int iCurOpp = ( iCur == 1 || iCur == 3 ) ? 4 - iCur : iCur;
|
|
||||||
// check that correspondent corners of triangles are linked
|
|
||||||
if ( !hexa.IsLinked( ind1[ iCur ], ind2[ iCurOpp ] ))
|
|
||||||
isOk = false;
|
|
||||||
else {
|
|
||||||
uniqueNodes[ iUnique ] = n;
|
|
||||||
uniqueNodes[ iUnique + 3 ] = curNodes[ind2[ iCurOpp ]];
|
|
||||||
iUnique++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // if ( nbUniqueNodes == 6 && nbRepl == 4 )
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
MESSAGE("MergeNodes() removes hexahedron "<< elem);
|
if ( nodeSet.insert( curNodes[ind[ iCur ]] ).second )
|
||||||
|
poly_nodes.push_back( curNodes[ind[ iCur ]]);
|
||||||
|
}
|
||||||
|
if ( nodeSet.size() < 3 )
|
||||||
|
poly_nodes.resize( poly_nodes.size() - nodeSet.size() );
|
||||||
|
else
|
||||||
|
quantities.push_back( nodeSet.size() );
|
||||||
|
}
|
||||||
|
if ( quantities.size() >= 4 )
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* newElem = aMesh->AddPolyhedralVolume( poly_nodes, quantities );
|
||||||
|
myLastCreatedElems.Append( newElem );
|
||||||
|
if ( aShapeId && newElem )
|
||||||
|
aMesh->SetMeshElementOnShape( newElem, aShapeId );
|
||||||
|
rmElemIds.push_back( elem->GetID() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} // HEXAHEDRON
|
} // case HEXAHEDRON
|
||||||
|
|
||||||
default:
|
default:
|
||||||
isOk = false;
|
isOk = false;
|
||||||
@ -7885,7 +7743,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
|||||||
|
|
||||||
} // if ( nbNodes != nbUniqueNodes ) // some nodes stick
|
} // if ( nbNodes != nbUniqueNodes ) // some nodes stick
|
||||||
|
|
||||||
if ( isOk ) // the non-poly elem remains valid after sticking nodes
|
if ( isOk ) // a non-poly elem remains valid after sticking nodes
|
||||||
{
|
{
|
||||||
if ( nbNodes != nbUniqueNodes ||
|
if ( nbNodes != nbUniqueNodes ||
|
||||||
!aMesh->ChangeElementNodes( elem, & curNodes[0], nbNodes ))
|
!aMesh->ChangeElementNodes( elem, & curNodes[0], nbNodes ))
|
||||||
|
Loading…
Reference in New Issue
Block a user