#16609: EDF - mesh computation : strange behavior

Fix pattern mapping to a face with hole

+
1) Optimize ElementsOnShape::Classifier::Init()
2) Optimize SMDS_VtkCellIterator (replace vtkIdList by std::vector)
3) Prevent SIGSEGV upon Compute() after base mesh removal
This commit is contained in:
eap 2019-03-15 21:29:39 +03:00
parent dce0afd0a6
commit 63d5619b14
5 changed files with 65 additions and 58 deletions

View File

@ -4642,17 +4642,15 @@ void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape,
else else
{ {
Bnd_Box box; Bnd_Box box;
BRepBndLib::Add( myShape, box );
if ( myShape.ShapeType() == TopAbs_FACE ) if ( myShape.ShapeType() == TopAbs_FACE )
{ {
BRepAdaptor_Surface SA( TopoDS::Face( myShape ), /*useBoundaries=*/false ); BRepAdaptor_Surface SA( TopoDS::Face( myShape ), /*useBoundaries=*/false );
if ( SA.GetType() == GeomAbs_BSplineSurface ) if ( SA.GetType() == GeomAbs_BSplineSurface )
{
box.SetVoid();
BRepBndLib::AddOptimal( myShape, box, BRepBndLib::AddOptimal( myShape, box,
/*useTriangulation=*/true, /*useShapeTolerance=*/true ); /*useTriangulation=*/true, /*useShapeTolerance=*/true );
}
} }
if ( box.IsVoid() )
BRepBndLib::Add( myShape, box );
myBox.Clear(); myBox.Clear();
myBox.Add( box.CornerMin() ); myBox.Add( box.CornerMin() );
myBox.Add( box.CornerMax() ); myBox.Add( box.CornerMax() );

View File

@ -23,37 +23,37 @@
#include <vtkCell.h> #include <vtkCell.h>
#include <vtkIdList.h> #include <vtkIdList.h>
_GetVtkNodes::_GetVtkNodes( vtkIdList* _vtkIdList, _GetVtkNodes::_GetVtkNodes( TVtkIdList& vtkIds,
SMDS_Mesh* mesh, SMDS_Mesh* mesh,
int vtkCellId, int vtkCellId,
SMDSAbs_EntityType aType ) SMDSAbs_EntityType type )
{ {
vtkUnstructuredGrid* grid = mesh->GetGrid(); vtkUnstructuredGrid* grid = mesh->GetGrid();
const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( aType ); const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( type );
vtkIdType npts, *pts;
grid->GetCellPoints( vtkCellId, npts, pts );
vtkIds.resize( npts );
if ( interlace.empty() ) if ( interlace.empty() )
{ {
grid->GetCellPoints( vtkCellId, _vtkIdList ); vtkIds.assign( pts, pts + npts );
} }
else else
{ {
vtkIdType npts, *pts; for (vtkIdType i = 0; i < npts; i++)
grid->GetCellPoints( vtkCellId, npts, pts ); vtkIds[ i ] = pts[ interlace[i] ];
_vtkIdList->SetNumberOfIds( npts );
for (int i = 0; i < npts; i++)
_vtkIdList->SetId(i, pts[interlace[i]]);
} }
} }
_GetVtkNodesToUNV::_GetVtkNodesToUNV( vtkIdList* _vtkIdList, _GetVtkNodesToUNV::_GetVtkNodesToUNV( TVtkIdList& vtkIds,
SMDS_Mesh* mesh, SMDS_Mesh* mesh,
int vtkCellId, int vtkCellId,
SMDSAbs_EntityType aType ) SMDSAbs_EntityType type )
{ {
vtkIdType * pts, npts;
vtkUnstructuredGrid* grid = mesh->GetGrid(); vtkUnstructuredGrid* grid = mesh->GetGrid();
grid->GetCellPoints( (vtkIdType)vtkCellId, npts, pts ); vtkIdType npts, *pts;
grid->GetCellPoints( vtkCellId, npts, pts );
const int *ids = 0; const int *ids = 0;
switch (aType) switch ( type )
{ {
case SMDSEntity_Quad_Edge: case SMDSEntity_Quad_Edge:
{ {
@ -115,28 +115,27 @@ _GetVtkNodesToUNV::_GetVtkNodesToUNV( vtkIdList* _vtkIdList,
case SMDSEntity_Polyhedra: case SMDSEntity_Polyhedra:
case SMDSEntity_Quad_Polyhedra: case SMDSEntity_Quad_Polyhedra:
default: default:
const std::vector<int>& i = SMDS_MeshCell::interlacedSmdsOrder( aType, npts ); const std::vector<int>& i = SMDS_MeshCell::interlacedSmdsOrder( type, npts );
if ( !i.empty() ) if ( !i.empty() )
ids = & i[0]; ids = & i[0];
} }
_vtkIdList->SetNumberOfIds( npts ); vtkIds.resize( npts );
if ( ids ) if ( ids )
for (int i = 0; i < npts; i++) for (int i = 0; i < npts; i++)
_vtkIdList->SetId(i, pts[ids[i]]); vtkIds[ i ] = pts[ ids[i] ];
else else
for (int i = 0; i < npts; i++) vtkIds.assign( pts, pts + npts );
_vtkIdList->SetId(i, pts[i]);
} }
_GetVtkNodesPolyh::_GetVtkNodesPolyh( vtkIdList* _vtkIdList, _GetVtkNodesPolyh::_GetVtkNodesPolyh( TVtkIdList& vtkIds,
SMDS_Mesh* mesh, SMDS_Mesh* mesh,
int vtkCellId, int vtkCellId,
SMDSAbs_EntityType aType ) SMDSAbs_EntityType type )
{ {
vtkUnstructuredGrid* grid = mesh->GetGrid(); vtkUnstructuredGrid* grid = mesh->GetGrid();
switch (aType) switch ( type )
{ {
case SMDSEntity_Polyhedra: case SMDSEntity_Polyhedra:
{ {
@ -144,20 +143,20 @@ _GetVtkNodesPolyh::_GetVtkNodesPolyh( vtkIdList* _vtkIdList,
vtkIdType* ptIds = 0; vtkIdType* ptIds = 0;
grid->GetFaceStream( vtkCellId, nFaces, ptIds ); grid->GetFaceStream( vtkCellId, nFaces, ptIds );
int id = 0, nbNodesInFaces = 0; int id = 0, nbNodesInFaces = 0;
for (int i = 0; i < nFaces; i++) for ( int i = 0; i < nFaces; i++ )
{ {
int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
nbNodesInFaces += nodesInFace; nbNodesInFaces += nodesInFace;
id += (nodesInFace + 1); id += (nodesInFace + 1);
} }
_vtkIdList->SetNumberOfIds( nbNodesInFaces ); vtkIds.resize( nbNodesInFaces );
id = 0; id = 0;
int n = 0; int n = 0;
for (int i = 0; i < nFaces; i++) for ( int i = 0; i < nFaces; i++ )
{ {
int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
for (int k = 1; k <= nodesInFace; k++) for ( int k = 1; k <= nodesInFace; k++ )
_vtkIdList->SetId(n++, ptIds[id + k]); vtkIds[ n++ ] = ptIds[ id + k ];
id += (nodesInFace + 1); id += (nodesInFace + 1);
} }
break; break;

View File

@ -25,7 +25,8 @@
#include "SMDSAbs_ElementType.hxx" #include "SMDSAbs_ElementType.hxx"
#include <vtkCell.h> #include <vtkCell.h>
#include <vtkIdList.h>
typedef std::vector< vtkIdType > TVtkIdList;
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
/*! /*!
@ -33,15 +34,15 @@
*/ */
struct _GetVtkNodes struct _GetVtkNodes
{ {
_GetVtkNodes( vtkIdList* nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type); _GetVtkNodes( TVtkIdList& nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type);
}; };
struct _GetVtkNodesToUNV struct _GetVtkNodesToUNV
{ {
_GetVtkNodesToUNV( vtkIdList* nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type); _GetVtkNodesToUNV( TVtkIdList& nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type);
}; };
struct _GetVtkNodesPolyh struct _GetVtkNodesPolyh
{ {
_GetVtkNodesPolyh( vtkIdList* nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type); _GetVtkNodesPolyh( TVtkIdList& nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type);
}; };
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
@ -55,20 +56,20 @@ public:
typedef typename SMDS_ITERATOR::value_type result_type; typedef typename SMDS_ITERATOR::value_type result_type;
SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType)
: _mesh(mesh), _index(0), _vtkIdList( vtkIdList::New() ) : _mesh(mesh), _index(0)
{ {
GET_VTK_NODES getNodes( _vtkIdList, mesh, vtkCellId, aType ); GET_VTK_NODES getNodes( _vtkIdList, mesh, vtkCellId, aType );
} }
virtual ~SMDS_VtkCellIterator() { _vtkIdList->Delete(); } virtual ~SMDS_VtkCellIterator() {}
virtual bool more() { return ( _index < _vtkIdList->GetNumberOfIds() ); } virtual bool more() { return ( _index < _vtkIdList.size() ); }
virtual result_type next() { virtual result_type next() {
vtkIdType id = _vtkIdList->GetId( _index++ ); vtkIdType id = _vtkIdList[ _index++ ];
return static_cast<result_type>( _mesh->FindNodeVtk( id )); return static_cast<result_type>( _mesh->FindNodeVtk( id ));
} }
protected: protected:
SMDS_Mesh* _mesh; SMDS_Mesh* _mesh;
int _index; size_t _index;
vtkIdList* _vtkIdList; TVtkIdList _vtkIdList;
}; };
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------

View File

@ -81,7 +81,8 @@
using namespace std; using namespace std;
typedef map< const SMDS_MeshElement*, int > TNodePointIDMap; typedef std::map< const SMDS_MeshElement*, int > TNodePointIDMap;
typedef std::list< TopoDS_Edge > TWire;
#define smdsNode( elem ) static_cast<const SMDS_MeshNode*>( elem ) #define smdsNode( elem ) static_cast<const SMDS_MeshNode*>( elem )
@ -2480,20 +2481,21 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace,
// If there are several wires, define the order of edges of inner wires: // If there are several wires, define the order of edges of inner wires:
// compute UV of inner edge-points using 2 methods: the one for in-face points // compute UV of inner edge-points using 2 methods: the one for in-face points
// and the one for on-edge points and then choose the best edge order // and the one for on-edge points and then choose the best edge order
// by the best correspondence of the 2 results // by the best correspondence of the 2 results.
// The wires are sorted by number of edges to correspond to wires of the pattern
if ( nbWires > 1 ) if ( nbWires > 1 )
{ {
// compute UV of inner edge-points using the method for in-face points // compute UV of inner edge-points using the method for in-face points
// and divide eList into a list of separate wires // and divide eList into a list of separate wires
bool aBool; bool aBool;
list< list< TopoDS_Edge > > wireList; list< TWire > wireList;
list<TopoDS_Edge>::iterator eIt = elIt; list<TopoDS_Edge>::iterator eIt = elIt;
list<int>::iterator nbEIt = nbVertexInWires.begin(); list<int>::iterator nbEIt = nbVertexInWires.begin();
for ( nbEIt++; nbEIt != nbVertexInWires.end(); nbEIt++ ) for ( nbEIt++; nbEIt != nbVertexInWires.end(); nbEIt++ )
{ {
int nbEdges = *nbEIt; int nbEdges = *nbEIt;
wireList.push_back( list< TopoDS_Edge >() ); wireList.push_back( list< TopoDS_Edge >() );
list< TopoDS_Edge > & wire = wireList.back(); TWire & wire = wireList.back();
for ( iE = 0 ; iE < nbEdges; eIt++, iE++ ) for ( iE = 0 ; iE < nbEdges; eIt++, iE++ )
{ {
list< TPoint* > & ePoints = getShapePoints( *eIt ); list< TPoint* > & ePoints = getShapePoints( *eIt );
@ -2524,13 +2526,13 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace,
// find points - edge correspondence for wires of unique size, // find points - edge correspondence for wires of unique size,
// edge order within a wire should be defined only // edge order within a wire should be defined only
list< list< TopoDS_Edge > >::iterator wlIt = wireList.begin(); list< TWire >::iterator wlIt = wireList.begin();
while ( wlIt != wireList.end() ) while ( wlIt != wireList.end() )
{ {
list< TopoDS_Edge >& wire = (*wlIt); TWire& wire = (*wlIt);
size_t nbEdges = wire.size(); size_t nbEdges = wire.size();
wlIt++; wlIt++;
if ( wlIt != wireList.end() && (*wlIt).size() != nbEdges ) // a unique size wire if ( wlIt == wireList.end() || (*wlIt).size() != nbEdges ) // a unique size wire
{ {
// choose the best first edge of a wire // choose the best first edge of a wire
setFirstEdge( wire, id1 ); setFirstEdge( wire, id1 );
@ -2546,6 +2548,12 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace,
edgesPoints->insert( edgesPoints->end(), ePoints.begin(), (--ePoints.end())); edgesPoints->insert( edgesPoints->end(), ePoints.begin(), (--ePoints.end()));
} }
} }
else
{
// skip same size wires
while ( wlIt != wireList.end() && (*wlIt).size() == nbEdges )
wlIt++;
}
id1 += nbEdges; id1 += nbEdges;
} }
@ -2556,7 +2564,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace,
while ( wlIt != wireList.end() ) while ( wlIt != wireList.end() )
{ {
size_t nbSameSize = 0, nbEdges = (*wlIt).size(); size_t nbSameSize = 0, nbEdges = (*wlIt).size();
list< list< TopoDS_Edge > >::iterator wlIt2 = wlIt; list< TWire >::iterator wlIt2 = wlIt;
wlIt2++; wlIt2++;
while ( wlIt2 != wireList.end() && (*wlIt2).size() == nbEdges ) { // a same size wire while ( wlIt2 != wireList.end() && (*wlIt2).size() == nbEdges ) { // a same size wire
nbSameSize++; nbSameSize++;
@ -2573,7 +2581,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace,
for ( wlIt = wireList.begin(); wlIt != wireList.end(); wlIt++ ) for ( wlIt = wireList.begin(); wlIt != wireList.end(); wlIt++ )
{ {
list< TopoDS_Edge >& wire = (*wlIt); TWire& wire = (*wlIt);
eList.splice( eList.end(), wire, wire.begin(), wire.end() ); eList.splice( eList.end(), wire, wire.begin(), wire.end() );
} }
@ -4930,12 +4938,12 @@ void SMESH_Pattern::DumpPoints() const
SMESH_Pattern::TPoint::TPoint() SMESH_Pattern::TPoint::TPoint()
{ {
#ifdef _DEBUG_ #ifdef _DEBUG_
myInitXYZ.SetCoord(0,0,0); myInitXYZ.SetCoord(7,7,7);
myInitUV.SetCoord(0.,0.); myInitUV.SetCoord(7.,7.);
myInitU = 0; myInitU = 7;
myXYZ.SetCoord(0,0,0); myXYZ.SetCoord(7,7,7);
myUV.SetCoord(0.,0.); myUV.SetCoord(7.,7.);
myU = 0; myU = 7;
#endif #endif
} }

View File

@ -2452,7 +2452,8 @@ void SMESH_subMesh::loadDependentMeshes()
{ {
list< OwnListenerData >::iterator d; list< OwnListenerData >::iterator d;
for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d ) for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
if ( _father != d->mySubMesh->_father ) if ( _father != d->mySubMesh->_father &&
_father->FindMesh( d->myMeshID ))
d->mySubMesh->_father->Load(); d->mySubMesh->_father->Load();
// map< EventListener*, EventListenerData* >::iterator l_d = _eventListeners.begin(); // map< EventListener*, EventListenerData* >::iterator l_d = _eventListeners.begin();