Salome HOME
Fix other crashs with attractors in other out of bounds cases
authorChristophe Bourcier <christophe.bourcier@cea.fr>
Fri, 1 Sep 2017 07:34:44 +0000 (09:34 +0200)
committerChristophe Bourcier <christophe.bourcier@cea.fr>
Fri, 1 Sep 2017 07:34:44 +0000 (09:34 +0200)
src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx
src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx
tests/attractor_edge_on_border.py [new file with mode: 0644]
tests/attractor_point_outside_face.py [new file with mode: 0644]
tests/tests.set

index d06617b1cdfc808b02a37eb417b486c14493ebc9..c8f821a21452b0eef9d2c3c428e91d23e31f80bb 100644 (file)
@@ -174,6 +174,19 @@ bool BLSURFPlugin_Attractor::init(){
   return true;
 }
 
+// check that i and j are inside the bounds of the grid to avoid out of bounds errors
+// in affectation of the grid's vectors
+void BLSURFPlugin_Attractor::avoidOutOfBounds(int& i, int& j){
+  if (i > _gridU)
+    i = _gridU;
+  if (i < 0)
+    i = 0;
+  if (j > _gridV)
+    j = _gridV;
+  if (j < 0)
+    j = 0;
+}
+
 void BLSURFPlugin_Attractor::edgeInit(Handle(Geom_Surface) theSurf, const TopoDS_Edge& anEdge){
   gp_Pnt2d P2;
   double first;
@@ -189,12 +202,16 @@ void BLSURFPlugin_Attractor::edgeInit(Handle(Geom_Surface) theSurf, const TopoDS
 #else
   curveProjector.PerformAdvanced (aCurve3d, first, last, aCurve2d);
 #endif
-  
+
   int N = 1200;
   for (i=0; i<=N; i++){
     P2 = aCurve2d->Value(first + i * (last-first) / N);
     i0 = floor( (P2.X() - _u1) * _gridU / (_u2 - _u1) + 0.5 );
     j0 = floor( (P2.Y() - _v1) * _gridV / (_v2 - _v1) + 0.5 );
+
+    // Avoid out of bounds errors when the ends of the edge are outside the face
+    avoidOutOfBounds(i0, j0);
+
     TPnt[0] = 0.;
     TPnt[1] = i0;
     TPnt[2] = j0;
@@ -222,18 +239,8 @@ double BLSURFPlugin_Attractor::_distanceFromMap(double u, double v){
   int i = floor ( (u - _u1) * _gridU / (_u2 - _u1) + 0.5 );
   int j = floor ( (v - _v1) * _gridV / (_v2 - _v1) + 0.5 );
   
-  // avoid out of bounds of _DMap
-  if (i > _DMap.size())
-    i = _DMap.size()-1;
-
-  if (i < 0)
-    i = 0;
-
-  if (j > _DMap[i].size())
-    j = _DMap[i].size()-1;
-
-  if (j < 0)
-    j = 0;
+  // Avoid out of bounds errors in _DMap
+  avoidOutOfBounds(i, j);
 
   return _DMap[i][j];
 }
@@ -284,15 +291,17 @@ void BLSURFPlugin_Attractor::BuildMap() {
   TTrialSet::iterator min;
   TTrialSet::iterator found;
   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(_face);
-  
+
   // While there are points in "Trial" (representing a kind of advancing front), loop on them -----------------------------------------------------------
   while (_trial.size() > 0 ) {
     min = _trial.begin();                        // Get trial point with min distance from start
     i0 = (*min)[1];
     j0 = (*min)[2];
+    // Avoid out of bounds errors in _known affectations
+    avoidOutOfBounds(i0, j0);
     _known[i0][j0] = true;                       // Move it to "Known"
     _trial.erase(min);                           // Remove it from "Trial"
-    
+
     // Loop on neighbours of the trial min --------------------------------------------------------------------------------------------------------------
     for (i=i0 - 1 ; i <= i0 + 1 ; i++){ 
       if (!aSurf->IsUPeriodic()){                          // Periodic conditions in U  
@@ -303,7 +312,7 @@ void BLSURFPlugin_Attractor::BuildMap() {
       }
       ip = (i + _gridU + 1) % (_gridU+1);                  // We get a periodic index :
       for (j=j0 - 1 ; j <= j0 + 1 ; j++){                  //    ip=modulo(i,N+2) so that  i=-1->ip=N; i=0 -> ip=0 ; ... ; i=N+1 -> ip=0;  
-        if (!aSurf->IsVPeriodic()){                        // Periodic conditions in V . 
+          if (!aSurf->IsVPeriodic()){                        // Periodic conditions in V .
           if (j > _gridV ){
             break; }
           else if (j < 0){
index b3ef69a21eb0b7ff1a6cba977d79fe7bb43df205..1f5d8b64c91e5522c0997ffa75f001ccfb57b333 100644 (file)
@@ -88,6 +88,7 @@ class BLSURFPlugin_Attractor {
     
     bool init();                                                // Calculates the discrete points correponding to attractor 
                                                                 // and intialises the map of distances
+    void avoidOutOfBounds(int& i, int&j);
     void edgeInit(Handle(Geom_Surface) aSurf, const TopoDS_Edge& anEdge);
     
     double              GetSize (double u, double v);
diff --git a/tests/attractor_edge_on_border.py b/tests/attractor_edge_on_border.py
new file mode 100644 (file)
index 0000000..c10597c
--- /dev/null
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+
+import sys
+import salome
+
+salome.salome_init()
+theStudy = salome.myStudy
+
+import  SMESH, SALOMEDS
+
+## Compute the minimum area of the faces of the mesh
+def getMinArea(mesh):
+  faces = mesh.GetElementsByType(SMESH.FACE)
+  areas = [mesh.GetArea(face) for face in faces]
+  return min(areas)
+
+###
+### GEOM component
+###
+
+import GEOM
+from salome.geom import geomBuilder
+import math
+import SALOMEDS
+
+
+geompy = geomBuilder.New(theStudy)
+
+O = geompy.MakeVertex(0, 0, 0)
+OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
+OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
+OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
+Face_1 = geompy.MakeFaceHW(100, 100, 1)
+Box_1 = geompy.MakePrismVecH(Face_1, OZ, -100)
+# define the edge slightly longer than the face to test out of bounds case.
+P1 = geompy.MakeVertex(-50.5, 0, 0)
+P2 = geompy.MakeVertex(50.5, 0, 0)
+Edge_1 = geompy.MakeEdge(P1, P2)
+geompy.addToStudy( O, 'O' )
+geompy.addToStudy( OX, 'OX' )
+geompy.addToStudy( OY, 'OY' )
+geompy.addToStudy( OZ, 'OZ' )
+geompy.addToStudy( Face_1, 'Face_1' )
+geompy.addToStudy( Box_1, 'Box_1' )
+geompy.addToStudy( Edge_1, 'Edge_1' )
+
+sub_Face_1 = geompy.GetInPlace(Box_1, Face_1)
+geompy.addToStudyInFather(Box_1, sub_Face_1, "Face_1")
+
+###
+### SMESH component
+###
+
+from salome.smesh import smeshBuilder
+
+smesh = smeshBuilder.New(theStudy)
+Mesh_1 = smesh.Mesh(Box_1)
+MG_CADSurf = Mesh_1.Triangle(algo=smeshBuilder.MG_CADSurf)
+MG_CADSurf_Parameters_1 = MG_CADSurf.Parameters()
+MG_CADSurf_Parameters_1.SetPhySize( 14.1421 )
+MG_CADSurf_Parameters_1.SetMinSize( 0.141421 )
+MG_CADSurf_Parameters_1.SetMaxSize( 28.2843 )
+MG_CADSurf_Parameters_1.SetChordalError( 7.07107 )
+#MG_CADSurf_Parameters_1.SetAttractorGeom( sub_Face_1, Edge_1, 1, 14.1421, 5, 5 )
+
+Mesh_1.Compute()
+
+min_area_without_attractor = getMinArea(Mesh_1)
+
+print "min_area_without_attractor: ", min_area_without_attractor
+
+MG_CADSurf_Parameters_1.SetAttractorGeom( sub_Face_1, Edge_1, 1, 14.1421, 5, 5 )
+
+Mesh_1.Compute()
+
+min_area_with_attractor = getMinArea(Mesh_1)
+
+print "min_area_with_attractor: ", min_area_with_attractor
+
+assert min_area_with_attractor < min_area_without_attractor
+
+assert min_area_with_attractor < 1
+
+if salome.sg.hasDesktop():
+  salome.sg.updateObjBrowser(True)
diff --git a/tests/attractor_point_outside_face.py b/tests/attractor_point_outside_face.py
new file mode 100644 (file)
index 0000000..9513ac3
--- /dev/null
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+
+import sys
+import salome
+
+salome.salome_init()
+theStudy = salome.myStudy
+
+import  SMESH, SALOMEDS
+
+## Compute the minimum area of the faces of the mesh
+def getMinArea(mesh):
+  faces = mesh.GetElementsByType(SMESH.FACE)
+  areas = [mesh.GetArea(face) for face in faces]
+  return min(areas)
+
+###
+### GEOM component
+###
+
+import GEOM
+from salome.geom import geomBuilder
+import math
+import SALOMEDS
+
+
+geompy = geomBuilder.New(theStudy)
+
+O = geompy.MakeVertex(0, 0, 0)
+OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
+OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
+OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
+radius = 10
+height = 100
+Cylinder_1 = geompy.MakeCylinderRH(radius, height)
+
+p_half_height = geompy.MakeVertex(0, 0, height/2.)
+plane_z = geompy.MakePlane(p_half_height, OZ, 2.5*radius)
+
+Part_1 = geompy.MakePartition([Cylinder_1], [plane_z], Limit=geompy.ShapeType["FACE"])
+
+
+geompy.addToStudy( O, 'O' )
+geompy.addToStudy( OX, 'OX' )
+geompy.addToStudy( OY, 'OY' )
+geompy.addToStudy( OZ, 'OZ' )
+geompy.addToStudy( Part_1, 'Part_1' )
+
+
+p_edge_vert_opp_1 = geompy.MakeVertex(-radius, 0, 0)
+geompy.addToStudy( p_edge_vert_opp_1, 'p_edge_vert_opp_1' )
+
+edge_vert_opp_1 = geompy.MakePrismVecH(p_edge_vert_opp_1, OZ, height/2.)
+geompy.addToStudy( edge_vert_opp_1, 'edge_vert_opp_1' )
+
+p_edge_vert_opp_2 = geompy.MakeVertex(-radius, 0, height/4.)
+geompy.addToStudy( p_edge_vert_opp_2, 'p_edge_vert_opp_2' )
+
+p_face_cyl_1 = geompy.MakeVertex(0, radius, height/4.)
+p_face_cyl_2 = geompy.MakeVertex(0, radius, 3*height/4.)
+
+face_1 = geompy.GetFaceNearPoint(Part_1, p_face_cyl_1)
+face_2 = geompy.GetFaceNearPoint(Part_1, p_face_cyl_2)
+
+geompy.addToStudyInFather(Part_1, face_1, "face_1")
+geompy.addToStudyInFather(Part_1, face_2, "face_2")
+
+###
+### SMESH component
+###
+
+from salome.smesh import smeshBuilder
+
+smesh = smeshBuilder.New(theStudy)
+Mesh_1 = smesh.Mesh(Part_1)
+MG_CADSurf = Mesh_1.Triangle(algo=smeshBuilder.MG_CADSurf)
+MG_CADSurf_Parameters_1 = MG_CADSurf.Parameters()
+MG_CADSurf_Parameters_1.SetPhySize( 14.1421 )
+MG_CADSurf_Parameters_1.SetMinSize( 0.141421 )
+MG_CADSurf_Parameters_1.SetMaxSize( 28.2843 )
+MG_CADSurf_Parameters_1.SetChordalError( 7.07107 )
+#MG_CADSurf_Parameters_1.SetAttractorGeom( sub_Face_1, Edge_1, 1, 14.1421, 5, 5 )
+
+ok = Mesh_1.Compute()
+
+if not ok:
+  raise Exception("Mesh not computed")
+
+min_area_without_attractor = getMinArea(Mesh_1)
+
+print "min_area_without_attractor: ", min_area_without_attractor
+
+MG_CADSurf_Parameters_1.SetAttractorGeom( face_1, edge_vert_opp_1, 1, 14.1421, 5, 5 )
+# the attractor is not on the face. It is done on purpose to test this out of bounds case.
+MG_CADSurf_Parameters_1.SetAttractorGeom( face_2, p_edge_vert_opp_2, 1, 14.1421, 5, 5 )
+
+ok = Mesh_1.Compute()
+
+if not ok:
+  raise Exception("Mesh with attractors not computed")
+
+min_area_with_attractor = getMinArea(Mesh_1)
+
+print "min_area_with_attractor: ", min_area_with_attractor
+
+assert min_area_with_attractor < min_area_without_attractor
+
+assert min_area_with_attractor < 1
+
+if salome.sg.hasDesktop():
+  salome.sg.updateObjBrowser(True)
index bcc05da6ac109126866be5d35b5ed7c9473f3739..8ece1feb29300ed82237d0e934efce524737119f 100644 (file)
@@ -19,6 +19,8 @@
 
 SET(TEST_NAMES
   attractor
+  attractor_edge_on_border
+  attractor_point_outside_face
   enforced_internal_vertex
   enforced_vertex
   multithread