Salome HOME
#16609: EDF - mesh computation : strange behavior
authoreap <eap@opencascade.com>
Fri, 15 Mar 2019 18:29:39 +0000 (21:29 +0300)
committereap <eap@opencascade.com>
Fri, 15 Mar 2019 18:29:39 +0000 (21:29 +0300)
 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

src/Controls/SMESH_Controls.cxx
src/SMDS/SMDS_VtkCellIterator.cxx
src/SMDS/SMDS_VtkCellIterator.hxx
src/SMESH/SMESH_Pattern.cxx
src/SMESH/SMESH_subMesh.cxx

index a6fa8ee..c40f590 100644 (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() );
index 5557041..5c6aec3 100644 (file)
 #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;
index 2a974a4..01bd72c 100644 (file)
@@ -25,7 +25,8 @@
 #include "SMDSAbs_ElementType.hxx"
 
 #include <vtkCell.h>
-#include <vtkIdList.h>
+
+typedef std::vector< vtkIdType > TVtkIdList;
 
 //--------------------------------------------------------------------------------
 /*!
  */
 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;
 };
 
 //--------------------------------------------------------------------------------
index 182a67c..c1694cb 100644 (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
 }
 
index 4efa35d..ecbfde4 100644 (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();