From 2cc662ea288ab891a16c965a1443fc2368e8798c Mon Sep 17 00:00:00 2001 From: eap Date: Tue, 15 Oct 2019 21:25:46 +0300 Subject: [PATCH] #17828 [CEA 17805] Polyhedron Mesh volume calculation and volume orientation criterion 1) Fix BadOrientedVolume criterion to detect invalid polyhedrons 2) Fix SMESH_MeshEditor::Reorient() to correct orientation of polyhedron facets --- src/Controls/SMESH_Controls.cxx | 14 +++++++++++- src/SMESH/SMESH_MeshEditor.cxx | 38 ++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 06c40dae2..676c68aca 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -2286,7 +2286,19 @@ bool BadOrientedVolume::IsSatisfy( long theId ) return false; SMDS_VolumeTool vTool( myMesh->FindElement( theId )); - return !vTool.IsForward(); + + bool isOk = true; + if ( vTool.IsPoly() ) + { + isOk = true; + for ( int i = 0; i < vTool.NbFaces() && isOk; ++i ) + isOk = vTool.IsFaceExternal( i ); + } + else + { + isOk = vTool.IsForward(); + } + return !isOk; } SMDSAbs_ElementType BadOrientedVolume::GetType() const diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 7466070e4..01e5f628a 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -1093,19 +1093,37 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) MESSAGE("Warning: bad volumic element"); return false; } - const int nbFaces = aPolyedre->NbFaces(); + SMDS_VolumeTool vTool( aPolyedre ); + const int nbFaces = vTool.NbFaces(); + vector quantities( nbFaces ); vector poly_nodes; - vector quantities (nbFaces); - // reverse each face of the polyedre - for (int iface = 1; iface <= nbFaces; iface++) { - int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface); - quantities[iface - 1] = nbFaceNodes; + // check if all facets are oriented equally + bool sameOri = true; + vector& facetOri = quantities; // keep orientation in quantities so far + for (int iface = 0; iface < nbFaces; iface++) + { + facetOri[ iface ] = vTool.IsFaceExternal( iface ); + if ( facetOri[ iface ] != facetOri[ 0 ]) + sameOri = false; + } - for (inode = nbFaceNodes; inode >= 1; inode--) { - const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode); - poly_nodes.push_back(curNode); - } + // reverse faces of the polyhedron + int neededOri = sameOri ? 1 - facetOri[0] : 1; + poly_nodes.reserve( vTool.NbNodes() ); + for ( int iface = 0; iface < nbFaces; iface++ ) + { + int nbFaceNodes = vTool.NbFaceNodes( iface ); + const SMDS_MeshNode** nodes = vTool.GetFaceNodes( iface ); + bool toReverse = ( facetOri[ iface ] != neededOri ); + + quantities[ iface ] = nbFaceNodes; + + if ( toReverse ) + for ( int inode = nbFaceNodes - 1; inode >= 0; inode-- ) + poly_nodes.push_back( nodes[ inode ]); + else + poly_nodes.insert( poly_nodes.end(), nodes, nodes + nbFaceNodes ); } return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities ); } -- 2.39.2