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
This commit is contained in:
eap 2015-04-07 20:39:18 +03:00
parent 627b77ffd2
commit 80e28740d3
11 changed files with 142 additions and 32 deletions

View File

@ -5140,8 +5140,7 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType,
if (aCreator) if (aCreator)
{ {
TopoDS_Shape shape = GeomObjectToShape( theGeomObject ); TopoDS_Shape shape = GeomObjectToShape( theGeomObject );
if ( !shape.IsNull() ) return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll );
return aCreator->IsApplicable( shape, toCheckAll );
} }
else else
{ {
@ -5149,6 +5148,10 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType,
} }
SMESH_CATCH( SMESH::doNothing ); SMESH_CATCH( SMESH::doNothing );
#ifdef _DEBUG_
cout << "SMESH_Gen_i::IsApplicable(): exception in " << ( theAlgoType ? theAlgoType : "") << endl;
#endif
return true; return true;
} }

View File

@ -55,7 +55,8 @@ public:
MapShapeNbElems& aResMap); MapShapeNbElems& aResMap);
static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll); static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
protected:
protected:
const StdMeshers_ViscousLayers* _viscousLayersHyp; const StdMeshers_ViscousLayers* _viscousLayersHyp;
}; };

View File

@ -2549,7 +2549,7 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable()
for ( iE = 0; iE < *nbE; ++e, ++iE ) for ( iE = 0; iE < *nbE; ++e, ++iE )
if ( SMESH_Algo::isDegenerated( *e )) if ( SMESH_Algo::isDegenerated( *e ))
{ {
ee.erase( e ); e = --ee.erase( e );
--(*nbE); --(*nbE);
--iE; --iE;
} }

View File

