22797: EDF 9014 SMESH: Problem with the 3D extrusion algorithm

1) pb with invalid node param on EDGEs after 2D Projection
2) pb of search of source FACEs of the prism
This commit is contained in:
eap 2014-10-31 20:38:10 +03:00
parent a671072fe6
commit b905bf1432
4 changed files with 84 additions and 28 deletions

View File

@ -2804,6 +2804,28 @@ bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMes
(shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape )); (shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape ));
} }
//=======================================================================
//function : IsBlock
//purpose :
//=======================================================================
bool SMESH_MesherHelper::IsBlock( const TopoDS_Shape& shape )
{
if ( shape.IsNull() )
return false;
TopoDS_Shell shell;
TopExp_Explorer exp( shape, TopAbs_SHELL );
if ( !exp.More() ) return false;
shell = TopoDS::Shell( exp.Current() );
if ( exp.Next(), exp.More() ) return false;
TopoDS_Vertex v;
TopTools_IndexedMapOfOrientedShape map;
return SMESH_Block::FindBlockShapes( shell, v, v, map );
}
//================================================================================ //================================================================================
/*! /*!
* \brief Return maximal tolerance of shape * \brief Return maximal tolerance of shape

View File

@ -221,6 +221,8 @@ class SMESH_EXPORT SMESH_MesherHelper
static bool IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh ); static bool IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh );
static bool IsBlock( const TopoDS_Shape& shape );
static double MaxTolerance( const TopoDS_Shape& shape ); static double MaxTolerance( const TopoDS_Shape& shape );
static double GetAngle( const TopoDS_Edge & E1, const TopoDS_Edge & E2, static double GetAngle( const TopoDS_Edge & E1, const TopoDS_Edge & E2,

View File

@ -687,6 +687,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
TopTools_MapOfShape meshedSolids; TopTools_MapOfShape meshedSolids;
list< Prism_3D::TPrismTopo > meshedPrism; list< Prism_3D::TPrismTopo > meshedPrism;
list< TopoDS_Face > suspectSourceFaces;
TopTools_ListIteratorOfListOfShape solidIt; TopTools_ListIteratorOfListOfShape solidIt;
while ( meshedSolids.Extent() < nbSolids ) while ( meshedSolids.Extent() < nbSolids )
@ -717,6 +718,10 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
{ {
meshedFaces.push_front( prism.myTop ); meshedFaces.push_front( prism.myTop );
} }
else
{
suspectSourceFaces.push_back( prism.myTop );
}
meshedPrism.push_back( prism ); meshedPrism.push_back( prism );
} }
} }
@ -746,6 +751,10 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
solidList.Remove( solidIt ); solidList.Remove( solidIt );
continue; // already computed prism continue; // already computed prism
} }
if ( myHelper->IsBlock( solid )) {
solidIt.Next();
continue; // too trivial
}
// find a source FACE of the SOLID: it's a FACE sharing a bottom EDGE with wFace // find a source FACE of the SOLID: it's a FACE sharing a bottom EDGE with wFace
const TopoDS_Edge& wEdge = (*wQuad)->side[ QUAD_TOP_SIDE ].grid->Edge(0); const TopoDS_Edge& wEdge = (*wQuad)->side[ QUAD_TOP_SIDE ].grid->Edge(0);
PShapeIteratorPtr faceIt = myHelper->GetAncestors( wEdge, *myHelper->GetMesh(), PShapeIteratorPtr faceIt = myHelper->GetAncestors( wEdge, *myHelper->GetMesh(),
@ -760,6 +769,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
myHelper->IsSubShape( candidateF, solid ) && myHelper->IsSubShape( candidateF, solid ) &&
!myHelper->GetMesh()->GetSubMesh( candidateF )->IsMeshComputed() && !myHelper->GetMesh()->GetSubMesh( candidateF )->IsMeshComputed() &&
initPrism( prism, solid ) && initPrism( prism, solid ) &&
!myHelper->GetMesh()->GetSubMesh( prism.myTop )->IsMeshComputed() &&
project2dMesh( prismIt->myBottom, candidateF)) project2dMesh( prismIt->myBottom, candidateF))
{ {
mySetErrorToSM = true; mySetErrorToSM = true;
@ -789,31 +799,49 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
break; // to compute prisms with avident sources break; // to compute prisms with avident sources
} }
if ( meshedFaces.empty() )
{
meshedFaces.splice( meshedFaces.end(), suspectSourceFaces );
}
// find FACEs with local 1D hyps, which has to be computed by now, // find FACEs with local 1D hyps, which has to be computed by now,
// or at least any computed FACEs // or at least any computed FACEs
for ( int iF = 1; ( meshedFaces.empty() && iF < faceToSolids.Extent() ); ++iF ) if ( meshedFaces.empty() )
{ {
const TopoDS_Face& face = TopoDS::Face( faceToSolids.FindKey( iF )); int prevNbFaces = 0;
const TopTools_ListOfShape& solidList = faceToSolids.FindFromKey( face ); for ( int iF = 1; iF <= faceToSolids.Extent(); ++iF )
if ( solidList.IsEmpty() ) continue;
SMESH_subMesh* faceSM = theMesh.GetSubMesh( face );
if ( !faceSM->IsEmpty() )
{ {
meshedFaces.push_back( face ); // lower priority const TopoDS_Face& face = TopoDS::Face( faceToSolids.FindKey( iF ));
} const TopTools_ListOfShape& solidList = faceToSolids.FindFromKey( face );
else if ( solidList.IsEmpty() ) continue;
{ SMESH_subMesh* faceSM = theMesh.GetSubMesh( face );
bool allSubMeComputed = true; if ( !faceSM->IsEmpty() )
SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(false,true);
while ( smIt->more() && allSubMeComputed )
allSubMeComputed = smIt->next()->IsMeshComputed();
if ( allSubMeComputed )
{ {
faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE ); int nbFaces = faceSM->GetSubMeshDS()->NbElements();
if ( !faceSM->IsEmpty() ) if ( prevNbFaces < nbFaces )
meshedFaces.push_front( face ); // higher priority {
else if ( !meshedFaces.empty() ) meshedFaces.pop_back();
faceSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); meshedFaces.push_back( face ); // lower priority
prevNbFaces = nbFaces;
}
}
else
{
bool allSubMeComputed = true;
SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(false,true);
while ( smIt->more() && allSubMeComputed )
allSubMeComputed = smIt->next()->IsMeshComputed();
if ( allSubMeComputed )
{
faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );
if ( !faceSM->IsEmpty() ) {
meshedFaces.push_front( face ); // higher priority
break;
}
else {
faceSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
}
}
} }
} }
} }
@ -1512,6 +1540,8 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
SMESH_subMesh* topSM = mesh->GetSubMesh( topE ); SMESH_subMesh* topSM = mesh->GetSubMesh( topE );
SMESH_subMesh* srcSM = botSM; SMESH_subMesh* srcSM = botSM;
SMESH_subMesh* tgtSM = topSM; SMESH_subMesh* tgtSM = topSM;
srcSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
tgtSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
if ( !srcSM->IsMeshComputed() && tgtSM->IsMeshComputed() ) if ( !srcSM->IsMeshComputed() && tgtSM->IsMeshComputed() )
std::swap( srcSM, tgtSM ); std::swap( srcSM, tgtSM );
@ -1521,7 +1551,6 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
srcSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE ); // nodes on VERTEXes srcSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE ); // nodes on VERTEXes
srcSM->ComputeStateEngine( SMESH_subMesh::COMPUTE ); // segments on the EDGE srcSM->ComputeStateEngine( SMESH_subMesh::COMPUTE ); // segments on the EDGE
} }
srcSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
if ( tgtSM->IsMeshComputed() && if ( tgtSM->IsMeshComputed() &&
tgtSM->GetSubMeshDS()->NbNodes() != srcSM->GetSubMeshDS()->NbNodes() ) tgtSM->GetSubMeshDS()->NbNodes() != srcSM->GetSubMeshDS()->NbNodes() )

View File

@ -706,7 +706,12 @@ namespace {
if ( !tgtFace.IsPartner( srcFace ) ) if ( !tgtFace.IsPartner( srcFace ) )
{ {
SMESH_MesherHelper edgeHelper( *tgtMesh );
edgeHelper.ToFixNodeParameters( true );
helper.ToFixNodeParameters( true );
int nbOkPos = 0; int nbOkPos = 0;
bool toCheck = true;
const double tol2d = 1e-12; const double tol2d = 1e-12;
srcN_tgtN = src2tgtNodes.begin(); srcN_tgtN = src2tgtNodes.begin();
for ( ; srcN_tgtN != src2tgtNodes.end(); ++srcN_tgtN ) for ( ; srcN_tgtN != src2tgtNodes.end(); ++srcN_tgtN )
@ -716,11 +721,11 @@ namespace {
{ {
case SMDS_TOP_FACE: case SMDS_TOP_FACE:
{ {
if ( nbOkPos < 10 ) break;
gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv; gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv;
if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) && if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) &&
(( uv - uvBis ).SquareModulus() < tol2d ) && (( uv - uvBis ).SquareModulus() < tol2d ))
( ++nbOkPos > 10 )) ++nbOkPos;
return true;
else else
nbOkPos = 0; nbOkPos = 0;
break; break;
@ -728,10 +733,8 @@ namespace {
case SMDS_TOP_EDGE: case SMDS_TOP_EDGE:
{ {
const TopoDS_Edge & tgtE = TopoDS::Edge( tgtMeshDS->IndexToShape( n->getshapeId() )); const TopoDS_Edge & tgtE = TopoDS::Edge( tgtMeshDS->IndexToShape( n->getshapeId() ));
double u = helper.GetNodeU( tgtE, n ), uBis = u; edgeHelper.SetSubShape( tgtE );
if (( !helper.CheckNodeU( tgtE, n, u, tol )) || edgeHelper.GetNodeU( tgtE, n, 0, &toCheck );
(( u - uBis ) < tol2d ))
nbOkPos = 0;
break; break;
} }
default:; default:;