mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-02-27 05:35:36 +05:00
bos #34269 [CEA] Function to check same face orientation for polyhedrals used on the computation of their volume.
This commit is contained in:
parent
e0c1dd6f36
commit
e3d582dca7
@ -730,7 +730,7 @@ double SMDS_VolumeTool::GetSize() const
|
|||||||
|
|
||||||
// split a polyhedron into tetrahedrons
|
// split a polyhedron into tetrahedrons
|
||||||
|
|
||||||
bool oriOk = true;
|
bool oriOk = AllFacesSameOriented();
|
||||||
SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
|
SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
|
||||||
for ( int f = 0; f < NbFaces(); ++f )
|
for ( int f = 0; f < NbFaces(); ++f )
|
||||||
{
|
{
|
||||||
@ -743,7 +743,6 @@ double SMDS_VolumeTool::GetSize() const
|
|||||||
p1 = p2;
|
p1 = p2;
|
||||||
}
|
}
|
||||||
V += p1.Dot( area );
|
V += p1.Dot( area );
|
||||||
oriOk = oriOk && IsFaceExternal( f );
|
|
||||||
}
|
}
|
||||||
V /= 6;
|
V /= 6;
|
||||||
if ( !oriOk && V > 0 )
|
if ( !oriOk && V > 0 )
|
||||||
@ -1596,6 +1595,60 @@ bool SMDS_VolumeTool::GetFaceBaryCenter (int faceIndex, double & X, double & Y,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Check that all the faces in a polyhedron follow the same orientation
|
||||||
|
* \remark there is no differentiation for outward and inward face orientation.
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
bool SMDS_VolumeTool::AllFacesSameOriented() const
|
||||||
|
{
|
||||||
|
SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
|
||||||
|
bool validOrientation = true;
|
||||||
|
std::map<Link, std::vector<int>> collectLinksOrientations;
|
||||||
|
me->myFwdLinks.clear();
|
||||||
|
for ( int faceId = 0; faceId < NbFaces(); ++faceId )
|
||||||
|
{
|
||||||
|
me->setFace( faceId );
|
||||||
|
myExternalFaces = false;
|
||||||
|
|
||||||
|
// Build the links
|
||||||
|
for ( int i = 0; i < myCurFace.myNbNodes; ++i )
|
||||||
|
{
|
||||||
|
NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1] );
|
||||||
|
std::map<Link, int>::const_iterator foundLink = myFwdLinks.find( link );
|
||||||
|
|
||||||
|
if ( foundLink == myFwdLinks.end() )
|
||||||
|
me->myFwdLinks.insert( make_pair( link, link.myOri ));
|
||||||
|
|
||||||
|
collectLinksOrientations[ link ].push_back( link.myOri );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check duality of the orientations
|
||||||
|
std::map<Link, std::vector<int>>::const_iterator theLinks;
|
||||||
|
for ( theLinks = collectLinksOrientations.begin(); theLinks != collectLinksOrientations.end(); theLinks++ )
|
||||||
|
{
|
||||||
|
if ( theLinks->second.size() == 2 ) // 99% of the cases there are 2 faces per link
|
||||||
|
{
|
||||||
|
if ( 1 != -1*theLinks->second[0]*theLinks->second[1] )
|
||||||
|
return false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( theLinks->second.size() % 2 != 0 )// Dont treat uneven number of links
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// In the other 1% of the cases we count the number occurrence and check that they match
|
||||||
|
int minusOne = std::count( theLinks->second.begin(), theLinks->second.end(), -1 );
|
||||||
|
int plusOne = std::count( theLinks->second.begin(), theLinks->second.end(), 1 );
|
||||||
|
if ( minusOne != plusOne )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return validOrientation;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : GetFaceArea
|
//function : GetFaceArea
|
||||||
//purpose : Return face area
|
//purpose : Return face area
|
||||||
|
@ -199,6 +199,10 @@ class SMDS_EXPORT SMDS_VolumeTool
|
|||||||
bool GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z) const;
|
bool GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z) const;
|
||||||
// Return barycenter of a face
|
// Return barycenter of a face
|
||||||
|
|
||||||
|
bool AllFacesSameOriented() const;
|
||||||
|
// Check that all the faces of a polyhedron have the same orientation
|
||||||
|
// no differentiation between inward and outward orientation is made.
|
||||||
|
|
||||||
double GetFaceArea( int faceIndex ) const;
|
double GetFaceArea( int faceIndex ) const;
|
||||||
// Return face area
|
// Return face area
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ print("dual_volume: ", dual_volume)
|
|||||||
print("dual_raw_volume: ", dual_raw_volume)
|
print("dual_raw_volume: ", dual_raw_volume)
|
||||||
|
|
||||||
assert (dual_volume >= dual_raw_volume)
|
assert (dual_volume >= dual_raw_volume)
|
||||||
|
assert abs( tetra_volume - dual_raw_volume )/tetra_volume < 1e-12
|
||||||
|
|
||||||
if salome.sg.hasDesktop():
|
if salome.sg.hasDesktop():
|
||||||
salome.sg.updateObjBrowser()
|
salome.sg.updateObjBrowser()
|
||||||
|
@ -128,6 +128,7 @@ print("dual_raw_volume: ", dual_raw_volume)
|
|||||||
assert (dual_volume >= dual_raw_volume)
|
assert (dual_volume >= dual_raw_volume)
|
||||||
|
|
||||||
assert abs(dual_volume-shape_volume)/shape_volume < 0.14
|
assert abs(dual_volume-shape_volume)/shape_volume < 0.14
|
||||||
|
assert abs(dual_raw_volume-tetra_volume)/tetra_volume < 1e-12
|
||||||
|
|
||||||
# Check groups
|
# Check groups
|
||||||
dual_Mesh_groups = dual_Mesh_1.GetGroups()
|
dual_Mesh_groups = dual_Mesh_1.GetGroups()
|
||||||
|
Loading…
Reference in New Issue
Block a user