From b905bf1432be723426745721b4afde568d54d459 Mon Sep 17 00:00:00 2001 From: eap Date: Fri, 31 Oct 2014 20:38:10 +0300 Subject: [PATCH] 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 --- src/SMESH/SMESH_MesherHelper.cxx | 22 +++++++ src/SMESH/SMESH_MesherHelper.hxx | 2 + src/StdMeshers/StdMeshers_Prism_3D.cxx | 71 +++++++++++++++------ src/StdMeshers/StdMeshers_Projection_2D.cxx | 17 +++-- 4 files changed, 84 insertions(+), 28 deletions(-) diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 6e5b08498..0d4173c28 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -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 diff --git a/src/SMESH/SMESH_MesherHelper.hxx b/src/SMESH/SMESH_MesherHelper.hxx index 430e6f374..ae6767d30 100644 --- a/src/SMESH/SMESH_MesherHelper.hxx +++ b/src/SMESH/SMESH_MesherHelper.hxx @@ -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, diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index fbc5704bd..62f538d84 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -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() ) diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index 66e7834ae..f8dd75016 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -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:; -- 2.39.2