#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
{
Bnd_Box box;
BRepBndLib::Add( myShape, box );
if ( myShape.ShapeType() == TopAbs_FACE )
{
BRepAdaptor_Surface SA( TopoDS::Face( myShape ), /*useBoundaries=*/false );
if ( SA.GetType() == GeomAbs_BSplineSurface )
{
box.SetVoid();
BRepBndLib::AddOptimal( myShape, box,
/*useTriangulation=*/true, /*useShapeTolerance=*/true );
}
}
if ( box.IsVoid() )
BRepBndLib::Add( myShape, box );
myBox.Clear();
myBox.Add( box.CornerMin() );
myBox.Add( box.CornerMax() );

View File

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

View File

@ -25,7 +25,8 @@
#include "SMDSAbs_ElementType.hxx"
#include <vtkCell.h>
#include <vtkIdList.h>
typedef std::vector< vtkIdType > TVtkIdList;
//--------------------------------------------------------------------------------
/*!
@ -33,15 +34,15 @@
*/
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
{
_GetVtkNodesToUNV( vtkIdList* nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type);
_GetVtkNodesToUNV( TVtkIdList& nodeIds, SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType type);
};
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;
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 );
}
virtual ~SMDS_VtkCellIterator() { _vtkIdList->Delete(); }
virtual bool more() { return ( _index < _vtkIdList->GetNumberOfIds() ); }
virtual ~SMDS_VtkCellIterator() {}
virtual bool more() { return ( _index < _vtkIdList.size() ); }
virtual result_type next() {
vtkIdType id = _vtkIdList->GetId( _index++ );
vtkIdType id = _vtkIdList[ _index++ ];
return static_cast<result_type>( _mesh->FindNodeVtk( id ));
}
protected:
SMDS_Mesh* _mesh;
int _index;
vtkIdList* _vtkIdList;
size_t _index;
TVtkIdList _vtkIdList;
};
//--------------------------------------------------------------------------------

View File

@ -81,7 +81,8 @@
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 )
@ -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:
// 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
// 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 )
{
// compute UV of inner edge-points using the method for in-face points
// and divide eList into a list of separate wires
bool aBool;
list< list< TopoDS_Edge > > wireList;
list< TWire > wireList;
list<TopoDS_Edge>::iterator eIt = elIt;
list<int>::iterator nbEIt = nbVertexInWires.begin();
for ( nbEIt++; nbEIt != nbVertexInWires.end(); nbEIt++ )
{
int nbEdges = *nbEIt;
wireList.push_back( list< TopoDS_Edge >() );
list< TopoDS_Edge > & wire = wireList.back();
TWire & wire = wireList.back();
for ( iE = 0 ; iE < nbEdges; eIt++, iE++ )
{
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,
// 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() )
{
list< TopoDS_Edge >& wire = (*wlIt);
TWire& wire = (*wlIt);
size_t nbEdges = wire.size();
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
setFirstEdge( wire, id1 );
@ -2546,6 +2548,12 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace,
edgesPoints->insert( edgesPoints->end(), ePoints.begin(), (--ePoints.end()));
}
}
else
{
// skip same size wires
while ( wlIt != wireList.end() && (*wlIt).size() == nbEdges )
wlIt++;
}
id1 += nbEdges;
}
@ -2556,7 +2564,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace,
while ( wlIt != wireList.end() )
{
size_t nbSameSize = 0, nbEdges = (*wlIt).size();
list< list< TopoDS_Edge > >::iterator wlIt2 = wlIt;
list< TWire >::iterator wlIt2 = wlIt;
wlIt2++;
while ( wlIt2 != wireList.end() && (*wlIt2).size() == nbEdges ) { // a same size wire
nbSameSize++;
@ -2573,7 +2581,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace,
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() );
}
@ -4930,12 +4938,12 @@ void SMESH_Pattern::DumpPoints() const
SMESH_Pattern::TPoint::TPoint()
{
#ifdef _DEBUG_
myInitXYZ.SetCoord(0,0,0);
myInitUV.SetCoord(0.,0.);
myInitU = 0;
myXYZ.SetCoord(0,0,0);
myUV.SetCoord(0.,0.);
myU = 0;
myInitXYZ.SetCoord(7,7,7);
myInitUV.SetCoord(7.,7.);
myInitU = 7;
myXYZ.SetCoord(7,7,7);
myUV.SetCoord(7.,7.);
myU = 7;
#endif
}

View File

@ -2452,7 +2452,8 @@ void SMESH_subMesh::loadDependentMeshes()
{
list< OwnListenerData >::iterator 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();
// map< EventListener*, EventListenerData* >::iterator l_d = _eventListeners.begin();