From b985bf2ff9ded39110d54ef7695f39444e11f576 Mon Sep 17 00:00:00 2001 From: Thomas Paviot Date: Thu, 23 May 2024 08:46:42 +0200 Subject: [PATCH 1/5] Move test suite to pytest --- test/test_core_extend_dataexchange.py | 171 +-- test/test_core_extend_shapefactory.py | 105 +- test/test_core_extend_topology.py | 297 ++-- test/test_core_geometry.py | 1107 +++++++------- test/test_core_meshdatasource.py | 284 ++-- test/test_core_ocaf.py | 303 ++-- test/test_core_tesselator.py | 211 ++- test/test_core_webgl.py | 186 ++- test/test_core_wrapper_features.py | 1930 +++++++++++++------------ 9 files changed, 2300 insertions(+), 2294 deletions(-) diff --git a/test/test_core_extend_dataexchange.py b/test/test_core_extend_dataexchange.py index ccfd55a2b..cfb00637c 100644 --- a/test/test_core_extend_dataexchange.py +++ b/test/test_core_extend_dataexchange.py @@ -18,7 +18,6 @@ ##along with pythonOCC. If not, see . import os -import unittest from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeTorus from OCC.Core.TopoDS import TopoDS_Compound @@ -61,107 +60,113 @@ def get_test_fullname(filename): A_TOPODS_SHAPE = BRepPrimAPI_MakeTorus(200, 50).Shape() -class TestExtendDataExchange(unittest.TestCase): - def check_is_file(self, filename): - self.assertTrue(os.path.isfile(filename)) +def check_is_file(filename): + assert os.path.isfile(filename) - def test_read_step_file(self): - read_step_file(STEP_AP203_SAMPLE_FILE) - read_step_file(STEP_AP214_SAMPLE_FILE) - def test_read_step_file_multiple_shape_as_root(self): - t = read_step_file(STEP_MULTIPLE_ROOT, as_compound=True) - self.assertTrue(isinstance(t, TopoDS_Compound)) +def test_read_step_file(): + read_step_file(STEP_AP203_SAMPLE_FILE) + read_step_file(STEP_AP214_SAMPLE_FILE) - l = read_step_file(STEP_MULTIPLE_ROOT, as_compound=False) - self.assertEqual(len(l), 3) - def test_read_step_file_names_colors(self): - read_step_file_with_names_colors(STEP_AP203_SAMPLE_FILE) - read_step_file_with_names_colors(STEP_AP214_SAMPLE_FILE) +def test_read_step_file_multiple_shape_as_root(): + t = read_step_file(STEP_MULTIPLE_ROOT, as_compound=True) + assert isinstance(t, TopoDS_Compound) - def test_read_iges_file(self): - read_iges_file(IGES_SAMPLE_FILE) + l = read_step_file(STEP_MULTIPLE_ROOT, as_compound=False) + assert len(l) == 3 - def test_read_iges_45_shapes(self): - all_shapes = read_iges_file( - IGES_45_FACES, return_as_shapes=True, verbosity=True - ) - self.assertEqual(len(all_shapes), 45) - def test_read_iges_45_shapes_as_one_compound(self): - shapes = read_iges_file(IGES_45_FACES, return_as_shapes=False, verbosity=True) - self.assertEqual(len(shapes), 1) - self.assertIsInstance(shapes[0], TopoDS_Compound) - topo_explorer = TopologyExplorer(shapes[0]) - self.assertEqual(topo_explorer.number_of_faces(), 45) +def test_read_step_file_names_colors(): + read_step_file_with_names_colors(STEP_AP203_SAMPLE_FILE) + read_step_file_with_names_colors(STEP_AP214_SAMPLE_FILE) - def test_read_stl_file(self): - read_stl_file(STL_ASCII_SAMPLE_FILE) - read_stl_file(STL_BINARY_SAMPLE_FILE) - def test_export_shape_to_svg(self): - svg_filename = get_test_fullname("sample.svg") - export_shape_to_svg(A_TOPODS_SHAPE, svg_filename) - self.check_is_file(svg_filename) +def test_read_iges_file(): + read_iges_file(IGES_SAMPLE_FILE) - def test_read_gltf_ascii_file(self): - shp = read_gltf_file(GLTF_ASCII_SAMPLE_FILE) - def test_read_gltf_binary_file(self): - shp = read_gltf_file(GLTF_BINARY_SAMPLE_FILE) +def test_read_iges_45_shapes(): + all_shapes = read_iges_file(IGES_45_FACES, return_as_shapes=True, verbosity=True) + assert len(all_shapes) == 45 - def test_write_step_ap203(self): - ap203_filename = get_test_fullname("sample_ap_203.stp") - write_step_file(A_TOPODS_SHAPE, ap203_filename, application_protocol="AP203") - self.check_is_file(ap203_filename) - def test_write_step_ap214(self): - as214_filename = get_test_fullname("sample_214.stp") - write_step_file(A_TOPODS_SHAPE, as214_filename, application_protocol="AP214IS") - self.check_is_file(as214_filename) +def test_read_iges_45_shapes_as_one_compound(): + shapes = read_iges_file(IGES_45_FACES, return_as_shapes=False, verbosity=True) + assert len(shapes) == 1 + assert isinstance(shapes[0], TopoDS_Compound) + topo_explorer = TopologyExplorer(shapes[0]) + assert topo_explorer.number_of_faces() == 45 - def test_write_step_ap242(self): - ap242_filename = get_test_fullname("sample_242.stp") - write_step_file(A_TOPODS_SHAPE, ap242_filename, application_protocol="AP242DIS") - self.check_is_file(ap242_filename) - def test_write_iges(self): - iges_filename = get_test_fullname("sample.igs") - write_iges_file(A_TOPODS_SHAPE, iges_filename) - self.check_is_file(iges_filename) +def test_read_stl_file(): + read_stl_file(STL_ASCII_SAMPLE_FILE) + read_stl_file(STL_BINARY_SAMPLE_FILE) - def test_stl_ascii(self): - stl_ascii_filename = get_test_fullname("sample_ascii.stl") - write_stl_file(A_TOPODS_SHAPE, stl_ascii_filename, mode="ascii") - self.check_is_file(stl_ascii_filename) - def test_stl_binary(self): - stl_binary_filename = get_test_fullname("sample_binary.stl") - write_stl_file(A_TOPODS_SHAPE, stl_binary_filename, mode="binary") - self.check_is_file(stl_binary_filename) +def test_export_shape_to_svg(): + svg_filename = get_test_fullname("sample.svg") + export_shape_to_svg(A_TOPODS_SHAPE, svg_filename) + check_is_file(svg_filename) - def test_write_ply(self): - ply_filename = get_test_fullname("sample.ply") - write_ply_file(A_TOPODS_SHAPE, ply_filename) - self.check_is_file(ply_filename) - def test_write_obj(self): - obj_filename = get_test_fullname("sample.obj") - write_obj_file(A_TOPODS_SHAPE, obj_filename) - self.check_is_file(obj_filename) +def test_read_gltf_ascii_file(): + shp = read_gltf_file(GLTF_ASCII_SAMPLE_FILE) - def test_write_gltf(self): - gltf_filename = get_test_fullname("sample.gltf") - write_gltf_file(A_TOPODS_SHAPE, gltf_filename) - self.check_is_file(gltf_filename) +def test_read_gltf_binary_file(): + shp = read_gltf_file(GLTF_BINARY_SAMPLE_FILE) -def suite(): - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(TestExtendDataExchange)) - return test_suite - - -if __name__ == "__main__": - unittest.main() + +def test_write_step_ap203(): + ap203_filename = get_test_fullname("sample_ap_203.stp") + write_step_file(A_TOPODS_SHAPE, ap203_filename, application_protocol="AP203") + check_is_file(ap203_filename) + + +def test_write_step_ap214(): + as214_filename = get_test_fullname("sample_214.stp") + write_step_file(A_TOPODS_SHAPE, as214_filename, application_protocol="AP214IS") + check_is_file(as214_filename) + + +def test_write_step_ap242(): + ap242_filename = get_test_fullname("sample_242.stp") + write_step_file(A_TOPODS_SHAPE, ap242_filename, application_protocol="AP242DIS") + check_is_file(ap242_filename) + + +def test_write_iges(): + iges_filename = get_test_fullname("sample.igs") + write_iges_file(A_TOPODS_SHAPE, iges_filename) + check_is_file(iges_filename) + + +def test_stl_ascii(): + stl_ascii_filename = get_test_fullname("sample_ascii.stl") + write_stl_file(A_TOPODS_SHAPE, stl_ascii_filename, mode="ascii") + check_is_file(stl_ascii_filename) + + +def test_stl_binary(): + stl_binary_filename = get_test_fullname("sample_binary.stl") + write_stl_file(A_TOPODS_SHAPE, stl_binary_filename, mode="binary") + check_is_file(stl_binary_filename) + + +def test_write_ply(): + ply_filename = get_test_fullname("sample.ply") + write_ply_file(A_TOPODS_SHAPE, ply_filename) + check_is_file(ply_filename) + + +def test_write_obj(): + obj_filename = get_test_fullname("sample.obj") + write_obj_file(A_TOPODS_SHAPE, obj_filename) + check_is_file(obj_filename) + + +def test_write_gltf(): + gltf_filename = get_test_fullname("sample.gltf") + write_gltf_file(A_TOPODS_SHAPE, gltf_filename) + check_is_file(gltf_filename) diff --git a/test/test_core_extend_shapefactory.py b/test/test_core_extend_shapefactory.py index 3c430e82b..7b41d2470 100644 --- a/test/test_core_extend_shapefactory.py +++ b/test/test_core_extend_shapefactory.py @@ -37,67 +37,62 @@ ) from OCC.Extend.TopologyUtils import TopologyExplorer +import pytest -class TestExtendShapeFactory(unittest.TestCase): - def test_midpoint(self): - p1 = gp_Pnt(0, 0, 0) - p2 = gp_Pnt(4, 5, 6) - p3 = midpoint(p1, p2) - self.assertEqual([p3.X(), p3.Y(), p3.Z()], [2, 2.5, 3.0]) - def test_measure_shape_volume(self): - # first the colume of a box a,b,c should be a*b*c - a = 10.0 - b = 23.0 - c = 98.1 - box = BRepPrimAPI_MakeBox(a, b, c).Shape() - box_volume = measure_shape_volume(box) - self.assertAlmostEqual(box_volume, a * b * c, places=6) - # for a sphere of radius r, it should be 4/3.pi.r^3 - r = 9.8775 # a random radius - sph = BRepPrimAPI_MakeSphere(r).Shape() - sph_volume = measure_shape_volume(sph) - self.assertAlmostEqual(sph_volume, 4.0 / 3.0 * math.pi * r**3, places=6) +def test_midpoint(): + p1 = gp_Pnt(0, 0, 0) + p2 = gp_Pnt(4, 5, 6) + p3 = midpoint(p1, p2) + assert [p3.X(), p3.Y(), p3.Z()] == [2, 2.5, 3.0] - def test_scale_shape(self): - box = BRepPrimAPI_MakeBox(10.0, 10.0, 10.0).Shape() - box2 = scale_shape(box, 2.0, 1.0, 1.0) - # volume should be double - box2_volume = measure_shape_volume(box2) - self.assertAlmostEqual(box2_volume, 2000.0, places=6) - def test_measure_shape_center_of_gravity(self): - # we compute the cog of a sphere centered at a point P - # then the cog must be P - x, y, z = 10.0, 3.0, -2.44 # random values for point P - radius = 20.0 - vector = gp_Vec(x, y, z) - sph = translate_shp(BRepPrimAPI_MakeSphere(radius).Shape(), vector) - cog, mass, mass_property = measure_shape_mass_center_of_gravity(sph) - self.assertAlmostEqual(cog.X(), x, places=6) - self.assertAlmostEqual(cog.Y(), y, places=6) - self.assertAlmostEqual(cog.Z(), z, places=6) - self.assertAlmostEqual(mass, 4 / 3 * math.pi * radius**3, places=6) - self.assertEqual(mass_property, "Volume") +def test_measure_shape_volume(): + # first the colume of a box a,b,c should be a*b*c + a = 10.0 + b = 23.0 + c = 98.1 + box = BRepPrimAPI_MakeBox(a, b, c).Shape() + box_volume = measure_shape_volume(box) + assert box_volume == pytest.approx(box_volume, a * b * c) + # for a sphere of radius r, it should be 4/3.pi.r^3 + r = 9.8775 # a random radius + sph = BRepPrimAPI_MakeSphere(r).Shape() + sph_volume = measure_shape_volume(sph) + assert sph_volume == pytest.approx(4.0 / 3.0 * math.pi * r**3) - def test_edge_to_bezier(self): - b = BRepPrimAPI_MakeTorus(30, 10).Shape() - t = TopologyExplorer(b) - for ed in t.edges(): - is_bezier, bezier_curve, degree = edge_to_bezier(ed) - self.assertTrue(isinstance(is_bezier, bool)) - if not is_bezier: - self.assertTrue(degree is None) - self.assertTrue(bezier_curve is None) - else: - self.assertTrue(isinstance(degree, int)) +def test_scale_shape(): + box = BRepPrimAPI_MakeBox(10.0, 10.0, 10.0).Shape() + box2 = scale_shape(box, 2.0, 1.0, 1.0) + # volume should be double + box2_volume = measure_shape_volume(box2) + assert pytest.approx(box2_volume) == 2000.0 -def suite(): - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(TestExtendShapeFactory)) - return test_suite +def test_measure_shape_center_of_gravity(): + # we compute the cog of a sphere centered at a point P + # then the cog must be P + x, y, z = 10.0, 3.0, -2.44 # random values for point P + radius = 20.0 + vector = gp_Vec(x, y, z) + sph = translate_shp(BRepPrimAPI_MakeSphere(radius).Shape(), vector) + cog, mass, mass_property = measure_shape_mass_center_of_gravity(sph) + assert cog.X() == pytest.approx(x) + assert cog.Y() == pytest.approx(y) + assert cog.Z() == pytest.approx(z) + assert mass == pytest.approx(4 / 3 * math.pi * radius**3) + assert mass_property == "Volume" -if __name__ == "__main__": - unittest.main() + +def test_edge_to_bezier(): + b = BRepPrimAPI_MakeTorus(30, 10).Shape() + t = TopologyExplorer(b) + for ed in t.edges(): + is_bezier, bezier_curve, degree = edge_to_bezier(ed) + assert isinstance(is_bezier, bool) + if not is_bezier: + assert degree is None + assert bezier_curve is None + else: + assert isinstance(degree, int) diff --git a/test/test_core_extend_topology.py b/test/test_core_extend_topology.py index e71f37c31..3d9adda82 100644 --- a/test/test_core_extend_topology.py +++ b/test/test_core_extend_topology.py @@ -48,148 +48,155 @@ def get_test_sphere_shape(radius=10.0): topo = TopologyExplorer(get_test_box_shape()) -class TestExtendTopology(unittest.TestCase): - def test_discretize_edge(self): - tor = BRepPrimAPI_MakeTorus(50, 20).Shape() - topo = TopologyExplorer(tor) - for edge in topo.edges(): - pnts = discretize_edge(edge) - self.assertTrue(pnts) - - def test_discretize_wire(self): - tor = BRepPrimAPI_MakeTorus(50, 20).Shape() - topo = TopologyExplorer(tor) - for wire in topo.wires(): - pnts = discretize_wire(wire) - self.assertTrue(pnts) - - def test_loop_faces(self): - i = 0 - for face in topo.faces(): - i += 1 - self.assertTrue(isinstance(face, TopoDS_Face)) - self.assertEqual(i, 6) - - def test_loop_edges(self): - i = 0 - for face in topo.edges(): - i += 1 - self.assertTrue(isinstance(face, TopoDS_Edge)) - self.assertEqual(i, 12) - - def test_number_of_topological_entities(self): - self.assertEqual(topo.number_of_faces(), 6) - self.assertEqual(topo.number_of_edges(), 12) - self.assertEqual(topo.number_of_vertices(), 8) - self.assertEqual(topo.number_of_wires(), 6) - self.assertEqual(topo.number_of_solids(), 1) - self.assertEqual(topo.number_of_shells(), 1) - self.assertEqual(topo.number_of_compounds(), 0) - self.assertEqual(topo.number_of_comp_solids(), 0) - - def test_nested_iteration(self): - """check nested looping""" - for f in topo.faces(): - for e in topo.edges(): - self.assertTrue(isinstance(f, TopoDS_Face)) - self.assertTrue(isinstance(e, TopoDS_Edge)) - - def test_kept_reference(self): - """did we keep a reference after looping several time through a list - of topological entities?""" - _faces = list(topo.faces()) - _tmp = [f.IsNull() == 0 for f in _faces] - _tmp.extend(f.IsNull() == 0 for f in _faces) - self.assertTrue(all(_tmp)) - - def test_edge_face(self): - edg = next(topo.edges()) - face = next(topo.faces()) - faces_from_edge = list(topo.faces_from_edge(edg)) - self.assertEqual(len(faces_from_edge), topo.number_of_faces_from_edge(edg)) - edges_from_face = list(topo.edges_from_face(face)) - self.assertEqual(len(edges_from_face), topo.number_of_edges_from_face(face)) - - def test_edge_wire(self): - edg = next(topo.edges()) - wire = next(topo.wires()) - wires_from_edge = list(topo.wires_from_edge(edg)) - self.assertEqual(len(wires_from_edge), topo.number_of_wires_from_edge(edg)) - edges_from_wire = list(topo.edges_from_wire(wire)) - self.assertEqual(len(edges_from_wire), topo.number_of_edges_from_wire(wire)) - - def test_vertex_edge(self): - edge = next(topo.edges()) - verts_from_edge = list(topo.vertices_from_edge(edge)) - self.assertEqual(len(verts_from_edge), topo.number_of_vertices_from_edge(edge)) - - def test_vertex_face(self): - vert = next(topo.vertices()) - face = next(topo.faces()) - faces_from_vertex = list(topo.faces_from_vertex(vert)) - self.assertEqual(len(faces_from_vertex), topo.number_of_faces_from_vertex(vert)) - verts_from_face = list(topo.vertices_from_face(face)) - self.assertEqual(len(verts_from_face), topo.number_of_vertices_from_face(face)) - - def test_face_solid(self): - face = next(topo.faces()) - solid = next(topo.solids()) - faces_from_solid = list(topo.faces_from_solids(solid)) - self.assertEqual(len(faces_from_solid), topo.number_of_faces_from_solids(solid)) - solids_from_face = list(topo.solids_from_face(face)) - self.assertEqual(len(solids_from_face), topo.number_of_solids_from_face(face)) - - def test_wire_face(self): - wire = next(topo.wires()) - face = next(topo.faces()) - faces_from_wire = list(topo.faces_from_wire(wire)) - self.assertEqual(len(faces_from_wire), topo.number_of_faces_from_wires(wire)) - wires_from_face = list(topo.wires_from_face(face)) - self.assertEqual(len(wires_from_face), topo.number_of_wires_from_face(face)) - - def test_edges_out_of_scope(self): - # check pointers going out of scope - face = next(topo.faces()) - _edges = list(TopologyExplorer(face).edges()) - for edg in _edges: - self.assertFalse(edg.IsNull()) - - def test_wires_out_of_scope(self): - # check pointers going out of scope - wire = next(topo.wires()) - _edges, _vertices = [], [] - _edges.extend(iter(WireExplorer(wire).ordered_edges())) - for edg in _edges: - self.assertFalse(edg.IsNull()) - _vertices.extend(iter(WireExplorer(wire).ordered_vertices())) - for v in _vertices: - self.assertFalse(v.IsNull()) - - def test_dump_topology_to_string(self): - box_shp = get_test_box_shape() - dump_topology_to_string(box_shp) - - def test_get_type_as_string(self): - box_shp = get_test_box_shape() - self.assertEqual(get_type_as_string(box_shp), "Solid") - - def test_get_sorted_hlr_edges(self): - box_shp = get_test_box_shape() - get_sorted_hlr_edges(box_shp) - - def test_list_of_shapes_to_compound(self): - box_shp = get_test_box_shape() - sph_shp = get_test_sphere_shape(20.0) - result, all_shape_converted = list_of_shapes_to_compound([box_shp, sph_shp]) - self.assertTrue(all_shape_converted) - self.assertEqual(get_type_as_string(result), "Compound") - - -def suite(): - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(TestExtendTopology)) - return test_suite - - -if __name__ == "__main__": - unittest.main() +def test_discretize_edge(): + tor = BRepPrimAPI_MakeTorus(50, 20).Shape() + topo = TopologyExplorer(tor) + for edge in topo.edges(): + pnts = discretize_edge(edge) + assert pnts + + +def test_discretize_wire(): + tor = BRepPrimAPI_MakeTorus(50, 20).Shape() + topo = TopologyExplorer(tor) + for wire in topo.wires(): + pnts = discretize_wire(wire) + assert pnts + + +def test_loop_faces(): + i = 0 + for face in topo.faces(): + i += 1 + assert isinstance(face, TopoDS_Face) + assert i == 6 + + +def test_loop_edges(): + i = 0 + for face in topo.edges(): + i += 1 + assert isinstance(face, TopoDS_Edge) + assert i == 12 + + +def test_number_of_topological_entities(): + assert topo.number_of_faces() == 6 + assert topo.number_of_edges() == 12 + assert topo.number_of_vertices() == 8 + assert topo.number_of_wires() == 6 + assert topo.number_of_solids() == 1 + assert topo.number_of_shells() == 1 + assert topo.number_of_compounds() == 0 + assert topo.number_of_comp_solids() == 0 + + +def test_nested_iteration(): + """check nested looping""" + for f in topo.faces(): + for e in topo.edges(): + assert isinstance(f, TopoDS_Face) + assert isinstance(e, TopoDS_Edge) + + +def test_kept_reference(): + """did we keep a reference after looping several time through a list + of topological entities?""" + _faces = list(topo.faces()) + _tmp = [f.IsNull() == 0 for f in _faces] + _tmp.extend(f.IsNull() == 0 for f in _faces) + assert all(_tmp) + + +def test_edge_face(): + edg = next(topo.edges()) + face = next(topo.faces()) + faces_from_edge = list(topo.faces_from_edge(edg)) + assert len(faces_from_edge) == topo.number_of_faces_from_edge(edg) + edges_from_face = list(topo.edges_from_face(face)) + assert len(edges_from_face) == topo.number_of_edges_from_face(face) + + +def test_edge_wire(): + edg = next(topo.edges()) + wire = next(topo.wires()) + wires_from_edge = list(topo.wires_from_edge(edg)) + assert len(wires_from_edge) == topo.number_of_wires_from_edge(edg) + edges_from_wire = list(topo.edges_from_wire(wire)) + assert len(edges_from_wire) == topo.number_of_edges_from_wire(wire) + + +def test_vertex_edge(): + edge = next(topo.edges()) + verts_from_edge = list(topo.vertices_from_edge(edge)) + assert len(verts_from_edge) == topo.number_of_vertices_from_edge(edge) + + +def test_vertex_face(): + vert = next(topo.vertices()) + face = next(topo.faces()) + faces_from_vertex = list(topo.faces_from_vertex(vert)) + assert len(faces_from_vertex) == topo.number_of_faces_from_vertex(vert) + verts_from_face = list(topo.vertices_from_face(face)) + assert len(verts_from_face) == topo.number_of_vertices_from_face(face) + + +def test_face_solid(): + face = next(topo.faces()) + solid = next(topo.solids()) + faces_from_solid = list(topo.faces_from_solids(solid)) + assert len(faces_from_solid) == topo.number_of_faces_from_solids(solid) + solids_from_face = list(topo.solids_from_face(face)) + assert len(solids_from_face) == topo.number_of_solids_from_face(face) + + +def test_wire_face(): + wire = next(topo.wires()) + face = next(topo.faces()) + faces_from_wire = list(topo.faces_from_wire(wire)) + assert len(faces_from_wire) == topo.number_of_faces_from_wires(wire) + wires_from_face = list(topo.wires_from_face(face)) + assert len(wires_from_face) == topo.number_of_wires_from_face(face) + + +def test_edges_out_of_scope(): + # check pointers going out of scope + face = next(topo.faces()) + _edges = list(TopologyExplorer(face).edges()) + for edg in _edges: + assert not edg.IsNull() + + +def test_wires_out_of_scope(): + # check pointers going out of scope + wire = next(topo.wires()) + _edges, _vertices = [], [] + _edges.extend(iter(WireExplorer(wire).ordered_edges())) + for edg in _edges: + assert not edg.IsNull() + _vertices.extend(iter(WireExplorer(wire).ordered_vertices())) + for v in _vertices: + assert not v.IsNull() + + +def test_dump_topology_to_string(): + box_shp = get_test_box_shape() + dump_topology_to_string(box_shp) + + +def test_get_type_as_string(): + box_shp = get_test_box_shape() + assert get_type_as_string(box_shp) == "Solid" + + +def test_get_sorted_hlr_edges(): + box_shp = get_test_box_shape() + get_sorted_hlr_edges(box_shp) + + +def test_list_of_shapes_to_compound(): + box_shp = get_test_box_shape() + sph_shp = get_test_sphere_shape(20.0) + result, all_shape_converted = list_of_shapes_to_compound([box_shp, sph_shp]) + assert all_shape_converted + assert get_type_as_string(result) == "Compound" diff --git a/test/test_core_geometry.py b/test/test_core_geometry.py index 34830e621..2297ec078 100644 --- a/test/test_core_geometry.py +++ b/test/test_core_geometry.py @@ -151,571 +151,568 @@ def make_face(shape): return face.Shape() -class TestGeometry(unittest.TestCase): - def test_point_from_curve(self): - """Test: point from curve""" - radius, abscissa = 5.0, 3.0 - C = Geom2d_Circle(gp.OX2d(), radius, True) - GAC = Geom2dAdaptor_Curve(C) - UA = GCPnts_UniformAbscissa(GAC, abscissa) - - if UA.IsDone(): - N = UA.NbPoints() - aSequence = [] - for count in range(1, N + 1): - P = gp_Pnt2d() - C.D0(UA.Parameter(count), P) - Parameter = UA.Parameter(count) - self.assertIsInstance(Parameter, float) - aSequence.append(P) - - Abscissa = UA.Abscissa() - self.assertEqual(Abscissa, abscissa) - - def test_project_point_on_curve(self): - """Test: project point on curve""" - P = gp_Pnt(1.0, 2.0, 3.0) - radius = 5.0 - - C = Geom_Circle(gp.XOY(), radius) - PPC = GeomAPI_ProjectPointOnCurve(P, C) - N = PPC.NearestPoint() - self.assertIsInstance(N, gp_Pnt) - NbResults = PPC.NbPoints() - edg = make_edge(C) - self.assertFalse(edg is None) - - if NbResults > 0: - for i in range(1, NbResults + 1): - Q = PPC.Point(i) - self.assertIsInstance(Q, gp_Pnt) - distance = PPC.Distance(i) - # in any case, it should be > 1 - self.assertGreater(distance, 1.0) - - pstring = f"N : at Distance : {repr(PPC.LowerDistance())}" - +def test_point_from_curve(): + """Test: point from curve""" + radius, abscissa = 5.0, 3.0 + C = Geom2d_Circle(gp.OX2d(), radius, True) + GAC = Geom2dAdaptor_Curve(C) + UA = GCPnts_UniformAbscissa(GAC, abscissa) + + if UA.IsDone(): + N = UA.NbPoints() + aSequence = [] + for count in range(1, N + 1): + P = gp_Pnt2d() + C.D0(UA.Parameter(count), P) + Parameter = UA.Parameter(count) + assert isinstance(Parameter, float) + aSequence.append(P) + + Abscissa = UA.Abscissa() + assert Abscissa == abscissa + + +def test_project_point_on_curve(): + """Test: project point on curve""" + P = gp_Pnt(1.0, 2.0, 3.0) + radius = 5.0 + + C = Geom_Circle(gp.XOY(), radius) + PPC = GeomAPI_ProjectPointOnCurve(P, C) + N = PPC.NearestPoint() + assert isinstance(N, gp_Pnt) + NbResults = PPC.NbPoints() + edg = make_edge(C) + assert edg is not None + + if NbResults > 0: for i in range(1, NbResults + 1): Q = PPC.Point(i) - self.assertIsInstance(Q, gp_Pnt) + assert isinstance(Q, gp_Pnt) distance = PPC.Distance(i) # in any case, it should be > 1 - self.assertGreater(distance, 1.0) - pstring = f"Q{repr(i)}: at Distance :{repr(PPC.Distance(i))}" + assert distance > 1.0 + + pstring = f"N : at Distance : {repr(PPC.LowerDistance())}" + + for i in range(1, NbResults + 1): + Q = PPC.Point(i) + assert isinstance(Q, gp_Pnt) + distance = PPC.Distance(i) + # in any case, it should be > 1 + assert distance > 1.0 + pstring = f"Q{repr(i)}: at Distance :{repr(PPC.Distance(i))}" + print(pstring) + + +def test_point_from_projections(): + """Test: point from projections""" + P = gp_Pnt(7.0, 8.0, 9.0) + radius = 5 + SP = Geom_SphericalSurface(gp_Ax3(gp.XOY()), radius) + PPS = GeomAPI_ProjectPointOnSurf(P, SP) + N = PPS.NearestPoint() + assert isinstance(N, gp_Pnt) + NbResults = PPS.NbPoints() + if NbResults > 0: + for i in range(1, NbResults + 1): + Q = PPS.Point(i) + assert isinstance(Q, gp_Pnt) + distance = PPS.Distance(i) + # in any case, it should be > 1 + assert distance > 1.0 + lower_d = PPS.LowerDistance() + assert lower_d > 1.0 + if NbResults > 0: + for i in range(1, NbResults + 1): + Q = PPS.Point(i) + distance = PPS.Distance(i) + pstring = f"Q{repr(i)}: at Distance :{repr(PPS.Distance(i))}" print(pstring) - def test_point_from_projections(self): - """Test: point from projections""" - P = gp_Pnt(7.0, 8.0, 9.0) - radius = 5 - SP = Geom_SphericalSurface(gp_Ax3(gp.XOY()), radius) - PPS = GeomAPI_ProjectPointOnSurf(P, SP) - N = PPS.NearestPoint() - self.assertTrue(isinstance(N, gp_Pnt)) - NbResults = PPS.NbPoints() + +def test_points_from_intersection(): + """Test: points from intersection""" + PL = gp_Pln(gp_Ax3(gp.XOY())) + MinorRadius, MajorRadius = 5, 8 + EL = gp_Elips(gp.YOZ(), MajorRadius, MinorRadius) + ICQ = IntAna_IntConicQuad(EL, PL, precision.Angular(), precision.Confusion()) + if ICQ.IsDone(): + NbResults = ICQ.NbPoints() if NbResults > 0: for i in range(1, NbResults + 1): - Q = PPS.Point(i) - self.assertTrue(isinstance(Q, gp_Pnt)) - distance = PPS.Distance(i) - # in any case, it should be > 1 - self.assertGreater(distance, 1.0) - lower_d = PPS.LowerDistance() - self.assertGreater(lower_d, 1.0) + P = ICQ.Point(i) + assert isinstance(P, gp_Pnt) + aPlane = GC_MakePlane(PL).Value() + aSurface = Geom_RectangularTrimmedSurface( + aPlane, -8.0, 8.0, -12.0, 12.0, True, True + ) + assert aSurface is not None + anEllips = GC_MakeEllipse(EL).Value() + assert isinstance(anEllips, Geom_Ellipse) + if ICQ.IsDone(): + NbResults = ICQ.NbPoints() if NbResults > 0: for i in range(1, NbResults + 1): - Q = PPS.Point(i) - distance = PPS.Distance(i) - pstring = f"Q{repr(i)}: at Distance :{repr(PPS.Distance(i))}" - print(pstring) - - def test_points_from_intersection(self): - """Test: points from intersection""" - PL = gp_Pln(gp_Ax3(gp.XOY())) - MinorRadius, MajorRadius = 5, 8 - EL = gp_Elips(gp.YOZ(), MajorRadius, MinorRadius) - ICQ = IntAna_IntConicQuad(EL, PL, precision.Angular(), precision.Confusion()) - if ICQ.IsDone(): - NbResults = ICQ.NbPoints() - if NbResults > 0: - for i in range(1, NbResults + 1): - P = ICQ.Point(i) - self.assertIsInstance(P, gp_Pnt) - aPlane = GC_MakePlane(PL).Value() - aSurface = Geom_RectangularTrimmedSurface( - aPlane, -8.0, 8.0, -12.0, 12.0, True, True - ) - self.assertIsNotNone(aSurface) - self.assertFalse(aSurface is None) - anEllips = GC_MakeEllipse(EL).Value() - self.assertIsInstance(anEllips, Geom_Ellipse) - if ICQ.IsDone(): - NbResults = ICQ.NbPoints() - if NbResults > 0: - for i in range(1, NbResults + 1): - P = ICQ.Point(i) - self.assertIsInstance(P, gp_Pnt) - # pstring = "P%i" % i - - def test_parabola(self): - """Test: parabola""" - # P is the vertex point - # P and D give the axis of symmetry - # 6 is the focal length of the parabola - P = gp_Pnt2d(2.0, 3.0) - D = gp_Dir2d(4.0, 5.0) - A = gp_Ax22d(P, D, True) - Para = gp_Parab2d(A, 6) - aParabola = GCE2d_MakeParabola(Para) - gParabola = aParabola.Value() - self.assertIsInstance(gParabola, Geom2d_Parabola) - aTrimmedCurve = Geom2d_TrimmedCurve(gParabola, -100, 100, True) - self.assertIsNotNone(aTrimmedCurve) - self.assertFalse(aTrimmedCurve is None) - - def test_axis(self): - """Test: axis""" - P1 = gp_Pnt(2, 3, 4) - D = gp_Dir(4, 5, 6) - A = gp_Ax3(P1, D) - IsDirectA = A.Direct() - self.assertTrue(IsDirectA) - AXDirection = A.XDirection() - self.assertIsInstance(AXDirection, gp_Dir) - AYDirection = A.YDirection() - self.assertIsInstance(AYDirection, gp_Dir) - P2 = gp_Pnt(5, 3, 4) - A2 = gp_Ax3(P2, D) - A2.YReverse() - # axis3 is now left handed - IsDirectA2 = A2.Direct() - self.assertFalse(IsDirectA2) - A2XDirection = A2.XDirection() - self.assertTrue(isinstance(A2XDirection, gp_Dir)) - A2YDirection = A2.YDirection() - self.assertTrue(isinstance(A2YDirection, gp_Dir)) - - def test_bspline(self): - """Test: bspline""" - array = [gp_Pnt2d(0, 0)] - array.append(gp_Pnt2d(1, 2)) - array.append(gp_Pnt2d(2, 3)) - array.append(gp_Pnt2d(4, 3)) - array.append(gp_Pnt2d(5, 5)) - - xxx = point2d_list_to_TColgp_Array1OfPnt2d(array) - SPL1 = Geom2dAPI_PointsToBSpline(xxx).Curve() - self.assertTrue(SPL1 is not None) - - harray = TColgp_HArray1OfPnt2d(1, 5) - harray.SetValue(1, gp_Pnt2d(7 + 0, 0)) - harray.SetValue(2, gp_Pnt2d(7 + 1, 2)) - harray.SetValue(3, gp_Pnt2d(7 + 2, 3)) - harray.SetValue(4, gp_Pnt2d(7 + 4, 3)) - harray.SetValue(5, gp_Pnt2d(7 + 5, 5)) - - anInterpolation = Geom2dAPI_Interpolate(harray, False, 0.01) - anInterpolation.Perform() - SPL2 = anInterpolation.Curve() - self.assertTrue(SPL2 is not None) - - harray2 = TColgp_HArray1OfPnt2d(1, 5) - harray2.SetValue(1, gp_Pnt2d(11 + 0, 0)) - harray2.SetValue(2, gp_Pnt2d(11 + 1, 2)) - harray2.SetValue(3, gp_Pnt2d(11 + 2, 3)) - harray2.SetValue(4, gp_Pnt2d(11 + 4, 3)) - harray2.SetValue(5, gp_Pnt2d(11 + 5, 5)) - - anInterpolation2 = Geom2dAPI_Interpolate(harray2, True, 0.01) - anInterpolation2.Perform() - SPL3 = anInterpolation2.Curve() - self.assertTrue(SPL3 is not None) - i = 0 - for P in array: - i = i + 1 - make_vertex(P) - for j in range(harray.Lower(), harray.Upper() + 1): - i = i + 1 - P = harray.Value(j) - make_vertex(P) - - for j in range(harray2.Lower(), harray2.Upper() + 1): - i = i + 1 - P = harray2.Value(j) - make_vertex(P) - - def test_curves2d_from_curves(self): - """Test: curves 2d from curves""" - major, minor = 12, 4 - axis = gp.OX2d() - ell = GCE2d_MakeEllipse(axis, major, minor) - E = ell.Value() - TC = Geom2d_TrimmedCurve(E, -1, 2, True) - SPL = geom2dconvert.CurveToBSplineCurve(TC, Convert_TgtThetaOver2) - self.assertTrue(SPL is not None) - - def test_curves2d_from_offset(self): - """Test: curves 2d from offset""" - array = [gp_Pnt2d(-4, 0)] - array.append(gp_Pnt2d(-7, 2)) - array.append(gp_Pnt2d(-6, 3)) - array.append(gp_Pnt2d(-4, 3)) - array.append(gp_Pnt2d(-3, 5)) - - xxx = point2d_list_to_TColgp_Array1OfPnt2d(array) - SPL1 = Geom2dAPI_PointsToBSpline(xxx).Curve() - self.assertTrue(SPL1 is not None) - - dist = 1 - OC = Geom2d_OffsetCurve(SPL1, dist) - result = OC.IsCN(2) - self.assertTrue(result) - - dist2 = 1.5 - OC2 = Geom2d_OffsetCurve(SPL1, dist2) - result2 = OC2.IsCN(2) - self.assertTrue(result2) - - def test_circles2d_from_curves(self): - """Test: circles2d from curves""" - P1 = gp_Pnt2d(9, 6) - P2 = gp_Pnt2d(10, 4) - P3 = gp_Pnt2d(6, 7) - C = gce_MakeCirc2d(P1, P2, P3).Value() - - QC = gccent.Outside(C) - P4 = gp_Pnt2d(-2, 7) - P5 = gp_Pnt2d(12, -3) - L = GccAna_Lin2d2Tan(P4, P5, precision.Confusion()).ThisSolution(1) - - QL = gccent.Unqualified(L) - radius = 2.0 - TR = GccAna_Circ2d2TanRad(QC, QL, radius, precision.Confusion()) - - if TR.IsDone(): - NbSol = TR.NbSolutions() - for k in range(1, NbSol + 1): - circ = TR.ThisSolution(k) - # find the solution circle - pnt1 = gp_Pnt2d() - parsol, pararg = TR.Tangency1(k, pnt1) - self.assertGreater(parsol, 0.0) - self.assertGreater(pararg, 0.0) - # find the first tangent point - pnt2 = gp_Pnt2d() - parsol, pararg = TR.Tangency2(k, pnt2) - self.assertGreater(parsol, 0.0) - self.assertGreater(pararg, 0.0) - # find the second tangent point - - aLine = GCE2d_MakeSegment(L, -2, 20).Value() - self.assertIsInstance(aLine, Geom2d_TrimmedCurve) - if TR.IsDone(): - NbSol = TR.NbSolutions() - for k in range(1, NbSol + 1): - circ = TR.ThisSolution(k) - aCircle = Geom2d_Circle(circ) - self.assertIsInstance(aCircle, Geom2d_Circle) - # find the solution circle (index, outvalue, outvalue, gp_Pnt2d) - pnt3 = gp_Pnt2d() - parsol, pararg = TR.Tangency1(k, pnt3) - self.assertGreater(parsol, 0.0) - self.assertGreater(pararg, 0.0) - # find the first tangent point - pnt4 = gp_Pnt2d() - parsol, pararg = TR.Tangency2(k, pnt4) - self.assertGreater(parsol, 0.0) - self.assertGreater(pararg, 0.0) - - def test_surface_from_curves(self): - """Test: surfaces from curves""" - array = [gp_Pnt(-4, 0, 2)] - array.append(gp_Pnt(-7, 2, 2)) - array.append(gp_Pnt(-6, 3, 1)) - array.append(gp_Pnt(-4, 3, -1)) - array.append(gp_Pnt(-3, 5, -2)) - - aaa = point_list_to_TColgp_Array1OfPnt(array) - SPL1 = GeomAPI_PointsToBSpline(aaa).Curve() - - a2 = [gp_Pnt(-4, 0, 2)] - a2.append(gp_Pnt(-2, 2, 0)) - a2.append(gp_Pnt(2, 3, -1)) - a2.append(gp_Pnt(3, 7, -2)) - a2.append(gp_Pnt(4, 9, -1)) - bbb = point_list_to_TColgp_Array1OfPnt(a2) - SPL2 = GeomAPI_PointsToBSpline(bbb).Curve() - - aGeomFill1 = GeomFill_BSplineCurves(SPL1, SPL2, GeomFill_StretchStyle) - - SPL3 = Geom_BSplineCurve.DownCast(SPL1.Translated(gp_Vec(10, 0, 0))) - SPL4 = Geom_BSplineCurve.DownCast(SPL2.Translated(gp_Vec(10, 0, 0))) - aGeomFill2 = GeomFill_BSplineCurves(SPL3, SPL4, GeomFill_CoonsStyle) - - SPL5 = Geom_BSplineCurve.DownCast(SPL1.Translated(gp_Vec(20, 0, 0))) - SPL6 = Geom_BSplineCurve.DownCast(SPL2.Translated(gp_Vec(20, 0, 0))) - aGeomFill3 = GeomFill_BSplineCurves(SPL5, SPL6, GeomFill_CurvedStyle) - - aBSplineSurface1 = aGeomFill1.Surface() - self.assertTrue(aBSplineSurface1 is not None) - aBSplineSurface2 = aGeomFill2.Surface() - self.assertTrue(aBSplineSurface2 is not None) - aBSplineSurface3 = aGeomFill3.Surface() - self.assertTrue(aBSplineSurface3 is not None) - - def test_pipes(self): - """Test: pipes""" - a1 = [gp_Pnt(-4, 0, 2)] - a1.append(gp_Pnt(-5, 1, 0)) - a1.append(gp_Pnt(-6, 2, -2)) - a1.append(gp_Pnt(-5, 4, -7)) - a1.append(gp_Pnt(-3, 5, -12)) - - xxx = point_list_to_TColgp_Array1OfPnt(a1) - SPL1 = GeomAPI_PointsToBSpline(xxx).Curve() - - aPipe = GeomFill_Pipe(SPL1, True) - aPipe.Perform(False, False) - aSurface = aPipe.Surface() - self.assertIsNotNone(aSurface) - + P = ICQ.Point(i) + assert isinstance(P, gp_Pnt) + # pstring = "P%i" % i + + +def test_parabola(): + """Test: parabola""" + # P is the vertex point + # P and D give the axis of symmetry + # 6 is the focal length of the parabola + P = gp_Pnt2d(2.0, 3.0) + D = gp_Dir2d(4.0, 5.0) + A = gp_Ax22d(P, D, True) + Para = gp_Parab2d(A, 6) + aParabola = GCE2d_MakeParabola(Para) + gParabola = aParabola.Value() + assert isinstance(gParabola, Geom2d_Parabola) + aTrimmedCurve = Geom2d_TrimmedCurve(gParabola, -100, 100, True) + assert aTrimmedCurve is not None + + +def test_axis(): + """Test: axis""" + P1 = gp_Pnt(2, 3, 4) + D = gp_Dir(4, 5, 6) + A = gp_Ax3(P1, D) + assert A.Direct() + AXDirection = A.XDirection() + assert isinstance(AXDirection, gp_Dir) + AYDirection = A.YDirection() + assert isinstance(AYDirection, gp_Dir) + P2 = gp_Pnt(5, 3, 4) + A2 = gp_Ax3(P2, D) + A2.YReverse() + # axis3 is now left handed + assert not A2.Direct() + + assert isinstance(A2.XDirection(), gp_Dir) + + assert isinstance(A2.YDirection(), gp_Dir) + + +def test_bspline(): + """Test: bspline""" + array = [gp_Pnt2d(0, 0)] + array.append(gp_Pnt2d(1, 2)) + array.append(gp_Pnt2d(2, 3)) + array.append(gp_Pnt2d(4, 3)) + array.append(gp_Pnt2d(5, 5)) + + xxx = point2d_list_to_TColgp_Array1OfPnt2d(array) + SPL1 = Geom2dAPI_PointsToBSpline(xxx).Curve() + assert SPL1 is not None + + harray = TColgp_HArray1OfPnt2d(1, 5) + harray.SetValue(1, gp_Pnt2d(7 + 0, 0)) + harray.SetValue(2, gp_Pnt2d(7 + 1, 2)) + harray.SetValue(3, gp_Pnt2d(7 + 2, 3)) + harray.SetValue(4, gp_Pnt2d(7 + 4, 3)) + harray.SetValue(5, gp_Pnt2d(7 + 5, 5)) + + anInterpolation = Geom2dAPI_Interpolate(harray, False, 0.01) + anInterpolation.Perform() + SPL2 = anInterpolation.Curve() + assert SPL2 is not None + + harray2 = TColgp_HArray1OfPnt2d(1, 5) + harray2.SetValue(1, gp_Pnt2d(11 + 0, 0)) + harray2.SetValue(2, gp_Pnt2d(11 + 1, 2)) + harray2.SetValue(3, gp_Pnt2d(11 + 2, 3)) + harray2.SetValue(4, gp_Pnt2d(11 + 4, 3)) + harray2.SetValue(5, gp_Pnt2d(11 + 5, 5)) + + anInterpolation2 = Geom2dAPI_Interpolate(harray2, True, 0.01) + anInterpolation2.Perform() + SPL3 = anInterpolation2.Curve() + assert SPL3 is not None + i = 0 + for P in array: + i = i + 1 + make_vertex(P) + for j in range(harray.Lower(), harray.Upper() + 1): + i = i + 1 + P = harray.Value(j) + make_vertex(P) + + for j in range(harray2.Lower(), harray2.Upper() + 1): + i = i + 1 + P = harray2.Value(j) + make_vertex(P) + + +def test_curves2d_from_curves(): + """Test: curves 2d from curves""" + major, minor = 12, 4 + axis = gp.OX2d() + ell = GCE2d_MakeEllipse(axis, major, minor) + E = ell.Value() + TC = Geom2d_TrimmedCurve(E, -1, 2, True) + SPL = geom2dconvert.CurveToBSplineCurve(TC, Convert_TgtThetaOver2) + assert SPL is not None + + +def test_curves2d_from_offset(): + """Test: curves 2d from offset""" + array = [gp_Pnt2d(-4, 0)] + array.append(gp_Pnt2d(-7, 2)) + array.append(gp_Pnt2d(-6, 3)) + array.append(gp_Pnt2d(-4, 3)) + array.append(gp_Pnt2d(-3, 5)) + + xxx = point2d_list_to_TColgp_Array1OfPnt2d(array) + SPL1 = Geom2dAPI_PointsToBSpline(xxx).Curve() + assert SPL1 is not None + + dist = 1 + OC = Geom2d_OffsetCurve(SPL1, dist) + assert OC.IsCN(2) + + dist2 = 1.5 + OC2 = Geom2d_OffsetCurve(SPL1, dist2) + assert OC2.IsCN(2) + + +def test_circles2d_from_curves(): + """Test: circles2d from curves""" + P1 = gp_Pnt2d(9, 6) + P2 = gp_Pnt2d(10, 4) + P3 = gp_Pnt2d(6, 7) + C = gce_MakeCirc2d(P1, P2, P3).Value() + + QC = gccent.Outside(C) + P4 = gp_Pnt2d(-2, 7) + P5 = gp_Pnt2d(12, -3) + L = GccAna_Lin2d2Tan(P4, P5, precision.Confusion()).ThisSolution(1) + + QL = gccent.Unqualified(L) + radius = 2.0 + TR = GccAna_Circ2d2TanRad(QC, QL, radius, precision.Confusion()) + + if TR.IsDone(): + NbSol = TR.NbSolutions() + for k in range(1, NbSol + 1): + circ = TR.ThisSolution(k) + # find the solution circle + pnt1 = gp_Pnt2d() + parsol, pararg = TR.Tangency1(k, pnt1) + assert parsol > 0.0 + assert pararg > 0.0 + # find the first tangent point + pnt2 = gp_Pnt2d() + parsol, pararg = TR.Tangency2(k, pnt2) + assert parsol > 0.0 + assert pararg > 0.0 + # find the second tangent point + + aLine = GCE2d_MakeSegment(L, -2, 20).Value() + assert isinstance(aLine, Geom2d_TrimmedCurve) + if TR.IsDone(): + NbSol = TR.NbSolutions() + for k in range(1, NbSol + 1): + circ = TR.ThisSolution(k) + aCircle = Geom2d_Circle(circ) + assert isinstance(aCircle, Geom2d_Circle) + # find the solution circle (index, outvalue, outvalue, gp_Pnt2d) + pnt3 = gp_Pnt2d() + parsol, pararg = TR.Tangency1(k, pnt3) + assert parsol > 0.0 + assert pararg > 0.0 + # find the first tangent point + pnt4 = gp_Pnt2d() + parsol, pararg = TR.Tangency2(k, pnt4) + assert parsol > 0.0 + assert pararg > 0.0 + + +def test_surface_from_curves(): + """Test: surfaces from curves""" + array = [gp_Pnt(-4, 0, 2)] + array.append(gp_Pnt(-7, 2, 2)) + array.append(gp_Pnt(-6, 3, 1)) + array.append(gp_Pnt(-4, 3, -1)) + array.append(gp_Pnt(-3, 5, -2)) + + aaa = point_list_to_TColgp_Array1OfPnt(array) + SPL1 = GeomAPI_PointsToBSpline(aaa).Curve() + + a2 = [gp_Pnt(-4, 0, 2)] + a2.append(gp_Pnt(-2, 2, 0)) + a2.append(gp_Pnt(2, 3, -1)) + a2.append(gp_Pnt(3, 7, -2)) + a2.append(gp_Pnt(4, 9, -1)) + bbb = point_list_to_TColgp_Array1OfPnt(a2) + SPL2 = GeomAPI_PointsToBSpline(bbb).Curve() + + aGeomFill1 = GeomFill_BSplineCurves(SPL1, SPL2, GeomFill_StretchStyle) + + SPL3 = Geom_BSplineCurve.DownCast(SPL1.Translated(gp_Vec(10, 0, 0))) + SPL4 = Geom_BSplineCurve.DownCast(SPL2.Translated(gp_Vec(10, 0, 0))) + aGeomFill2 = GeomFill_BSplineCurves(SPL3, SPL4, GeomFill_CoonsStyle) + + SPL5 = Geom_BSplineCurve.DownCast(SPL1.Translated(gp_Vec(20, 0, 0))) + SPL6 = Geom_BSplineCurve.DownCast(SPL2.Translated(gp_Vec(20, 0, 0))) + aGeomFill3 = GeomFill_BSplineCurves(SPL5, SPL6, GeomFill_CurvedStyle) + + aBSplineSurface1 = aGeomFill1.Surface() + assert aBSplineSurface1 is not None + aBSplineSurface2 = aGeomFill2.Surface() + assert aBSplineSurface2 is not None + aBSplineSurface3 = aGeomFill3.Surface() + assert aBSplineSurface3 is not None + + +def test_pipes(): + """Test: pipes""" + a1 = [gp_Pnt(-4, 0, 2)] + a1.append(gp_Pnt(-5, 1, 0)) + a1.append(gp_Pnt(-6, 2, -2)) + a1.append(gp_Pnt(-5, 4, -7)) + a1.append(gp_Pnt(-3, 5, -12)) + + xxx = point_list_to_TColgp_Array1OfPnt(a1) + SPL1 = GeomAPI_PointsToBSpline(xxx).Curve() + + aPipe = GeomFill_Pipe(SPL1, True) + aPipe.Perform(False, False) + aSurface = aPipe.Surface() + assert aSurface is not None + + E = GC_MakeEllipse(gp.XOY(), 2, 1).Value() + aPipe2 = GeomFill_Pipe(SPL1, E, GeomFill_IsConstantNormal) + aPipe2.Perform(False, False) + aSurface2 = aPipe2.Surface() + aSurface2.Translate(gp_Vec(5, 0, 0)) + + TC1 = GC_MakeSegment(gp_Pnt(1, 1, 1), gp_Pnt(2, 2, 2)).Value() + TC2 = GC_MakeSegment(gp_Pnt(1, 1, 0), gp_Pnt(3, 2, 1)).Value() + # TODO: following lines bug with occt-770 + # aPipe3 = GeomFill_Pipe(SPL1, TC1, TC2) + # aPipe3.Perform(False, False) + # aSurface3 = aPipe3.Surface() + # aSurface3.Translate(gp_Vec(10, 0, 0)) + + for mode in [ + GeomFill_IsConstantNormal, + GeomFill_IsCorrectedFrenet, + GeomFill_IsDarboux, + GeomFill_IsFrenet, + GeomFill_IsGuideAC, + GeomFill_IsGuideACWithContact, + GeomFill_IsGuidePlan, + GeomFill_IsGuidePlanWithContact, + ]: E = GC_MakeEllipse(gp.XOY(), 2, 1).Value() - aPipe2 = GeomFill_Pipe(SPL1, E, GeomFill_IsConstantNormal) + aPipe2 = GeomFill_Pipe(SPL1, TC1, TC2, mode) aPipe2.Perform(False, False) aSurface2 = aPipe2.Surface() - aSurface2.Translate(gp_Vec(5, 0, 0)) - - TC1 = GC_MakeSegment(gp_Pnt(1, 1, 1), gp_Pnt(2, 2, 2)).Value() - TC2 = GC_MakeSegment(gp_Pnt(1, 1, 0), gp_Pnt(3, 2, 1)).Value() - # TODO: following lines bug with occt-770 - # aPipe3 = GeomFill_Pipe(SPL1, TC1, TC2) - # aPipe3.Perform(False, False) - # aSurface3 = aPipe3.Surface() - # aSurface3.Translate(gp_Vec(10, 0, 0)) - - for mode in [ - GeomFill_IsConstantNormal, - GeomFill_IsCorrectedFrenet, - GeomFill_IsDarboux, - GeomFill_IsFrenet, - GeomFill_IsGuideAC, - GeomFill_IsGuideACWithContact, - GeomFill_IsGuidePlan, - GeomFill_IsGuidePlanWithContact, - ]: - E = GC_MakeEllipse(gp.XOY(), 2, 1).Value() - aPipe2 = GeomFill_Pipe(SPL1, TC1, TC2, mode) - aPipe2.Perform(False, False) - aSurface2 = aPipe2.Surface() - aSurface2.Translate(gp_Vec(5, 5, 0)) - - def test_bezier_surfaces(self): - """Test: Bezier surfaces""" - array1 = TColgp_Array2OfPnt(1, 3, 1, 3) - array2 = TColgp_Array2OfPnt(1, 3, 1, 3) - array3 = TColgp_Array2OfPnt(1, 3, 1, 3) - array4 = TColgp_Array2OfPnt(1, 3, 1, 3) - - array1.SetValue(1, 1, gp_Pnt(1, 1, 1)) - array1.SetValue(1, 2, gp_Pnt(2, 1, 2)) - array1.SetValue(1, 3, gp_Pnt(3, 1, 1)) - array1.SetValue(2, 1, gp_Pnt(1, 2, 1)) - array1.SetValue(2, 2, gp_Pnt(2, 2, 2)) - array1.SetValue(2, 3, gp_Pnt(3, 2, 0)) - array1.SetValue(3, 1, gp_Pnt(1, 3, 2)) - array1.SetValue(3, 2, gp_Pnt(2, 3, 1)) - array1.SetValue(3, 3, gp_Pnt(3, 3, 0)) - - array2.SetValue(1, 1, gp_Pnt(3, 1, 1)) - array2.SetValue(1, 2, gp_Pnt(4, 1, 1)) - array2.SetValue(1, 3, gp_Pnt(5, 1, 2)) - array2.SetValue(2, 1, gp_Pnt(3, 2, 0)) - array2.SetValue(2, 2, gp_Pnt(4, 2, 1)) - array2.SetValue(2, 3, gp_Pnt(5, 2, 2)) - array2.SetValue(3, 1, gp_Pnt(3, 3, 0)) - array2.SetValue(3, 2, gp_Pnt(4, 3, 0)) - array2.SetValue(3, 3, gp_Pnt(5, 3, 1)) - - array3.SetValue(1, 1, gp_Pnt(1, 3, 2)) - array3.SetValue(1, 2, gp_Pnt(2, 3, 1)) - array3.SetValue(1, 3, gp_Pnt(3, 3, 0)) - array3.SetValue(2, 1, gp_Pnt(1, 4, 1)) - array3.SetValue(2, 2, gp_Pnt(2, 4, 0)) - array3.SetValue(2, 3, gp_Pnt(3, 4, 1)) - array3.SetValue(3, 1, gp_Pnt(1, 5, 1)) - array3.SetValue(3, 2, gp_Pnt(2, 5, 1)) - array3.SetValue(3, 3, gp_Pnt(3, 5, 2)) - - array4.SetValue(1, 1, gp_Pnt(3, 3, 0)) - array4.SetValue(1, 2, gp_Pnt(4, 3, 0)) - array4.SetValue(1, 3, gp_Pnt(5, 3, 1)) - array4.SetValue(2, 1, gp_Pnt(3, 4, 1)) - array4.SetValue(2, 2, gp_Pnt(4, 4, 1)) - array4.SetValue(2, 3, gp_Pnt(5, 4, 1)) - array4.SetValue(3, 1, gp_Pnt(3, 5, 2)) - array4.SetValue(3, 2, gp_Pnt(4, 5, 2)) - array4.SetValue(3, 3, gp_Pnt(5, 5, 1)) - - # BZ1, BZ2, BZ3, BZ4 = map(Geom_BezierSurface, [array1, array2, array3, array4]) - # bezierarray = TColGeom_Array2OfBezierSurface(1, 2, 1, 2) - # bezierarray.SetValue(1, 1, BZ1) - # bezierarray.SetValue(1, 2, BZ2) - # bezierarray.SetValue(2, 1, BZ3) - # bezierarray.SetValue(2, 2, BZ4) - - # BB = GeomConvert_CompBezierSurfacesToBSplineSurface(bezierarray) - # self.assertTrue(BB.IsDone()) - # poles = BB.Poles().Array2() - # uknots = BB.UKnots().Array1() - # vknots = BB.VKnots().Array1() - # umult = BB.UMultiplicities().Array1() - # vmult = BB.VMultiplicities().Array1() - # udeg = BB.UDegree() - # vdeg = BB.VDegree() - - # BSPLSURF = Geom_BSplineSurface( - # poles, uknots, vknots, umult, vmult, udeg, vdeg, False, False - # ) - # BSPLSURF.Translate(gp_Vec(0, 0, 2)) - - def test_surfaces_from_offsets(self): - """Test: surfaces from offsets""" - array1 = [gp_Pnt(-4, 5, 5)] - array1.append(gp_Pnt(-3, 6, 6)) - array1.append(gp_Pnt(-1, 7, 7)) - array1.append(gp_Pnt(0, 8, 8)) - array1.append(gp_Pnt(2, 9, 9)) - SPL1 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array1)).Curve() - - array2 = [gp_Pnt(-4, 5, 2)] - array2.append(gp_Pnt(-3, 6, 3)) - array2.append(gp_Pnt(-1, 7, 4)) - array2.append(gp_Pnt(0, 8, 5)) - array2.append(gp_Pnt(2, 9, 6)) - SPL2 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array2)).Curve() - - aGeomFill1 = GeomFill_BSplineCurves(SPL1, SPL2, GeomFill_StretchStyle) - aGeomSurface = aGeomFill1.Surface() - - offset = 1 - GOS = Geom_OffsetSurface(aGeomSurface, offset) - offset = 2 - GOS1 = Geom_OffsetSurface(aGeomSurface, offset) - offset = 3 - GOS2 = Geom_OffsetSurface(aGeomSurface, offset) - - face1 = make_face(aGeomSurface) - self.assertTrue(face1 is not None) - face2 = make_face(GOS) - self.assertTrue(face2 is not None) - face3 = make_face(GOS1) - self.assertTrue(face3 is not None) - face4 = make_face(GOS2) - self.assertTrue(face4 is not None) - - def test_surfaces_from_revolution(self): - """Test: surfaces from revolution""" - array = [gp_Pnt(0, 0, 1)] - array.append(gp_Pnt(1, 2, 2)) - array.append(gp_Pnt(2, 3, 3)) - array.append(gp_Pnt(4, 3, 4)) - array.append(gp_Pnt(5, 5, 5)) - aCurve = GeomAPI_PointsToBSpline( - point_list_to_TColgp_Array1OfPnt(array) - ).Curve() - SOR = Geom_SurfaceOfRevolution(aCurve, gp.OX()) - edge = make_edge(aCurve) - self.assertFalse(edge is None) - face = make_face(SOR) - self.assertFalse(face is None) - - def test_distances(self): - """Test: distances""" - array1 = [gp_Pnt(-5, 1, 2)] - array1.append(gp_Pnt(-5, 2, 2)) - array1.append(gp_Pnt(-5.3, 3, 1)) - array1.append(gp_Pnt(-5, 4, 1)) - array1.append(gp_Pnt(-5, 5, 2)) - SPL1 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array1)).Curve() - array2 = [gp_Pnt(4, 1, 2)] - array2.append(gp_Pnt(4, 2, 2)) - array2.append(gp_Pnt(3.7, 3, 1)) - array2.append(gp_Pnt(4, 4, 1)) - array2.append(gp_Pnt(4, 5, 2)) - SPL2 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array2)).Curve() - aGeomFill1 = GeomFill_BSplineCurves(SPL1, SPL2, GeomFill_StretchStyle) - aSurf1 = aGeomFill1.Surface() - - array3 = TColgp_Array2OfPnt(1, 5, 1, 5) - array3.SetValue(1, 1, gp_Pnt(-4, -4, 5)) - array3.SetValue(1, 2, gp_Pnt(-4, -2, 5)) - array3.SetValue(1, 3, gp_Pnt(-4, 0, 4)) - array3.SetValue(1, 4, gp_Pnt(-4, 2, 5)) - array3.SetValue(1, 5, gp_Pnt(-4, 4, 5)) - - array3.SetValue(2, 1, gp_Pnt(-2, -4, 4)) - array3.SetValue(2, 2, gp_Pnt(-2, -2, 4)) - array3.SetValue(2, 3, gp_Pnt(-2, 0, 4)) - array3.SetValue(2, 4, gp_Pnt(-2, 2, 4)) - array3.SetValue(2, 5, gp_Pnt(-2, 5, 4)) - - array3.SetValue(3, 1, gp_Pnt(0, -4, 3.5)) - array3.SetValue(3, 2, gp_Pnt(0, -2, 3.5)) - array3.SetValue(3, 3, gp_Pnt(0, 0, 3.5)) - array3.SetValue(3, 4, gp_Pnt(0, 2, 3.5)) - array3.SetValue(3, 5, gp_Pnt(0, 5, 3.5)) - - array3.SetValue(4, 1, gp_Pnt(2, -4, 4)) - array3.SetValue(4, 2, gp_Pnt(2, -2, 4)) - array3.SetValue(4, 3, gp_Pnt(2, 0, 3.5)) - array3.SetValue(4, 4, gp_Pnt(2, 2, 5)) - array3.SetValue(4, 5, gp_Pnt(2, 5, 4)) - - array3.SetValue(5, 1, gp_Pnt(4, -4, 5)) - array3.SetValue(5, 2, gp_Pnt(4, -2, 5)) - array3.SetValue(5, 3, gp_Pnt(4, 0, 5)) - array3.SetValue(5, 4, gp_Pnt(4, 2, 6)) - array3.SetValue(5, 5, gp_Pnt(4, 5, 5)) - - aSurf2 = GeomAPI_PointsToBSplineSurface(array3).Surface() - ESS = GeomAPI_ExtremaSurfaceSurface(aSurf1, aSurf2) - dist = ESS.LowerDistance() - self.assertGreater(dist, 1.20) - self.assertLess(dist, 1.25) - a, b = gp_Pnt(), gp_Pnt() - ESS.NearestPoints(a, b) - - NbExtrema = ESS.NbExtrema() - for k in range(1, NbExtrema + 1): - P3, P4 = gp_Pnt(), gp_Pnt() - ESS.Points(k, P3, P4) - aCurve = GC_MakeSegment(P3, P4).Value() - self.assertFalse(aCurve is None) - - def test_curve_adaptor(self): - # related to issue #1057 https://github.com/tpaviot/pythonocc-core/issues/1057 - p1 = gp_Pnt(5, -5, 0) - p2 = gp_Pnt(5, 5, 0) - ed1 = BRepBuilderAPI_MakeEdge(p2, p1).Edge() - c1 = BRepAdaptor_Curve(ed1) - self.assertTrue(isinstance(c1, BRepAdaptor_Curve)) - # self.assertTrue(isinstance(c1.Curve(), GeomAdaptor_Curve)) - # should pass on all platforms - # self.assertTrue(isinstance(c1.Curve().Curve(), Geom_Curve)) - # c2 = BRepAdaptor_Curve(ed1).Curve() - # only works on linux - # if sys.platform == "linux": - # self.assertTrue(isinstance(c2.Curve(), Geom_Curve)) - # self.assertTrue( - # isinstance(BRepAdaptor_Curve(ed1).Curve().Curve(), Geom_Curve) - # ) - - -def suite(): - uts = unittest.TestSuite() - uts.addTest(unittest.makeSuite(TestGeometry)) - return uts - - -if __name__ == "__main__": - unittest.main() + aSurface2.Translate(gp_Vec(5, 5, 0)) + + +def test_bezier_surfaces(): + """Test: Bezier surfaces""" + array1 = TColgp_Array2OfPnt(1, 3, 1, 3) + array2 = TColgp_Array2OfPnt(1, 3, 1, 3) + array3 = TColgp_Array2OfPnt(1, 3, 1, 3) + array4 = TColgp_Array2OfPnt(1, 3, 1, 3) + + array1.SetValue(1, 1, gp_Pnt(1, 1, 1)) + array1.SetValue(1, 2, gp_Pnt(2, 1, 2)) + array1.SetValue(1, 3, gp_Pnt(3, 1, 1)) + array1.SetValue(2, 1, gp_Pnt(1, 2, 1)) + array1.SetValue(2, 2, gp_Pnt(2, 2, 2)) + array1.SetValue(2, 3, gp_Pnt(3, 2, 0)) + array1.SetValue(3, 1, gp_Pnt(1, 3, 2)) + array1.SetValue(3, 2, gp_Pnt(2, 3, 1)) + array1.SetValue(3, 3, gp_Pnt(3, 3, 0)) + + array2.SetValue(1, 1, gp_Pnt(3, 1, 1)) + array2.SetValue(1, 2, gp_Pnt(4, 1, 1)) + array2.SetValue(1, 3, gp_Pnt(5, 1, 2)) + array2.SetValue(2, 1, gp_Pnt(3, 2, 0)) + array2.SetValue(2, 2, gp_Pnt(4, 2, 1)) + array2.SetValue(2, 3, gp_Pnt(5, 2, 2)) + array2.SetValue(3, 1, gp_Pnt(3, 3, 0)) + array2.SetValue(3, 2, gp_Pnt(4, 3, 0)) + array2.SetValue(3, 3, gp_Pnt(5, 3, 1)) + + array3.SetValue(1, 1, gp_Pnt(1, 3, 2)) + array3.SetValue(1, 2, gp_Pnt(2, 3, 1)) + array3.SetValue(1, 3, gp_Pnt(3, 3, 0)) + array3.SetValue(2, 1, gp_Pnt(1, 4, 1)) + array3.SetValue(2, 2, gp_Pnt(2, 4, 0)) + array3.SetValue(2, 3, gp_Pnt(3, 4, 1)) + array3.SetValue(3, 1, gp_Pnt(1, 5, 1)) + array3.SetValue(3, 2, gp_Pnt(2, 5, 1)) + array3.SetValue(3, 3, gp_Pnt(3, 5, 2)) + + array4.SetValue(1, 1, gp_Pnt(3, 3, 0)) + array4.SetValue(1, 2, gp_Pnt(4, 3, 0)) + array4.SetValue(1, 3, gp_Pnt(5, 3, 1)) + array4.SetValue(2, 1, gp_Pnt(3, 4, 1)) + array4.SetValue(2, 2, gp_Pnt(4, 4, 1)) + array4.SetValue(2, 3, gp_Pnt(5, 4, 1)) + array4.SetValue(3, 1, gp_Pnt(3, 5, 2)) + array4.SetValue(3, 2, gp_Pnt(4, 5, 2)) + array4.SetValue(3, 3, gp_Pnt(5, 5, 1)) + + # BZ1, BZ2, BZ3, BZ4 = map(Geom_BezierSurface, [array1, array2, array3, array4]) + # bezierarray = TColGeom_Array2OfBezierSurface(1, 2, 1, 2) + # bezierarray.SetValue(1, 1, BZ1) + # bezierarray.SetValue(1, 2, BZ2) + # bezierarray.SetValue(2, 1, BZ3) + # bezierarray.SetValue(2, 2, BZ4) + + # BB = GeomConvert_CompBezierSurfacesToBSplineSurface(bezierarray) + # assert BB.IsDone()) + # poles = BB.Poles().Array2() + # uknots = BB.UKnots().Array1() + # vknots = BB.VKnots().Array1() + # umult = BB.UMultiplicities().Array1() + # vmult = BB.VMultiplicities().Array1() + # udeg = BB.UDegree() + # vdeg = BB.VDegree() + + # BSPLSURF = Geom_BSplineSurface( + # poles, uknots, vknots, umult, vmult, udeg, vdeg, False, False + # ) + # BSPLSURF.Translate(gp_Vec(0, 0, 2)) + + +def test_surfaces_from_offsets(): + """Test: surfaces from offsets""" + array1 = [gp_Pnt(-4, 5, 5)] + array1.append(gp_Pnt(-3, 6, 6)) + array1.append(gp_Pnt(-1, 7, 7)) + array1.append(gp_Pnt(0, 8, 8)) + array1.append(gp_Pnt(2, 9, 9)) + SPL1 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array1)).Curve() + + array2 = [gp_Pnt(-4, 5, 2)] + array2.append(gp_Pnt(-3, 6, 3)) + array2.append(gp_Pnt(-1, 7, 4)) + array2.append(gp_Pnt(0, 8, 5)) + array2.append(gp_Pnt(2, 9, 6)) + SPL2 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array2)).Curve() + + aGeomFill1 = GeomFill_BSplineCurves(SPL1, SPL2, GeomFill_StretchStyle) + aGeomSurface = aGeomFill1.Surface() + + offset = 1 + GOS = Geom_OffsetSurface(aGeomSurface, offset) + offset = 2 + GOS1 = Geom_OffsetSurface(aGeomSurface, offset) + offset = 3 + GOS2 = Geom_OffsetSurface(aGeomSurface, offset) + + face1 = make_face(aGeomSurface) + assert face1 is not None + face2 = make_face(GOS) + assert face2 is not None + face3 = make_face(GOS1) + assert face3 is not None + face4 = make_face(GOS2) + assert face4 is not None + + +def test_surfaces_from_revolution(): + """Test: surfaces from revolution""" + array = [gp_Pnt(0, 0, 1)] + array.append(gp_Pnt(1, 2, 2)) + array.append(gp_Pnt(2, 3, 3)) + array.append(gp_Pnt(4, 3, 4)) + array.append(gp_Pnt(5, 5, 5)) + aCurve = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array)).Curve() + SOR = Geom_SurfaceOfRevolution(aCurve, gp.OX()) + edge = make_edge(aCurve) + assert edge is not None + face = make_face(SOR) + assert face is not None + + +def test_distances(): + """Test: distances""" + array1 = [gp_Pnt(-5, 1, 2)] + array1.append(gp_Pnt(-5, 2, 2)) + array1.append(gp_Pnt(-5.3, 3, 1)) + array1.append(gp_Pnt(-5, 4, 1)) + array1.append(gp_Pnt(-5, 5, 2)) + SPL1 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array1)).Curve() + array2 = [gp_Pnt(4, 1, 2)] + array2.append(gp_Pnt(4, 2, 2)) + array2.append(gp_Pnt(3.7, 3, 1)) + array2.append(gp_Pnt(4, 4, 1)) + array2.append(gp_Pnt(4, 5, 2)) + SPL2 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array2)).Curve() + aGeomFill1 = GeomFill_BSplineCurves(SPL1, SPL2, GeomFill_StretchStyle) + aSurf1 = aGeomFill1.Surface() + + array3 = TColgp_Array2OfPnt(1, 5, 1, 5) + array3.SetValue(1, 1, gp_Pnt(-4, -4, 5)) + array3.SetValue(1, 2, gp_Pnt(-4, -2, 5)) + array3.SetValue(1, 3, gp_Pnt(-4, 0, 4)) + array3.SetValue(1, 4, gp_Pnt(-4, 2, 5)) + array3.SetValue(1, 5, gp_Pnt(-4, 4, 5)) + + array3.SetValue(2, 1, gp_Pnt(-2, -4, 4)) + array3.SetValue(2, 2, gp_Pnt(-2, -2, 4)) + array3.SetValue(2, 3, gp_Pnt(-2, 0, 4)) + array3.SetValue(2, 4, gp_Pnt(-2, 2, 4)) + array3.SetValue(2, 5, gp_Pnt(-2, 5, 4)) + + array3.SetValue(3, 1, gp_Pnt(0, -4, 3.5)) + array3.SetValue(3, 2, gp_Pnt(0, -2, 3.5)) + array3.SetValue(3, 3, gp_Pnt(0, 0, 3.5)) + array3.SetValue(3, 4, gp_Pnt(0, 2, 3.5)) + array3.SetValue(3, 5, gp_Pnt(0, 5, 3.5)) + + array3.SetValue(4, 1, gp_Pnt(2, -4, 4)) + array3.SetValue(4, 2, gp_Pnt(2, -2, 4)) + array3.SetValue(4, 3, gp_Pnt(2, 0, 3.5)) + array3.SetValue(4, 4, gp_Pnt(2, 2, 5)) + array3.SetValue(4, 5, gp_Pnt(2, 5, 4)) + + array3.SetValue(5, 1, gp_Pnt(4, -4, 5)) + array3.SetValue(5, 2, gp_Pnt(4, -2, 5)) + array3.SetValue(5, 3, gp_Pnt(4, 0, 5)) + array3.SetValue(5, 4, gp_Pnt(4, 2, 6)) + array3.SetValue(5, 5, gp_Pnt(4, 5, 5)) + + aSurf2 = GeomAPI_PointsToBSplineSurface(array3).Surface() + ESS = GeomAPI_ExtremaSurfaceSurface(aSurf1, aSurf2) + dist = ESS.LowerDistance() + assert dist > 1.20 + assert dist < 1.25 + a, b = gp_Pnt(), gp_Pnt() + ESS.NearestPoints(a, b) + + NbExtrema = ESS.NbExtrema() + for k in range(1, NbExtrema + 1): + P3, P4 = gp_Pnt(), gp_Pnt() + ESS.Points(k, P3, P4) + aCurve = GC_MakeSegment(P3, P4).Value() + assert aCurve is not None + + +def test_curve_adaptor(): + # related to issue #1057 https://github.com/tpaviot/pythonocc-core/issues/1057 + p1 = gp_Pnt(5, -5, 0) + p2 = gp_Pnt(5, 5, 0) + ed1 = BRepBuilderAPI_MakeEdge(p2, p1).Edge() + c1 = BRepAdaptor_Curve(ed1) + assert isinstance(c1, BRepAdaptor_Curve) + # assert isinstance(c1.Curve(), GeomAdaptor_Curve)) + # should pass on all platforms + # assert isinstance(c1.Curve().Curve(), Geom_Curve)) + # c2 = BRepAdaptor_Curve(ed1).Curve() + # only works on linux + # if sys.platform == "linux": + # assert isinstance(c2.Curve(), Geom_Curve)) + # assert + # isinstance(BRepAdaptor_Curve(ed1).Curve().Curve(), Geom_Curve) + # ) diff --git a/test/test_core_meshdatasource.py b/test/test_core_meshdatasource.py index 124e0e2ef..7785a190f 100644 --- a/test/test_core_meshdatasource.py +++ b/test/test_core_meshdatasource.py @@ -29,149 +29,141 @@ STL_BOTTLE_FILENAME = os.path.join(".", "test_io", "bottle_ascii.stl") -class TestMeshDataSource(unittest.TestCase): - def test_instantiate_from_stl_file(self): - a_stl_mesh = rwstl.ReadFile(STL_BOTTLE_FILENAME) - MeshDS_DataSource(a_stl_mesh) - - def test_stl_file_check_bounding_box(self): - a_stl_mesh = rwstl.ReadFile(STL_BOTTLE_FILENAME) - a_ds = MeshDS_DataSource(a_stl_mesh) - bb = a_ds.GetBoundingBox().Get() - self.assertEqual(bb, (-26.5748, 4.426, -13.6694, 26.5269, 90.2, 13.5885)) - - def test_create_mesh_datasource(self): - # create data - coord_data = [ - gp_Pnt(0, 0, 0), - gp_Pnt(0, 1, 0), - gp_Pnt(0, 1, -1), - gp_Pnt(1, 0, 0), - gp_Pnt(1, 1, 0), - ] - ele2_node_data = [[0, 1, 4, 3], [1, 2, 4]] - # create data source - a_data_source = MeshDS_DataSource(coord_data, ele2_node_data) - # check node ids and number of elements - node_ids = TColStd_Array1OfInteger(1, 4) - is_ok, nb_nodes = a_data_source.GetNodesByElement(1, node_ids) - self.assertTrue(is_ok) - self.assertEqual(nb_nodes, 4) - self.assertEqual(node_ids.Value(1), 1) - self.assertEqual(node_ids.Value(2), 2) - self.assertEqual(node_ids.Value(3), 5) - self.assertEqual(node_ids.Value(4), 4) - is_ok, nb_nodes = a_data_source.GetNodesByElement(2, node_ids) - self.assertTrue(is_ok) - self.assertEqual(nb_nodes, 3) - self.assertEqual(node_ids.Value(1), 2) - self.assertEqual(node_ids.Value(2), 3) - self.assertEqual(node_ids.Value(3), 5) - # check normal of elements - is_ok, nx, ny, nz = a_data_source.GetNormal(1, 3) - self.assertTrue(is_ok) - self.assertEqual(nx, 0.0) - self.assertEqual(ny, 0.0) - self.assertEqual(nz, -1.0) - is_ok, nx, ny, nz = a_data_source.GetNormal(2, 3) - self.assertTrue(is_ok) - self.assertEqual(nx, 0.0) - self.assertEqual(ny, -1.0) - self.assertEqual(nz, 0.0) - # check normal of nodes - is_ok, nx, ny, nz = a_data_source.GetNodeNormal(1, 1) - self.assertTrue(is_ok) - self.assertEqual(nx, 0.0) - self.assertEqual(ny, 0.0) - self.assertEqual(nz, -1.0) - is_ok, nx, ny, nz = a_data_source.GetNodeNormal(1, 2) - self.assertEqual(nx, 0.0) - self.assertTrue(is_ok) - # floating point number comparison, rounded to 12 decimals - self.assertEqual(round(ny, 12), -round(sqrt(2) / 2, 12)) - self.assertEqual(round(nz, 12), -round(sqrt(2) / 2, 12)) - - def testset_check_normals(self): - # create data - coord_data = [ - gp_Pnt(0, 0, 0), - gp_Pnt(0, 1, 0), - gp_Pnt(0, 1, -1), - gp_Pnt(1, 0, 0), - gp_Pnt(1, 1, 0), - ] - ele2_node_data = [[0, 1, 4, 3], [1, 2, 4]] - node_normals_data = [ - [gp_Vec(0, 0, -1), gp_Vec(0, 0, -1), gp_Vec(0, 0, -1), gp_Vec(0, 0, -1)], - [gp_Vec(0, 0, -1), gp_Vec(0, 0, -1), gp_Vec(0, 0, -1)], - ] - elem_normals_data = [gp_Vec(0, 0, 1), gp_Vec(0, 0, 1)] - # create data source - a_data_source = MeshDS_DataSource(coord_data, ele2_node_data) - # check node ids and number of elements - # set and check normal of elements - a_data_source.SetElemNormals(elem_normals_data) - is_ok, nx, ny, nz = a_data_source.GetNormal(1, 3) - self.assertTrue(is_ok) - self.assertEqual(nx, 0.0) - self.assertEqual(ny, 0.0) - self.assertEqual(nz, 1.0) - # set and check normal of nodes - a_data_source.SetNodeNormals(node_normals_data) - is_ok, nx, ny, nz = a_data_source.GetNodeNormal(1, 2) - self.assertTrue(is_ok) - self.assertEqual(nx, 0.0) - self.assertEqual(ny, 0.0) - self.assertEqual(nz, -1.0) - # get all nodes - all_nodes = a_data_source.GetAllNodes() - self.assertEqual(all_nodes.NbBuckets(), 101) - all_nodes.Statistics() - # get all GetAllElements - all_elements = a_data_source.GetAllElements() - all_elements.Statistics() - self.assertEqual(all_elements.NbBuckets(), 101) - - def test_create_mesh_datasource_from_numpy_ndarray(self): - # 8 cube vertices - v1 = [0, 0, 0] - v2 = [0, 1, 0] - v3 = [1, 1, 0] - v4 = [1, 0, 0] - v5 = [0, 0, 1] - v6 = [0, 1, 1] - v7 = [1, 1, 1] - v8 = [1, 0, 1] - - # 12 cube faces - f1 = [7, 3, 0] - f2 = [0, 4, 7] - f3 = [0, 1, 2] - f4 = [0, 2, 3] - f5 = [4, 5, 6] - f6 = [4, 6, 7] - f7 = [6, 5, 1] - f8 = [6, 2, 1] - f9 = [4, 0, 5] - f10 = [0, 1, 5] - f11 = [3, 6, 7] - f12 = [2, 3, 6] - vertices = np.array([v1, v2, v3, v4, v5, v6, v7, v8], dtype=np.float32) - faces = np.array( - [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12], dtype=np.int32 - ) - - # create data source - a_data_source = MeshDS_DataSource(vertices, faces) - self.assertTrue(isinstance(a_data_source, MeshDS_DataSource)) - - -def suite(): - """builds the test suite""" - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(TestMeshDataSource)) - return test_suite - - -if __name__ == "__main__": - unittest.main() +def test_instantiate_from_stl_file(): + a_stl_mesh = rwstl.ReadFile(STL_BOTTLE_FILENAME) + MeshDS_DataSource(a_stl_mesh) + + +def test_stl_file_check_bounding_box(): + a_stl_mesh = rwstl.ReadFile(STL_BOTTLE_FILENAME) + a_ds = MeshDS_DataSource(a_stl_mesh) + bb = a_ds.GetBoundingBox().Get() + assert bb == (-26.5748, 4.426, -13.6694, 26.5269, 90.2, 13.5885) + + +def test_create_mesh_datasource(): + # create data + coord_data = [ + gp_Pnt(0, 0, 0), + gp_Pnt(0, 1, 0), + gp_Pnt(0, 1, -1), + gp_Pnt(1, 0, 0), + gp_Pnt(1, 1, 0), + ] + ele2_node_data = [[0, 1, 4, 3], [1, 2, 4]] + # create data source + a_data_source = MeshDS_DataSource(coord_data, ele2_node_data) + # check node ids and number of elements + node_ids = TColStd_Array1OfInteger(1, 4) + is_ok, nb_nodes = a_data_source.GetNodesByElement(1, node_ids) + assert is_ok + assert nb_nodes == 4 + assert node_ids.Value(1) == 1 + assert node_ids.Value(2) == 2 + assert node_ids.Value(3) == 5 + assert node_ids.Value(4) == 4 + is_ok, nb_nodes = a_data_source.GetNodesByElement(2, node_ids) + assert is_ok + assert nb_nodes == 3 + assert node_ids.Value(1) == 2 + assert node_ids.Value(2) == 3 + assert node_ids.Value(3) == 5 + # check normal of elements + is_ok, nx, ny, nz = a_data_source.GetNormal(1, 3) + assert is_ok + assert nx == 0.0 + assert ny == 0.0 + assert nz == -1.0 + is_ok, nx, ny, nz = a_data_source.GetNormal(2, 3) + assert is_ok + assert nx == 0.0 + assert ny == -1.0 + assert nz == 0.0 + # check normal of nodes + is_ok, nx, ny, nz = a_data_source.GetNodeNormal(1, 1) + assert is_ok + assert nx == 0.0 + assert ny == 0.0 + assert nz == -1.0 + is_ok, nx, ny, nz = a_data_source.GetNodeNormal(1, 2) + assert nx == 0.0 + assert is_ok + # floating point number comparison, rounded to 12 decimals + assert round(ny, 12) == -round(sqrt(2) / 2, 12) + assert round(nz, 12) == -round(sqrt(2) / 2, 12) + + +def testset_check_normals(): + # create data + coord_data = [ + gp_Pnt(0, 0, 0), + gp_Pnt(0, 1, 0), + gp_Pnt(0, 1, -1), + gp_Pnt(1, 0, 0), + gp_Pnt(1, 1, 0), + ] + ele2_node_data = [[0, 1, 4, 3], [1, 2, 4]] + node_normals_data = [ + [gp_Vec(0, 0, -1), gp_Vec(0, 0, -1), gp_Vec(0, 0, -1), gp_Vec(0, 0, -1)], + [gp_Vec(0, 0, -1), gp_Vec(0, 0, -1), gp_Vec(0, 0, -1)], + ] + elem_normals_data = [gp_Vec(0, 0, 1), gp_Vec(0, 0, 1)] + # create data source + a_data_source = MeshDS_DataSource(coord_data, ele2_node_data) + # check node ids and number of elements + # set and check normal of elements + a_data_source.SetElemNormals(elem_normals_data) + is_ok, nx, ny, nz = a_data_source.GetNormal(1, 3) + assert is_ok + assert nx == 0.0 + assert ny == 0.0 + assert nz == 1.0 + # set and check normal of nodes + a_data_source.SetNodeNormals(node_normals_data) + is_ok, nx, ny, nz = a_data_source.GetNodeNormal(1, 2) + assert is_ok + assert nx == 0.0 + assert ny == 0.0 + assert nz == -1.0 + # get all nodes + all_nodes = a_data_source.GetAllNodes() + assert all_nodes.NbBuckets() == 101 + all_nodes.Statistics() + # get all GetAllElements + all_elements = a_data_source.GetAllElements() + all_elements.Statistics() + assert all_elements.NbBuckets() == 101 + + +def test_create_mesh_datasource_from_numpy_ndarray(): + # 8 cube vertices + v1 = [0, 0, 0] + v2 = [0, 1, 0] + v3 = [1, 1, 0] + v4 = [1, 0, 0] + v5 = [0, 0, 1] + v6 = [0, 1, 1] + v7 = [1, 1, 1] + v8 = [1, 0, 1] + + # 12 cube faces + f1 = [7, 3, 0] + f2 = [0, 4, 7] + f3 = [0, 1, 2] + f4 = [0, 2, 3] + f5 = [4, 5, 6] + f6 = [4, 6, 7] + f7 = [6, 5, 1] + f8 = [6, 2, 1] + f9 = [4, 0, 5] + f10 = [0, 1, 5] + f11 = [3, 6, 7] + f12 = [2, 3, 6] + vertices = np.array([v1, v2, v3, v4, v5, v6, v7, v8], dtype=np.float32) + faces = np.array( + [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12], dtype=np.int32 + ) + + # create data source + a_data_source = MeshDS_DataSource(vertices, faces) + assert isinstance(a_data_source, MeshDS_DataSource) diff --git a/test/test_core_ocaf.py b/test/test_core_ocaf.py index 9e85a2018..725ea8f7f 100644 --- a/test/test_core_ocaf.py +++ b/test/test_core_ocaf.py @@ -51,158 +51,151 @@ def assert_warns_deprecated() -> Iterator[Any]: raise AssertionError("deprecated string not in message") -class TestOCAF(unittest.TestCase): - def test_create_doc(self) -> None: - """Creates an OCAF app and an empty document""" - # create an handle to a document - doc = TDocStd_Document("MDTV-CAF") - self.assertFalse(doc is None) - - def test_write_step_file(self) -> None: - """Exports a colored box into a STEP file""" - ### initialisation - doc = TDocStd_Document("pythonocc-doc") - self.assertTrue(doc is not None) - - # Get root assembly - shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) - colors = XCAFDoc_DocumentTool.ColorTool(doc.Main()) - ### create the shape to export - test_shape = BRepPrimAPI_MakeBox(100.0, 100.0, 100.0).Shape() - - ### add shape - shp_label = shape_tool.AddShape(test_shape) - ### set a color for this shape - r = 1.0 - g = b = 0.5 - red_color = Quantity_Color(r, g, b, Quantity_TypeOfColor.Quantity_TOC_RGB) - colors.SetColor(shp_label, red_color, XCAFDoc_ColorGen) - # write file - WS = XSControl_WorkSession() - writer = STEPCAFControl_Writer(WS, False) - writer.Transfer(doc, STEPControl_AsIs) - status = writer.Write("./test_io/test_ocaf_generated.stp") - self.assertTrue(status) - self.assertTrue(os.path.isfile("./test_io/test_ocaf_generated.stp")) - - def test_read_step_file(self) -> None: - """Reads the previous step file""" - # create an handle to a document - doc = TDocStd_Document("pythonocc-doc") - # Get root assembly - shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) - l_colors = XCAFDoc_DocumentTool.ColorTool(doc.Main()) - step_reader = STEPCAFControl_Reader() - step_reader.SetColorMode(True) - step_reader.SetLayerMode(True) - step_reader.SetNameMode(True) - step_reader.SetMatMode(True) - status = step_reader.ReadFile("./test_io/test_ocaf.stp") - self.assertEqual(status, IFSelect_RetDone) - step_reader.Transfer(doc) - - labels = TDF_LabelSequence() - color_labels = TDF_LabelSequence() - - shape_tool.GetFreeShapes(labels) - - self.assertEqual(labels.Length(), 1) - sub_shapes_labels = TDF_LabelSequence() - self.assertFalse(shape_tool.IsAssembly(labels.Value(1))) - shape_tool.GetSubShapes(labels.Value(1), sub_shapes_labels) - self.assertEqual(sub_shapes_labels.Length(), 0) - - l_colors.GetColors(color_labels) - self.assertEqual(color_labels.Length(), 1) - - label_shp = labels.Value(1) - a_shape = shape_tool.GetShape(label_shp) - self.assertFalse(a_shape.IsNull()) - - def test_read_step_file_from_string(self) -> None: - """The same as above, using a string""" - # create an handle to a document - doc = TDocStd_Document("pythonocc-doc") - # Get root assembly - shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) - l_colors = XCAFDoc_DocumentTool.ColorTool(doc.Main()) - step_reader = STEPCAFControl_Reader() - step_reader.SetColorMode(True) - step_reader.SetLayerMode(True) - step_reader.SetNameMode(True) - step_reader.SetMatMode(True) - - # load the step file to a string - with open("./test_io/test_ocaf.stp", "r", encoding="utf8") as step_file: - step_file_as_string = step_file.read() - status = step_reader.ReadStream("pythonocc_stream", step_file_as_string) - self.assertEqual(status, IFSelect_RetDone) - step_reader.Transfer(doc) - - labels = TDF_LabelSequence() - color_labels = TDF_LabelSequence() - - shape_tool.GetFreeShapes(labels) - - self.assertEqual(labels.Length(), 1) - sub_shapes_labels = TDF_LabelSequence() - self.assertFalse(shape_tool.IsAssembly(labels.Value(1))) - shape_tool.GetSubShapes(labels.Value(1), sub_shapes_labels) - self.assertEqual(sub_shapes_labels.Length(), 0) - - l_colors.GetColors(color_labels) - self.assertEqual(color_labels.Length(), 1) - - label_shp = labels.Value(1) - a_shape = shape_tool.GetShape(label_shp) - self.assertFalse(a_shape.IsNull()) - - def test_read_step_material(self) -> None: - # create an handle to a document - doc = TDocStd_Document("pythonocc-doc") - - # Get root assembly - shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) - mat_tool = XCAFDoc_DocumentTool.MaterialTool(doc.Main()) - step_reader = STEPCAFControl_Reader() - - status = step_reader.ReadFile("./test_io/eight_cyl.stp") - - self.assertEqual(status, IFSelect_RetDone) - step_reader.Transfer(doc) - - shape_labels = TDF_LabelSequence() - material_labels = TDF_LabelSequence() - - shape_tool.GetFreeShapes(shape_labels) - mat_tool.GetMaterialLabels(material_labels) - - number_of_shapes = shape_labels.Length() - self.assertEqual(number_of_shapes, 8) - for i in range(1, number_of_shapes + 1): - label = shape_labels.Value(i) - a_shape = shape_tool.GetShape(label) - - # materials - number_of_materials = material_labels.Length() - self.assertEqual(number_of_materials, 8) - for i in range(1, number_of_materials + 1): - ( - ok, - material_name, - material_description, - material_density, - material_densname, - material_densvaltype, - ) = mat_tool.GetMaterial(material_labels.Value(i)) - self.assertTrue(ok) - - -def suite() -> unittest.TestSuite: - suite = unittest.TestSuite() - suite.addTest(unittest.makeSuite(TestOCAF)) - return suite - - -if __name__ == "__main__": - unittest.main() +def test_create_doc() -> None: + """Creates an OCAF app and an empty document""" + # create an handle to a document + doc = TDocStd_Document("MDTV-CAF") + assert doc is not None + + +def test_write_step_file() -> None: + """Exports a colored box into a STEP file""" + ### initialisation + doc = TDocStd_Document("pythonocc-doc") + assert doc is not None + + # Get root assembly + shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) + colors = XCAFDoc_DocumentTool.ColorTool(doc.Main()) + ### create the shape to export + test_shape = BRepPrimAPI_MakeBox(100.0, 100.0, 100.0).Shape() + + ### add shape + shp_label = shape_tool.AddShape(test_shape) + ### set a color for this shape + r = 1.0 + g = b = 0.5 + red_color = Quantity_Color(r, g, b, Quantity_TypeOfColor.Quantity_TOC_RGB) + colors.SetColor(shp_label, red_color, XCAFDoc_ColorGen) + # write file + WS = XSControl_WorkSession() + writer = STEPCAFControl_Writer(WS, False) + writer.Transfer(doc, STEPControl_AsIs) + status = writer.Write("./test_io/test_ocaf_generated.stp") + assert status + assert os.path.isfile("./test_io/test_ocaf_generated.stp") + + +def test_read_step_file() -> None: + """Reads the previous step file""" + # create an handle to a document + doc = TDocStd_Document("pythonocc-doc") + # Get root assembly + shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) + l_colors = XCAFDoc_DocumentTool.ColorTool(doc.Main()) + step_reader = STEPCAFControl_Reader() + step_reader.SetColorMode(True) + step_reader.SetLayerMode(True) + step_reader.SetNameMode(True) + step_reader.SetMatMode(True) + status = step_reader.ReadFile("./test_io/test_ocaf.stp") + assert status == IFSelect_RetDone + step_reader.Transfer(doc) + + labels = TDF_LabelSequence() + color_labels = TDF_LabelSequence() + + shape_tool.GetFreeShapes(labels) + + assert labels.Length() == 1 + sub_shapes_labels = TDF_LabelSequence() + assert not shape_tool.IsAssembly(labels.Value(1)) + shape_tool.GetSubShapes(labels.Value(1), sub_shapes_labels) + assert sub_shapes_labels.Length() == 0 + + l_colors.GetColors(color_labels) + assert color_labels.Length() == 1 + + label_shp = labels.Value(1) + a_shape = shape_tool.GetShape(label_shp) + assert not a_shape.IsNull() + + +def test_read_step_file_from_string() -> None: + """The same as above, using a string""" + # create an handle to a document + doc = TDocStd_Document("pythonocc-doc") + # Get root assembly + shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) + l_colors = XCAFDoc_DocumentTool.ColorTool(doc.Main()) + step_reader = STEPCAFControl_Reader() + step_reader.SetColorMode(True) + step_reader.SetLayerMode(True) + step_reader.SetNameMode(True) + step_reader.SetMatMode(True) + + # load the step file to a string + with open("./test_io/test_ocaf.stp", "r", encoding="utf8") as step_file: + step_file_as_string = step_file.read() + status = step_reader.ReadStream("pythonocc_stream", step_file_as_string) + assert status == IFSelect_RetDone + step_reader.Transfer(doc) + + labels = TDF_LabelSequence() + color_labels = TDF_LabelSequence() + + shape_tool.GetFreeShapes(labels) + + assert labels.Length() == 1 + sub_shapes_labels = TDF_LabelSequence() + assert not shape_tool.IsAssembly(labels.Value(1)) + shape_tool.GetSubShapes(labels.Value(1), sub_shapes_labels) + assert sub_shapes_labels.Length() == 0 + + l_colors.GetColors(color_labels) + assert color_labels.Length() == 1 + + label_shp = labels.Value(1) + a_shape = shape_tool.GetShape(label_shp) + assert not a_shape.IsNull() + + +def test_read_step_material() -> None: + # create an handle to a document + doc = TDocStd_Document("pythonocc-doc") + + # Get root assembly + shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) + mat_tool = XCAFDoc_DocumentTool.MaterialTool(doc.Main()) + step_reader = STEPCAFControl_Reader() + + status = step_reader.ReadFile("./test_io/eight_cyl.stp") + + assert status == IFSelect_RetDone + step_reader.Transfer(doc) + + shape_labels = TDF_LabelSequence() + material_labels = TDF_LabelSequence() + + shape_tool.GetFreeShapes(shape_labels) + mat_tool.GetMaterialLabels(material_labels) + + number_of_shapes = shape_labels.Length() + assert number_of_shapes == 8 + for i in range(1, number_of_shapes + 1): + label = shape_labels.Value(i) + a_shape = shape_tool.GetShape(label) + + # materials + number_of_materials = material_labels.Length() + assert number_of_materials == 8 + for i in range(1, number_of_materials + 1): + ( + ok, + material_name, + material_description, + material_density, + material_densname, + material_densvaltype, + ) = mat_tool.GetMaterial(material_labels.Value(i)) + assert ok diff --git a/test/test_core_tesselator.py b/test/test_core_tesselator.py index a532b33b4..d7bbd8723 100644 --- a/test/test_core_tesselator.py +++ b/test/test_core_tesselator.py @@ -34,111 +34,106 @@ from OCC.Extend.DataExchange import read_step_file -class TestTesselator(unittest.TestCase): - """A class for testing tessellation algorithm""" - - def test_tessellate_box(self): - """1st test : tessellation of a box""" - a_box = BRepPrimAPI_MakeBox(10, 20, 30).Shape() - tess = ShapeTesselator(a_box) - tess.Compute() - self.assertEqual(tess.ObjGetTriangleCount(), 12) - self.assertEqual(tess.ObjGetNormalCount(), 24) - - def test_tessellate_torus(self): - """2nd test : tessellation of a torus""" - a_torus = BRepPrimAPI_MakeTorus(10, 4).Shape() - tess = ShapeTesselator(a_torus) - tess.Compute() - self.assertGreater(tess.ObjGetTriangleCount(), 100) - self.assertGreater(tess.ObjGetNormalCount(), 100) - - def test_tessellate_torus_with_edges(self): - """2nd test : tessellation of a torus""" - a_torus = BRepPrimAPI_MakeTorus(10, 4).Shape() - tess = ShapeTesselator(a_torus) - tess.Compute(compute_edges=True) - self.assertGreater(tess.ObjGetTriangleCount(), 100) - self.assertGreater(tess.ObjGetNormalCount(), 100) - - def test_tessellate_torus_with_bad_quality(self): - """2nd test : tessellation of a torus""" - a_torus = BRepPrimAPI_MakeTorus(10, 4).Shape() - tess = ShapeTesselator(a_torus) - tess.Compute(mesh_quality=40.0) - # since mesh quality is much lower, we should count less vertices and - # triangles - self.assertGreater(tess.ObjGetTriangleCount(), 10) - self.assertLess(tess.ObjGetTriangleCount(), 100) - self.assertGreater(tess.ObjGetNormalCount(), 10) - self.assertLess(tess.ObjGetNormalCount(), 100) - - def test_export_to_x3d(self): - """3rd test : export a sphere to X3D file format""" - a_sphere = BRepPrimAPI_MakeSphere(10.0).Shape() - tess = ShapeTesselator(a_sphere) - tess.Compute() - tess.ExportShapeToX3D(os.path.join("test_io", "sphere.x3d")) - self.assertTrue(os.path.exists(os.path.join("test_io", "sphere.x3d"))) - - def test_export_to_x3d_TriangleSet(self): - """3rd test : export a sphere to an X3D TriangleSet triangle mesh""" - a_sphere = BRepPrimAPI_MakeBox(10.0, 10.0, 10.0).Shape() - sphere_tess = ShapeTesselator(a_sphere) - sphere_tess.Compute() - sphere_triangle_set_string = sphere_tess.ExportShapeToX3DTriangleSet() - self.assertTrue(sphere_triangle_set_string.startswith(" 100 + assert tess.ObjGetNormalCount() > 100 + + +def test_tessellate_torus_with_edges(): + """2nd test : tessellation of a torus""" + a_torus = BRepPrimAPI_MakeTorus(10, 4).Shape() + tess = ShapeTesselator(a_torus) + tess.Compute(compute_edges=True) + assert tess.ObjGetTriangleCount() > 100 + assert tess.ObjGetNormalCount() > 100 + + +def test_tessellate_torus_with_bad_quality(): + """2nd test : tessellation of a torus""" + a_torus = BRepPrimAPI_MakeTorus(10, 4).Shape() + tess = ShapeTesselator(a_torus) + tess.Compute(mesh_quality=40.0) + # since mesh quality is much lower, we should count less vertices and + # triangles + assert tess.ObjGetTriangleCount() > 10 + assert tess.ObjGetTriangleCount() < 100 + assert tess.ObjGetNormalCount() > 10 + assert tess.ObjGetNormalCount() < 100 + + +def test_export_to_x3d(): + """3rd test : export a sphere to X3D file format""" + a_sphere = BRepPrimAPI_MakeSphere(10.0).Shape() + tess = ShapeTesselator(a_sphere) + tess.Compute() + tess.ExportShapeToX3D(os.path.join("test_io", "sphere.x3d")) + assert os.path.exists(os.path.join("test_io", "sphere.x3d")) + + +def test_export_to_x3d_TriangleSet(): + """3rd test : export a sphere to an X3D TriangleSet triangle mesh""" + a_sphere = BRepPrimAPI_MakeBox(10.0, 10.0, 10.0).Shape() + sphere_tess = ShapeTesselator(a_sphere) + sphere_tess.Compute() + sphere_triangle_set_string = sphere_tess.ExportShapeToX3DTriangleSet() + assert sphere_triangle_set_string.startswith(" Iterator[Any]: @@ -140,950 +141,983 @@ def assert_warns_deprecated() -> Iterator[Any]: raise AssertionError("deprecated string not in message") -class TestWrapperFeatures(unittest.TestCase): - def test_hash(self) -> None: - """ - Check whether the __hash__ function is equal to HashCode() - """ - s = Standard_Transient() - id_s = id(s) - hash1_s = s.__hash__() - self.assertNotEqual(id_s, hash1_s) - - def test_const_Standard_Real_byref(self) -> None: - """ - Test wrapper for const Standard_Real & - """ - t = TColStd_Array1OfReal(1, 10) - t.SetValue(3, 3.14) - self.assertEqual(t.Value(3), 3.14) - - def test_const_Standard_Integer_byref(self) -> None: - """ - Test wrapper for const Standard_Integer & - """ - t = TColStd_Array1OfInteger(1, 2) - t.SetValue(1, 3) - t.SetValue(2, 33) - self.assertEqual(t.Value(1), 3) - self.assertEqual(t.Value(2), 33) - - def test_handle_standard_transient_copy(self) -> None: - def evil_function(t: Standard_Transient) -> Standard_Transient: - handle = Standard_Transient(t) - return handle - - t = Standard_Transient() - self.assertIsNotNone(t) - self.assertIsNotNone(evil_function(t)) - - def test_list(self) -> None: - """ - Test python lists features - """ - P1 = gp_Pnt(1, 2, 3) - P2 = gp_Pnt(2, 3, 4) - P3 = gp_Pnt(5, 7, 8) - l = [P1, P2] - self.assertEqual(P1 in l, True) - self.assertNotEqual(P3 in l, True) - self.assertEqual(l.index(P1), 0) - self.assertEqual(l.index(P2), 1) - # Do the same for Vertices (TopoDS_Shape has - # a HashCode() method overloaded - V1 = BRepBuilderAPI_MakeVertex(P1).Vertex() - V2 = BRepBuilderAPI_MakeVertex(P2).Vertex() - V3 = BRepBuilderAPI_MakeVertex(P3).Vertex() - vl = [V1, V2] - self.assertEqual(V1 in vl, True) - self.assertNotEqual(V3 in vl, True) - # index test() - self.assertEqual(vl.index(V1), 0) - self.assertEqual(vl.index(V2), 1) - # reverse() test - vl.reverse() - self.assertEqual(vl.index(V1), 1) - self.assertEqual(vl.index(V2), 0) - - def test_dict(self) -> None: - """ - Test python dict features - """ - P1 = gp_Pnt(1, 2, 3) - P2 = gp_Pnt(2, 3, 4) - d = {P1: "P1", P2: "P2"} - self.assertEqual(d[P1] == "P1", True) - self.assertEqual(d[P2] == "P2", True) - - def test_topology(self) -> None: - """ - Checks the Topology.py utility script. - """ - - def get_shape() -> TopoDS_Shape: - shape = BRepPrimAPI_MakeBox(10.0, 10.0, 10.0).Shape() - self.assertEqual(shape.IsNull(), False) - return shape - - returned_shape = get_shape() - self.assertEqual(returned_shape.IsNull(), False) - - def test_gp_Vec_operators(self) -> None: - """ - Test gp_Vec division by a float number or an integer - This test fails on py3k with SWIG versions older than 3.0.8 - SWIG 3.0.9 fixes this issue. - See https://github.com/tpaviot/pythonocc-core/issues/257 - """ - # division by a float - v1 = gp_Vec(2.0, 2.0, 2.0) - v2 = v1 / 2.0 - self.assertEqual(v2.Magnitude(), sqrt(3.0)) - # division by an integer - v3 = gp_Vec(4, 4, 4) - v4 = v3 / 2 - self.assertEqual((v4.X(), v4.Y(), v4.Z()), (2, 2, 2)) - # adding two gp_Vec - v5 = gp_Vec(1, 2, 3) + gp_Vec(4, 5, 6) - self.assertEqual((v5.X(), v5.Y(), v5.Z()), (5, 7, 9)) - # subtracting two gp_Vec - v6 = gp_Vec(1, 2, 3) - gp_Vec(6, 5, 4) - self.assertEqual((v6.X(), v6.Y(), v6.Z()), (-5, -3, -1)) - - def test_gp_Quaternion(self) -> None: - """ - Test Interpolate method of qp_QuaternionSLerp. - This method takes a by ref parameter q. - """ - vX = gp_Vec(12, 0, 0) - vY = gp_Vec(0, 12, 0) - - q = gp_Quaternion() - q1 = gp_Quaternion(vX, vX) - q2 = gp_Quaternion(vX, vY) - interp = gp_QuaternionSLerp(q1, q2) - interp.Init(q1, q2) - for i in range(10): - i__ = i / 10.0 - interp.Interpolate(i__, q) - if i == 0: - self.assertEqual(q.X(), 0.0) - self.assertEqual(q.Y(), 0.0) - self.assertEqual(q.Z(), 0.0) - self.assertEqual(q.W(), 1.0) - else: - self.assertEqual(q.X(), 0.0) - self.assertEqual(q.Y(), 0.0) - self.assertGreater(q.Z(), 0.0) - self.assertLess(q.W(), 1.0) - - def test_traverse_box_topology(self) -> None: - """ - Test traversing faces for a box. Assert 6 faces are returned - """ - box_shp = BRepPrimAPI_MakeBox(10.0, 20.0, 30.0).Shape() - - def get_faces(shp) -> List[TopoDS_Shape]: - ex = TopExp_Explorer(shp, TopAbs_FACE) - seq = [] - while ex.More(): - s1 = ex.Current() - seq.append(s1) - ex.Next() - return seq - - faces = get_faces(box_shp) - self.assertEqual(len(faces), 6) - for f in faces: - self.assertEqual(f.IsNull(), False) - - def test_static_method(self) -> None: - """ - Test wrapper for static methods. - - ... snippet from the SWIG documentation ... - - Static class members present a special problem for Python. - Prior to Python-2.2, Python classes had no support for static methods - and no version of Python supports static member variables in a manner - that - SWIG can utilize. Therefore, SWIG generates wrappers that try to work - around - some of these issues. To illustrate, suppose you have a class like - this: - - class Spam { - public: - static void foo(); - static int bar; - }; - In Python, the static member can be access in three different ways: - - >>> example.Spam_foo() # Spam::foo() - >>> s = example.Spam() - >>> s.foo() # Spam::foo() via an instance - >>> example.Spam.foo() # Spam::foo(). Python-2.2 only - - ... end snippet ... - - In order that SWIG properly wraps static methods, the keyword 'static' - must be included in the interface file. For instance, in the - Interface.i file, the following line: - - static Standard_Boolean SetCVal(const char * name, const char * val); - - makes possible to use the method as: - >>> from OCC.Core.Interface import * - >>> Interface_Static_SetCVal("write.step.schema","AP203") - """ - # needs to be inited otherwise the following does not work - STEPControl_Writer() - # Note : static methods are wrapped with lowercase convention - # so SetCVal can be accessed with setcval - r = Interface_Static.SetCVal("write.step.schema", "AP203") - self.assertEqual(r, 1) - l = Interface_Static.CVal("write.step.schema") - self.assertEqual(l, "AP203") - - def test_ft1(self) -> None: - """Test: Standard_Integer & by reference transformator""" - p = gp_Pnt(1, 2, 3.2) - p_coord = p.Coord() - self.assertEqual(p_coord[0], 1.0) - self.assertEqual(p_coord[1], 2.0) - self.assertEqual(p_coord[2], 3.2) - - def test_Standard_Real_by_ref_passed_returned(self) -> None: - """ - Check getters and setters for method that take/return - Standard_Real by reference. Ref github Issue #710 - """ - # create a 2*2 matrix - # | -1. -2. | - # m = | 4. 5.5 | - # lower indices are 0, to comply with python list indexing - mat = math_Matrix(0, 1, 0, 1) - mat.SetValue(0, 0, -1) - mat.SetValue(0, 1, -2) - mat.SetValue(1, 0, 4) - mat.SetValue(1, 1, 5.5) - # the returned value should be the same - self.assertEqual(mat.GetValue(0, 0), -1) - self.assertEqual(mat.GetValue(0, 1), -2) - self.assertEqual(mat.GetValue(1, 0), 4) - self.assertEqual(mat.GetValue(1, 1), 5.5) - - def test_Standard_Integer_by_ref_passed_returned(self) -> None: - """ - Checks the Standard_Integer & byreference return parameter - """ - sfs = ShapeFix_Solid() - sfs.SetFixShellMode(5) - self.assertEqual(sfs.GetFixShellMode(), 5) - - def test_Standard_Boolean_by_ref_passed_returned(self) -> None: - """ - Checks the Standard_Boolean & byreference return parameter - """ - sfw = ShapeFix_Wire() - sfw.SetModifyGeometryMode(True) - self.assertEqual(sfw.GetModifyGeometryMode(), True) - sfw.SetModifyGeometryMode(False) - self.assertEqual(sfw.GetModifyGeometryMode(), False) - - def test_TopoDS_byref_arguments(self) -> None: - """ - Test byref pass arguments to TopoDS - """ - cyl1 = BRepPrimAPI_MakeCylinder(10.0, 10.0).Shape() - cyl2 = BRepPrimAPI_MakeCylinder(100.0, 50.0).Shape() - c = TopoDS_Compound() - self.assertTrue(c.IsNull()) - bb = TopoDS_Builder() - bb.MakeCompound(c) - for child in [cyl1, cyl2]: - bb.Add(c, child) - self.assertFalse(c.IsNull()) - - def test_Standard_Boolean_byref(self) -> None: - """ - Test byref returned standard_boolean - """ - cs = ChFiDS_ChamfSpine() - cs.SetDistAngle(1.0, 45) - self.assertEqual(cs.GetDistAngle(), (1.0, 45.0)) - - def test_pickle_topods_shape_to_from(self) -> None: - """ - Checks if the pickle python module works for TopoDS_Shapes - """ - # Create the shape - box_shape = BRepPrimAPI_MakeBox(100, 200, 300).Shape() - shp_dump = pickle.dumps(box_shape) - # file to dump to/from - filename = os.path.join(".", "test_io", "box_shape_generated.brep") - # write to file - with open(filename, "wb") as output: - output.write(shp_dump) - self.assertTrue(os.path.isfile(filename)) - # load from file - with open(filename, "rb") as dump_from_file: - pickled_shape = pickle.load(dump_from_file) - self.assertFalse(pickled_shape.IsNull()) - - def test_sub_class(self) -> None: - """Test: subclass""" - # Checks that OCC objects can be subclassed, and passed as parameters. - # In this test, we create - # a MyPoint and MyVec class, inheriting from gp_Pnt and gp_Vec. - - class MyPoint(gp_Pnt): - def __init__(self, *kargs: float) -> None: - gp_Pnt.__init__(self, *kargs) - self.x = 4 - - def get_x(self) -> int: - return self.x - - class MyVec(gp_Vec): - def __init__(self, *kargs: float) -> None: - gp_Vec.__init__(self, *kargs) - self._an_attribute = "something" - - def get_attribute(self) -> Any: - return self._an_attribute - - # Create the first point - point1 = MyPoint(1.0, 2.0, 3.0) - point1_coord = point1.Coord() - self.assertEqual(point1_coord[0], 1.0) - self.assertEqual(point1_coord[1], 2.0) - self.assertEqual(point1_coord[2], 3.0) - self.assertEqual(point1.get_x(), 4.0) - # Create the second point - point2 = MyPoint(2.0, 2.0, 3.0) - # Then create the vec from these two points - # The magnitude of the vector should equal 1.0 - vec = MyVec(point1, point2) - self.assertEqual(vec.Magnitude(), 1.0) - self.assertEqual(vec.get_attribute(), "something") - - def test_protected_constructor(self) -> None: - """Test: protected constructor""" - # 1st, class with no subclass - tds_builder = TopoDS_Builder() - self.assertTrue(hasattr(tds_builder, "MakeCompound")) - - def test_auto_import_of_dependent_modules(self) -> None: - """Test: automatic import of dependent modules""" - returned_object = GCE2d_MakeSegment(gp_Pnt2d(1, 1), gp_Pnt2d(3, 4)).Value() - # for this unittest, don't use the issinstance() function, - # since the OCC.Geom2d module - # is *not* manually imported - returned_object_type = f"{type(returned_object)}" - self.assertEqual( - returned_object_type, "" - ) - - def test_hash_eq_operator(self) -> None: - """test that the == wrapper is ok""" - # test Standard - s = Standard_Transient() - s2 = Standard_Transient() - self.assertFalse(s == s2) - self.assertTrue(s == s) - # test list.index, that uses __eq__ method - p1 = gp_Pnt(0.0, 0.0, 0.0) - line = gp_Lin(p1, gp_Dir(1.0, 0.0, 0.0)) - items = [p1, line] - res = items.index(line) - self.assertEqual(res, 1.0) - - def test_eq_operator(self) -> None: - shape_1 = BRepPrimAPI_MakeBox(10, 20, 30).Shape() - shape_2 = BRepPrimAPI_MakeBox(10, 20, 30).Shape() - self.assertFalse(shape_1 == shape_2) - self.assertTrue(shape_1 == shape_1) - self.assertFalse(shape_1 == "some_string") - - def test_neq_operator(self) -> None: - # test Standard - s = Standard_Transient() - s2 = Standard_Transient() - self.assertTrue(s != s2) - self.assertFalse(s != s) - shape_1 = BRepPrimAPI_MakeBox(10, 20, 30).Shape() - shape_2 = BRepPrimAPI_MakeBox(10, 20, 30).Shape() - self.assertTrue(shape_1 != shape_2) - self.assertFalse(shape_1 != shape_1) - self.assertTrue(shape_1 != "some_string") - - def test_inherit_topods_shape(self) -> None: - t = self - - class InheritEdge(TopoDS_Edge): - def __init__(self, edge: TopoDS_Edge) -> None: - # following constructor creates an empty TopoDS_Edge - super(InheritEdge, self).__init__() - # we need to copy the base shape using the following three - # lines - t.assertTrue(self.IsNull()) - self.TShape(edge.TShape()) - self.Location(edge.Location()) - self.Orientation(edge.Orientation()) - t.assertFalse(self.IsNull()) - # then it becomes possible to extend the base class - - # create a line, compute its length - base_edge = BRepBuilderAPI_MakeEdge( - gp_Pnt(100.0, 0.0, 0.0), gp_Pnt(150.0, 0.0, 0.0) - ).Edge() - inherited_edge = InheritEdge(base_edge) - g1 = GProp_GProps() - brepgprop.LinearProperties(inherited_edge, g1) - length = g1.Mass() - self.assertEqual(length, 50.0) - - def test_default_constructor_DEFINE_STANDARD_ALLOC(self) -> None: - """OCE classes the defines standard alllocator can be instantiated - if they're not abstract nor define any protected or private - constructor""" - b = BRep_Builder() - self.assertIsInstance(b, BRep_Builder) - t = TopoDS_Builder() - self.assertIsInstance(t, TopoDS_Builder) - s = ShapeAnalysis_Curve() - self.assertIsInstance(s, ShapeAnalysis_Curve) - - def test_handling_exceptions(self) -> None: - """asserts that handling of OCC exceptions is handled correctly caught - see issue #259 -- Standard errors like Standard_OutOfRange not caught - """ - # Standard_OutOfRange - with self.assertRaises(RuntimeError): - gp_Dir(0, 0, 1).Coord(-1) - # StdFail_NotDone - with self.assertRaises(RuntimeError): - BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(0, 0, 0)).Edge() - # Standard_DomainError - with self.assertRaises(RuntimeError): - BRepPrimAPI_MakeBox(0, 0, 0).Shape() - # Standard_OutOfRange, related to specific issue in #778 - # Note: the exception is raised if and only if OCCT is compiled - # using -D BUILD_RELEASE_DISABLE_EXCEPTIONS=OFF - with self.assertRaises(RuntimeError): - BRepBuilderAPI_Sewing().FreeEdge(-1) - - def test_memory_handle_getobject(self) -> None: - """ - See https://github.com/tpaviot/pythonocc-generator/pull/24 - This commit tries to fix the issue tpaviot/pythonocc-core#292. - When we got a handle from ann API function and called GetObject() - the lifetime of the object was determined only by the handle. - This lead to crashes, when only a reference to the object was stored. - The commit registers the handle with its object to prevent premature - destruction. - This test case ensures everything is ok. Following lines used to crash - on pythonocc-0.16.5 - """ - a = gp_Pnt(0.0, 0.0, 0.0) - b = gp_Pnt(100.0, 100.0, 100.0) - line3 = GC_MakeSegment(a, b).Value() - self.assertEqual(line3.FirstParameter(), 0.0) - self.assertEqual(GC_MakeSegment(a, b).Value().FirstParameter(), 0.0) - self.assertTrue(b.IsEqual(line3.EndPoint(), 0.01)) - self.assertTrue(b.IsEqual(GC_MakeSegment(a, b).Value().EndPoint(), 0.01)) - - def test_local_properties(self) -> None: - """Get and modify class local properties""" - graphic_params = Graphic3d_RenderingParams() - self.assertEqual(graphic_params.RaytracingDepth, 3) - graphic_params.RaytracingDepth = 5 - self.assertEqual(graphic_params.RaytracingDepth, 5) - - def test_repr_overload(self) -> None: - """Test if repr string is properly returned""" - p = gp_Pnt(1, 2, 3) - self.assertEqual(repr(p), "") - empty_shape = TopoDS_Shape() - self.assertEqual(repr(empty_shape), "") - shp = BRepPrimAPI_MakeBox(10, 20, 30).Shape() - self.assertEqual(repr(shp), "") - - def test_downcast_curve(self) -> None: - """Test if a GeomCurve can be DownCasted to a GeomLine""" - edge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0)).Edge() - curve, _, _ = BRep_Tool.Curve(edge) - self.assertTrue(isinstance(curve, Geom_Curve)) - # The edge is internally a line, so we should be able to downcast it - line = Geom_Line.DownCast(curve) - self.assertTrue(isinstance(line, Geom_Curve)) - # Hence, it should not be possible to downcast it as a B-Spline curve - with self.assertRaises(SystemError): - Geom_BSplineCurve.DownCast(curve) - - def test_return_enum(self) -> None: - """Check that returned enums are properly handled, whether they're returned - by reference or not. To check that point, we use the BRepCheck_ListOfStatus class, - where methods take and return BRepCheck_Status values - """ - los1 = BRepCheck_ListOfStatus() - los1.Append(BRepCheck_Multiple3DCurve) - los1.Append(BRepCheck_EmptyWire) - self.assertEqual(los1.First(), BRepCheck_Multiple3DCurve) - self.assertEqual(los1.Last(), BRepCheck_EmptyWire) - # then check with an iterator - los2 = BRepCheck_ListOfStatus() - los2.Append(BRepCheck_Multiple3DCurve) - los2.Append(BRepCheck_EmptyWire) - it = BRepCheck_ListIteratorOfListOfStatus(los2) - while it.More(): - self.assertTrue(isinstance(it.Value(), int)) - it.Next() - - def test_array_iterator(self) -> None: - P0 = gp_Pnt(1, 2, 3) - list_of_points = TColgp_Array1OfPnt(5, 8) - self.assertEqual(len(list_of_points), 4) - - # set item - list_of_points[1] = P0 - - # then get item - self.assertEqual(list_of_points[1].Coord(), (1.0, 2.0, 3.0)) - with self.assertRaises(IndexError): - list_of_points[4] - # iterator creation - it = iter(list_of_points) - next(it) - - # test loop over iterable - for pnt in list_of_points: - self.assertTrue(isinstance(pnt, gp_Pnt)) - - def test_repr_for_null_TopoDS_Shape(self) -> None: - # create null vertex and shape - v = TopoDS_Vertex() - self.assertTrue("Null" in repr(v)) - s = TopoDS_Shape() - self.assertTrue("Null" in repr(s)) - - def test_in_place_operators(self) -> None: - # operator += - a = gp_XYZ(1.0, 2.0, 3.0) - self.assertEqual(a.X(), 1.0) - self.assertEqual(a.Y(), 2.0) - self.assertEqual(a.Z(), 3.0) - a += gp_XYZ(4.0, 5.0, 6.0) - self.assertEqual(a.X(), 5.0) - self.assertEqual(a.Y(), 7.0) - self.assertEqual(a.Z(), 9.0) - # operator *= with a scalar - b1 = gp_XYZ(2.0, 4.0, 5.0) - self.assertEqual(b1.X(), 2.0) - self.assertEqual(b1.Y(), 4.0) - self.assertEqual(b1.Z(), 5.0) - b1 *= 2 - self.assertEqual(b1.X(), 4.0) - self.assertEqual(b1.Y(), 8.0) - self.assertEqual(b1.Z(), 10.0) - # operator *= with a gp_XYZ - b2 = gp_XYZ(4.0, 5.0, 6.0) - self.assertEqual(b2.X(), 4.0) - self.assertEqual(b2.Y(), 5.0) - self.assertEqual(b2.Z(), 6.0) - b2 *= gp_XYZ(3.0, 6.0, 7.0) - self.assertEqual(b2.X(), 12.0) - self.assertEqual(b2.Y(), 30.0) - self.assertEqual(b2.Z(), 42.0) - # operator *= with a gp_Mat - b3 = gp_XYZ(1.0, 2.0, 3.0) - self.assertEqual(b3.X(), 1.0) - self.assertEqual(b3.Y(), 2.0) - self.assertEqual(b3.Z(), 3.0) - m_ident = gp_Mat() - m_ident.SetIdentity() - b3 *= m_ident - self.assertEqual(b3.X(), 1.0) - self.assertEqual(b3.Y(), 2.0) - self.assertEqual(b3.Z(), 3.0) - # operator -= - c = gp_XYZ(3.0, 2.0, 1.0) - self.assertEqual(c.X(), 3.0) - self.assertEqual(c.Y(), 2.0) - self.assertEqual(c.Z(), 1.0) - c -= gp_XYZ(1.0, 0.5, 1.5) - self.assertEqual(c.X(), 2.0) - self.assertEqual(c.Y(), 1.5) - self.assertEqual(c.Z(), -0.5) - # operator /= - d = gp_XYZ(12.0, 14.0, 18.0) - self.assertEqual(d.X(), 12.0) - self.assertEqual(d.Y(), 14.0) - self.assertEqual(d.Z(), 18.0) - d /= 2.0 - self.assertEqual(d.X(), 6.0) - self.assertEqual(d.Y(), 7.0) - self.assertEqual(d.Z(), 9.0) - - def test_shape_conversion_as_py_none(self) -> None: - """see issue #600 and PR #614 - a null topods_shape should be returned as Py_None by the TopoDS transformer - the following test case returns a null topods_shape - """ - box = BRepPrimAPI_MakeBox(1.0, 1.0, 1.0).Shape() - hlr = HLRBRep_Algo() - hlr.Add(box) - projector = HLRAlgo_Projector(gp_Ax2(gp_Pnt(), gp_Dir(-1.75, 1.1, 5))) - hlr.Projector(projector) - hlr.Update() - hlr.Hide() - hlr_shapes = HLRBRep_HLRToShape(hlr) - visible_smooth_edges = hlr_shapes.Rg1LineVCompound() - self.assertTrue(visible_smooth_edges is None) - - def test_Dump(self) -> None: - """some objects can be serialized to a string""" - math_matrix = math_Matrix(1, 2, 3, 4) - serialized_matrix = math_matrix.Dump() - # should output - expected_output = "math_Matrix of RowNumber = 2 and ColNumber = 2\nmath_Matrix ( 1, 3 ) = 0\nmath_Matrix ( 1, 4 ) = 0\nmath_Matrix ( 2, 3 ) = 0\nmath_Matrix ( 2, 4 ) = 0\n" - self.assertEqual(expected_output, serialized_matrix) - - def test_DumpJson(self) -> None: - """Since opencascade 7x, some objects can be serialized to json""" - # create a sphere with a radius of 10. - sph = BRepPrimAPI_MakeSphere(10.0).Shape() - # compute the Bnd box for this sphere - bnd_box = Bnd_Box() - brepbndlib.Add(sph, bnd_box) - # check the result - corner_min = bnd_box.CornerMin() - self.assertEqual( - [ - round(corner_min.X(), 3), - round(corner_min.Y(), 3), - round(corner_min.Z(), 3), - ], - [-10.0, -10.0, -10.0], - ) - # check dump json export is working - json_string = bnd_box.DumpJson() - # try to the output string - json_imported_dict = json.loads(json_string) - self.assertEqual(json_imported_dict["CornerMin"], [-10, -10, -10]) - self.assertEqual(json_imported_dict["CornerMax"], [10, 10, 10]) - - def test_ImportFromJson(self) -> None: - """Since opencascade 7x, some objects can be serialized to json""" - # create a sphere with a radius of 10. - p1 = gp_Pnt(1.0, 3.14, -5) - p2 = gp_Pnt() - p2.InitFromJson(p1.DumpJson()) - self.assertEqual(p2.X(), 1.0) - self.assertEqual(p2.Y(), 3.14) - self.assertEqual(p2.Z(), -5) - - def test_json_pickle(self) -> None: - p1 = gp_Pnt(-1.0, 0.414, 7.88) - dmp = pickle.dumps(p1) - res = pickle.loads(dmp) - self.assertEqual(res.X(), -1.0) - self.assertEqual(res.Y(), 0.414) - self.assertEqual(res.Z(), 7.88) - - def test_harray1_harray2_hsequence(self) -> None: - """Check that special wrappers for harray1, harray2 and hsequence. - Only check that related classes can be instantiated. - """ - TopTools_HArray1OfShape(0, 3) - TopTools_HArray2OfShape(0, 3, 0, 3) - TopTools_HSequenceOfShape() - - def test_NCollection_List(self) -> None: - """Check that python proxy for NCollection_List is ok""" - l = TopTools_ListOfShape() - shp1 = BRepPrimAPI_MakeBox(10, 20, 30).Shape() - shp2 = BRepPrimAPI_MakeBox(20, 30, 40).Shape() - l.Append(shp1) - l.Append(shp2) - self.assertEqual(l.Size(), 2) - self.assertEqual(len(l), 2) - l.RemoveFirst() - self.assertEqual(len(l), 1) - - def test_NCollection_Sequence(self) -> None: - """Check that python proxy for NCollection_Sequence is ok""" - l = TDF_LabelSequence() - self.assertEqual(l.Size(), 0) - self.assertEqual(len(l), 0) - - def test_NCollection_Datamap_extension(self) -> None: - """NCollection_DataMap class adds a Keys() method that return keys in a Python List""" - box1 = BRepPrimAPI_MakeBox(gp_Pnt(0, 0, 0), gp_Pnt(20, 20, 20)).Shape() - box2 = BRepPrimAPI_MakeBox(gp_Pnt(10, 10, 10), gp_Pnt(30, 30, 30)).Shape() - - # Create meshes for the proximity algorithm - deflection = 1e-3 - mesher1 = BRepMesh_IncrementalMesh(box1, deflection) - mesher2 = BRepMesh_IncrementalMesh(box2, deflection) - mesher1.Perform() - mesher2.Perform() - - # Perform shape proximity check - tolerance = 0.1 - isect_test = BRepExtrema_ShapeProximity(box1, box2, tolerance) - isect_test.Perform() - - # Get intersect faces from Shape1 - overlaps1 = isect_test.OverlapSubShapes1() - face_indices1 = overlaps1.Keys() - self.assertEqual(face_indices1, [1, 3, 5]) - - def test_class_not_wrapped_exception(self) -> None: - """checks that calling a non wrapped class raises - an ClassNotWrapped exception - """ - - @classnotwrapped - class TestNotWrapped: - pass - - with self.assertRaises(ClassNotWrappedError): - TestNotWrapped() - - # now check with some non wrapped classes/methods from occt - # TDF_LabelNode is excluded from the wrapper. - # I don't remember why but that's not the point - with self.assertRaises(ClassNotWrappedError): - TDF_LabelNode() - - def test_method_not_wrapped_exception(self) -> None: - """checks that calling a non wrapped class raises - an ClassNotWrapped exception - """ - - class TestClass: - def meth1(self) -> None: - pass # does not raise any exception - - @methodnotwrapped - def meth2(self) -> None: - pass # calling this method will raise an exception - - a = TestClass() - a.meth1() - with self.assertRaises(MethodNotWrappedError): - a.meth2() - # test with OCC - m = AIS_Manipulator() - with self.assertRaises(MethodNotWrappedError): - m.TransformBehavior() - - def test_import_all_modules(self) -> None: - """try to import all modules, and look for linking errors - or syntax errors in the pytho ninterface generated by SWIG - """ - pythonocc_core_path = OCC.Core.__path__[0] - available_core_modules = glob.glob(os.path.join(pythonocc_core_path, "*.py")) - nb_available_modules = len(available_core_modules) - # don't know the exact number of modules, it's around 305 or 306 - self.assertTrue(nb_available_modules > 300) - - # try to import the module - for core_module in available_core_modules: - module_name = os.path.basename(core_module).split(".")[0] - importlib.import_module(f"OCC.Core.{module_name}") - - def test_aliases(self) -> None: - """some classes are defined in c++ as typedef, i.e. they are only - aliases, e.g. BRepOffsetAPI_Sewing is an alias for BRepBuilderAPI_Sewing - """ - sewing_1 = BRepOffsetAPI_Sewing() - sewing_2 = BRepBuilderAPI_Sewing() - - def test_Standard_Type(self) -> None: - """test that Standard_Type returns the correct type name""" - edge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0)).Edge() - curve, _, _ = BRep_Tool.Curve(edge) - line = Geom_Line.DownCast(curve) - self.assertEqual(line.DynamicType().Name(), "Geom_Line") - - def test_BRepClass_FaceClassifier(self) -> None: - """ensure BRepClass_FaceClassifier can be instantiated""" - bfc = BRepClass_FaceClassifier() - self.assertIsInstance(bfc, BRepClass_FaceClassifier) - - def test_wrap_enum(self) -> None: - """check that enum integer values match c++ name""" - red = Quantity_Color(Quantity_NameOfColor.Quantity_NOC_RED) - self.assertEqual(red.Red(), 1.0) - self.assertEqual(red.Green(), 0.0) - self.assertEqual(red.Blue(), 0.0) - green = Quantity_Color(Quantity_NameOfColor.Quantity_NOC_GREEN) - self.assertEqual(green.Red(), 0.0) - self.assertEqual(green.Green(), 1.0) - self.assertEqual(green.Blue(), 0.0) - blue = Quantity_Color(Quantity_NameOfColor.Quantity_NOC_BLUE) - self.assertEqual(blue.Red(), 0.0) - self.assertEqual(blue.Green(), 0.0) - self.assertEqual(blue.Blue(), 1.0) - white = Quantity_Color(Quantity_NameOfColor.Quantity_NOC_WHITE) - self.assertEqual(white.Red(), 1.0) - self.assertEqual(white.Green(), 1.0) - self.assertEqual(white.Blue(), 1.0) - - def test_topabs_orientation_byref(self): - # see Issue https://github.com/tpaviot/pythonocc-core/issues/1038 - box = BRepPrimAPI_MakeBox(10, 20, 30).Shape() - box_face = list(TopologyExplorer(box).faces())[0] - - facetopo = BRepClass_FaceExplorer(box_face) - facetopo.InitWires() # get ready to explore wires/loops of this face - - edge_1 = BRepClass_Edge() - edge_2 = BRepClass_Edge() - edge_3 = BRepClass_Edge() - edge_4 = BRepClass_Edge() - - facetopo.InitEdges() - topabs_ori_1 = facetopo.CurrentEdge(edge_1) - facetopo.NextEdge() - topabs_ori_2 = facetopo.CurrentEdge(edge_2) - facetopo.NextEdge() - topabs_ori_3 = facetopo.CurrentEdge(edge_3) - facetopo.NextEdge() - topabs_ori_4 = facetopo.CurrentEdge(edge_4) - self.assertEqual(topabs_ori_1, TopAbs_Orientation.TopAbs_REVERSED) - self.assertEqual(topabs_ori_2, TopAbs_Orientation.TopAbs_REVERSED) - self.assertEqual(topabs_ori_3, TopAbs_Orientation.TopAbs_FORWARD) - self.assertEqual(topabs_ori_4, TopAbs_Orientation.TopAbs_FORWARD) - - def test_Standard_ShortReal_and_Standard_Real_returned_by_reference(self): - """the HLRAlgo_EdgeIterator.Visible returns both Standar_Real and Standard_ShortReal - by references""" - start = 1.0 # Standard_Real - tol_start = 2 # Standard_ShortReal - end = 3.0 # Standard_Real - tol_end = 4.0 # Standard_ShortReal - - hlralgo_edge_status = HLRAlgo_EdgeStatus(start, tol_start, end, tol_end) - hlr_edg_it = HLRAlgo_EdgeIterator() - hlr_edg_it.InitVisible(hlralgo_edge_status) - - # visible should return both 4 floats and doubles - self.assertEqual(hlr_edg_it.Visible(), (start, tol_start, end, tol_end)) - - def test_deprecated_static_functions(self): - """since pythonocc-core 7.7.1, static functions are not wrapped anymore by a free function. - e.g., calling gp.OX() should be preferred to gp_OX()""" - with self.assertWarns(DeprecationWarning): - gp_OX() - self.assertTrue(isinstance(gp.OX(), gp_Ax1)) - - def test_wrap_extendedstring_as_pyunicodestring(self): - """not necessary anymore to instanciate a TCollection_ExtendedString, - pass a regular python string""" - # Create XDE document - app = TDocStd_Application() - binxcafdrivers.DefineFormat(app) - doc = TDocStd_Document(f"example") - app.NewDocument("BinXCAF", doc) - shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) - shape = BRepPrimAPI_MakeBox(10, 10, 10).Shape() - label = shape_tool.AddShape(shape, False) - - a_unicode_string = "Some text with umlauts äöü and japanese (琵琶)" - TDataStd_Name.Set(label, a_unicode_string) - # Initialize the STEP exporter - step_writer = STEPCAFControl_Writer() - Interface_Static.SetIVal("write.stepcaf.subshapes.name", 1) - Interface_Static.SetCVal("write.step.schema", "AP214") - Interface_Static.SetCVal("write.step.product.name", "my product") - step_writer.Transfer(doc, STEPControl_AsIs) - status = step_writer.Write("compound_with_unicode_label.step") - - if status != IFSelect_RetDone: - raise AssertionError("write failed") - - # check that the unicode string was actually exported to file - with open("compound_with_unicode_label.step", "r", encoding="utf8") as f: - step_file_content = f.read() - self.assertTrue(a_unicode_string in step_file_content) - - def test_ReadStream(self): - """read a step file from a string""" - with open( - os.path.join(".", "test_io", "io1-ug-214.stp"), "r", encoding="utf8" - ) as step_file: - step_file_content = step_file.read() - step_reader = STEPControl_Reader() - result = step_reader.ReadStream("stream_name", step_file_content) - self.assertEqual(result, IFSelect_RetDone) - step_reader.TransferRoots() - - def test_WriteStream(self): - """write a step file to a string""" - the_shape = BRepPrimAPI_MakeBox(10, 20, 30).Shape() - step_writer = STEPControl_Writer() - step_writer.Transfer(the_shape, STEPControl_AsIs) - result, step_str = step_writer.WriteStream() - self.assertEqual(result, IFSelect_RetDone) - self.assertGreater( - len(step_str), 15000 - ) # TODO: length depends on architecture? - - def test_shape_analysis_free_bounds(self): - """test special wrapper for ShapeAnalysis::ConnectEdgesToWires""" - p1 = gp_Pnt() - p2 = gp_Pnt(1, 0, 0) - e1 = BRepBuilderAPI_MakeEdge(p1, p2).Edge() - - p3 = gp_Pnt(1, 1, 0) - e2 = BRepBuilderAPI_MakeEdge(p2, p3).Edge() - - edges = TopTools_HSequenceOfShape() - edges.Append(e1) - edges.Append(e2) - - result = ShapeAnalysis_FreeBounds.ConnectEdgesToWires(edges, 1.0e-7, False) - self.assertEqual(result.Length(), 1) - - def test_const_ref_return(self): - """const byref should be wrapped as copy constructors to prevent memory issues, - see issue #1277""" - - def get_bounds(adaptor): - return list(adaptor.Surface().BSpline().Bounds()) - - a_reader = IGESCAFControl_Reader() - iges_filename = os.path.join(".", "test_io", "testfile.igs") - if a_reader.ReadFile(iges_filename) != 1: - raise ValueError("Can't open IGES file.") - - a_doc = TDocStd_Document("iges") - if not a_reader.Transfer(a_doc): - raise ValueError("Cannot transfer data from IGES file.") - - shape_tool = XCAFDoc_DocumentTool.ShapeTool(a_doc.Main()) - - shp_labels = TDF_LabelSequence() - shape_tool.GetShapes(shp_labels) - - shape_label = shp_labels.Value(1) - shape = shape_tool.GetShape(shape_label) - - adaptor = BRepAdaptor_Surface(shape) - bounds = get_bounds(adaptor) - # should returns [0.0, 35.53017372307497, 0.0, 27.81101597164092] - self.assertEqual(bounds, [0.0, 35.53017372307497, 0.0, 27.81101597164092]) - - -def suite() -> unittest.TestSuite: - test_suite = unittest.TestSuite() - test_suite.addTest(unittest.makeSuite(TestWrapperFeatures)) - return test_suite - - -if __name__ == "__main__": - unittest.main() +def test_hash() -> None: + s = Standard_Transient() + assert id(s) != hash(s) + + +def test_const_Standard_Real_byref() -> None: + """ + Test wrapper for const Standard_Real & + """ + t = TColStd_Array1OfReal(1, 10) + t.SetValue(3, 3.14) + assert t.Value(3) == 3.14 + + +def test_const_Standard_Integer_byref() -> None: + """ + Test wrapper for const Standard_Integer & + """ + t = TColStd_Array1OfInteger(1, 2) + t.SetValue(1, 3) + t.SetValue(2, 33) + assert t.Value(1) == 3 + assert t.Value(2) == 33 + + +def test_handle_standard_transient_copy() -> None: + def evil_function(t: Standard_Transient) -> Standard_Transient: + handle = Standard_Transient(t) + return handle + + t = Standard_Transient() + assert t is not None + assert evil_function(t) is not None + + +def test_list() -> None: + """ + Test python lists features + """ + P1 = gp_Pnt(1, 2, 3) + P2 = gp_Pnt(2, 3, 4) + P3 = gp_Pnt(5, 7, 8) + l = [P1, P2] + assert P1 in l + assert P3 not in l + assert l.index(P1) == 0 + assert l.index(P2) == 1 + # Do the same for Vertices (TopoDS_Shape has + # a HashCode() method overloaded + V1 = BRepBuilderAPI_MakeVertex(P1).Vertex() + V2 = BRepBuilderAPI_MakeVertex(P2).Vertex() + V3 = BRepBuilderAPI_MakeVertex(P3).Vertex() + vl = [V1, V2] + assert V1 in vl + assert V3 not in vl + # index test() + assert vl.index(V1) == 0 + assert vl.index(V2) == 1 + # reverse() test + vl.reverse() + assert vl.index(V1) == 1 + assert vl.index(V2) == 0 + + +def test_dict() -> None: + """ + Test python dict features + """ + P1 = gp_Pnt(1, 2, 3) + P2 = gp_Pnt(2, 3, 4) + d = {P1: "P1", P2: "P2"} + assert d[P1] == "P1" + assert d[P2] == "P2" + + +def test_topology() -> None: + """ + Checks the Topology.py utility script. + """ + + def get_shape() -> TopoDS_Shape: + shape = BRepPrimAPI_MakeBox(10.0, 10.0, 10.0).Shape() + assert not shape.IsNull() + return shape + + returned_shape = get_shape() + assert not returned_shape.IsNull() + + +def test_gp_Vec_operators() -> None: + """ + Test gp_Vec division by a float number or an integer + This test fails on py3k with SWIG versions older than 3.0.8 + SWIG 3.0.9 fixes this issue. + See https://github.com/tpaviot/pythonocc-core/issues/257 + """ + # division by a float + v1 = gp_Vec(2.0, 2.0, 2.0) + v2 = v1 / 2.0 + assert v2.Magnitude() == sqrt(3.0) + # division by an integer + v3 = gp_Vec(4, 4, 4) + v4 = v3 / 2 + assert (v4.X(), v4.Y(), v4.Z()) == (2, 2, 2) + # adding two gp_Vec + v5 = gp_Vec(1, 2, 3) + gp_Vec(4, 5, 6) + assert (v5.X(), v5.Y(), v5.Z()) == (5, 7, 9) + # subtracting two gp_Vec + v6 = gp_Vec(1, 2, 3) - gp_Vec(6, 5, 4) + assert (v6.X(), v6.Y(), v6.Z()) == (-5, -3, -1) + + +def test_gp_Quaternion() -> None: + """ + Test Interpolate method of qp_QuaternionSLerp. + This method takes a by ref parameter q. + """ + vX = gp_Vec(12, 0, 0) + vY = gp_Vec(0, 12, 0) + + q = gp_Quaternion() + q1 = gp_Quaternion(vX, vX) + q2 = gp_Quaternion(vX, vY) + interp = gp_QuaternionSLerp(q1, q2) + interp.Init(q1, q2) + for i in range(10): + i__ = i / 10.0 + interp.Interpolate(i__, q) + if i == 0: + assert q.X() == 0.0 + assert q.Y() == 0.0 + assert q.Z() == 0.0 + assert q.W() == 1.0 + else: + assert q.X() == 0.0 + assert q.Y() == 0.0 + assert q.Z() > 0.0 + assert q.W() < 1.0 + + +def test_traverse_box_topology() -> None: + """ + Test traversing faces for a box. Assert 6 faces are returned + """ + box_shp = BRepPrimAPI_MakeBox(10.0, 20.0, 30.0).Shape() + + def get_faces(shp) -> List[TopoDS_Shape]: + ex = TopExp_Explorer(shp, TopAbs_FACE) + seq = [] + while ex.More(): + s1 = ex.Current() + seq.append(s1) + ex.Next() + return seq + + faces = get_faces(box_shp) + assert len(faces) == 6 + for f in faces: + assert not f.IsNull() + + +def test_static_method() -> None: + """ + Test wrapper for static methods. + + ... snippet from the SWIG documentation ... + + Static class members present a special problem for Python. + Prior to Python-2.2, Python classes had no support for static methods + and no version of Python supports static member variables in a manner + that + SWIG can utilize. Therefore, SWIG generates wrappers that try to work + around + some of these issues. To illustrate, suppose you have a class like + this: + + class Spam { + public: + static void foo(); + static int bar; + }; + In Python, the static member can be access in three different ways: + + >>> example.Spam_foo() # Spam::foo() + >>> s = example.Spam() + >>> s.foo() # Spam::foo() via an instance + >>> example.Spam.foo() # Spam::foo(). Python-2.2 only + + ... end snippet ... + + In order that SWIG properly wraps static methods, the keyword 'static' + must be included in the interface file. For instance, in the + Interface.i file, the following line: + + static Standard_Boolean SetCVal(const char * name, const char * val); + + makes possible to use the method as: + >>> from OCC.Core.Interface import * + >>> Interface_Static_SetCVal("write.step.schema","AP203") + """ + # needs to be inited otherwise the following does not work + STEPControl_Writer() + # Note : static methods are wrapped with lowercase convention + # so SetCVal can be accessed with setcval + r = Interface_Static.SetCVal("write.step.schema", "AP203") + assert r == 1 + l = Interface_Static.CVal("write.step.schema") + assert l == "AP203" + + +def test_ft1() -> None: + """Test: Standard_Integer & by reference transformator""" + p = gp_Pnt(1, 2, 3.2) + p_coord = p.Coord() + assert p_coord[0] == 1.0 + assert p_coord[1] == 2.0 + assert p_coord[2] == 3.2 + + +def test_Standard_Real_by_ref_passed_returned() -> None: + """ + Check getters and setters for method that take/return + Standard_Real by reference. Ref github Issue #710 + """ + # create a 2*2 matrix + # | -1. -2. | + # m = | 4. 5.5 | + # lower indices are 0, to comply with python list indexing + mat = math_Matrix(0, 1, 0, 1) + mat.SetValue(0, 0, -1) + mat.SetValue(0, 1, -2) + mat.SetValue(1, 0, 4) + mat.SetValue(1, 1, 5.5) + # the returned value should be the same + assert mat.GetValue(0, 0) == -1 + assert mat.GetValue(0, 1) == -2 + assert mat.GetValue(1, 0) == 4 + assert mat.GetValue(1, 1) == 5.5 + + +def test_Standard_Integer_by_ref_passed_returned() -> None: + """ + Checks the Standard_Integer & byreference return parameter + """ + sfs = ShapeFix_Solid() + sfs.SetFixShellMode(5) + assert sfs.GetFixShellMode() == 5 + + +def test_Standard_Boolean_by_ref_passed_returned() -> None: + """ + Checks the Standard_Boolean & byreference return parameter + """ + sfw = ShapeFix_Wire() + sfw.SetModifyGeometryMode(True) + assert sfw.GetModifyGeometryMode() + sfw.SetModifyGeometryMode(False) + assert not sfw.GetModifyGeometryMode() + + +def test_TopoDS_byref_arguments() -> None: + """ + Test byref pass arguments to TopoDS + """ + cyl1 = BRepPrimAPI_MakeCylinder(10.0, 10.0).Shape() + cyl2 = BRepPrimAPI_MakeCylinder(100.0, 50.0).Shape() + c = TopoDS_Compound() + assert c.IsNull() + bb = TopoDS_Builder() + bb.MakeCompound(c) + for child in [cyl1, cyl2]: + bb.Add(c, child) + assert not c.IsNull() + + +def test_Standard_Boolean_byref() -> None: + """ + Test byref returned standard_boolean + """ + cs = ChFiDS_ChamfSpine() + cs.SetDistAngle(1.0, 45) + assert cs.GetDistAngle() == (1.0, 45.0) + + +def test_pickle_topods_shape_to_from() -> None: + """ + Checks if the pickle python module works for TopoDS_Shapes + """ + # Create the shape + box_shape = BRepPrimAPI_MakeBox(100, 200, 300).Shape() + shp_dump = pickle.dumps(box_shape) + # file to dump to/from + filename = os.path.join(".", "test_io", "box_shape_generated.brep") + # write to file + with open(filename, "wb") as output: + output.write(shp_dump) + assert os.path.isfile(filename) + # load from file + with open(filename, "rb") as dump_from_file: + pickled_shape = pickle.load(dump_from_file) + assert not pickled_shape.IsNull() + + +def test_sub_class() -> None: + """Test: subclass""" + # Checks that OCC objects can be subclassed, and passed as parameters. + # In this test, we create + # a MyPoint and MyVec class, inheriting from gp_Pnt and gp_Vec. + + class MyPoint(gp_Pnt): + def __init__(self, *kargs: float) -> None: + gp_Pnt.__init__(self, *kargs) + self.x = 4 + + def get_x(self) -> int: + return self.x + + class MyVec(gp_Vec): + def __init__(self, *kargs: float) -> None: + gp_Vec.__init__(self, *kargs) + self._an_attribute = "something" + + def get_attribute(self) -> Any: + return self._an_attribute + + # Create the first point + point1 = MyPoint(1.0, 2.0, 3.0) + point1_coord = point1.Coord() + assert point1_coord[0] == 1.0 + assert point1_coord[1] == 2.0 + assert point1_coord[2] == 3.0 + assert point1.get_x() == 4.0 + # Create the second point + point2 = MyPoint(2.0, 2.0, 3.0) + # Then create the vec from these two points + # The magnitude of the vector should equal 1.0 + vec = MyVec(point1, point2) + assert vec.Magnitude() == 1.0 + assert vec.get_attribute() == "something" + + +def test_protected_constructor() -> None: + """Test: protected constructor""" + # 1st, class with no subclass + tds_builder = TopoDS_Builder() + assert hasattr(tds_builder, "MakeCompound") + + +def test_auto_import_of_dependent_modules() -> None: + """Test: automatic import of dependent modules""" + returned_object = GCE2d_MakeSegment(gp_Pnt2d(1, 1), gp_Pnt2d(3, 4)).Value() + # for this unittest, don't use the issinstance() function, + # since the OCC.Geom2d module + # is *not* manually imported + returned_object_type = f"{type(returned_object)}" + assert returned_object_type == "" + + +def test_hash_eq_operator() -> None: + """test that the == wrapper is ok""" + # test Standard + s = Standard_Transient() + s2 = Standard_Transient() + assert s != s2 + assert s == s + # test list.index, that uses __eq__ method + p1 = gp_Pnt(0.0, 0.0, 0.0) + line = gp_Lin(p1, gp_Dir(1.0, 0.0, 0.0)) + items = [p1, line] + res = items.index(line) + assert res == 1.0 + + +def test_eq_operator() -> None: + shape_1 = BRepPrimAPI_MakeBox(10, 20, 30).Shape() + shape_2 = BRepPrimAPI_MakeBox(10, 20, 30).Shape() + assert shape_1 != shape_2 + assert shape_1 == shape_1 + assert shape_1 != "some_string" + + +def test_neq_operator() -> None: + # test Standard + s = Standard_Transient() + s2 = Standard_Transient() + assert s != s2 + assert not s != s + shape_1 = BRepPrimAPI_MakeBox(10, 20, 30).Shape() + shape_2 = BRepPrimAPI_MakeBox(10, 20, 30).Shape() + assert shape_1 != shape_2 + assert not shape_1 != shape_1 + assert shape_1 != "some_string" + + +def test_inherit_topods_shape() -> None: + class InheritEdge(TopoDS_Edge): + def __init__(self, edge: TopoDS_Edge) -> None: + # following constructor creates an empty TopoDS_Edge + super(InheritEdge, self).__init__() + # we need to copy the base shape using the following three + # lines + assert self.IsNull() + self.TShape(edge.TShape()) + self.Location(edge.Location()) + self.Orientation(edge.Orientation()) + assert not self.IsNull() + + # create a line, compute its length + base_edge = BRepBuilderAPI_MakeEdge( + gp_Pnt(100.0, 0.0, 0.0), gp_Pnt(150.0, 0.0, 0.0) + ).Edge() + inherited_edge = InheritEdge(base_edge) + g1 = GProp_GProps() + brepgprop.LinearProperties(inherited_edge, g1) + length = g1.Mass() + assert length == 50.0 + + +def test_default_constructor_DEFINE_STANDARD_ALLOC() -> None: + """OCE classes the defines standard alllocator can be instantiated + if they're not abstract nor define any protected or private + constructor""" + b = BRep_Builder() + assert isinstance(b, BRep_Builder) + t = TopoDS_Builder() + assert isinstance(t, TopoDS_Builder) + s = ShapeAnalysis_Curve() + assert isinstance(s, ShapeAnalysis_Curve) + + +def test_handling_exceptions() -> None: + """asserts that handling of OCC exceptions is handled correctly caught + see issue #259 -- Standard errors like Standard_OutOfRange not caught + """ + # Standard_OutOfRange + with pytest.raises(RuntimeError): + gp_Dir(0, 0, 1).Coord(-1) + # StdFail_NotDone + with pytest.raises(RuntimeError): + BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(0, 0, 0)).Edge() + # Standard_DomainError + with pytest.raises(RuntimeError): + BRepPrimAPI_MakeBox(0, 0, 0).Shape() + # Standard_OutOfRange, related to specific issue in #778 + # Note: the exception is raised if and only if OCCT is compiled + # using -D BUILD_RELEASE_DISABLE_EXCEPTIONS=OFF + with pytest.raises(RuntimeError): + BRepBuilderAPI_Sewing().FreeEdge(-1) + + +def test_memory_handle_getobject() -> None: + """ + See https://github.com/tpaviot/pythonocc-generator/pull/24 + This commit tries to fix the issue tpaviot/pythonocc-core#292. + When we got a handle from ann API function and called GetObject() + the lifetime of the object was determined only by the handle. + This lead to crashes, when only a reference to the object was stored. + The commit registers the handle with its object to prevent premature + destruction. + This test case ensures everything is ok. Following lines used to crash + on pythonocc-0.16.5 + """ + a = gp_Pnt(0.0, 0.0, 0.0) + b = gp_Pnt(100.0, 100.0, 100.0) + line3 = GC_MakeSegment(a, b).Value() + assert line3.FirstParameter() == 0.0 + assert GC_MakeSegment(a, b).Value().FirstParameter() == 0.0 + assert b.IsEqual(line3.EndPoint(), 0.01) + assert b.IsEqual(GC_MakeSegment(a, b).Value().EndPoint(), 0.01) + + +def test_local_properties() -> None: + """Get and modify class local properties""" + graphic_params = Graphic3d_RenderingParams() + assert graphic_params.RaytracingDepth == 3 + graphic_params.RaytracingDepth = 5 + assert graphic_params.RaytracingDepth == 5 + + +def test_repr_overload() -> None: + """Test if repr string is properly returned""" + p = gp_Pnt(1, 2, 3) + assert repr(p) == "" + empty_shape = TopoDS_Shape() + assert repr(empty_shape) == "" + shp = BRepPrimAPI_MakeBox(10, 20, 30).Shape() + assert repr(shp) == "" + + +def test_downcast_curve() -> None: + """Test if a GeomCurve can be DownCasted to a GeomLine""" + edge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0)).Edge() + curve, _, _ = BRep_Tool.Curve(edge) + assert isinstance(curve, Geom_Curve) + # The edge is internally a line, so we should be able to downcast it + line = Geom_Line.DownCast(curve) + assert isinstance(line, Geom_Curve) + # Hence, it should not be possible to downcast it as a B-Spline curve + with pytest.raises(SystemError): + Geom_BSplineCurve.DownCast(curve) + + +def test_return_enum() -> None: + """Check that returned enums are properly handled, whether they're returned + by reference or not. To check that point, we use the BRepCheck_ListOfStatus class, + where methods take and return BRepCheck_Status values + """ + los1 = BRepCheck_ListOfStatus() + los1.Append(BRepCheck_Multiple3DCurve) + los1.Append(BRepCheck_EmptyWire) + assert los1.First() == BRepCheck_Multiple3DCurve + assert los1.Last() == BRepCheck_EmptyWire + # then check with an iterator + los2 = BRepCheck_ListOfStatus() + los2.Append(BRepCheck_Multiple3DCurve) + los2.Append(BRepCheck_EmptyWire) + it = BRepCheck_ListIteratorOfListOfStatus(los2) + while it.More(): + assert isinstance(it.Value(), int) + it.Next() + + +def test_array_iterator() -> None: + P0 = gp_Pnt(1, 2, 3) + list_of_points = TColgp_Array1OfPnt(5, 8) + assert len(list_of_points) == 4 + + # set item + list_of_points[1] = P0 + + # then get item + assert list_of_points[1].Coord() == (1.0, 2.0, 3.0) + with pytest.raises(IndexError): + list_of_points[4] + # iterator creation + it = iter(list_of_points) + next(it) + + # test loop over iterable + for pnt in list_of_points: + assert isinstance(pnt, gp_Pnt) + + +def test_repr_for_null_TopoDS_Shape() -> None: + # create null vertex and shape + v = TopoDS_Vertex() + assert "Null" in repr(v) + s = TopoDS_Shape() + assert "Null" in repr(s) + + +def test_in_place_operators() -> None: + # operator += + a = gp_XYZ(1.0, 2.0, 3.0) + assert a.X() == 1.0 + assert a.Y() == 2.0 + assert a.Z() == 3.0 + a += gp_XYZ(4.0, 5.0, 6.0) + assert a.X() == 5.0 + assert a.Y() == 7.0 + assert a.Z() == 9.0 + # operator *= with a scalar + b1 = gp_XYZ(2.0, 4.0, 5.0) + assert b1.X() == 2.0 + assert b1.Y() == 4.0 + assert b1.Z() == 5.0 + b1 *= 2 + assert b1.X() == 4.0 + assert b1.Y() == 8.0 + assert b1.Z() == 10.0 + # operator *= with a gp_XYZ + b2 = gp_XYZ(4.0, 5.0, 6.0) + assert b2.X() == 4.0 + assert b2.Y() == 5.0 + assert b2.Z() == 6.0 + b2 *= gp_XYZ(3.0, 6.0, 7.0) + assert b2.X() == 12.0 + assert b2.Y() == 30.0 + assert b2.Z() == 42.0 + # operator *= with a gp_Mat + b3 = gp_XYZ(1.0, 2.0, 3.0) + assert b3.X() == 1.0 + assert b3.Y() == 2.0 + assert b3.Z() == 3.0 + m_ident = gp_Mat() + m_ident.SetIdentity() + b3 *= m_ident + assert b3.X() == 1.0 + assert b3.Y() == 2.0 + assert b3.Z() == 3.0 + # operator -= + c = gp_XYZ(3.0, 2.0, 1.0) + assert c.X() == 3.0 + assert c.Y() == 2.0 + assert c.Z() == 1.0 + c -= gp_XYZ(1.0, 0.5, 1.5) + assert c.X() == 2.0 + assert c.Y() == 1.5 + assert c.Z() == -0.5 + # operator /= + d = gp_XYZ(12.0, 14.0, 18.0) + assert d.X() == 12.0 + assert d.Y() == 14.0 + assert d.Z() == 18.0 + d /= 2.0 + assert d.X() == 6.0 + assert d.Y() == 7.0 + assert d.Z() == 9.0 + + +def test_shape_conversion_as_py_none() -> None: + """see issue #600 and PR #614 + a null topods_shape should be returned as Py_None by the TopoDS transformer + the following test case returns a null topods_shape + """ + box = BRepPrimAPI_MakeBox(1.0, 1.0, 1.0).Shape() + hlr = HLRBRep_Algo() + hlr.Add(box) + projector = HLRAlgo_Projector(gp_Ax2(gp_Pnt(), gp_Dir(-1.75, 1.1, 5))) + hlr.Projector(projector) + hlr.Update() + hlr.Hide() + hlr_shapes = HLRBRep_HLRToShape(hlr) + visible_smooth_edges = hlr_shapes.Rg1LineVCompound() + assert visible_smooth_edges is None + + +def test_Dump() -> None: + """some objects can be serialized to a string""" + math_matrix = math_Matrix(1, 2, 3, 4) + serialized_matrix = math_matrix.Dump() + # should output + expected_output = "math_Matrix of RowNumber = 2 and ColNumber = 2\nmath_Matrix ( 1, 3 ) = 0\nmath_Matrix ( 1, 4 ) = 0\nmath_Matrix ( 2, 3 ) = 0\nmath_Matrix ( 2, 4 ) = 0\n" + assert expected_output == serialized_matrix + + +def test_DumpJson() -> None: + """Since opencascade 7x, some objects can be serialized to json""" + # create a sphere with a radius of 10. + sph = BRepPrimAPI_MakeSphere(10.0).Shape() + # compute the Bnd box for this sphere + bnd_box = Bnd_Box() + brepbndlib.Add(sph, bnd_box) + # check the result + corner_min = bnd_box.CornerMin() + assert [ + round(corner_min.X(), 3), + round(corner_min.Y(), 3), + round(corner_min.Z(), 3), + ] == [-10.0, -10.0, -10.0] + + # check dump json export is working + json_string = bnd_box.DumpJson() + # try to the output string + json_imported_dict = json.loads(json_string) + assert json_imported_dict["CornerMin"] == [-10, -10, -10] + assert json_imported_dict["CornerMax"] == [10, 10, 10] + + +def test_ImportFromJson() -> None: + """Since opencascade 7x, some objects can be serialized to json""" + # create a sphere with a radius of 10. + p1 = gp_Pnt(1.0, 3.14, -5) + p2 = gp_Pnt() + p2.InitFromJson(p1.DumpJson()) + assert p2.X() == 1.0 + assert p2.Y() == 3.14 + assert p2.Z() == -5 + + +def test_json_pickle() -> None: + p1 = gp_Pnt(-1.0, 0.414, 7.88) + dmp = pickle.dumps(p1) + res = pickle.loads(dmp) + assert res.X() == -1.0 + assert res.Y() == 0.414 + assert res.Z() == 7.88 + + +def test_harray1_harray2_hsequence() -> None: + """Check that special wrappers for harray1, harray2 and hsequence. + Only check that related classes can be instantiated. + """ + TopTools_HArray1OfShape(0, 3) + TopTools_HArray2OfShape(0, 3, 0, 3) + TopTools_HSequenceOfShape() + + +def test_NCollection_List() -> None: + """Check that python proxy for NCollection_List is ok""" + l = TopTools_ListOfShape() + shp1 = BRepPrimAPI_MakeBox(10, 20, 30).Shape() + shp2 = BRepPrimAPI_MakeBox(20, 30, 40).Shape() + l.Append(shp1) + l.Append(shp2) + assert l.Size() == 2 + assert len(l) == 2 + l.RemoveFirst() + assert len(l) == 1 + + +def test_NCollection_Sequence() -> None: + """Check that python proxy for NCollection_Sequence is ok""" + l = TDF_LabelSequence() + assert l.Size() == 0 + assert len(l) == 0 + + +def test_NCollection_Datamap_extension() -> None: + """NCollection_DataMap class adds a Keys() method that return keys in a Python List""" + box1 = BRepPrimAPI_MakeBox(gp_Pnt(0, 0, 0), gp_Pnt(20, 20, 20)).Shape() + box2 = BRepPrimAPI_MakeBox(gp_Pnt(10, 10, 10), gp_Pnt(30, 30, 30)).Shape() + + # Create meshes for the proximity algorithm + deflection = 1e-3 + mesher1 = BRepMesh_IncrementalMesh(box1, deflection) + mesher2 = BRepMesh_IncrementalMesh(box2, deflection) + mesher1.Perform() + mesher2.Perform() + + # Perform shape proximity check + tolerance = 0.1 + isect_test = BRepExtrema_ShapeProximity(box1, box2, tolerance) + isect_test.Perform() + + # Get intersect faces from Shape1 + overlaps1 = isect_test.OverlapSubShapes1() + face_indices1 = overlaps1.Keys() + assert face_indices1 == [1, 3, 5] + + +def test_class_not_wrapped_exception() -> None: + """checks that calling a non wrapped class raises + an ClassNotWrapped exception + """ + + @classnotwrapped + class TestNotWrapped: + pass + + with pytest.raises(ClassNotWrappedError): + TestNotWrapped() + + # now check with some non wrapped classes/methods from occt + # TDF_LabelNode is excluded from the wrapper. + # I don't remember why but that's not the point + with pytest.raises(ClassNotWrappedError): + TDF_LabelNode() + + +def test_method_not_wrapped_exception() -> None: + """checks that calling a non wrapped class raises + an ClassNotWrapped exception + """ + + class TestClass: + def meth1(self) -> None: + pass # does not raise any exception + + @methodnotwrapped + def meth2(self) -> None: + pass # calling this method will raise an exception + + a = TestClass() + a.meth1() + with pytest.raises(MethodNotWrappedError): + a.meth2() + # test with OCC + m = AIS_Manipulator() + with pytest.raises(MethodNotWrappedError): + m.TransformBehavior() + + +def test_import_all_modules() -> None: + """try to import all modules, and look for linking errors + or syntax errors in the pytho ninterface generated by SWIG + """ + pythonocc_core_path = OCC.Core.__path__[0] + available_core_modules = glob.glob(os.path.join(pythonocc_core_path, "*.py")) + nb_available_modules = len(available_core_modules) + # don't know the exact number of modules, it's around 305 or 306 + assert nb_available_modules > 300 + + # try to import the module + for core_module in available_core_modules: + module_name = os.path.basename(core_module).split(".")[0] + importlib.import_module(f"OCC.Core.{module_name}") + + +def test_aliases() -> None: + """some classes are defined in c++ as typedef, i.e. they are only + aliases, e.g. BRepOffsetAPI_Sewing is an alias for BRepBuilderAPI_Sewing + """ + sewing_1 = BRepOffsetAPI_Sewing() + sewing_2 = BRepBuilderAPI_Sewing() + + +def test_Standard_Type() -> None: + """test that Standard_Type returns the correct type name""" + edge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0)).Edge() + curve, _, _ = BRep_Tool.Curve(edge) + line = Geom_Line.DownCast(curve) + assert line.DynamicType().Name() == "Geom_Line" + + +def test_BRepClass_FaceClassifier() -> None: + """ensure BRepClass_FaceClassifier can be instantiated""" + bfc = BRepClass_FaceClassifier() + assert isinstance(bfc, BRepClass_FaceClassifier) + + +def test_wrap_enum() -> None: + """check that enum integer values match c++ name""" + red = Quantity_Color(Quantity_NameOfColor.Quantity_NOC_RED) + assert red.Red() == 1.0 + assert red.Green() == 0.0 + assert red.Blue() == 0.0 + green = Quantity_Color(Quantity_NameOfColor.Quantity_NOC_GREEN) + assert green.Red() == 0.0 + assert green.Green() == 1.0 + assert green.Blue() == 0.0 + blue = Quantity_Color(Quantity_NameOfColor.Quantity_NOC_BLUE) + assert blue.Red() == 0.0 + assert blue.Green() == 0.0 + assert blue.Blue() == 1.0 + white = Quantity_Color(Quantity_NameOfColor.Quantity_NOC_WHITE) + assert white.Red() == 1.0 + assert white.Green() == 1.0 + assert white.Blue() == 1.0 + + +def test_topabs_orientation_byref(): + # see Issue https://github.com/tpaviot/pythonocc-core/issues/1038 + box = BRepPrimAPI_MakeBox(10, 20, 30).Shape() + box_face = list(TopologyExplorer(box).faces())[0] + + facetopo = BRepClass_FaceExplorer(box_face) + facetopo.InitWires() # get ready to explore wires/loops of this face + + edge_1 = BRepClass_Edge() + edge_2 = BRepClass_Edge() + edge_3 = BRepClass_Edge() + edge_4 = BRepClass_Edge() + + facetopo.InitEdges() + topabs_ori_1 = facetopo.CurrentEdge(edge_1) + facetopo.NextEdge() + topabs_ori_2 = facetopo.CurrentEdge(edge_2) + facetopo.NextEdge() + topabs_ori_3 = facetopo.CurrentEdge(edge_3) + facetopo.NextEdge() + topabs_ori_4 = facetopo.CurrentEdge(edge_4) + assert topabs_ori_1 == TopAbs_Orientation.TopAbs_REVERSED + assert topabs_ori_2 == TopAbs_Orientation.TopAbs_REVERSED + assert topabs_ori_3 == TopAbs_Orientation.TopAbs_FORWARD + assert topabs_ori_4 == TopAbs_Orientation.TopAbs_FORWARD + + +def test_Standard_ShortReal_and_Standard_Real_returned_by_reference(): + """the HLRAlgo_EdgeIterator.Visible returns both Standar_Real and Standard_ShortReal + by references""" + start = 1.0 # Standard_Real + tol_start = 2 # Standard_ShortReal + end = 3.0 # Standard_Real + tol_end = 4.0 # Standard_ShortReal + + hlralgo_edge_status = HLRAlgo_EdgeStatus(start, tol_start, end, tol_end) + hlr_edg_it = HLRAlgo_EdgeIterator() + hlr_edg_it.InitVisible(hlralgo_edge_status) + + # visible should return both 4 floats and doubles + assert hlr_edg_it.Visible() == (start, tol_start, end, tol_end) + + +def test_deprecated_static_functions(): + """since pythonocc-core 7.7.1, static functions are not wrapped anymore by a free function. + e.g., calling gp.OX() should be preferred to gp_OX()""" + with pytest.warns(DeprecationWarning): + gp_OX() + assert isinstance(gp.OX(), gp_Ax1) + + +def test_wrap_extendedstring_as_pyunicodestring(): + """not necessary anymore to instanciate a TCollection_ExtendedString, + pass a regular python string""" + # Create XDE document + app = TDocStd_Application() + binxcafdrivers.DefineFormat(app) + doc = TDocStd_Document("example") + app.NewDocument("BinXCAF", doc) + shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) + shape = BRepPrimAPI_MakeBox(10, 10, 10).Shape() + label = shape_tool.AddShape(shape, False) + + a_unicode_string = "Some text with umlauts äöü and japanese (琵琶)" + TDataStd_Name.Set(label, a_unicode_string) + # Initialize the STEP exporter + step_writer = STEPCAFControl_Writer() + Interface_Static.SetIVal("write.stepcaf.subshapes.name", 1) + Interface_Static.SetCVal("write.step.schema", "AP214") + Interface_Static.SetCVal("write.step.product.name", "my product") + step_writer.Transfer(doc, STEPControl_AsIs) + status = step_writer.Write("compound_with_unicode_label.step") + + if status != IFSelect_RetDone: + raise AssertionError("write failed") + + # check that the unicode string was actually exported to file + with open("compound_with_unicode_label.step", "r", encoding="utf8") as f: + step_file_content = f.read() + assert a_unicode_string in step_file_content + + +def test_ReadStream(): + """read a step file from a string""" + with open( + os.path.join(".", "test_io", "io1-ug-214.stp"), "r", encoding="utf8" + ) as step_file: + step_file_content = step_file.read() + step_reader = STEPControl_Reader() + result = step_reader.ReadStream("stream_name", step_file_content) + assert result == IFSelect_RetDone + step_reader.TransferRoots() + + +def test_WriteStream(): + """write a step file to a string""" + the_shape = BRepPrimAPI_MakeBox(10, 20, 30).Shape() + step_writer = STEPControl_Writer() + step_writer.Transfer(the_shape, STEPControl_AsIs) + result, step_str = step_writer.WriteStream() + assert result == IFSelect_RetDone + assert len(step_str) > 15000 # TODO: length depends on architecture? + + +def test_shape_analysis_free_bounds(): + """test special wrapper for ShapeAnalysis::ConnectEdgesToWires""" + p1 = gp_Pnt() + p2 = gp_Pnt(1, 0, 0) + e1 = BRepBuilderAPI_MakeEdge(p1, p2).Edge() + + p3 = gp_Pnt(1, 1, 0) + e2 = BRepBuilderAPI_MakeEdge(p2, p3).Edge() + + edges = TopTools_HSequenceOfShape() + edges.Append(e1) + edges.Append(e2) + + result = ShapeAnalysis_FreeBounds.ConnectEdgesToWires(edges, 1.0e-7, False) + assert result.Length() == 1 + + +def test_const_ref_return(): + """const byref should be wrapped as copy constructors to prevent memory issues, + see issue #1277""" + + def get_bounds(adaptor): + return list(adaptor.Surface().BSpline().Bounds()) + + a_reader = IGESCAFControl_Reader() + iges_filename = os.path.join(".", "test_io", "testfile.igs") + if a_reader.ReadFile(iges_filename) != 1: + raise ValueError("Can't open IGES file.") + + a_doc = TDocStd_Document("iges") + if not a_reader.Transfer(a_doc): + raise ValueError("Cannot transfer data from IGES file.") + + shape_tool = XCAFDoc_DocumentTool.ShapeTool(a_doc.Main()) + + shp_labels = TDF_LabelSequence() + shape_tool.GetShapes(shp_labels) + + shape_label = shp_labels.Value(1) + shape = shape_tool.GetShape(shape_label) + + adaptor = BRepAdaptor_Surface(shape) + bounds = get_bounds(adaptor) + # should returns [0.0, 35.53017372307497, 0.0, 27.81101597164092] + assert bounds == [0.0, 35.53017372307497, 0.0, 27.81101597164092] From a7a1d79a9348b823421c1300d732c89fe96cdcce Mon Sep 17 00:00:00 2001 From: Thomas Paviot Date: Thu, 23 May 2024 09:04:16 +0200 Subject: [PATCH 2/5] Add test for issue #1218 --- test/test_core_wrapper_features.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/test/test_core_wrapper_features.py b/test/test_core_wrapper_features.py index 16e7ebfd1..38360eb08 100644 --- a/test/test_core_wrapper_features.py +++ b/test/test_core_wrapper_features.py @@ -32,7 +32,7 @@ from OCC.Core.Standard import Standard_Transient from OCC.Core.Bnd import Bnd_Box from OCC.Core.BRepExtrema import BRepExtrema_ShapeProximity -from OCC.Core.BRepAdaptor import BRepAdaptor_Surface +from OCC.Core.BRepAdaptor import BRepAdaptor_Curve, BRepAdaptor_Surface from OCC.Core.BRepClass import BRepClass_FaceExplorer, BRepClass_Edge from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_Sewing from OCC.Core.BRepBndLib import brepbndlib @@ -1121,3 +1121,16 @@ def get_bounds(adaptor): bounds = get_bounds(adaptor) # should returns [0.0, 35.53017372307497, 0.0, 27.81101597164092] assert bounds == [0.0, 35.53017372307497, 0.0, 27.81101597164092] + + +def test_const_ref_return_2(): + """See issue #1218""" + + def make_curve(): + p1 = gp_Pnt(5, -5, 0) + p2 = gp_Pnt(5, 5, 0) + ed1 = BRepBuilderAPI_MakeEdge(p2, p1).Edge() + c = BRepAdaptor_Curve(ed1).Curve().Curve() + return c + + assert isinstance(make_curve(), Geom_Curve) From fd86308c5a10101db09b424464d1c93b29098782 Mon Sep 17 00:00:00 2001 From: Thomas Paviot Date: Thu, 23 May 2024 10:45:33 +0200 Subject: [PATCH 3/5] Add person/organization in step export --- test/test_core_wrapper_features.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/test/test_core_wrapper_features.py b/test/test_core_wrapper_features.py index 38360eb08..a11254fd2 100644 --- a/test/test_core_wrapper_features.py +++ b/test/test_core_wrapper_features.py @@ -115,14 +115,16 @@ MethodNotWrappedError, ClassNotWrappedError, ) -from OCC.Core.BinXCAFDrivers import binxcafdrivers -from OCC.Core.TDocStd import TDocStd_Application, TDocStd_Document +from OCC.Core.TDocStd import TDocStd_Document from OCC.Core.XCAFDoc import XCAFDoc_DocumentTool from OCC.Core.TDataStd import TDataStd_Name from OCC.Core.STEPCAFControl import STEPCAFControl_Writer from OCC.Core.IGESCAFControl import IGESCAFControl_Reader from OCC.Core.IFSelect import IFSelect_RetDone from OCC.Core.ShapeAnalysis import ShapeAnalysis_FreeBounds +from OCC.Core.APIHeaderSection import APIHeaderSection_MakeHeader +from OCC.Core.TCollection import TCollection_HAsciiString +from OCC.Core.Interface import Interface_HArray1OfHAsciiString from OCC.Extend.TopologyUtils import TopologyExplorer @@ -1027,22 +1029,36 @@ def test_wrap_extendedstring_as_pyunicodestring(): """not necessary anymore to instanciate a TCollection_ExtendedString, pass a regular python string""" # Create XDE document - app = TDocStd_Application() - binxcafdrivers.DefineFormat(app) doc = TDocStd_Document("example") - app.NewDocument("BinXCAF", doc) shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main()) shape = BRepPrimAPI_MakeBox(10, 10, 10).Shape() label = shape_tool.AddShape(shape, False) a_unicode_string = "Some text with umlauts äöü and japanese (琵琶)" TDataStd_Name.Set(label, a_unicode_string) - # Initialize the STEP exporter + step_writer = STEPCAFControl_Writer() Interface_Static.SetIVal("write.stepcaf.subshapes.name", 1) Interface_Static.SetCVal("write.step.schema", "AP214") Interface_Static.SetCVal("write.step.product.name", "my product") step_writer.Transfer(doc, STEPControl_AsIs) + + # Initialize the STEP exporter + hs = APIHeaderSection_MakeHeader(step_writer.ChangeWriter().Model()) + hs.SetName(TCollection_HAsciiString("model name")) + hs.SetAuthorValue(1, TCollection_HAsciiString("My name")) + hs.SetAuthorisation(TCollection_HAsciiString("authorization")) + + descr = Interface_HArray1OfHAsciiString(1, 3) + descr.SetValue(1, TCollection_HAsciiString("a description")) + descr.SetValue(2, TCollection_HAsciiString("split into")) + descr.SetValue(3, TCollection_HAsciiString("three items")) + hs.SetDescription(descr) + + org = Interface_HArray1OfHAsciiString(1, 1) + org.SetValue(1, TCollection_HAsciiString("pythonocc organization")) + hs.SetOrganization(org) + status = step_writer.Write("compound_with_unicode_label.step") if status != IFSelect_RetDone: From ffd5f992a2d909eba094c87b505155d263255123 Mon Sep 17 00:00:00 2001 From: Thomas Paviot Date: Thu, 23 May 2024 10:46:14 +0200 Subject: [PATCH 4/5] Run pytest verbose --- ci/conda/run_test.bat | 2 +- ci/conda/run_test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/conda/run_test.bat b/ci/conda/run_test.bat index 5077b6190..eb4a77b12 100644 --- a/ci/conda/run_test.bat +++ b/ci/conda/run_test.bat @@ -1,5 +1,5 @@ cd ..\work\test -pytest +pytest -sv mypy test_mypy_classic_occ_bottle.py python core_display_tkinter_unittest.py python core_display_pyqt5_unittest.py diff --git a/ci/conda/run_test.sh b/ci/conda/run_test.sh index 1f75f1ac0..40cc8dd72 100644 --- a/ci/conda/run_test.sh +++ b/ci/conda/run_test.sh @@ -1,6 +1,6 @@ #!/bin/bash if [ "$(uname)" == "Linux" ]; then cd ../work/test - pytest + pytest -sv mypy test_mypy_classic_occ_bottle.py fi From 0cf2a45f7bc54783f09873972ab704213de18d15 Mon Sep 17 00:00:00 2001 From: Thomas Paviot Date: Thu, 23 May 2024 11:07:31 +0200 Subject: [PATCH 5/5] simplify test_core_geometry --- test/test_core_geometry.py | 320 ++++++++++++++++++------------------- 1 file changed, 159 insertions(+), 161 deletions(-) diff --git a/test/test_core_geometry.py b/test/test_core_geometry.py index 2297ec078..99659e0ff 100644 --- a/test/test_core_geometry.py +++ b/test/test_core_geometry.py @@ -155,20 +155,21 @@ def test_point_from_curve(): """Test: point from curve""" radius, abscissa = 5.0, 3.0 C = Geom2d_Circle(gp.OX2d(), radius, True) - GAC = Geom2dAdaptor_Curve(C) - UA = GCPnts_UniformAbscissa(GAC, abscissa) - - if UA.IsDone(): - N = UA.NbPoints() - aSequence = [] - for count in range(1, N + 1): - P = gp_Pnt2d() - C.D0(UA.Parameter(count), P) - Parameter = UA.Parameter(count) - assert isinstance(Parameter, float) - aSequence.append(P) - - Abscissa = UA.Abscissa() + geom2d_adaptor_curve = Geom2dAdaptor_Curve(C) + uniform_abscissa = GCPnts_UniformAbscissa(geom2d_adaptor_curve, abscissa) + + assert uniform_abscissa.IsDone() + + N = uniform_abscissa.NbPoints() + aSequence = [] + for count in range(1, N + 1): + P = gp_Pnt2d() + C.D0(uniform_abscissa.Parameter(count), P) + Parameter = uniform_abscissa.Parameter(count) + assert isinstance(Parameter, float) + aSequence.append(P) + + Abscissa = uniform_abscissa.Abscissa() assert Abscissa == abscissa @@ -181,28 +182,26 @@ def test_project_point_on_curve(): PPC = GeomAPI_ProjectPointOnCurve(P, C) N = PPC.NearestPoint() assert isinstance(N, gp_Pnt) - NbResults = PPC.NbPoints() + nb_results = PPC.NbPoints() + assert nb_results > 0 edg = make_edge(C) assert edg is not None - if NbResults > 0: - for i in range(1, NbResults + 1): - Q = PPC.Point(i) - assert isinstance(Q, gp_Pnt) - distance = PPC.Distance(i) - # in any case, it should be > 1 - assert distance > 1.0 + for i in range(1, nb_results + 1): + Q = PPC.Point(i) + assert isinstance(Q, gp_Pnt) + distance = PPC.Distance(i) + # in any case, it should be > 1 + assert distance > 1.0 pstring = f"N : at Distance : {repr(PPC.LowerDistance())}" - for i in range(1, NbResults + 1): + for i in range(1, nb_results + 1): Q = PPC.Point(i) assert isinstance(Q, gp_Pnt) distance = PPC.Distance(i) # in any case, it should be > 1 assert distance > 1.0 - pstring = f"Q{repr(i)}: at Distance :{repr(PPC.Distance(i))}" - print(pstring) def test_point_from_projections(): @@ -213,50 +212,49 @@ def test_point_from_projections(): PPS = GeomAPI_ProjectPointOnSurf(P, SP) N = PPS.NearestPoint() assert isinstance(N, gp_Pnt) - NbResults = PPS.NbPoints() - if NbResults > 0: - for i in range(1, NbResults + 1): - Q = PPS.Point(i) - assert isinstance(Q, gp_Pnt) - distance = PPS.Distance(i) - # in any case, it should be > 1 - assert distance > 1.0 + nb_results = PPS.NbPoints() + assert nb_results > 0 + + for i in range(1, nb_results + 1): + Q = PPS.Point(i) + assert isinstance(Q, gp_Pnt) + distance = PPS.Distance(i) + # in any case, it should be > 1 + assert distance > 1.0 + lower_d = PPS.LowerDistance() assert lower_d > 1.0 - if NbResults > 0: - for i in range(1, NbResults + 1): - Q = PPS.Point(i) - distance = PPS.Distance(i) - pstring = f"Q{repr(i)}: at Distance :{repr(PPS.Distance(i))}" - print(pstring) + for i in range(1, nb_results + 1): + Q = PPS.Point(i) + distance = PPS.Distance(i) def test_points_from_intersection(): """Test: points from intersection""" - PL = gp_Pln(gp_Ax3(gp.XOY())) + plane = gp_Pln(gp_Ax3(gp.XOY())) MinorRadius, MajorRadius = 5, 8 EL = gp_Elips(gp.YOZ(), MajorRadius, MinorRadius) - ICQ = IntAna_IntConicQuad(EL, PL, precision.Angular(), precision.Confusion()) - if ICQ.IsDone(): - NbResults = ICQ.NbPoints() - if NbResults > 0: - for i in range(1, NbResults + 1): - P = ICQ.Point(i) - assert isinstance(P, gp_Pnt) - aPlane = GC_MakePlane(PL).Value() + int_conic_quad = IntAna_IntConicQuad( + EL, plane, precision.Angular(), precision.Confusion() + ) + assert int_conic_quad.IsDone() + nb_results = int_conic_quad.NbPoints() + assert nb_results > 0 + for i in range(1, nb_results + 1): + P = int_conic_quad.Point(i) + assert isinstance(P, gp_Pnt) + aPlane = GC_MakePlane(plane).Value() aSurface = Geom_RectangularTrimmedSurface( aPlane, -8.0, 8.0, -12.0, 12.0, True, True ) assert aSurface is not None - anEllips = GC_MakeEllipse(EL).Value() - assert isinstance(anEllips, Geom_Ellipse) - if ICQ.IsDone(): - NbResults = ICQ.NbPoints() - if NbResults > 0: - for i in range(1, NbResults + 1): - P = ICQ.Point(i) - assert isinstance(P, gp_Pnt) - # pstring = "P%i" % i + an_ellips = GC_MakeEllipse(EL).Value() + assert isinstance(an_ellips, Geom_Ellipse) + nb_results = int_conic_quad.NbPoints() + assert nb_results > 0 + for i in range(1, nb_results + 1): + P = int_conic_quad.Point(i) + assert isinstance(P, gp_Pnt) def test_parabola(): @@ -268,8 +266,8 @@ def test_parabola(): D = gp_Dir2d(4.0, 5.0) A = gp_Ax22d(P, D, True) Para = gp_Parab2d(A, 6) - aParabola = GCE2d_MakeParabola(Para) - gParabola = aParabola.Value() + a_parabola = GCE2d_MakeParabola(Para) + gParabola = a_parabola.Value() assert isinstance(gParabola, Geom2d_Parabola) aTrimmedCurve = Geom2d_TrimmedCurve(gParabola, -100, 100, True) assert aTrimmedCurve is not None @@ -277,16 +275,16 @@ def test_parabola(): def test_axis(): """Test: axis""" - P1 = gp_Pnt(2, 3, 4) + point_1 = gp_Pnt(2, 3, 4) D = gp_Dir(4, 5, 6) - A = gp_Ax3(P1, D) + A = gp_Ax3(point_1, D) assert A.Direct() AXDirection = A.XDirection() assert isinstance(AXDirection, gp_Dir) AYDirection = A.YDirection() assert isinstance(AYDirection, gp_Dir) - P2 = gp_Pnt(5, 3, 4) - A2 = gp_Ax3(P2, D) + point_2 = gp_Pnt(5, 3, 4) + A2 = gp_Ax3(point_2, D) A2.YReverse() # axis3 is now left handed assert not A2.Direct() @@ -305,8 +303,8 @@ def test_bspline(): array.append(gp_Pnt2d(5, 5)) xxx = point2d_list_to_TColgp_Array1OfPnt2d(array) - SPL1 = Geom2dAPI_PointsToBSpline(xxx).Curve() - assert SPL1 is not None + spline_1 = Geom2dAPI_PointsToBSpline(xxx).Curve() + assert spline_1 is not None harray = TColgp_HArray1OfPnt2d(1, 5) harray.SetValue(1, gp_Pnt2d(7 + 0, 0)) @@ -317,8 +315,8 @@ def test_bspline(): anInterpolation = Geom2dAPI_Interpolate(harray, False, 0.01) anInterpolation.Perform() - SPL2 = anInterpolation.Curve() - assert SPL2 is not None + spline_2 = anInterpolation.Curve() + assert spline_2 is not None harray2 = TColgp_HArray1OfPnt2d(1, 5) harray2.SetValue(1, gp_Pnt2d(11 + 0, 0)) @@ -329,8 +327,8 @@ def test_bspline(): anInterpolation2 = Geom2dAPI_Interpolate(harray2, True, 0.01) anInterpolation2.Perform() - SPL3 = anInterpolation2.Curve() - assert SPL3 is not None + spline_3 = anInterpolation2.Curve() + assert spline_3 is not None i = 0 for P in array: i = i + 1 @@ -353,8 +351,8 @@ def test_curves2d_from_curves(): ell = GCE2d_MakeEllipse(axis, major, minor) E = ell.Value() TC = Geom2d_TrimmedCurve(E, -1, 2, True) - SPL = geom2dconvert.CurveToBSplineCurve(TC, Convert_TgtThetaOver2) - assert SPL is not None + spline = geom2dconvert.CurveToBSplineCurve(TC, Convert_TgtThetaOver2) + assert spline is not None def test_curves2d_from_offset(): @@ -366,68 +364,68 @@ def test_curves2d_from_offset(): array.append(gp_Pnt2d(-3, 5)) xxx = point2d_list_to_TColgp_Array1OfPnt2d(array) - SPL1 = Geom2dAPI_PointsToBSpline(xxx).Curve() - assert SPL1 is not None + spline_1 = Geom2dAPI_PointsToBSpline(xxx).Curve() + assert spline_1 is not None dist = 1 - OC = Geom2d_OffsetCurve(SPL1, dist) - assert OC.IsCN(2) + offset_curve = Geom2d_OffsetCurve(spline_1, dist) + assert offset_curve.IsCN(2) dist2 = 1.5 - OC2 = Geom2d_OffsetCurve(SPL1, dist2) - assert OC2.IsCN(2) + offset_curve_2 = Geom2d_OffsetCurve(spline_1, dist2) + assert offset_curve_2.IsCN(2) def test_circles2d_from_curves(): """Test: circles2d from curves""" - P1 = gp_Pnt2d(9, 6) - P2 = gp_Pnt2d(10, 4) - P3 = gp_Pnt2d(6, 7) - C = gce_MakeCirc2d(P1, P2, P3).Value() + point_1 = gp_Pnt2d(9, 6) + point_2 = gp_Pnt2d(10, 4) + point_3 = gp_Pnt2d(6, 7) + C = gce_MakeCirc2d(point_1, point_2, point_3).Value() QC = gccent.Outside(C) - P4 = gp_Pnt2d(-2, 7) - P5 = gp_Pnt2d(12, -3) - L = GccAna_Lin2d2Tan(P4, P5, precision.Confusion()).ThisSolution(1) + point_4 = gp_Pnt2d(-2, 7) + point_5 = gp_Pnt2d(12, -3) + L = GccAna_Lin2d2Tan(point_4, point_5, precision.Confusion()).ThisSolution(1) QL = gccent.Unqualified(L) radius = 2.0 TR = GccAna_Circ2d2TanRad(QC, QL, radius, precision.Confusion()) - if TR.IsDone(): - NbSol = TR.NbSolutions() - for k in range(1, NbSol + 1): - circ = TR.ThisSolution(k) - # find the solution circle - pnt1 = gp_Pnt2d() - parsol, pararg = TR.Tangency1(k, pnt1) - assert parsol > 0.0 - assert pararg > 0.0 - # find the first tangent point - pnt2 = gp_Pnt2d() - parsol, pararg = TR.Tangency2(k, pnt2) - assert parsol > 0.0 - assert pararg > 0.0 - # find the second tangent point - - aLine = GCE2d_MakeSegment(L, -2, 20).Value() - assert isinstance(aLine, Geom2d_TrimmedCurve) - if TR.IsDone(): - NbSol = TR.NbSolutions() - for k in range(1, NbSol + 1): - circ = TR.ThisSolution(k) - aCircle = Geom2d_Circle(circ) - assert isinstance(aCircle, Geom2d_Circle) - # find the solution circle (index, outvalue, outvalue, gp_Pnt2d) - pnt3 = gp_Pnt2d() - parsol, pararg = TR.Tangency1(k, pnt3) - assert parsol > 0.0 - assert pararg > 0.0 - # find the first tangent point - pnt4 = gp_Pnt2d() - parsol, pararg = TR.Tangency2(k, pnt4) - assert parsol > 0.0 - assert pararg > 0.0 + assert TR.IsDone() + + nb_sol = TR.NbSolutions() + for k in range(1, nb_sol + 1): + circ = TR.ThisSolution(k) + # find the solution circle + pnt1 = gp_Pnt2d() + parsol, pararg = TR.Tangency1(k, pnt1) + assert parsol > 0.0 + assert pararg > 0.0 + # find the first tangent point + pnt2 = gp_Pnt2d() + parsol, pararg = TR.Tangency2(k, pnt2) + assert parsol > 0.0 + assert pararg > 0.0 + # find the second tangent point + + a_line = GCE2d_MakeSegment(L, -2, 20).Value() + assert isinstance(a_line, Geom2d_TrimmedCurve) + nb_sol = TR.NbSolutions() + for k in range(1, nb_sol + 1): + circ = TR.ThisSolution(k) + aCircle = Geom2d_Circle(circ) + assert isinstance(aCircle, Geom2d_Circle) + # find the solution circle (index, outvalue, outvalue, gp_Pnt2d) + pnt3 = gp_Pnt2d() + parsol, pararg = TR.Tangency1(k, pnt3) + assert parsol > 0.0 + assert pararg > 0.0 + # find the first tangent point + pnt4 = gp_Pnt2d() + parsol, pararg = TR.Tangency2(k, pnt4) + assert parsol > 0.0 + assert pararg > 0.0 def test_surface_from_curves(): @@ -439,7 +437,7 @@ def test_surface_from_curves(): array.append(gp_Pnt(-3, 5, -2)) aaa = point_list_to_TColgp_Array1OfPnt(array) - SPL1 = GeomAPI_PointsToBSpline(aaa).Curve() + spline_1 = GeomAPI_PointsToBSpline(aaa).Curve() a2 = [gp_Pnt(-4, 0, 2)] a2.append(gp_Pnt(-2, 2, 0)) @@ -447,24 +445,24 @@ def test_surface_from_curves(): a2.append(gp_Pnt(3, 7, -2)) a2.append(gp_Pnt(4, 9, -1)) bbb = point_list_to_TColgp_Array1OfPnt(a2) - SPL2 = GeomAPI_PointsToBSpline(bbb).Curve() + spline_2 = GeomAPI_PointsToBSpline(bbb).Curve() - aGeomFill1 = GeomFill_BSplineCurves(SPL1, SPL2, GeomFill_StretchStyle) + a_geom_fill_1 = GeomFill_BSplineCurves(spline_1, spline_2, GeomFill_StretchStyle) - SPL3 = Geom_BSplineCurve.DownCast(SPL1.Translated(gp_Vec(10, 0, 0))) - SPL4 = Geom_BSplineCurve.DownCast(SPL2.Translated(gp_Vec(10, 0, 0))) - aGeomFill2 = GeomFill_BSplineCurves(SPL3, SPL4, GeomFill_CoonsStyle) + spline_3 = Geom_BSplineCurve.DownCast(spline_1.Translated(gp_Vec(10, 0, 0))) + spline_4 = Geom_BSplineCurve.DownCast(spline_2.Translated(gp_Vec(10, 0, 0))) + a_geom_fill_2 = GeomFill_BSplineCurves(spline_3, spline_4, GeomFill_CoonsStyle) - SPL5 = Geom_BSplineCurve.DownCast(SPL1.Translated(gp_Vec(20, 0, 0))) - SPL6 = Geom_BSplineCurve.DownCast(SPL2.Translated(gp_Vec(20, 0, 0))) - aGeomFill3 = GeomFill_BSplineCurves(SPL5, SPL6, GeomFill_CurvedStyle) + spline_5 = Geom_BSplineCurve.DownCast(spline_1.Translated(gp_Vec(20, 0, 0))) + spline_6 = Geom_BSplineCurve.DownCast(spline_2.Translated(gp_Vec(20, 0, 0))) + a_geom_fill_3 = GeomFill_BSplineCurves(spline_5, spline_6, GeomFill_CurvedStyle) - aBSplineSurface1 = aGeomFill1.Surface() - assert aBSplineSurface1 is not None - aBSplineSurface2 = aGeomFill2.Surface() - assert aBSplineSurface2 is not None - aBSplineSurface3 = aGeomFill3.Surface() - assert aBSplineSurface3 is not None + a_bspline_surface_1 = a_geom_fill_1.Surface() + assert a_bspline_surface_1 is not None + a_bspline_surface_2 = a_geom_fill_2.Surface() + assert a_bspline_surface_2 is not None + a_bspline_surface_3 = a_geom_fill_3.Surface() + assert a_bspline_surface_3 is not None def test_pipes(): @@ -476,25 +474,25 @@ def test_pipes(): a1.append(gp_Pnt(-3, 5, -12)) xxx = point_list_to_TColgp_Array1OfPnt(a1) - SPL1 = GeomAPI_PointsToBSpline(xxx).Curve() + spline_1 = GeomAPI_PointsToBSpline(xxx).Curve() - aPipe = GeomFill_Pipe(SPL1, True) - aPipe.Perform(False, False) - aSurface = aPipe.Surface() + a_pipe = GeomFill_Pipe(spline_1, True) + a_pipe.Perform(False, False) + aSurface = a_pipe.Surface() assert aSurface is not None E = GC_MakeEllipse(gp.XOY(), 2, 1).Value() - aPipe2 = GeomFill_Pipe(SPL1, E, GeomFill_IsConstantNormal) - aPipe2.Perform(False, False) - aSurface2 = aPipe2.Surface() - aSurface2.Translate(gp_Vec(5, 0, 0)) + a_pipe2 = GeomFill_Pipe(spline_1, E, GeomFill_IsConstantNormal) + a_pipe2.Perform(False, False) + a_surface_2 = a_pipe2.Surface() + a_surface_2.Translate(gp_Vec(5, 0, 0)) TC1 = GC_MakeSegment(gp_Pnt(1, 1, 1), gp_Pnt(2, 2, 2)).Value() TC2 = GC_MakeSegment(gp_Pnt(1, 1, 0), gp_Pnt(3, 2, 1)).Value() # TODO: following lines bug with occt-770 - # aPipe3 = GeomFill_Pipe(SPL1, TC1, TC2) - # aPipe3.Perform(False, False) - # aSurface3 = aPipe3.Surface() + # a_pipe3 = GeomFill_Pipe(spline_1, TC1, TC2) + # a_pipe3.Perform(False, False) + # aSurface3 = a_pipe3.Surface() # aSurface3.Translate(gp_Vec(10, 0, 0)) for mode in [ @@ -508,10 +506,10 @@ def test_pipes(): GeomFill_IsGuidePlanWithContact, ]: E = GC_MakeEllipse(gp.XOY(), 2, 1).Value() - aPipe2 = GeomFill_Pipe(SPL1, TC1, TC2, mode) - aPipe2.Perform(False, False) - aSurface2 = aPipe2.Surface() - aSurface2.Translate(gp_Vec(5, 5, 0)) + a_pipe2 = GeomFill_Pipe(spline_1, TC1, TC2, mode) + a_pipe2.Perform(False, False) + a_surface_2 = a_pipe2.Surface() + a_surface_2.Translate(gp_Vec(5, 5, 0)) def test_bezier_surfaces(): @@ -578,10 +576,10 @@ def test_bezier_surfaces(): # udeg = BB.UDegree() # vdeg = BB.VDegree() - # BSPLSURF = Geom_BSplineSurface( + # BsplineSURF = Geom_BSplineSurface( # poles, uknots, vknots, umult, vmult, udeg, vdeg, False, False # ) - # BSPLSURF.Translate(gp_Vec(0, 0, 2)) + # BsplineSURF.Translate(gp_Vec(0, 0, 2)) def test_surfaces_from_offsets(): @@ -591,17 +589,17 @@ def test_surfaces_from_offsets(): array1.append(gp_Pnt(-1, 7, 7)) array1.append(gp_Pnt(0, 8, 8)) array1.append(gp_Pnt(2, 9, 9)) - SPL1 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array1)).Curve() + spline_1 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array1)).Curve() array2 = [gp_Pnt(-4, 5, 2)] array2.append(gp_Pnt(-3, 6, 3)) array2.append(gp_Pnt(-1, 7, 4)) array2.append(gp_Pnt(0, 8, 5)) array2.append(gp_Pnt(2, 9, 6)) - SPL2 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array2)).Curve() + spline_2 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array2)).Curve() - aGeomFill1 = GeomFill_BSplineCurves(SPL1, SPL2, GeomFill_StretchStyle) - aGeomSurface = aGeomFill1.Surface() + a_geom_fill_1 = GeomFill_BSplineCurves(spline_1, spline_2, GeomFill_StretchStyle) + aGeomSurface = a_geom_fill_1.Surface() offset = 1 GOS = Geom_OffsetSurface(aGeomSurface, offset) @@ -642,15 +640,15 @@ def test_distances(): array1.append(gp_Pnt(-5.3, 3, 1)) array1.append(gp_Pnt(-5, 4, 1)) array1.append(gp_Pnt(-5, 5, 2)) - SPL1 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array1)).Curve() + spline_1 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array1)).Curve() array2 = [gp_Pnt(4, 1, 2)] array2.append(gp_Pnt(4, 2, 2)) array2.append(gp_Pnt(3.7, 3, 1)) array2.append(gp_Pnt(4, 4, 1)) array2.append(gp_Pnt(4, 5, 2)) - SPL2 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array2)).Curve() - aGeomFill1 = GeomFill_BSplineCurves(SPL1, SPL2, GeomFill_StretchStyle) - aSurf1 = aGeomFill1.Surface() + spline_2 = GeomAPI_PointsToBSpline(point_list_to_TColgp_Array1OfPnt(array2)).Curve() + a_geom_fill_1 = GeomFill_BSplineCurves(spline_1, spline_2, GeomFill_StretchStyle) + aSurf1 = a_geom_fill_1.Surface() array3 = TColgp_Array2OfPnt(1, 5, 1, 5) array3.SetValue(1, 1, gp_Pnt(-4, -4, 5)) @@ -693,9 +691,9 @@ def test_distances(): NbExtrema = ESS.NbExtrema() for k in range(1, NbExtrema + 1): - P3, P4 = gp_Pnt(), gp_Pnt() - ESS.Points(k, P3, P4) - aCurve = GC_MakeSegment(P3, P4).Value() + point_3, point_4 = gp_Pnt(), gp_Pnt() + ESS.Points(k, point_3, point_4) + aCurve = GC_MakeSegment(point_3, point_4).Value() assert aCurve is not None