mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-12 01:30:34 +05:00
020461: EDF 1102 GHS3DPLUGIN: Bad detection of volumes with Ghs3d mesh
SMESH_MesherHelper: - void SetCheckNodePosition(bool toCheck) { myCheckNodePos = toCheck; } /*! + * \brief Check and fix node UV on a face + * \retval bool - false if UV is bad and could not be fixed + */ + bool CheckNodeUV(const TopoDS_Face& F, + const SMDS_MeshNode* n, + gp_XY& uv, + const double tol) const; - bool myCheckNodePos; + std::set< int > myOkNodePosShapes;
This commit is contained in:
parent
72ca340bff
commit
6510081be2
@ -7689,7 +7689,6 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
|
|||||||
SMESH_subMesh* sm = smIt->next();
|
SMESH_subMesh* sm = smIt->next();
|
||||||
if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() ) {
|
if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() ) {
|
||||||
aHelper.SetSubShape( sm->GetSubShape() );
|
aHelper.SetSubShape( sm->GetSubShape() );
|
||||||
if ( !theForce3d) aHelper.SetCheckNodePosition(true);
|
|
||||||
nbCheckedElems += convertElemToQuadratic(smDS, aHelper, theForce3d);
|
nbCheckedElems += convertElemToQuadratic(smDS, aHelper, theForce3d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ namespace {
|
|||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh)
|
SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh)
|
||||||
: myMesh(&theMesh), myShapeID(0), myCreateQuadratic(false), myCheckNodePos(false)
|
: myMesh(&theMesh), myShapeID(0), myCreateQuadratic(false)
|
||||||
{
|
{
|
||||||
mySetElemOnShape = ( ! myMesh->HasShapeToMesh() );
|
mySetElemOnShape = ( ! myMesh->HasShapeToMesh() );
|
||||||
}
|
}
|
||||||
@ -326,9 +326,8 @@ gp_Pnt2d SMESH_MesherHelper::GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& u
|
|||||||
* \param F - the face
|
* \param F - the face
|
||||||
* \param n - the node
|
* \param n - the node
|
||||||
* \param n2 - a node of element being created located inside a face
|
* \param n2 - a node of element being created located inside a face
|
||||||
|
* \param check - optional flag returing false if found UV are invalid
|
||||||
* \retval gp_XY - resulting UV
|
* \retval gp_XY - resulting UV
|
||||||
*
|
|
||||||
* Auxilary function called form GetMediumNode()
|
|
||||||
*/
|
*/
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
@ -339,37 +338,14 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F,
|
|||||||
{
|
{
|
||||||
gp_Pnt2d uv( 1e100, 1e100 );
|
gp_Pnt2d uv( 1e100, 1e100 );
|
||||||
const SMDS_PositionPtr Pos = n->GetPosition();
|
const SMDS_PositionPtr Pos = n->GetPosition();
|
||||||
|
bool uvOK = false;
|
||||||
if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE)
|
if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE)
|
||||||
{
|
{
|
||||||
// node has position on face
|
// node has position on face
|
||||||
const SMDS_FacePosition* fpos =
|
const SMDS_FacePosition* fpos =
|
||||||
static_cast<const SMDS_FacePosition*>(n->GetPosition().get());
|
static_cast<const SMDS_FacePosition*>(n->GetPosition().get());
|
||||||
uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter());
|
uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter());
|
||||||
if ( check && *check )
|
uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), BRep_Tool::Tolerance( F ));
|
||||||
{
|
|
||||||
// check that uv is correct
|
|
||||||
TopLoc_Location loc;
|
|
||||||
Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
|
|
||||||
double tol = 2 * BRep_Tool::Tolerance( F );
|
|
||||||
gp_Pnt nodePnt = XYZ( n );
|
|
||||||
if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
|
|
||||||
if ( nodePnt.Distance( surface->Value( uv.X(), uv.Y() )) > tol ) {
|
|
||||||
// uv incorrect, project the node to surface
|
|
||||||
GeomAPI_ProjectPointOnSurf projector( nodePnt, surface, tol );
|
|
||||||
if ( !projector.IsDone() || projector.NbPoints() < 1 ) {
|
|
||||||
MESSAGE( "SMESH_MesherHelper::GetNodeUV() failed to project" )
|
|
||||||
return uv.XY();
|
|
||||||
}
|
|
||||||
Quantity_Parameter U,V;
|
|
||||||
projector.LowerDistanceParameters(U,V);
|
|
||||||
if ( nodePnt.Distance( surface->Value( U, V )) > tol )
|
|
||||||
MESSAGE( "SMESH_MesherHelper::GetNodeUV(), invalid projection" );
|
|
||||||
uv.SetCoord( U,V );
|
|
||||||
}
|
|
||||||
else if ( uv.XY().Modulus() > numeric_limits<double>::min() ) {
|
|
||||||
*check = false; // parameters are OK, do not check further more
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE)
|
else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE)
|
||||||
{
|
{
|
||||||
@ -383,39 +359,43 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F,
|
|||||||
double f, l;
|
double f, l;
|
||||||
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
|
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
|
||||||
uv = C2d->Value( epos->GetUParameter() );
|
uv = C2d->Value( epos->GetUParameter() );
|
||||||
|
uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), BRep_Tool::Tolerance( E ));
|
||||||
|
|
||||||
// for a node on a seam edge select one of UVs on 2 pcurves
|
// for a node on a seam edge select one of UVs on 2 pcurves
|
||||||
if ( n2 && IsSeamShape( edgeID ) )
|
if ( n2 && IsSeamShape( edgeID ) )
|
||||||
|
{
|
||||||
uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
|
uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
|
||||||
|
}
|
||||||
// adjust uv to period
|
else
|
||||||
TopLoc_Location loc;
|
{ // adjust uv to period
|
||||||
Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc);
|
TopLoc_Location loc;
|
||||||
Standard_Boolean isUPeriodic = S->IsUPeriodic();
|
Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc);
|
||||||
Standard_Boolean isVPeriodic = S->IsVPeriodic();
|
Standard_Boolean isUPeriodic = S->IsUPeriodic();
|
||||||
if ( isUPeriodic || isVPeriodic ) {
|
Standard_Boolean isVPeriodic = S->IsVPeriodic();
|
||||||
Standard_Real UF,UL,VF,VL;
|
if ( isUPeriodic || isVPeriodic ) {
|
||||||
S->Bounds(UF,UL,VF,VL);
|
Standard_Real UF,UL,VF,VL;
|
||||||
if(isUPeriodic)
|
S->Bounds(UF,UL,VF,VL);
|
||||||
uv.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod(uv.X(),UF,UL));
|
if(isUPeriodic)
|
||||||
if(isVPeriodic)
|
uv.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod(uv.X(),UF,UL));
|
||||||
uv.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod(uv.Y(),VF,VL));
|
if(isVPeriodic)
|
||||||
|
uv.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod(uv.Y(),VF,VL));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX)
|
else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX)
|
||||||
{
|
{
|
||||||
if ( int vertexID = n->GetPosition()->GetShapeId() ) {
|
if ( int vertexID = n->GetPosition()->GetShapeId() ) {
|
||||||
bool ok = true;
|
|
||||||
const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID));
|
const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID));
|
||||||
try {
|
try {
|
||||||
uv = BRep_Tool::Parameters( V, F );
|
uv = BRep_Tool::Parameters( V, F );
|
||||||
|
uvOK = true;
|
||||||
}
|
}
|
||||||
catch (Standard_Failure& exc) {
|
catch (Standard_Failure& exc) {
|
||||||
ok = false;
|
|
||||||
}
|
}
|
||||||
if ( !ok ) {
|
if ( !uvOK ) {
|
||||||
for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !ok && vert.More(); vert.Next() )
|
for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() )
|
||||||
ok = ( V == vert.Current() );
|
uvOK = ( V == vert.Current() );
|
||||||
if ( !ok ) {
|
if ( !uvOK ) {
|
||||||
#ifdef _DEBUG_
|
#ifdef _DEBUG_
|
||||||
MESSAGE ( "SMESH_MesherHelper::GetNodeUV(); Vertex " << vertexID
|
MESSAGE ( "SMESH_MesherHelper::GetNodeUV(); Vertex " << vertexID
|
||||||
<< " not in face " << GetMeshDS()->ShapeToIndex( F ) );
|
<< " not in face " << GetMeshDS()->ShapeToIndex( F ) );
|
||||||
@ -423,14 +403,14 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F,
|
|||||||
// get UV of a vertex closest to the node
|
// get UV of a vertex closest to the node
|
||||||
double dist = 1e100;
|
double dist = 1e100;
|
||||||
gp_Pnt pn = XYZ( n );
|
gp_Pnt pn = XYZ( n );
|
||||||
for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !ok && vert.More(); vert.Next() ) {
|
for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() ) {
|
||||||
TopoDS_Vertex curV = TopoDS::Vertex( vert.Current() );
|
TopoDS_Vertex curV = TopoDS::Vertex( vert.Current() );
|
||||||
gp_Pnt p = BRep_Tool::Pnt( curV );
|
gp_Pnt p = BRep_Tool::Pnt( curV );
|
||||||
double curDist = p.SquareDistance( pn );
|
double curDist = p.SquareDistance( pn );
|
||||||
if ( curDist < dist ) {
|
if ( curDist < dist ) {
|
||||||
dist = curDist;
|
dist = curDist;
|
||||||
uv = BRep_Tool::Parameters( curV, F );
|
uv = BRep_Tool::Parameters( curV, F );
|
||||||
if ( dist < DBL_MIN ) break;
|
uvOK = ( dist < DBL_MIN );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -454,9 +434,58 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F,
|
|||||||
uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
|
uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( check )
|
||||||
|
*check = uvOK;
|
||||||
|
|
||||||
return uv.XY();
|
return uv.XY();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Check and fix node UV on a face
|
||||||
|
* \retval bool - false if UV is bad and could not be fixed
|
||||||
|
*/
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face& F,
|
||||||
|
const SMDS_MeshNode* n,
|
||||||
|
gp_XY& uv,
|
||||||
|
const double tol) const
|
||||||
|
{
|
||||||
|
if ( !myOkNodePosShapes.count( n->GetPosition()->GetShapeId() ))
|
||||||
|
{
|
||||||
|
// check that uv is correct
|
||||||
|
TopLoc_Location loc;
|
||||||
|
Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
|
||||||
|
gp_Pnt nodePnt = XYZ( n );
|
||||||
|
if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
|
||||||
|
if ( nodePnt.Distance( surface->Value( uv.X(), uv.Y() )) > tol )
|
||||||
|
{
|
||||||
|
// uv incorrect, project the node to surface
|
||||||
|
GeomAPI_ProjectPointOnSurf projector( nodePnt, surface, tol );
|
||||||
|
if ( !projector.IsDone() || projector.NbPoints() < 1 )
|
||||||
|
{
|
||||||
|
MESSAGE( "SMESH_MesherHelper::CheckNodeUV() failed to project" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Quantity_Parameter U,V;
|
||||||
|
projector.LowerDistanceParameters(U,V);
|
||||||
|
if ( nodePnt.Distance( surface->Value( U, V )) > tol )
|
||||||
|
{
|
||||||
|
MESSAGE( "SMESH_MesherHelper::CheckNodeUV(), invalid projection" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uv.SetCoord( U,V );
|
||||||
|
}
|
||||||
|
else if ( uv.Modulus() > numeric_limits<double>::min() )
|
||||||
|
{
|
||||||
|
((SMESH_MesherHelper*) this)->myOkNodePosShapes.insert( n->GetPosition()->GetShapeId() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Return middle UV taking in account surface period
|
* \brief Return middle UV taking in account surface period
|
||||||
@ -583,23 +612,26 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
|
|||||||
F = TopoDS::Face(myShape);
|
F = TopoDS::Face(myShape);
|
||||||
faceID = myShapeID;
|
faceID = myShapeID;
|
||||||
}
|
}
|
||||||
|
bool uvOK1, uvOK2;
|
||||||
|
gp_XY p1 = GetNodeUV(F,n1,n2, &uvOK1);
|
||||||
|
gp_XY p2 = GetNodeUV(F,n2,n1, &uvOK2);
|
||||||
|
|
||||||
gp_XY p1 = GetNodeUV(F,n1,n2, &myCheckNodePos);
|
if ( uvOK1 && uvOK2 )
|
||||||
gp_XY p2 = GetNodeUV(F,n2,n1, &myCheckNodePos);
|
{
|
||||||
|
if ( IsDegenShape( Pos1->GetShapeId() ))
|
||||||
|
p1.SetCoord( myParIndex, p2.Coord( myParIndex ));
|
||||||
|
else if ( IsDegenShape( Pos2->GetShapeId() ))
|
||||||
|
p2.SetCoord( myParIndex, p1.Coord( myParIndex ));
|
||||||
|
|
||||||
if ( IsDegenShape( Pos1->GetShapeId() ))
|
TopLoc_Location loc;
|
||||||
p1.SetCoord( myParIndex, p2.Coord( myParIndex ));
|
Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc);
|
||||||
else if ( IsDegenShape( Pos2->GetShapeId() ))
|
gp_XY uv = GetMiddleUV( S, p1, p2 );
|
||||||
p2.SetCoord( myParIndex, p1.Coord( myParIndex ));
|
gp_Pnt P = S->Value( uv.X(), uv.Y() ).Transformed(loc);
|
||||||
|
n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
|
||||||
TopLoc_Location loc;
|
meshDS->SetNodeOnFace(n12, faceID, uv.X(), uv.Y());
|
||||||
Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc);
|
myTLinkNodeMap.insert(make_pair(link,n12));
|
||||||
gp_XY uv = GetMiddleUV( S, p1, p2 );
|
return n12;
|
||||||
gp_Pnt P = S->Value( uv.X(), uv.Y() ).Transformed(loc);
|
}
|
||||||
n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
|
|
||||||
meshDS->SetNodeOnFace(n12, faceID, uv.X(), uv.Y());
|
|
||||||
myTLinkNodeMap.insert(make_pair(link,n12));
|
|
||||||
return n12;
|
|
||||||
}
|
}
|
||||||
if (edgeID>0 || shapeType == TopAbs_EDGE) {
|
if (edgeID>0 || shapeType == TopAbs_EDGE) {
|
||||||
|
|
||||||
@ -611,8 +643,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
|
|||||||
edgeID = myShapeID;
|
edgeID = myShapeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
double p1 = GetNodeU(E,n1, &myCheckNodePos);
|
double p1 = GetNodeU(E,n1);
|
||||||
double p2 = GetNodeU(E,n2, &myCheckNodePos);
|
double p2 = GetNodeU(E,n2);
|
||||||
|
|
||||||
double f,l;
|
double f,l;
|
||||||
Handle(Geom_Curve) C = BRep_Tool::Curve(E, f, l);
|
Handle(Geom_Curve) C = BRep_Tool::Curve(E, f, l);
|
||||||
|
@ -151,15 +151,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetElementsOnShape(bool toSet) { mySetElemOnShape = toSet; }
|
void SetElementsOnShape(bool toSet) { mySetElemOnShape = toSet; }
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Enable/disable checking of node parameters on shapes while adding elements.
|
|
||||||
* In case of incorrect parameters mudium node place is computed as the middle
|
|
||||||
* of two nodes. Default is false.
|
|
||||||
* NOTE that this flag is reset to "not to check" if check with non-default partameter
|
|
||||||
* is successful
|
|
||||||
*/
|
|
||||||
void SetCheckNodePosition(bool toCheck) { myCheckNodePos = toCheck; }
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Set shape to make elements on without calling IsQuadraticSubMesh()
|
* \brief Set shape to make elements on without calling IsQuadraticSubMesh()
|
||||||
*/
|
*/
|
||||||
@ -260,6 +251,14 @@ public:
|
|||||||
const SMDS_MeshNode* n,
|
const SMDS_MeshNode* n,
|
||||||
const SMDS_MeshNode* inFaceNode=0,
|
const SMDS_MeshNode* inFaceNode=0,
|
||||||
bool* check=0) const;
|
bool* check=0) const;
|
||||||
|
/*!
|
||||||
|
* \brief Check and fix node UV on a face
|
||||||
|
* \retval bool - false if UV is bad and could not be fixed
|
||||||
|
*/
|
||||||
|
bool CheckNodeUV(const TopoDS_Face& F,
|
||||||
|
const SMDS_MeshNode* n,
|
||||||
|
gp_XY& uv,
|
||||||
|
const double tol) const;
|
||||||
/*!
|
/*!
|
||||||
* \brief Return middle UV taking in account surface period
|
* \brief Return middle UV taking in account surface period
|
||||||
*/
|
*/
|
||||||
@ -393,7 +392,7 @@ protected:
|
|||||||
// to create quadratic elements
|
// to create quadratic elements
|
||||||
bool myCreateQuadratic;
|
bool myCreateQuadratic;
|
||||||
bool mySetElemOnShape;
|
bool mySetElemOnShape;
|
||||||
bool myCheckNodePos;
|
std::set< int > myOkNodePosShapes;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user