From fdf08fc57e14f7fad444118bce0fd3d04fad8ab0 Mon Sep 17 00:00:00 2001 From: Marie-Pierre Oudot Date: Fri, 24 Apr 2026 10:54:31 +0200 Subject: [PATCH 1/3] Add test for plane boundaryBox where TopoDS_Shape is neither vertex, edge or surface --- src/Core/Geom/OCCHelper.cpp | 22 ++++++++++++++++++++++ test_link/test_issue262.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 test_link/test_issue262.py diff --git a/src/Core/Geom/OCCHelper.cpp b/src/Core/Geom/OCCHelper.cpp index 1061aeb4..96abe4b2 100644 --- a/src/Core/Geom/OCCHelper.cpp +++ b/src/Core/Geom/OCCHelper.cpp @@ -1004,6 +1004,7 @@ computeBoundingBox(const TopoDS_Shape& shape, gp_Pnt& pmin, gp_Pnt& pmax) { Bnd_Box box; BRepCheck_Analyzer analyzer(shape); + if (analyzer.IsValid()) { BRepBndLib::AddClose(shape, box); } else { @@ -1011,8 +1012,29 @@ computeBoundingBox(const TopoDS_Shape& shape, gp_Pnt& pmin, gp_Pnt& pmax) } if (box.IsVoid()) + { BRepBndLib::Add(shape, box); + } + TopAbs_ShapeEnum type = shape.ShapeType(); + if (type != TopAbs_FACE && type != TopAbs_EDGE && type != TopAbs_VERTEX) + { + // On teste si la box est plane + // Récupérer les coins min et max + gp_Pnt minCorner = box.CornerMin(); + gp_Pnt maxCorner = box.CornerMax(); + + // Calculer les dimensions + double width = maxCorner.X() - minCorner.X(); + double height = maxCorner.Y() - minCorner.Y(); + double depth = maxCorner.Z() - minCorner.Z(); + + // Vérifier si l'une des dimensions est nulle ou quasi-nulle + double tolerance = 1e-7; + if (width < tolerance || height < tolerance || depth < tolerance) { + BRepBndLib::Add(shape, box); + } + } double xmin, ymin, zmin, xmax, ymax, zmax; box.Get(xmin, ymin, zmin, xmax, ymax, zmax); pmin.SetCoord(xmin, ymin, zmin); diff --git a/test_link/test_issue262.py b/test_link/test_issue262.py new file mode 100644 index 00000000..881c1e41 --- /dev/null +++ b/test_link/test_issue262.py @@ -0,0 +1,28 @@ +import pyMagix3D as Mgx3D +import math + +# Issue262 : Le bloc créé oar boite englobante d'un volume peut avoir de mauvaises dimensions +# la création d'un bloc sur une sphère crée un bloc plat + +def assertPoint(tm, name, x, y, z): + p = tm.getCoord(name) + assert math.isclose(p.getX(), x, rel_tol=1e-7) + assert math.isclose(p.getY(), y, rel_tol=1e-7) + assert math.isclose(p.getZ(), z, rel_tol=1e-7) + +def test_issue262(): + ctx = Mgx3D.getStdContext() + ctx.clearSession() # Clean the session after the previous test + gm = ctx.getGeomManager() + tm = ctx.getTopoManager() + # Création du volume Vol0000 + gm.newSphere (Mgx3D.Point(0, 0, 0), 1, Mgx3D.Portion.ENTIER) + # Création d'un bloc topologique structuré sans projection (Vol0000) + tm.newFreeTopoOnGeometry ("Vol0000") + # Annulation de : Création d'un bloc topologique structuré sans projection (Vol0000) + ctx.undo() + # Création d'un bloc unitaire mis dans le groupe AAA + ctx.getTopoManager().newFreeBoundedTopoInGroup ("AAA", 3, ["Vol0000"]) + + assertPoint(tm, "Som0000", -1, -1, -1) + assertPoint(tm, "Som0007", 1, 1, 1) \ No newline at end of file From 261a49ddfd7a54f1ee85e30813241a6ac1612a3b Mon Sep 17 00:00:00 2001 From: Marie-Pierre Oudot Date: Thu, 21 May 2026 14:27:50 +0200 Subject: [PATCH 2/3] Update compute BoundaryBox with addOptimal --- src/Core/Geom/OCCHelper.cpp | 32 +--------- test_link/test_bounding_box.py | 96 +++++++++++++++++++++++++++++ test_link/test_free_bounded_topo.py | 16 ----- test_link/test_issue225.py | 21 ------- test_link/test_issue262.py | 28 --------- test_link/test_law_biexponential.py | 35 +++++------ test_link/test_law_geometric.py | 31 +++++----- test_link/test_law_hyperbolic.py | 31 +++++----- test_link/test_order_join_curves.py | 8 ++- 9 files changed, 147 insertions(+), 151 deletions(-) create mode 100644 test_link/test_bounding_box.py delete mode 100755 test_link/test_free_bounded_topo.py delete mode 100755 test_link/test_issue225.py delete mode 100644 test_link/test_issue262.py diff --git a/src/Core/Geom/OCCHelper.cpp b/src/Core/Geom/OCCHelper.cpp index 96abe4b2..70b1c4a2 100644 --- a/src/Core/Geom/OCCHelper.cpp +++ b/src/Core/Geom/OCCHelper.cpp @@ -1003,38 +1003,8 @@ void OCCHelper:: computeBoundingBox(const TopoDS_Shape& shape, gp_Pnt& pmin, gp_Pnt& pmax) { Bnd_Box box; - BRepCheck_Analyzer analyzer(shape); - if (analyzer.IsValid()) { - BRepBndLib::AddClose(shape, box); - } else { - BRepBndLib::AddOptimal(shape, box); - } - - if (box.IsVoid()) - { - BRepBndLib::Add(shape, box); - } - - TopAbs_ShapeEnum type = shape.ShapeType(); - if (type != TopAbs_FACE && type != TopAbs_EDGE && type != TopAbs_VERTEX) - { - // On teste si la box est plane - // Récupérer les coins min et max - gp_Pnt minCorner = box.CornerMin(); - gp_Pnt maxCorner = box.CornerMax(); - - // Calculer les dimensions - double width = maxCorner.X() - minCorner.X(); - double height = maxCorner.Y() - minCorner.Y(); - double depth = maxCorner.Z() - minCorner.Z(); - - // Vérifier si l'une des dimensions est nulle ou quasi-nulle - double tolerance = 1e-7; - if (width < tolerance || height < tolerance || depth < tolerance) { - BRepBndLib::Add(shape, box); - } - } + BRepBndLib::AddOptimal(shape, box); double xmin, ymin, zmin, xmax, ymax, zmax; box.Get(xmin, ymin, zmin, xmax, ymax, zmax); pmin.SetCoord(xmin, ymin, zmin); diff --git a/test_link/test_bounding_box.py b/test_link/test_bounding_box.py new file mode 100644 index 00000000..6200d3a1 --- /dev/null +++ b/test_link/test_bounding_box.py @@ -0,0 +1,96 @@ +import math +import os +import pyMagix3D as Mgx3D +import pytest + +step_file_name = "mambo/Basic/B18.step" +tol = 1e-7 + +def assertPoint(tm, name, x, y, z): + p = tm.getCoord(name) + assert math.isclose(p.getX(), x, rel_tol=tol) + assert math.isclose(p.getY(), y, rel_tol=tol) + assert math.isclose(p.getZ(), z, rel_tol=tol) + +# Issue 225 : Le bloc créé par boite englobante d'un volume peut avoir de mauvaises dimensions +def test_issue225(capfd): + ctx = Mgx3D.getStdContext() + ctx.clearSession() # Clean the session after the previous test + gm = ctx.getGeomManager() + tm = ctx.getTopoManager () + + magix3d_test_data_dir = os.environ['MAGIX3D_TEST_DATA_DIR'] + full_path = os.path.join(magix3d_test_data_dir, step_file_name) + + ctx.setLengthUnit(Mgx3D.Unit.centimeter) + gm.importSTEP(full_path) + assert gm.getNbVolumes()==1 + tm.newFreeTopoOnGeometry("Vol0000") + assert math.isclose(tm.getEdgeLength("Ar0002"), 0.1, abs_tol=tol) #0.1 + assert math.isclose(tm.getEdgeLength("Ar0007"), 0.1, abs_tol=1e-4) #0.10003610119179525 + assert math.isclose(tm.getEdgeLength("Ar0009"), 0.05, abs_tol=tol) #0.05000000000000623 + +# Issue 262 : Le bloc créé par boite englobante d'un volume peut avoir de mauvaises dimensions +# la création d'un bloc sur une sphère crée un bloc plat +def test_issue262(): + ctx = Mgx3D.getStdContext() + ctx.clearSession() # Clean the session after the previous test + gm = ctx.getGeomManager() + tm = ctx.getTopoManager() + # Création du volume Vol0000 + gm.newSphere (Mgx3D.Point(0, 0, 0), 1, Mgx3D.Portion.ENTIER) + # Création d'un bloc topologique structuré sans projection (Vol0000) + tm.newFreeTopoOnGeometry ("Vol0000") + + assertPoint(tm, "Som0000", -1, -1, -1) + assertPoint(tm, "Som0007", 1, 1, 1) + + # Annulation de : Création d'un bloc topologique structuré sans projection (Vol0000) + ctx.undo() + # Création d'un bloc unitaire mis dans le groupe AAA + ctx.getTopoManager().newFreeBoundedTopoInGroup ("AAA", 3, ["Vol0000"]) + + assertPoint(tm, "Som0000", -1, -1, -1) + assertPoint(tm, "Som0007", 1, 1, 1) + +def test_freeboundedtopoForPoints(): + ctx = Mgx3D.getStdContext() + ctx.clearSession() # Clean the session after the previous test + gm = ctx.getGeomManager () + tm = ctx.getTopoManager () + + gm.newVertex(Mgx3D.Point(-1.8, -.7, 1.2)) + gm.newVertex(Mgx3D.Point(-.7, .45, -.1)) + tm.newFreeBoundedTopoInGroup ("aaa", 3, ["Pt0000","Pt0001"]) + assertPoint(tm, "Som0007", -0.7, 0.45, 1.2) + +def test_freeboundedtopoForSphere(): + ctx = Mgx3D.getStdContext() + ctx.clearSession() # Clean the session after the previous test + gm = ctx.getGeomManager () + tm = ctx.getTopoManager () + + gm.newSphere (Mgx3D.Point(0, 0, 0), 1, 150) + tm.newFreeTopoOnGeometry ("Vol0000") + assertPoint(tm, "Som0007", 1.0, 1.0, 1.0) + +def test_freeboundedtopoForCylinder(): + ctx = Mgx3D.getStdContext() + ctx.clearSession() # Clean the session after the previous test + gm = ctx.getGeomManager () + tm = ctx.getTopoManager () + + gm.newCylinder (Mgx3D.Point(0, 0, 0), 1, Mgx3D.Vector(10, 0, 0), 360) + tm.newFreeTopoOnGeometry ("Vol0000") + assertPoint(tm, "Som0007", 10, 1.0, 1.0) + +def test_bounding_box_with_scale(): + ctx = Mgx3D.getStdContext() + ctx.clearSession() # Clean the session after the previous test + gm = ctx.getGeomManager () + tm = ctx.getTopoManager () + + gm.newSphere (Mgx3D.Point(0, 0, 0), 1, 125) + gm.scaleAll(10, 20, 10) + tm.newFreeTopoOnGeometry ("Vol0000") + assertPoint(tm, "Som0007", 10.0, 20.0, 10.0) diff --git a/test_link/test_free_bounded_topo.py b/test_link/test_free_bounded_topo.py deleted file mode 100755 index 9f7b76a9..00000000 --- a/test_link/test_free_bounded_topo.py +++ /dev/null @@ -1,16 +0,0 @@ -import pyMagix3D as Mgx3D -import pytest - -def test_freeboundedtopo(): - ctx = Mgx3D.getStdContext() - ctx.clearSession() # Clean the session after the previous test - gm = ctx.getGeomManager () - tm = ctx.getTopoManager () - - gm.newVertex(Mgx3D.Point(-1.8, -.7, 1.2)) - gm.newVertex(Mgx3D.Point(-.7, .45, -.1)) - tm.newFreeBoundedTopoInGroup ("aaa", 3, ["Pt0000","Pt0001"]) - c = tm.getCoord("Som0007") - assert c.getX() == -0.7 - assert c.getY() == 0.45 - assert c.getZ() == 1.2 diff --git a/test_link/test_issue225.py b/test_link/test_issue225.py deleted file mode 100755 index 153c176e..00000000 --- a/test_link/test_issue225.py +++ /dev/null @@ -1,21 +0,0 @@ -import math -import os -import pyMagix3D as Mgx3D -import pytest - -step_file_name = "mambo/Basic/B18.step" - -def test_issue225(capfd): - ctx = Mgx3D.getStdContext() - ctx.clearSession() # Clean the session after the previous test - gm = ctx.getGeomManager() - tm = ctx.getTopoManager () - - magix3d_test_data_dir = os.environ['MAGIX3D_TEST_DATA_DIR'] - full_path = os.path.join(magix3d_test_data_dir, step_file_name) - - ctx.setLengthUnit(Mgx3D.Unit.centimeter) - gm.importSTEP(full_path) - assert gm.getNbVolumes()==1 - tm.newFreeTopoOnGeometry("Vol0000") - assert math.isclose(tm.getEdgeLength("Ar0007"), 0.1, abs_tol=1e-6) \ No newline at end of file diff --git a/test_link/test_issue262.py b/test_link/test_issue262.py deleted file mode 100644 index 881c1e41..00000000 --- a/test_link/test_issue262.py +++ /dev/null @@ -1,28 +0,0 @@ -import pyMagix3D as Mgx3D -import math - -# Issue262 : Le bloc créé oar boite englobante d'un volume peut avoir de mauvaises dimensions -# la création d'un bloc sur une sphère crée un bloc plat - -def assertPoint(tm, name, x, y, z): - p = tm.getCoord(name) - assert math.isclose(p.getX(), x, rel_tol=1e-7) - assert math.isclose(p.getY(), y, rel_tol=1e-7) - assert math.isclose(p.getZ(), z, rel_tol=1e-7) - -def test_issue262(): - ctx = Mgx3D.getStdContext() - ctx.clearSession() # Clean the session after the previous test - gm = ctx.getGeomManager() - tm = ctx.getTopoManager() - # Création du volume Vol0000 - gm.newSphere (Mgx3D.Point(0, 0, 0), 1, Mgx3D.Portion.ENTIER) - # Création d'un bloc topologique structuré sans projection (Vol0000) - tm.newFreeTopoOnGeometry ("Vol0000") - # Annulation de : Création d'un bloc topologique structuré sans projection (Vol0000) - ctx.undo() - # Création d'un bloc unitaire mis dans le groupe AAA - ctx.getTopoManager().newFreeBoundedTopoInGroup ("AAA", 3, ["Vol0000"]) - - assertPoint(tm, "Som0000", -1, -1, -1) - assertPoint(tm, "Som0007", 1, 1, 1) \ No newline at end of file diff --git a/test_link/test_law_biexponential.py b/test_link/test_law_biexponential.py index e9329b6f..e0638424 100644 --- a/test_link/test_law_biexponential.py +++ b/test_link/test_law_biexponential.py @@ -239,28 +239,25 @@ def test_law_biexponential_onSurface(capfd): ctx.getGeomManager().newCylinder (Mgx3D.Point(1.5, 0, 0), 1, Mgx3D.Vector(0, 0, 4), 3.600000e+02) # Fusion Booléenne de Vol0001 Vol0000 ctx.getGeomManager ( ).fuse (["Vol0001","Vol0000"]) - # Fusion de surfaces Surf0007 Surf0010 Surf0012 - ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0010","Surf0012"]) - # Fusion de surfaces Surf0008 Surf0011 Surf0014 - ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0011","Surf0014"]) - # Fusion de surfaces Surf0006 Surf0013 - ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0013"]) - # Fusion de surfaces Surf0017 Surf0009 - ctx.getGeomManager ( ).joinSurfaces (["Surf0017","Surf0009"]) - # Fusion de courbes Crb0006 Crb0016 - ctx.getGeomManager ( ).joinCurves (["Crb0006","Crb0016"]) + # Fusion de surfaces Surf0006 Surf0010 Surf0012 + ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0010","Surf0012"]) + # Fusion de surfaces Surf0007 Surf0011 Surf0013 + ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0011","Surf0013"]) + # Fusion de surfaces Surf0008 Surf0009 Surf0014 + ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0009", "Surf0014"]) + # Fusion de courbes Crb0006 Crb0007 Crb0016 + ctx.getGeomManager ( ).joinCurves (["Crb0006", "Crb0007","Crb0016"]) # Fusion de courbes Crb0018 Crb0009 Crb0008 ctx.getGeomManager ( ).joinCurves (["Crb0018","Crb0009","Crb0008"]) - # Fusion de courbes Crb0020 Crb0007 - ctx.getGeomManager ( ).joinCurves (["Crb0020","Crb0007"]) + # Création d'un bloc topologique structuré sans projection (Vol0002) ctx.getTopoManager().newFreeTopoOnGeometry ("Vol0002") # Découpage suivant Ar0011 des blocs Bl0000 ctx.getTopoManager().splitBlocks (["Bl0000"],"Ar0011", .5) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0023 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0018", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0017", True) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0022 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0018", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0017", True) # Changement de discrétisation pour les arêtes Ar0023 emp = Mgx3D.EdgeMeshingPropertyBiexponential(20, s1_ar0023, s1_ar0023) @@ -269,7 +266,7 @@ def test_law_biexponential_onSurface(capfd): emp = Mgx3D.EdgeMeshingPropertyBiexponential(20, s1_ar0022, s2_ar0022) ctx.getTopoManager().setMeshingProperty (emp, ["Ar0022"]) - # Création du maillage pour tous les blocs + # Création du maillage pour tous les blocs ctx.getMeshManager().newAllBlocksMesh() # Sauvegarde du maillage (mli) @@ -287,7 +284,7 @@ def test_law_biexponential_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n9, n193) - s1_ar0023) > eps ) # real meshing edge size - assert( abs(l2_norme(n9, n193) - 4.14588643711679e-3) < eps ) + assert( abs(l2_norme(n9, n193) - 4.14578719225745e-3) < eps ) # test of last mesh edge size of topo edge Ar0023 n10 = mesh_lima.noeud(10) @@ -295,7 +292,7 @@ def test_law_biexponential_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n10, n211) - s1_ar0023) > eps ) # real meshing edge size - assert( abs(l2_norme(n10, n211) - 4.15171460239938e-3) < eps ) + assert( abs(l2_norme(n10, n211) - 4.15160096753457e-3) < eps ) # test of first mesh edge size of topo edge Ar0022 @@ -304,7 +301,7 @@ def test_law_biexponential_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n11, n174) - s1_ar0022) > eps ) # real meshing edge size - assert( abs(l2_norme(n11, n174) - 7.89083037828939e-1) < eps ) + assert( abs(l2_norme(n11, n174) - 7.89003595950745e-1) < eps ) # test of last mesh edge size of topo edge Ar0022 n8 = mesh_lima.noeud(8) @@ -312,6 +309,6 @@ def test_law_biexponential_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n8, n192) - s2_ar0022) > eps ) # real meshing edge size - assert( abs(l2_norme(n8, n192) - 4.9378232958398e-1) < eps ) + assert( abs(l2_norme(n8, n192) - 4.93740651566053e-1) < eps ) os.remove(filename) \ No newline at end of file diff --git a/test_link/test_law_geometric.py b/test_link/test_law_geometric.py index 21263e7e..a0a2ea93 100644 --- a/test_link/test_law_geometric.py +++ b/test_link/test_law_geometric.py @@ -196,28 +196,25 @@ def test_law_geometric_onSurface(capfd): ctx.getGeomManager().newCylinder (Mgx3D.Point(1.5, 0, 0), 1, Mgx3D.Vector(0, 0, 4), 3.600000e+02) # Fusion Booléenne de Vol0001 Vol0000 ctx.getGeomManager ( ).fuse (["Vol0001","Vol0000"]) - # Fusion de surfaces Surf0007 Surf0010 Surf0012 - ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0010","Surf0012"]) - # Fusion de surfaces Surf0008 Surf0011 Surf0014 - ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0011","Surf0014"]) - # Fusion de surfaces Surf0006 Surf0013 - ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0013"]) - # Fusion de surfaces Surf0017 Surf0009 - ctx.getGeomManager ( ).joinSurfaces (["Surf0017","Surf0009"]) - # Fusion de courbes Crb0006 Crb0016 - ctx.getGeomManager ( ).joinCurves (["Crb0006","Crb0016"]) + # Fusion de surfaces Surf0006 Surf0010 Surf0012 + ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0010","Surf0012"]) + # Fusion de surfaces Surf0007 Surf0011 Surf0013 + ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0011","Surf0013"]) + # Fusion de surfaces Surf0008 Surf0009 Surf0014 + ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0009", "Surf0014"]) + # Fusion de courbes Crb0006 Crb0007 Crb0016 + ctx.getGeomManager ( ).joinCurves (["Crb0006", "Crb0007","Crb0016"]) # Fusion de courbes Crb0018 Crb0009 Crb0008 ctx.getGeomManager ( ).joinCurves (["Crb0018","Crb0009","Crb0008"]) - # Fusion de courbes Crb0020 Crb0007 - ctx.getGeomManager ( ).joinCurves (["Crb0020","Crb0007"]) - # Création d'un bloc topologique structuré sans projection (Vol0002) + + # Création d'un bloc topologique structuré sans projection (Vol0002) ctx.getTopoManager().newFreeTopoOnGeometry ("Vol0002") # Découpage suivant Ar0011 des blocs Bl0000 ctx.getTopoManager().splitBlocks (["Bl0000"],"Ar0011", .5) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0023 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0018", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0017", True) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0022 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0018", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0017", True) # Changement de discrétisation pour les arêtes Ar0023 emp = Mgx3D.EdgeMeshingPropertyGeometric(10, 1.1, True, True, s1_ar0023) @@ -244,7 +241,7 @@ def test_law_geometric_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n9, n143) - s1_ar0023) > eps ) # real meshing edge size - assert( abs(l2_norme(n9, n143) - 3.94206709724702e-3) < eps ) + assert( abs(l2_norme(n9, n143) - 3.94428397846855e-3) < eps ) # test of first mesh edge size of topo edge Ar0022 n8 = mesh_lima.noeud(8) @@ -252,7 +249,7 @@ def test_law_geometric_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n8, n142) - s1_ar0022) > eps ) # real meshing edge size - assert( abs(l2_norme(n8, n142) - 2.12853778510894) < eps ) + assert( abs(l2_norme(n8, n142) - 2.12743146085374) < eps ) os.remove(filename) diff --git a/test_link/test_law_hyperbolic.py b/test_link/test_law_hyperbolic.py index 3c0ebc91..62f0fe3c 100644 --- a/test_link/test_law_hyperbolic.py +++ b/test_link/test_law_hyperbolic.py @@ -72,28 +72,25 @@ def test_law_hyperbolic_onSurface(capfd): ctx.getGeomManager().newCylinder (Mgx3D.Point(1.5, 0, 0), 1, Mgx3D.Vector(0, 0, 4), 3.600000e+02) # Fusion Booléenne de Vol0001 Vol0000 ctx.getGeomManager ( ).fuse (["Vol0001","Vol0000"]) - # Fusion de surfaces Surf0007 Surf0010 Surf0012 - ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0010","Surf0012"]) - # Fusion de surfaces Surf0008 Surf0011 Surf0014 - ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0011","Surf0014"]) - # Fusion de surfaces Surf0006 Surf0013 - ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0013"]) - # Fusion de surfaces Surf0017 Surf0009 - ctx.getGeomManager ( ).joinSurfaces (["Surf0017","Surf0009"]) - # Fusion de courbes Crb0006 Crb0016 - ctx.getGeomManager ( ).joinCurves (["Crb0006","Crb0016"]) + # Fusion de surfaces Surf0006 Surf0010 Surf0012 + ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0010","Surf0012"]) + # Fusion de surfaces Surf0007 Surf0011 Surf0013 + ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0011","Surf0013"]) + # Fusion de surfaces Surf0008 Surf0009 Surf0014 + ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0009", "Surf0014"]) + # Fusion de courbes Crb0006 Crb0007 Crb0016 + ctx.getGeomManager ( ).joinCurves (["Crb0006", "Crb0007","Crb0016"]) # Fusion de courbes Crb0018 Crb0009 Crb0008 ctx.getGeomManager ( ).joinCurves (["Crb0018","Crb0009","Crb0008"]) - # Fusion de courbes Crb0020 Crb0007 - ctx.getGeomManager ( ).joinCurves (["Crb0020","Crb0007"]) - # Création d'un bloc topologique structuré sans projection (Vol0002) + + # Création d'un bloc topologique structuré sans projection (Vol0002) ctx.getTopoManager().newFreeTopoOnGeometry ("Vol0002") # Découpage suivant Ar0011 des blocs Bl0000 ctx.getTopoManager().splitBlocks (["Bl0000"],"Ar0011", .5) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0023 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0018", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0017", True) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0022 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0018", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0017", True) # Changement de discrétisation pour les arêtes Ar0023 emp = Mgx3D.EdgeMeshingPropertyHyperbolic(10,s1_ar0023,s2_ar0023) @@ -117,7 +114,7 @@ def test_law_hyperbolic_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n9, n143) - s2_ar0023) > eps ) # real meshing edge size - assert( abs(l2_norme(n9, n143) - 1.48428681456749) < eps ) + assert( abs(l2_norme(n9, n143) - 1.49367283095557) < eps ) # test of last mesh edge size of topo edge Ar0023 n10 = mesh_lima.noeud(10) @@ -125,6 +122,6 @@ def test_law_hyperbolic_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n10, n151) - s1_ar0023) > eps ) # real meshing edge size - assert( abs(l2_norme(n10, n151) - 0.0119670075859925) < eps ) + assert( abs(l2_norme(n10, n151) - 0.0119324377806415) < eps ) os.remove(filename) \ No newline at end of file diff --git a/test_link/test_order_join_curves.py b/test_link/test_order_join_curves.py index 0d2a6e0f..e87f8779 100644 --- a/test_link/test_order_join_curves.py +++ b/test_link/test_order_join_curves.py @@ -1,5 +1,8 @@ import pyMagix3D as Mgx3D +# Issue 228 : L'ordre des entités créées par la commande sectionByPlane peut varier d'une exécution à l'autre +# Corrigé par le nouveau calcul de boite englobante +# NB : les ids des surfaces sont impactés def test_order_join_curves(): ctx = Mgx3D.getStdContext() ctx.clearSession() # Clean the session after the previous test @@ -17,11 +20,12 @@ def test_order_join_curves(): gm.translateAll(Mgx3D.Vector(1, 0, 0)) # Homothétie de tout gm.scaleAll(1.000000e+00, 2.000000e+00, 3.000000e+00) + # Fusion Booléenne de Vol0009 Vol0006 Vol0005 Vol0010 Vol0008 ... gm.fuse (["Vol0005","Vol0006","Vol0007","Vol0008","Vol0009","Vol0010"]) gm.joinSurfaces (["Surf0020","Surf0021","Surf0022","Surf0023","Surf0024","Surf0025"]) - gm.joinSurfaces (["Surf0027","Surf0032","Surf0035","Surf0036","Surf0039","Surf0042"]) - gm.joinSurfaces (["Surf0013","Surf0014","Surf0018","Surf0026","Surf0034","Surf0038","Surf0040"]) + gm.joinSurfaces (["Surf0026","Surf0031","Surf0033","Surf0034","Surf0036","Surf0038"]) + gm.joinSurfaces (["Surf0017","Surf0018","Surf0019","Surf0039","Surf0040","Surf0041","Surf0042"]) gm.joinCurves (["Crb0020","Crb0021","Crb0024","Crb0040","Crb0043","Crb0045","Crb0050"]) gm.joinCurves (["Crb0013","Crb0014","Crb0018","Crb0026","Crb0028","Crb0030","Crb0038"]) From 8bc40211be96575d572ff87c050b0717da1d787d Mon Sep 17 00:00:00 2001 From: Marie-Pierre Oudot Date: Fri, 12 Jun 2026 16:10:35 +0200 Subject: [PATCH 3/3] Add third parameter useTriangulation==false --- src/Core/Geom/OCCHelper.cpp | 2 +- test_link/test_law_biexponential.py | 35 ++++++++++++++++------------- test_link/test_law_geometric.py | 31 +++++++++++++------------ test_link/test_law_hyperbolic.py | 31 +++++++++++++------------ test_link/test_order_join_curves.py | 8 ++----- 5 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/Core/Geom/OCCHelper.cpp b/src/Core/Geom/OCCHelper.cpp index 70b1c4a2..bc9d6c81 100644 --- a/src/Core/Geom/OCCHelper.cpp +++ b/src/Core/Geom/OCCHelper.cpp @@ -1004,7 +1004,7 @@ computeBoundingBox(const TopoDS_Shape& shape, gp_Pnt& pmin, gp_Pnt& pmax) { Bnd_Box box; - BRepBndLib::AddOptimal(shape, box); + BRepBndLib::AddOptimal(shape, box, false); double xmin, ymin, zmin, xmax, ymax, zmax; box.Get(xmin, ymin, zmin, xmax, ymax, zmax); pmin.SetCoord(xmin, ymin, zmin); diff --git a/test_link/test_law_biexponential.py b/test_link/test_law_biexponential.py index e0638424..e9329b6f 100644 --- a/test_link/test_law_biexponential.py +++ b/test_link/test_law_biexponential.py @@ -239,25 +239,28 @@ def test_law_biexponential_onSurface(capfd): ctx.getGeomManager().newCylinder (Mgx3D.Point(1.5, 0, 0), 1, Mgx3D.Vector(0, 0, 4), 3.600000e+02) # Fusion Booléenne de Vol0001 Vol0000 ctx.getGeomManager ( ).fuse (["Vol0001","Vol0000"]) - # Fusion de surfaces Surf0006 Surf0010 Surf0012 - ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0010","Surf0012"]) - # Fusion de surfaces Surf0007 Surf0011 Surf0013 - ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0011","Surf0013"]) - # Fusion de surfaces Surf0008 Surf0009 Surf0014 - ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0009", "Surf0014"]) - # Fusion de courbes Crb0006 Crb0007 Crb0016 - ctx.getGeomManager ( ).joinCurves (["Crb0006", "Crb0007","Crb0016"]) + # Fusion de surfaces Surf0007 Surf0010 Surf0012 + ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0010","Surf0012"]) + # Fusion de surfaces Surf0008 Surf0011 Surf0014 + ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0011","Surf0014"]) + # Fusion de surfaces Surf0006 Surf0013 + ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0013"]) + # Fusion de surfaces Surf0017 Surf0009 + ctx.getGeomManager ( ).joinSurfaces (["Surf0017","Surf0009"]) + # Fusion de courbes Crb0006 Crb0016 + ctx.getGeomManager ( ).joinCurves (["Crb0006","Crb0016"]) # Fusion de courbes Crb0018 Crb0009 Crb0008 ctx.getGeomManager ( ).joinCurves (["Crb0018","Crb0009","Crb0008"]) - + # Fusion de courbes Crb0020 Crb0007 + ctx.getGeomManager ( ).joinCurves (["Crb0020","Crb0007"]) # Création d'un bloc topologique structuré sans projection (Vol0002) ctx.getTopoManager().newFreeTopoOnGeometry ("Vol0002") # Découpage suivant Ar0011 des blocs Bl0000 ctx.getTopoManager().splitBlocks (["Bl0000"],"Ar0011", .5) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0023 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0017", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0018", True) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0022 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0017", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0018", True) # Changement de discrétisation pour les arêtes Ar0023 emp = Mgx3D.EdgeMeshingPropertyBiexponential(20, s1_ar0023, s1_ar0023) @@ -266,7 +269,7 @@ def test_law_biexponential_onSurface(capfd): emp = Mgx3D.EdgeMeshingPropertyBiexponential(20, s1_ar0022, s2_ar0022) ctx.getTopoManager().setMeshingProperty (emp, ["Ar0022"]) - # Création du maillage pour tous les blocs + # Création du maillage pour tous les blocs ctx.getMeshManager().newAllBlocksMesh() # Sauvegarde du maillage (mli) @@ -284,7 +287,7 @@ def test_law_biexponential_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n9, n193) - s1_ar0023) > eps ) # real meshing edge size - assert( abs(l2_norme(n9, n193) - 4.14578719225745e-3) < eps ) + assert( abs(l2_norme(n9, n193) - 4.14588643711679e-3) < eps ) # test of last mesh edge size of topo edge Ar0023 n10 = mesh_lima.noeud(10) @@ -292,7 +295,7 @@ def test_law_biexponential_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n10, n211) - s1_ar0023) > eps ) # real meshing edge size - assert( abs(l2_norme(n10, n211) - 4.15160096753457e-3) < eps ) + assert( abs(l2_norme(n10, n211) - 4.15171460239938e-3) < eps ) # test of first mesh edge size of topo edge Ar0022 @@ -301,7 +304,7 @@ def test_law_biexponential_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n11, n174) - s1_ar0022) > eps ) # real meshing edge size - assert( abs(l2_norme(n11, n174) - 7.89003595950745e-1) < eps ) + assert( abs(l2_norme(n11, n174) - 7.89083037828939e-1) < eps ) # test of last mesh edge size of topo edge Ar0022 n8 = mesh_lima.noeud(8) @@ -309,6 +312,6 @@ def test_law_biexponential_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n8, n192) - s2_ar0022) > eps ) # real meshing edge size - assert( abs(l2_norme(n8, n192) - 4.93740651566053e-1) < eps ) + assert( abs(l2_norme(n8, n192) - 4.9378232958398e-1) < eps ) os.remove(filename) \ No newline at end of file diff --git a/test_link/test_law_geometric.py b/test_link/test_law_geometric.py index a0a2ea93..21263e7e 100644 --- a/test_link/test_law_geometric.py +++ b/test_link/test_law_geometric.py @@ -196,25 +196,28 @@ def test_law_geometric_onSurface(capfd): ctx.getGeomManager().newCylinder (Mgx3D.Point(1.5, 0, 0), 1, Mgx3D.Vector(0, 0, 4), 3.600000e+02) # Fusion Booléenne de Vol0001 Vol0000 ctx.getGeomManager ( ).fuse (["Vol0001","Vol0000"]) - # Fusion de surfaces Surf0006 Surf0010 Surf0012 - ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0010","Surf0012"]) - # Fusion de surfaces Surf0007 Surf0011 Surf0013 - ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0011","Surf0013"]) - # Fusion de surfaces Surf0008 Surf0009 Surf0014 - ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0009", "Surf0014"]) - # Fusion de courbes Crb0006 Crb0007 Crb0016 - ctx.getGeomManager ( ).joinCurves (["Crb0006", "Crb0007","Crb0016"]) + # Fusion de surfaces Surf0007 Surf0010 Surf0012 + ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0010","Surf0012"]) + # Fusion de surfaces Surf0008 Surf0011 Surf0014 + ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0011","Surf0014"]) + # Fusion de surfaces Surf0006 Surf0013 + ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0013"]) + # Fusion de surfaces Surf0017 Surf0009 + ctx.getGeomManager ( ).joinSurfaces (["Surf0017","Surf0009"]) + # Fusion de courbes Crb0006 Crb0016 + ctx.getGeomManager ( ).joinCurves (["Crb0006","Crb0016"]) # Fusion de courbes Crb0018 Crb0009 Crb0008 ctx.getGeomManager ( ).joinCurves (["Crb0018","Crb0009","Crb0008"]) - - # Création d'un bloc topologique structuré sans projection (Vol0002) + # Fusion de courbes Crb0020 Crb0007 + ctx.getGeomManager ( ).joinCurves (["Crb0020","Crb0007"]) + # Création d'un bloc topologique structuré sans projection (Vol0002) ctx.getTopoManager().newFreeTopoOnGeometry ("Vol0002") # Découpage suivant Ar0011 des blocs Bl0000 ctx.getTopoManager().splitBlocks (["Bl0000"],"Ar0011", .5) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0023 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0017", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0018", True) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0022 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0017", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0018", True) # Changement de discrétisation pour les arêtes Ar0023 emp = Mgx3D.EdgeMeshingPropertyGeometric(10, 1.1, True, True, s1_ar0023) @@ -241,7 +244,7 @@ def test_law_geometric_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n9, n143) - s1_ar0023) > eps ) # real meshing edge size - assert( abs(l2_norme(n9, n143) - 3.94428397846855e-3) < eps ) + assert( abs(l2_norme(n9, n143) - 3.94206709724702e-3) < eps ) # test of first mesh edge size of topo edge Ar0022 n8 = mesh_lima.noeud(8) @@ -249,7 +252,7 @@ def test_law_geometric_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n8, n142) - s1_ar0022) > eps ) # real meshing edge size - assert( abs(l2_norme(n8, n142) - 2.12743146085374) < eps ) + assert( abs(l2_norme(n8, n142) - 2.12853778510894) < eps ) os.remove(filename) diff --git a/test_link/test_law_hyperbolic.py b/test_link/test_law_hyperbolic.py index 62f0fe3c..3c0ebc91 100644 --- a/test_link/test_law_hyperbolic.py +++ b/test_link/test_law_hyperbolic.py @@ -72,25 +72,28 @@ def test_law_hyperbolic_onSurface(capfd): ctx.getGeomManager().newCylinder (Mgx3D.Point(1.5, 0, 0), 1, Mgx3D.Vector(0, 0, 4), 3.600000e+02) # Fusion Booléenne de Vol0001 Vol0000 ctx.getGeomManager ( ).fuse (["Vol0001","Vol0000"]) - # Fusion de surfaces Surf0006 Surf0010 Surf0012 - ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0010","Surf0012"]) - # Fusion de surfaces Surf0007 Surf0011 Surf0013 - ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0011","Surf0013"]) - # Fusion de surfaces Surf0008 Surf0009 Surf0014 - ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0009", "Surf0014"]) - # Fusion de courbes Crb0006 Crb0007 Crb0016 - ctx.getGeomManager ( ).joinCurves (["Crb0006", "Crb0007","Crb0016"]) + # Fusion de surfaces Surf0007 Surf0010 Surf0012 + ctx.getGeomManager ( ).joinSurfaces (["Surf0007","Surf0010","Surf0012"]) + # Fusion de surfaces Surf0008 Surf0011 Surf0014 + ctx.getGeomManager ( ).joinSurfaces (["Surf0008","Surf0011","Surf0014"]) + # Fusion de surfaces Surf0006 Surf0013 + ctx.getGeomManager ( ).joinSurfaces (["Surf0006","Surf0013"]) + # Fusion de surfaces Surf0017 Surf0009 + ctx.getGeomManager ( ).joinSurfaces (["Surf0017","Surf0009"]) + # Fusion de courbes Crb0006 Crb0016 + ctx.getGeomManager ( ).joinCurves (["Crb0006","Crb0016"]) # Fusion de courbes Crb0018 Crb0009 Crb0008 ctx.getGeomManager ( ).joinCurves (["Crb0018","Crb0009","Crb0008"]) - - # Création d'un bloc topologique structuré sans projection (Vol0002) + # Fusion de courbes Crb0020 Crb0007 + ctx.getGeomManager ( ).joinCurves (["Crb0020","Crb0007"]) + # Création d'un bloc topologique structuré sans projection (Vol0002) ctx.getTopoManager().newFreeTopoOnGeometry ("Vol0002") # Découpage suivant Ar0011 des blocs Bl0000 ctx.getTopoManager().splitBlocks (["Bl0000"],"Ar0011", .5) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0023 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0017", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0023"], "Surf0018", True) # Affectation d'une projection vers Surf0018 pour les entités topologiques Ar0022 - ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0017", True) + ctx.getTopoManager ( ).setGeomAssociation (["Ar0022"], "Surf0018", True) # Changement de discrétisation pour les arêtes Ar0023 emp = Mgx3D.EdgeMeshingPropertyHyperbolic(10,s1_ar0023,s2_ar0023) @@ -114,7 +117,7 @@ def test_law_hyperbolic_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n9, n143) - s2_ar0023) > eps ) # real meshing edge size - assert( abs(l2_norme(n9, n143) - 1.49367283095557) < eps ) + assert( abs(l2_norme(n9, n143) - 1.48428681456749) < eps ) # test of last mesh edge size of topo edge Ar0023 n10 = mesh_lima.noeud(10) @@ -122,6 +125,6 @@ def test_law_hyperbolic_onSurface(capfd): # target meshing edge size (not respected) assert( abs(l2_norme(n10, n151) - s1_ar0023) > eps ) # real meshing edge size - assert( abs(l2_norme(n10, n151) - 0.0119324377806415) < eps ) + assert( abs(l2_norme(n10, n151) - 0.0119670075859925) < eps ) os.remove(filename) \ No newline at end of file diff --git a/test_link/test_order_join_curves.py b/test_link/test_order_join_curves.py index e87f8779..0d2a6e0f 100644 --- a/test_link/test_order_join_curves.py +++ b/test_link/test_order_join_curves.py @@ -1,8 +1,5 @@ import pyMagix3D as Mgx3D -# Issue 228 : L'ordre des entités créées par la commande sectionByPlane peut varier d'une exécution à l'autre -# Corrigé par le nouveau calcul de boite englobante -# NB : les ids des surfaces sont impactés def test_order_join_curves(): ctx = Mgx3D.getStdContext() ctx.clearSession() # Clean the session after the previous test @@ -20,12 +17,11 @@ def test_order_join_curves(): gm.translateAll(Mgx3D.Vector(1, 0, 0)) # Homothétie de tout gm.scaleAll(1.000000e+00, 2.000000e+00, 3.000000e+00) - # Fusion Booléenne de Vol0009 Vol0006 Vol0005 Vol0010 Vol0008 ... gm.fuse (["Vol0005","Vol0006","Vol0007","Vol0008","Vol0009","Vol0010"]) gm.joinSurfaces (["Surf0020","Surf0021","Surf0022","Surf0023","Surf0024","Surf0025"]) - gm.joinSurfaces (["Surf0026","Surf0031","Surf0033","Surf0034","Surf0036","Surf0038"]) - gm.joinSurfaces (["Surf0017","Surf0018","Surf0019","Surf0039","Surf0040","Surf0041","Surf0042"]) + gm.joinSurfaces (["Surf0027","Surf0032","Surf0035","Surf0036","Surf0039","Surf0042"]) + gm.joinSurfaces (["Surf0013","Surf0014","Surf0018","Surf0026","Surf0034","Surf0038","Surf0040"]) gm.joinCurves (["Crb0020","Crb0021","Crb0024","Crb0040","Crb0043","Crb0045","Crb0050"]) gm.joinCurves (["Crb0013","Crb0014","Crb0018","Crb0026","Crb0028","Crb0030","Crb0038"])