From 5664a0b12ca2c67314d0a44259aa565556f5b0b8 Mon Sep 17 00:00:00 2001 From: Christophe Bourcier Date: Fri, 1 Sep 2017 09:34:44 +0200 Subject: [PATCH] Fix other crashs with attractors in other out of bounds cases --- src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx | 41 +++++--- src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx | 1 + tests/attractor_edge_on_border.py | 85 +++++++++++++++ tests/attractor_point_outside_face.py | 111 ++++++++++++++++++++ tests/tests.set | 2 + 5 files changed, 224 insertions(+), 16 deletions(-) create mode 100644 tests/attractor_edge_on_border.py create mode 100644 tests/attractor_point_outside_face.py diff --git a/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx b/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx index d06617b..c8f821a 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx @@ -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){ diff --git a/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx b/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx index b3ef69a..1f5d8b6 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx @@ -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 index 0000000..c10597c --- /dev/null +++ b/tests/attractor_edge_on_border.py @@ -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 index 0000000..9513ac3 --- /dev/null +++ b/tests/attractor_point_outside_face.py @@ -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) diff --git a/tests/tests.set b/tests/tests.set index bcc05da..8ece1fe 100644 --- a/tests/tests.set +++ b/tests/tests.set @@ -19,6 +19,8 @@ SET(TEST_NAMES attractor + attractor_edge_on_border + attractor_point_outside_face enforced_internal_vertex enforced_vertex multithread -- 2.39.2