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 ));
}
//=======================================================================
//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

View File

@ -221,6 +221,8 @@ class SMESH_EXPORT SMESH_MesherHelper
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 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;
list< Prism_3D::TPrismTopo > meshedPrism;
list< TopoDS_Face > suspectSourceFaces;
TopTools_ListIteratorOfListOfShape solidIt;
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 );
}
else
{
suspectSourceFaces.push_back( prism.myTop );
}
meshedPrism.push_back( prism );
}
}
@ -746,6 +751,10 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
solidList.Remove( solidIt );
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
const TopoDS_Edge& wEdge = (*wQuad)->side[ QUAD_TOP_SIDE ].grid->Edge(0);
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->GetMesh()->GetSubMesh( candidateF )->IsMeshComputed() &&
initPrism( prism, solid ) &&
!myHelper->GetMesh()->GetSubMesh( prism.myTop )->IsMeshComputed() &&
project2dMesh( prismIt->myBottom, candidateF))
{
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
}
if ( meshedFaces.empty() )
{
meshedFaces.splice( meshedFaces.end(), suspectSourceFaces );
}
// find FACEs with local 1D hyps, which has to be computed by now,
// 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 ));
const TopTools_ListOfShape& solidList = faceToSolids.FindFromKey( face );
if ( solidList.IsEmpty() ) continue;
SMESH_subMesh* faceSM = theMesh.GetSubMesh( face );
if ( !faceSM->IsEmpty() )
int prevNbFaces = 0;
for ( int iF = 1; iF <= faceToSolids.Extent(); ++iF )
{
meshedFaces.push_back( face ); // lower priority
}
else
{
bool allSubMeComputed = true;
SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(false,true);
while ( smIt->more() && allSubMeComputed )
allSubMeComputed = smIt->next()->IsMeshComputed();
if ( allSubMeComputed )
const TopoDS_Face& face = TopoDS::Face( faceToSolids.FindKey( iF ));
const TopTools_ListOfShape& solidList = faceToSolids.FindFromKey( face );
if ( solidList.IsEmpty() ) continue;
SMESH_subMesh* faceSM = theMesh.GetSubMesh( face );
if ( !faceSM->IsEmpty() )
{
faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );
if ( !faceSM->IsEmpty() )
meshedFaces.push_front( face ); // higher priority
else
faceSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
int nbFaces = faceSM->GetSubMeshDS()->NbElements();
if ( prevNbFaces < nbFaces )
{
if ( !meshedFaces.empty() ) meshedFaces.pop_back();
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* srcSM = botSM;
SMESH_subMesh* tgtSM = topSM;
srcSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
tgtSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
if ( !srcSM->IsMeshComputed() && tgtSM->IsMeshComputed() )
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->ComputeStateEngine( SMESH_subMesh::COMPUTE ); // segments on the EDGE
}
srcSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
if ( tgtSM->IsMeshComputed() &&
tgtSM->GetSubMeshDS()->NbNodes() != srcSM->GetSubMeshDS()->NbNodes() )

View File

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