@ -756,6 +756,10 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
TopoDS_Face nextFace1 = GetNextFace( edgeToFace1, *eIt1, face1 ); TopoDS_Face nextFace1 = GetNextFace( edgeToFace1, *eIt1, face1 );
TopoDS_Face nextFace2 = GetNextFace( edgeToFace2, *eIt2, face2 ); TopoDS_Face nextFace2 = GetNextFace( edgeToFace2, *eIt2, face2 );
if ( !nextFace1.IsNull() && !nextFace2.IsNull() ) { 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 )); FE1.push_back( make_pair( nextFace1, *eIt1 ));
FE2.push_back( make_pair( nextFace2, *eIt2 )); FE2.push_back( make_pair( nextFace2, *eIt2 ));
} }
@ -1170,11 +1174,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
if ( !VV1[1].IsNull() ) { if ( !VV1[1].IsNull() ) {
InsertAssociation( VV1[0], VV2[0], theMap ); InsertAssociation( VV1[0], VV2[0], theMap );
InsertAssociation( VV1[1], VV2[1], theMap ); InsertAssociation( VV1[1], VV2[1], theMap );
TShapeShapeMap::EAssocType asType = theMap._assocType;
theMap.SetAssocType( TShapeShapeMap::PROPAGATION );
if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
{
theMap.SetAssocType( TShapeShapeMap::PROPAGATION );
return true; return true;
} theMap._assocType = asType;
} }
} }
break; // try by vertex closeness 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[0], VV1[0], theMap );
InsertAssociation( VV1[1], VV1[1], theMap ); InsertAssociation( VV1[1], VV1[1], theMap );
if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) TShapeShapeMap::EAssocType asType = theMap._assocType;
{ theMap.SetAssocType( TShapeShapeMap::COMMON_VERTEX );
theMap.SetAssocType( TShapeShapeMap::COMMON_VERTEX ); if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
return true; return true;
} theMap._assocType = asType;
} }
} }
} }
@ -1593,20 +1597,21 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1,
// reverse edges2 if needed // reverse edges2 if needed
if ( SMESH_MesherHelper::IsClosedEdge( *edge1Beg )) if ( SMESH_MesherHelper::IsClosedEdge( *edge1Beg ))
{ {
double f,l; // Commented (so far?) as it's not checked if orientation must be same or reversed
Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( *edge1Beg, face1,f,l ); // double f,l;
if ( edge1Beg->Orientation() == TopAbs_REVERSED ) // Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( *edge1Beg, face1,f,l );
std::swap( f,l ); // if ( edge1Beg->Orientation() == TopAbs_REVERSED )
gp_Pnt2d uv1 = dUV + c1->Value( f * 0.8 + l * 0.2 ).XY(); // 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 ); // Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( *edge2Beg, face2,f,l );
if ( edge2Beg->Orientation() == TopAbs_REVERSED ) // if ( edge2Beg->Orientation() == TopAbs_REVERSED )
std::swap( f,l ); // std::swap( f,l );
gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 ); // gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 );
gp_Pnt2d uv3 = c2->Value( l * 0.8 + f * 0.2 ); // gp_Pnt2d uv3 = c2->Value( l * 0.8 + f * 0.2 );
if ( uv1.SquareDistance( uv2 ) > uv1.SquareDistance( uv3 )) // if ( uv1.SquareDistance( uv2 ) > uv1.SquareDistance( uv3 ))
edge2Beg->Reverse(); // edge2Beg->Reverse();
} }
else else
{ {

View File

@ -427,15 +427,44 @@ namespace {
// get ordered src EDGEs // get ordered src EDGEs
TError err; TError err;
srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err); srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err);
if ( err && !err->IsOK() ) if ( err && !err->IsOK() || srcWires.empty() )
return err; return err;
SMESH_MesherHelper srcHelper( *srcMesh );
srcHelper.SetSubShape( srcFace );
// make corresponding sequence of tgt EDGEs // make corresponding sequence of tgt EDGEs
tgtWires.resize( srcWires.size() ); tgtWires.resize( srcWires.size() );
for ( size_t iW = 0; iW < srcWires.size(); ++iW ) for ( size_t iW = 0; iW < srcWires.size(); ++iW )
{ {
list< TopoDS_Edge > tgtEdges; // check ori
bool reverse = false;
StdMeshers_FaceSidePtr srcWire = srcWires[iW]; 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 TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
for ( int iE = 0; iE < srcWire->NbEdges(); ++iE ) for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
{ {
@ -443,6 +472,7 @@ namespace {
TopoDS_Edge tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true)); TopoDS_Edge tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true));
TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false ); TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false );
if ( srcE.Orientation() != srcEbis.Orientation() ) if ( srcE.Orientation() != srcEbis.Orientation() )
//if ( reverse )
tgtE.Reverse(); tgtE.Reverse();
// reverse a seam edge encountered for the second time // reverse a seam edge encountered for the second time
const int index = edgeMap.Add( tgtE ); const int index = edgeMap.Add( tgtE );
@ -999,6 +1029,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
srcMesh = tgtMesh; srcMesh = tgtMesh;
SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
SMESH_MesherHelper helper( theMesh );
// --------------------------- // ---------------------------
// Make sub-shapes association // Make sub-shapes association
@ -1015,8 +1046,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
{ {
if ( srcShape.ShapeType() == TopAbs_FACE ) if ( srcShape.ShapeType() == TopAbs_FACE )
{ {
int nbE1 = SMESH_MesherHelper::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true ); int nbE1 = helper.Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
int nbE2 = SMESH_MesherHelper::Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true ); int nbE2 = helper.Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true );
if ( nbE1 != nbE2 ) if ( nbE1 != nbE2 )
return error(COMPERR_BAD_SHAPE, return error(COMPERR_BAD_SHAPE,
SMESH_Comment("Different number of edges in source and target faces: ") 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)); 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 // 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); shape2ShapeMap, _src2tgtNodes, is1DComputed);
} }
SMESH_MesherHelper helper( theMesh );
helper.SetSubShape( tgtFace ); helper.SetSubShape( tgtFace );
// it will remove mesh built on edges and vertices in failure case // 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 && u2nodesOnSeam.size() > 0 &&
seam.ShapeType() == TopAbs_EDGE ) seam.ShapeType() == TopAbs_EDGE )
{ {
int nbE1 = SMESH_MesherHelper::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true ); int nbE1 = helper.Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
int nbE2 = SMESH_MesherHelper::Count( srcFace, TopAbs_EDGE, /*ignoreSame=*/true ); int nbE2 = helper.Count( srcFace, TopAbs_EDGE, /*ignoreSame=*/true );
if ( nbE1 != nbE2 ) // 2 EDGEs are mapped to a seam EDGE if ( nbE1 != nbE2 ) // 2 EDGEs are mapped to a seam EDGE
{ {
// find the 2 EDGEs of srcFace // find the 2 EDGEs of srcFace

View File

@ -541,3 +541,39 @@ void StdMeshers_Projection_3D::SetEventListener(SMESH_subMesh* subMesh)
_sourceHypo->GetSourceMesh() ); _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;
}

View File

@ -57,7 +57,9 @@ public:
*/ */
virtual void SetEventListener(SMESH_subMesh* whenSetToSubMesh); virtual void SetEventListener(SMESH_subMesh* whenSetToSubMesh);
protected: static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
protected:
const StdMeshers_ProjectionSource3D* _sourceHypo; const StdMeshers_ProjectionSource3D* _sourceHypo;

View File

@ -223,6 +223,7 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
lay->setStretchFactor( GroupC1, 1); lay->setStretchFactor( GroupC1, 1);
lay->setStretchFactor( myReversedEdgesBox, 1); lay->setStretchFactor( myReversedEdgesBox, 1);
myReversedEdgesHelper = 0;
if ( !aGeomEntry.isEmpty() || !aMainEntry.isEmpty() ) if ( !aGeomEntry.isEmpty() || !aMainEntry.isEmpty() )
{ {
myReversedEdgesHelper = new StdMeshersGUI_PropagationHelperWdg( myDirectionWidget, fr, false ); myReversedEdgesHelper = new StdMeshersGUI_PropagationHelperWdg( myDirectionWidget, fr, false );

View File

@ -66,6 +66,17 @@ StdMeshers_Projection_3D_i::~StdMeshers_Projection_3D_i()
return ( ::StdMeshers_Projection_3D* )myBaseImpl; 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 );
}
//============================================================================= //=============================================================================
/*! /*!

View File

@ -37,6 +37,7 @@
#include "StdMeshers_Projection_3D.hxx" #include "StdMeshers_Projection_3D.hxx"
class SMESH_Gen; class SMESH_Gen;
class TopoDS_Shape;
// ====================================================== // ======================================================
// Projection 3D algorithm // Projection 3D algorithm
@ -57,6 +58,9 @@ public:
// Get implementation // Get implementation
::StdMeshers_Projection_3D* GetImpl(); ::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);
}; };
// ====================================================== // ======================================================

View File

@ -225,7 +225,7 @@ STDMESHERS_I_EXPORT
else if (strcmp(aHypName, "Projection_2D") == 0) else if (strcmp(aHypName, "Projection_2D") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_2D_i>; aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_2D_i>;
else if (strcmp(aHypName, "Projection_3D") == 0) else if (strcmp(aHypName, "Projection_3D") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_3D_i, StdMeshers_Hexa_3D_i>; aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_3D_i, StdMeshers_Projection_3D_i>;
else if (strcmp(aHypName, "Prism_3D") == 0) else if (strcmp(aHypName, "Prism_3D") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_Prism_3D_i, StdMeshers_Prism_3D_i>; aCreator = new StdHypothesisCreator_i<StdMeshers_Prism_3D_i, StdMeshers_Prism_3D_i>;
else if (strcmp(aHypName, "RadialPrism_3D") == 0) else if (strcmp(aHypName, "RadialPrism_3D") == 0)