From: eap Date: Tue, 7 Apr 2015 17:39:18 +0000 (+0300) Subject: 23036: [CEA 1459] Regression projection 1D2D X-Git-Tag: V7_6_0b1~4 X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=commitdiff_plain;h=80e28740d3fd1b3debb41e25c7fe515cc1305eef 23036: [CEA 1459] Regression projection 1D2D + Fix Pb: SIGSEGV in StdMeshers_Prism_3D::IsApplicable() on the shape of 23036 + Fix Pb: "Projection 3D" algo is available in Create mesh dlg on the shape of 23036 + Add debug trace in case of exceptions in IsApplicable() + Fix 52667: SIGSEGV at attempt to create mesh without Geometry when setting hypothesis --- diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 468352968..58bbe32f0 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -5140,8 +5140,7 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType, if (aCreator) { TopoDS_Shape shape = GeomObjectToShape( theGeomObject ); - if ( !shape.IsNull() ) - return aCreator->IsApplicable( shape, toCheckAll ); + return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll ); } else { @@ -5149,6 +5148,10 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType, } SMESH_CATCH( SMESH::doNothing ); + +#ifdef _DEBUG_ + cout << "SMESH_Gen_i::IsApplicable(): exception in " << ( theAlgoType ? theAlgoType : "") << endl; +#endif return true; } diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.hxx b/src/StdMeshers/StdMeshers_Hexa_3D.hxx index 415db0d9e..e186863a5 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.hxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.hxx @@ -55,7 +55,8 @@ public: MapShapeNbElems& aResMap); static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll); -protected: + + protected: const StdMeshers_ViscousLayers* _viscousLayersHyp; }; diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index 343a3471a..0bd7070dc 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -2549,7 +2549,7 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable() for ( iE = 0; iE < *nbE; ++e, ++iE ) if ( SMESH_Algo::isDegenerated( *e )) { - ee.erase( e ); + e = --ee.erase( e ); --(*nbE); --iE; } diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index a21f5d7aa..85ecfac3a 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -756,6 +756,10 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopoDS_Face nextFace1 = GetNextFace( edgeToFace1, *eIt1, face1 ); TopoDS_Face nextFace2 = GetNextFace( edgeToFace2, *eIt2, face2 ); if ( !nextFace1.IsNull() && !nextFace2.IsNull() ) { + if ( SMESH_MesherHelper::GetSubShapeOri( nextFace1, *eIt1 ) == eIt1->Orientation() ) + nextFace1.Reverse(); + if ( SMESH_MesherHelper::GetSubShapeOri( nextFace2, *eIt2 ) == eIt2->Orientation() ) + nextFace2.Reverse(); FE1.push_back( make_pair( nextFace1, *eIt1 )); FE2.push_back( make_pair( nextFace2, *eIt2 )); } @@ -1170,11 +1174,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the if ( !VV1[1].IsNull() ) { InsertAssociation( VV1[0], VV2[0], theMap ); InsertAssociation( VV1[1], VV2[1], theMap ); + TShapeShapeMap::EAssocType asType = theMap._assocType; + theMap.SetAssocType( TShapeShapeMap::PROPAGATION ); if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) - { - theMap.SetAssocType( TShapeShapeMap::PROPAGATION ); return true; - } + theMap._assocType = asType; } } break; // try by vertex closeness @@ -1230,11 +1234,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the { InsertAssociation( VV1[0], VV1[0], theMap ); InsertAssociation( VV1[1], VV1[1], theMap ); - if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) - { - theMap.SetAssocType( TShapeShapeMap::COMMON_VERTEX ); + TShapeShapeMap::EAssocType asType = theMap._assocType; + theMap.SetAssocType( TShapeShapeMap::COMMON_VERTEX ); + if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) return true; - } + theMap._assocType = asType; } } } @@ -1593,20 +1597,21 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, // reverse edges2 if needed if ( SMESH_MesherHelper::IsClosedEdge( *edge1Beg )) { - double f,l; - Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( *edge1Beg, face1,f,l ); - if ( edge1Beg->Orientation() == TopAbs_REVERSED ) - std::swap( f,l ); - gp_Pnt2d uv1 = dUV + c1->Value( f * 0.8 + l * 0.2 ).XY(); - - Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( *edge2Beg, face2,f,l ); - if ( edge2Beg->Orientation() == TopAbs_REVERSED ) - std::swap( f,l ); - gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 ); - gp_Pnt2d uv3 = c2->Value( l * 0.8 + f * 0.2 ); - - if ( uv1.SquareDistance( uv2 ) > uv1.SquareDistance( uv3 )) - edge2Beg->Reverse(); + // Commented (so far?) as it's not checked if orientation must be same or reversed + // double f,l; + // Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( *edge1Beg, face1,f,l ); + // if ( edge1Beg->Orientation() == TopAbs_REVERSED ) + // std::swap( f,l ); + // gp_Pnt2d uv1 = dUV + c1->Value( f * 0.8 + l * 0.2 ).XY(); + + // Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( *edge2Beg, face2,f,l ); + // if ( edge2Beg->Orientation() == TopAbs_REVERSED ) + // std::swap( f,l ); + // gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 ); + // gp_Pnt2d uv3 = c2->Value( l * 0.8 + f * 0.2 ); + + // if ( uv1.SquareDistance( uv2 ) > uv1.SquareDistance( uv3 )) + // edge2Beg->Reverse(); } else { diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index bde99cd86..2db02b2ce 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -427,15 +427,44 @@ namespace { // get ordered src EDGEs TError err; srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err); - if ( err && !err->IsOK() ) + if ( err && !err->IsOK() || srcWires.empty() ) return err; + SMESH_MesherHelper srcHelper( *srcMesh ); + srcHelper.SetSubShape( srcFace ); + // make corresponding sequence of tgt EDGEs tgtWires.resize( srcWires.size() ); for ( size_t iW = 0; iW < srcWires.size(); ++iW ) { - list< TopoDS_Edge > tgtEdges; + // check ori + bool reverse = false; StdMeshers_FaceSidePtr srcWire = srcWires[iW]; + // for ( int iE = 0; iE < srcWire->NbEdges(); ++iE ) + // { + // if ( srcHelper.IsRealSeam( srcWire->EdgeID( iE ))) + // continue; + // TopoDS_Shape srcE = srcWire->Edge( iE ); + // TopoDS_Shape tgtE = shape2ShapeMap( srcE, /*isSrc=*/true); + // if ( shape2ShapeMap._assocType == TShapeShapeMap::PROPAGATION || + // shape2ShapeMap._assocType == TShapeShapeMap::PROPAGATION) + // { + // reverse = false; + // } + // else if ( tgtMesh == srcMesh ) + // { + // reverse = (( srcE.Orientation() == srcHelper.GetSubShapeOri( srcFace, srcE )) != + // ( tgtE.Orientation() == srcHelper.GetSubShapeOri( tgtFace, tgtE ))); + // } + // else + // { + // TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false ); + // reverse = ( srcE.Orientation() != srcEbis.Orientation() ); + // } + // break; + // } + + list< TopoDS_Edge > tgtEdges; TopTools_IndexedMapOfShape edgeMap; // to detect seam edges for ( int iE = 0; iE < srcWire->NbEdges(); ++iE ) { @@ -443,6 +472,7 @@ namespace { TopoDS_Edge tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true)); TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false ); if ( srcE.Orientation() != srcEbis.Orientation() ) + //if ( reverse ) tgtE.Reverse(); // reverse a seam edge encountered for the second time const int index = edgeMap.Add( tgtE ); @@ -999,6 +1029,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& srcMesh = tgtMesh; SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); + SMESH_MesherHelper helper( theMesh ); // --------------------------- // Make sub-shapes association @@ -1015,8 +1046,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& { if ( srcShape.ShapeType() == TopAbs_FACE ) { - int nbE1 = SMESH_MesherHelper::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true ); - int nbE2 = SMESH_MesherHelper::Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true ); + int nbE1 = helper.Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true ); + int nbE2 = helper.Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true ); if ( nbE1 != nbE2 ) return error(COMPERR_BAD_SHAPE, SMESH_Comment("Different number of edges in source and target faces: ") @@ -1026,6 +1057,23 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& } TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD)); + // orient faces + // if ( srcMesh == tgtMesh ) + // { + // TopoDS_Shape solid = + // helper.GetCommonAncestor( srcFace, tgtFace, *tgtMesh, TopAbs_SOLID ); + // if ( !solid.IsNull() ) + // { + // srcFace.Orientation( helper.GetSubShapeOri( solid, srcFace )); + // tgtFace.Orientation( helper.GetSubShapeOri( solid, tgtFace )); + // } + // else if ( helper.NbAncestors( srcFace, *tgtMesh, TopAbs_SOLID ) == 1 && + // helper.NbAncestors( tgtFace, *tgtMesh, TopAbs_SOLID ) == 1 ) + // { + // srcFace.Orientation( helper.GetSubShapeOri( tgtMesh->GetShapeToMesh(), srcFace )); + // tgtFace.Orientation( helper.GetSubShapeOri( tgtMesh->GetShapeToMesh(), tgtFace )); + // } + // } // ---------------------------------------------- // Assure that mesh on a source Face is computed // ---------------------------------------------- @@ -1072,7 +1120,6 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& shape2ShapeMap, _src2tgtNodes, is1DComputed); } - SMESH_MesherHelper helper( theMesh ); helper.SetSubShape( tgtFace ); // it will remove mesh built on edges and vertices in failure case @@ -1308,8 +1355,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& u2nodesOnSeam.size() > 0 && seam.ShapeType() == TopAbs_EDGE ) { - int nbE1 = SMESH_MesherHelper::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true ); - int nbE2 = SMESH_MesherHelper::Count( srcFace, TopAbs_EDGE, /*ignoreSame=*/true ); + int nbE1 = helper.Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true ); + int nbE2 = helper.Count( srcFace, TopAbs_EDGE, /*ignoreSame=*/true ); if ( nbE1 != nbE2 ) // 2 EDGEs are mapped to a seam EDGE { // find the 2 EDGEs of srcFace diff --git a/src/StdMeshers/StdMeshers_Projection_3D.cxx b/src/StdMeshers/StdMeshers_Projection_3D.cxx index e6a76eddc..1dc3ace8d 100644 --- a/src/StdMeshers/StdMeshers_Projection_3D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_3D.cxx @@ -541,3 +541,39 @@ void StdMeshers_Projection_3D::SetEventListener(SMESH_subMesh* subMesh) _sourceHypo->GetSourceMesh() ); } +//================================================================================ +/*! + * \brief Return true if the algorithm can mesh this shape + * \param [in] aShape - shape to check + * \param [in] toCheckAll - if true, this check returns OK if all shapes are OK, + * else, returns OK if at least one shape is OK + */ +//================================================================================ + +bool StdMeshers_Projection_3D::IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll) +{ + TopExp_Explorer exp0( aShape, TopAbs_SOLID ); + if ( !exp0.More() ) return false; + + TopTools_IndexedMapOfOrientedShape blockShapes; + TopoDS_Vertex v; + TopoDS_Shell shell; + for ( ; exp0.More(); exp0.Next() ) + { + int nbFoundShells = 0; + TopExp_Explorer exp1( exp0.Current(), TopAbs_SHELL ); + for ( ; exp1.More(); exp1.Next(), ++nbFoundShells ) + { + shell = TopoDS::Shell( exp1.Current() ); + if ( nbFoundShells == 2 ) break; + } + if ( nbFoundShells != 1 ) { + if ( toCheckAll ) return false; + continue; + } + bool isBlock = SMESH_Block::FindBlockShapes( shell, v, v, blockShapes ); + if ( toCheckAll && !isBlock ) return false; + if ( !toCheckAll && isBlock ) return true; + } + return toCheckAll; +} diff --git a/src/StdMeshers/StdMeshers_Projection_3D.hxx b/src/StdMeshers/StdMeshers_Projection_3D.hxx index e0895badf..27e177348 100644 --- a/src/StdMeshers/StdMeshers_Projection_3D.hxx +++ b/src/StdMeshers/StdMeshers_Projection_3D.hxx @@ -57,7 +57,9 @@ public: */ virtual void SetEventListener(SMESH_subMesh* whenSetToSubMesh); -protected: + static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll); + + protected: const StdMeshers_ProjectionSource3D* _sourceHypo; diff --git a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx index cfb80164e..0d86a141a 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx @@ -223,6 +223,7 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame() lay->setStretchFactor( GroupC1, 1); lay->setStretchFactor( myReversedEdgesBox, 1); + myReversedEdgesHelper = 0; if ( !aGeomEntry.isEmpty() || !aMainEntry.isEmpty() ) { myReversedEdgesHelper = new StdMeshersGUI_PropagationHelperWdg( myDirectionWidget, fr, false ); diff --git a/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx index 4f7a92412..dfe12adfd 100644 --- a/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx @@ -66,6 +66,17 @@ StdMeshers_Projection_3D_i::~StdMeshers_Projection_3D_i() return ( ::StdMeshers_Projection_3D* )myBaseImpl; } +//================================================================================ +/*! + * \brief Return true if the algorithm is applicable to a shape + */ +//================================================================================ + +CORBA::Boolean StdMeshers_Projection_3D_i::IsApplicable(const TopoDS_Shape &S, + CORBA::Boolean toCheckAll) +{ + return ::StdMeshers_Projection_3D::IsApplicable( S, toCheckAll ); +} //============================================================================= /*! diff --git a/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx b/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx index 58413c102..f2b65aab2 100644 --- a/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx @@ -37,6 +37,7 @@ #include "StdMeshers_Projection_3D.hxx" class SMESH_Gen; +class TopoDS_Shape; // ====================================================== // Projection 3D algorithm @@ -57,6 +58,9 @@ public: // Get implementation ::StdMeshers_Projection_3D* GetImpl(); + + // Return true if the algorithm is applicable to a shape + static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll); }; // ====================================================== diff --git a/src/StdMeshers_I/StdMeshers_i.cxx b/src/StdMeshers_I/StdMeshers_i.cxx index f794db25f..c7ae1a76a 100644 --- a/src/StdMeshers_I/StdMeshers_i.cxx +++ b/src/StdMeshers_I/StdMeshers_i.cxx @@ -225,7 +225,7 @@ STDMESHERS_I_EXPORT else if (strcmp(aHypName, "Projection_2D") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Projection_3D") == 0) - aCreator = new StdHypothesisCreator_i; + aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "Prism_3D") == 0) aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "RadialPrism_3D") == 0)