Closed hroncok closed 5 years ago
I have a patch ready, will test.
Ah, the frombuffer calls probably need a dtype with explicit byte ordering. This is a stab in the dark because I don't have a BE machine to test on, but it didn't make things worse on my machine. There are probably other places this happens too, like in the PLY loader.
Thanks for the report!
Well i have basically the same commit, running trough Fedora buildsystem.
Ah sorry didn't see above! Sounds good, after grepping it looks like it's just ply and GLTF that possibly need the same treatment. I'll hold off committing on this as I have no way of telling if it is fixing the issue haha.
I got to: 15 failed, 168 passed, 10 deselected, 5093 warnings in 102.45 seconds
I've also changed:
face_normals = blob[normal_index].astype('<f8')
vertices = blob[vertex_index.reshape((-1, 3))].astype('<f8')
load_glb mostly
BTW AFAIK PLY is textual so the endianness should not matter
=================================== FAILURES ===================================
_____________________________ GLTFTest.test_units ______________________________
self = <tests.test_gltf.GLTFTest testMethod=test_units>
def test_units(self):
"""
Trimesh will store units as a GLTF extra if they are defined,
so check that.
"""
original = g.get_mesh('pins.glb')
# export it as a a GLB file
export = original.export('glb')
kwargs = g.trimesh.io.gltf.load_glb(
g.trimesh.util.wrap_as_stream(export))
> reloaded = g.trimesh.io.load.load_kwargs(kwargs)
tests/test_gltf.py:25:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
trimesh/io/load.py:374: in load_kwargs
return handler()
trimesh/io/load.py:321: in handle_scene
k, v in kwargs['geometry'].items()})
trimesh/io/load.py:321: in <dictcomp>
k, v in kwargs['geometry'].items()})
trimesh/io/load.py:374: in load_kwargs
return handler()
trimesh/io/load.py:345: in handle_trimesh_kwargs
return Trimesh(**kwargs)
trimesh/base.py:177: in __init__
self.process()
trimesh/base.py:209: in process
self.merge_vertices()
trimesh/base.py:990: in merge_vertices
grouping.merge_vertices_hash(self, distance=distance)
trimesh/grouping.py:38: in merge_vertices_hash
mesh.update_vertices(unique, inverse)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <trimesh.base.Trimesh object at 0x3ff94a313c8>
mask = array([ 2, 241, 104, 323, 330, 350, 352, 26, 211, 128, 213, 364, 150,
362, 144, 6, 185, 182, 189, 186, 188,...209, 453, 454, 455, 295, 296,
297, 481, 482, 267, 268, 554, 553, 196, 195, 200, 199, 202, 201,
308, 307])
inverse = array([ 82, 82, 0, 0, 74, 74, 15, 15, 42, 42, 43, 43, 43,
43, 42, 42, 29, 29, 32, 32, 31,... 7, 7, 7, 0, 0,
29, 29, 32, 32, 31, 31, 29, 29, 44, 44, 45, 45, 45,
45, 44, 44])
def update_vertices(self, mask, inverse=None):
"""
Update vertices with a mask.
Parameters
----------
vertex_mask : (len(self.vertices)) bool
Array of which vertices to keep
inverse : (len(self.vertices)) int
Array to reconstruct vertex references
such as output by np.unique
"""
# if the mesh is already empty we can't remove anything
if self.is_empty:
return
# make sure mask is a numpy array
mask = np.asanyarray(mask)
if ((mask.dtype.name == 'bool' and mask.all()) or
len(mask) == 0 or self.is_empty):
# mask doesn't remove any vertices so exit early
return
# re- index faces from inverse
if inverse is not None and util.is_shape(self.faces, (-1, 3)):
> self.faces = inverse[self.faces.reshape(-1)].reshape((-1, 3))
E IndexError: index 2718040064 is out of bounds for axis 1 with size 744
trimesh/base.py:1018: IndexError
_________________________ PermutateTest.test_permutate _________________________
self = <tests.test_permutate.PermutateTest testMethod=test_permutate>
def test_permutate(self):
def close(a, b):
if len(a) == len(b) == 0:
return False
if a.shape != b.shape:
return False
return g.np.allclose(a, b)
def make_assertions(mesh, test, rigid=False):
if (close(test.face_adjacency,
mesh.face_adjacency) and
len(mesh.faces) > MIN_FACES):
raise ValueError(
'face adjacency of %s the same after permutation!',
mesh.metadata['file_name'])
if (close(test.face_adjacency_edges,
mesh.face_adjacency_edges) and
len(mesh.faces) > MIN_FACES):
raise ValueError(
'face adjacency edges of %s the same after permutation!',
mesh.metadata['file_name'])
self.assertFalse(close(test.faces,
mesh.faces))
self.assertFalse(close(test.vertices,
mesh.vertices))
self.assertFalse(test.md5() == mesh.md5())
# rigid transforms don't change area or volume
if rigid:
assert g.np.allclose(mesh.area, test.area)
# volume is very dependent on meshes being watertight and sane
if (mesh.is_watertight and
test.is_watertight and
mesh.is_winding_consistent and
test.is_winding_consistent):
assert g.np.allclose(mesh.volume, test.volume, rtol=.05)
for mesh in g.get_meshes():
if len(mesh.faces) < MIN_FACES:
continue
# warp the mesh to be a unit cube
mesh.vertices /= mesh.extents
original = mesh.copy()
for i in range(5):
mesh = original.copy()
noise = g.trimesh.permutate.noise(mesh,
magnitude=mesh.scale / 50.0)
# make sure that if we permutate vertices with no magnitude
# area and volume remain the same
no_noise = g.trimesh.permutate.noise(mesh, magnitude=0.0)
transform = g.trimesh.permutate.transform(mesh)
tessellate = g.trimesh.permutate.tessellation(mesh)
make_assertions(mesh, noise, rigid=False)
> make_assertions(mesh, no_noise, rigid=True)
tests/test_permutate.py:72:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
mesh = <trimesh.base.Trimesh object at 0x3ff9258a160>
test = <trimesh.base.Trimesh object at 0x3ff930c2390>, rigid = True
def make_assertions(mesh, test, rigid=False):
if (close(test.face_adjacency,
mesh.face_adjacency) and
len(mesh.faces) > MIN_FACES):
raise ValueError(
'face adjacency of %s the same after permutation!',
mesh.metadata['file_name'])
if (close(test.face_adjacency_edges,
mesh.face_adjacency_edges) and
len(mesh.faces) > MIN_FACES):
raise ValueError(
'face adjacency edges of %s the same after permutation!',
> mesh.metadata['file_name'])
E ValueError: ('face adjacency edges of %s the same after permutation!', '1002_tray_bottom.STL')
tests/test_permutate.py:34: ValueError
____________________________ RepairTests.test_multi ____________________________
self = <tests.test_repair.RepairTests testMethod=test_multi>
def test_multi(self):
"""
Try repairing a multibody geometry
"""
# create a multibody mesh with two cubes
a = g.get_mesh('unit_cube.STL')
b = a.copy()
b.apply_translation([2, 0, 0])
m = a + b
# should be a volume: watertight, correct winding
assert m.is_volume
# flip one face
m.faces[:1] = g.np.fliplr(m.faces[:1])
# flip every face
m.invert()
# not a volume
assert not m.is_volume
m.fix_normals(multibody=False)
# shouldn't fix inversion of one cube
> assert not m.is_volume
E AssertionError: assert not True
E + where True = <trimesh.base.Trimesh object at 0x3ff928fe208>.is_volume
tests/test_repair.py:120: AssertionError
WIP in https://github.com/mikedh/trimesh/pull/250
Still the failures above, but I have to go now. Will revisit later.
@mikedh any hints where to look for clues for the last remaining failing tests?
That is a surprisingly helpful error message haha, thanks pytest. The first failure seems traceable to GLB somewhere loading faces with the wrong endian-ness (that face index is way higher than it should be).
The permutate/repair failures are more puzzling. It looks almost like a cache failure, like the cache isn't being cleared correctly when things are modified. You might add an assert or two after operations that mutate the mesh to make sure mesh._data.fast_hash()
has changed. Although test_caching
is pretty thorough (IMHO) and should really be failing too in the case that xxhash or CRC32 is screwy on BE machines.
Oh, it could also be that STL file that's failing is loading without raising, but didn't actually load anything. I'd add an assert to make sure it loaded something (i.e. assert len(mesh.faces) > 0
right above the failures you're seeing). Or possibly we should add a face count truth JSON in tests/data
to make sure trimesh is loading all the faces it should be.
It would be nice to have this checked in CI, though it looks like neither CircleCI or Travis support any BE builds. Are the Fedora builds automatic once this is fixed?
Unfortunately the only Fedora thing I know that can be used as a CI doesn't have BE builders. The Fedora official builders are not a CI and probably should not be misused like one, but it is possible to push a RPM package to them manually.
Gotcha, I guess another testing option is something like a qemu
image with Alpine/PPC, but that's a lot of work and this issue is narrow enough that it is probably not necessary.
I think this is better than before, but I have no ability to test and this is a bit of a narrow issue. Closing for now, though feel free to re- open, and PR's are gladly accepted. Thanks for the report!
JFYI current s390x test log for 2.36.13:
+ /usr/bin/python3 -m pytest -v -k 'not test_export'
============================= test session starts ==============================
platform linux -- Python 3.7.2, pytest-3.9.3, py-1.7.0, pluggy-0.8.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /builddir/build/BUILD/trimesh-2.36.13, inifile:
collecting ... collected 212 items / 9 deselected
tests/test_boolean.py::BooleanTest::test_boolean PASSED [ 0%]
tests/test_boolean.py::BooleanTest::test_multiple PASSED [ 0%]
tests/test_bounds.py::BoundsTest::test_2D PASSED [ 1%]
tests/test_bounds.py::BoundsTest::test_cylinder PASSED [ 1%]
tests/test_bounds.py::BoundsTest::test_obb_mesh PASSED [ 2%]
tests/test_bounds.py::BoundsTest::test_obb_order PASSED [ 2%]
tests/test_bounds.py::BoundsTest::test_obb_points PASSED [ 3%]
tests/test_cache.py::CacheTest::test_contiguous PASSED [ 3%]
tests/test_cache.py::CacheTest::test_hash PASSED [ 4%]
tests/test_cache.py::CacheTest::test_track PASSED [ 4%]
tests/test_camera.py::CameraTests::test_K PASSED [ 5%]
tests/test_camera.py::CameraTests::test_consistency PASSED [ 5%]
tests/test_collision.py::CollisionTest::test_collision PASSED [ 6%]
tests/test_collision.py::CollisionTest::test_distance PASSED [ 6%]
tests/test_collision.py::CollisionTest::test_scene PASSED [ 7%]
tests/test_color.py::VisualTest::test_concatenate PASSED [ 7%]
tests/test_color.py::VisualTest::test_conversion PASSED [ 8%]
tests/test_color.py::VisualTest::test_data_model PASSED [ 8%]
tests/test_color.py::VisualTest::test_interpolate PASSED [ 9%]
tests/test_color.py::VisualTest::test_smooth PASSED [ 9%]
tests/test_color.py::VisualTest::test_uv_to_color PASSED [ 10%]
tests/test_color.py::VisualTest::test_vertex PASSED [ 10%]
tests/test_color.py::VisualTest::test_visual PASSED [ 11%]
tests/test_convex.py::ConvexTest::test_convex PASSED [ 11%]
tests/test_convex.py::ConvexTest::test_primitives PASSED [ 12%]
tests/test_convex.py::ConvexTest::test_projections PASSED [ 12%]
tests/test_creation.py::CreationTest::test_annulus PASSED [ 13%]
tests/test_creation.py::CreationTest::test_axis PASSED [ 13%]
tests/test_creation.py::CreationTest::test_camera_marker PASSED [ 14%]
tests/test_creation.py::CreationTest::test_path_sweep PASSED [ 14%]
tests/test_creation.py::CreationTest::test_soup PASSED [ 15%]
tests/test_creation.py::CreationTest::test_spheres PASSED [ 15%]
tests/test_creation.py::CreationTest::test_triangulate PASSED [ 16%]
tests/test_creation.py::CreationTest::test_triangulate_plumbing PASSED [ 16%]
tests/test_curvature.py::CurvatureTest::test_gaussian_curvature PASSED [ 17%]
tests/test_curvature.py::CurvatureTest::test_mean_curvature PASSED [ 17%]
tests/test_curvature.py::CurvatureTest::test_vertex_defect PASSED [ 18%]
tests/test_decomposition.py::DecompositionTest::test_convex_decomposition PASSED [ 18%]
tests/test_dxf.py::DXFTest::test_bulge PASSED [ 19%]
tests/test_dxf.py::DXFTest::test_dxf PASSED [ 19%]
tests/test_dxf.py::DXFTest::test_spline PASSED [ 20%]
tests/test_dxf.py::DXFTest::test_text PASSED [ 20%]
tests/test_dxf.py::DXFTest::test_versions PASSED [ 21%]
tests/test_edges.py::EdgeTest::test_face_unique PASSED [ 21%]
tests/test_facets.py::FacetTest::test_facet PASSED [ 22%]
tests/test_gltf.py::GLTFTest::test_cesium PASSED [ 22%]
tests/test_gltf.py::GLTFTest::test_duck PASSED [ 23%]
tests/test_gltf.py::GLTFTest::test_tex_export PASSED [ 23%]
tests/test_gltf.py::GLTFTest::test_units PASSED [ 24%]
tests/test_graph.py::GraphTest::test_components PASSED [ 24%]
tests/test_graph.py::GraphTest::test_engine_time PASSED [ 25%]
tests/test_graph.py::GraphTest::test_engines PASSED [ 25%]
tests/test_graph.py::GraphTest::test_smoothed PASSED [ 26%]
tests/test_graph.py::GraphTest::test_soup PASSED [ 26%]
tests/test_graph.py::GraphTest::test_traversals PASSED [ 27%]
tests/test_graph.py::GraphTest::test_vertex_adjacency_graph PASSED [ 27%]
tests/test_graph.py::GraphTest::test_watertight PASSED [ 28%]
tests/test_grouping.py::GroupTests::test_blocks PASSED [ 28%]
tests/test_grouping.py::GroupTests::test_boolean_rows PASSED [ 29%]
tests/test_grouping.py::GroupTests::test_cluster PASSED [ 29%]
tests/test_grouping.py::GroupTests::test_group_rows PASSED [ 30%]
tests/test_grouping.py::GroupTests::test_group_vector PASSED [ 30%]
tests/test_grouping.py::GroupTests::test_runs PASSED [ 31%]
tests/test_grouping.py::GroupTests::test_unique_float PASSED [ 31%]
tests/test_grouping.py::GroupTests::test_unique_rows PASSED [ 32%]
tests/test_html.py::ViewTest::test_JSHTML PASSED [ 32%]
tests/test_html.py::ViewTest::test_inNB PASSED [ 33%]
tests/test_identifier.py::IdentifierTest::test_identifier PASSED [ 33%]
tests/test_identifier.py::IdentifierTest::test_scene_id PASSED [ 33%]
tests/test_inertia.py::InertiaTest::test_inertia PASSED [ 34%]
tests/test_inertia.py::InertiaTest::test_primitives PASSED [ 34%]
tests/test_integrate.py::IntegrateTest::test_integrate PASSED [ 35%]
tests/test_loaded.py::LoaderTest::test_3MF PASSED [ 35%]
tests/test_loaded.py::LoaderTest::test_obj_compressed PASSED [ 36%]
tests/test_loaded.py::LoaderTest::test_obj_groups PASSED [ 36%]
tests/test_loaded.py::LoaderTest::test_obj_multiobj PASSED [ 37%]
tests/test_loaded.py::LoaderTest::test_obj_quad PASSED [ 37%]
tests/test_loaded.py::LoaderTest::test_obj_simple_order PASSED [ 38%]
tests/test_loaded.py::LoaderTest::test_obj_split_attributes PASSED [ 38%]
tests/test_loaded.py::LoaderTest::test_remote PASSED [ 39%]
tests/test_loaded.py::LoaderTest::test_stl PASSED [ 39%]
tests/test_mesh.py::MeshTests::test_meshes PASSED [ 40%]
tests/test_mesh.py::MeshTests::test_none PASSED [ 40%]
tests/test_mesh.py::MeshTests::test_validate PASSED [ 41%]
tests/test_mesh.py::MeshTests::test_vertex_neighbors PASSED [ 41%]
tests/test_normals.py::NormalsTest::test_face_normals PASSED [ 42%]
tests/test_normals.py::NormalsTest::test_vertex_normal PASSED [ 42%]
tests/test_nsphere.py::NSphereTest::test_isnsphere PASSED [ 43%]
tests/test_nsphere.py::NSphereTest::test_minball PASSED [ 43%]
tests/test_packing.py::PackingTest::test_obb PASSED [ 44%]
tests/test_packing.py::PackingTest::test_paths PASSED [ 44%]
tests/test_paths.py::VectorTests::test_discrete PASSED [ 45%]
tests/test_paths.py::VectorTests::test_edges PASSED [ 45%]
tests/test_paths.py::VectorTests::test_poly PASSED [ 46%]
tests/test_paths.py::VectorTests::test_random_polygon PASSED [ 46%]
tests/test_paths.py::VectorTests::test_sample PASSED [ 47%]
tests/test_paths.py::ArcTests::test_center PASSED [ 47%]
tests/test_paths.py::ArcTests::test_center_random PASSED [ 48%]
tests/test_paths.py::ArcTests::test_multiroot PASSED [ 48%]
tests/test_paths.py::SplitTest::test_split PASSED [ 49%]
tests/test_paths.py::SectionTest::test_section PASSED [ 49%]
tests/test_paths.py::CreationTests::test_circle PASSED [ 50%]
tests/test_paths.py::CreationTests::test_rect PASSED [ 50%]
tests/test_permutate.py::PermutateTest::test_base PASSED [ 51%]
tests/test_permutate.py::PermutateTest::test_permutate FAILED [ 51%]
tests/test_permutate.py::PermutateTest::test_tesselation PASSED [ 52%]
tests/test_points.py::PointsTest::test_kmeans PASSED [ 52%]
tests/test_points.py::PointsTest::test_plane PASSED [ 53%]
tests/test_points.py::PointsTest::test_pointcloud PASSED [ 53%]
tests/test_points.py::PointsTest::test_tsp PASSED [ 54%]
tests/test_points.py::PointsTest::test_vertex_only PASSED [ 54%]
tests/test_poses.py::PosesTest::test_multiple PASSED [ 55%]
tests/test_poses.py::PosesTest::test_nonsampling_poses PASSED [ 55%]
tests/test_poses.py::PosesTest::test_round PASSED [ 56%]
tests/test_primitives.py::PrimitiveTest::test_box PASSED [ 56%]
tests/test_primitives.py::PrimitiveTest::test_extrusion PASSED [ 57%]
tests/test_primitives.py::PrimitiveTest::test_primitives PASSED [ 57%]
tests/test_primitives.py::PrimitiveTest::test_sample PASSED [ 58%]
tests/test_proximity.py::NearestTest::test_acute_edge_case PASSED [ 58%]
tests/test_proximity.py::NearestTest::test_coplanar_signed_distance PASSED [ 59%]
tests/test_proximity.py::NearestTest::test_edge_case PASSED [ 59%]
tests/test_proximity.py::NearestTest::test_helper PASSED [ 60%]
tests/test_proximity.py::NearestTest::test_naive PASSED [ 60%]
tests/test_proximity.py::NearestTest::test_nearest_naive PASSED [ 61%]
tests/test_raster.py::RasterTest::test_rasterize PASSED [ 61%]
tests/test_ray.py::RayTests::test_box PASSED [ 62%]
tests/test_ray.py::RayTests::test_contain_single PASSED [ 62%]
tests/test_ray.py::RayTests::test_contains PASSED [ 63%]
tests/test_ray.py::RayTests::test_multiple_hits PASSED [ 63%]
tests/test_ray.py::RayTests::test_on_edge PASSED [ 64%]
tests/test_ray.py::RayTests::test_on_vertex PASSED [ 64%]
tests/test_ray.py::RayTests::test_rays PASSED [ 65%]
tests/test_ray.py::RayTests::test_rps PASSED [ 65%]
tests/test_registration.py::RegistrationTest::test_icp_mesh PASSED [ 66%]
tests/test_registration.py::RegistrationTest::test_icp_points PASSED [ 66%]
tests/test_registration.py::RegistrationTest::test_mesh PASSED [ 66%]
tests/test_registration.py::RegistrationTest::test_procrustes PASSED [ 67%]
tests/test_remesh.py::SubDivideTest::test_subdivide PASSED [ 67%]
tests/test_render.py::RenderTest::test_args PASSED [ 68%]
tests/test_repair.py::RepairTests::test_fill_holes PASSED [ 68%]
tests/test_repair.py::RepairTests::test_fix_normals PASSED [ 69%]
tests/test_repair.py::RepairTests::test_multi FAILED [ 69%]
tests/test_repair.py::RepairTests::test_winding PASSED [ 70%]
tests/test_sample.py::SampleTest::test_sample PASSED [ 70%]
tests/test_scene.py::SceneTests::test_3DXML PASSED [ 71%]
tests/test_scene.py::SceneTests::test_camera PASSED [ 71%]
tests/test_scene.py::SceneTests::test_doubling PASSED [ 72%]
tests/test_scene.py::SceneTests::test_dupe PASSED [ 72%]
tests/test_scene.py::SceneTests::test_empty PASSED [ 73%]
tests/test_scene.py::SceneTests::test_scaling PASSED [ 73%]
tests/test_scene.py::SceneTests::test_scene PASSED [ 74%]
tests/test_scene.py::SceneTests::test_tri PASSED [ 74%]
tests/test_scene.py::SceneTests::test_zipped PASSED [ 75%]
tests/test_scene.py::GraphTests::test_forest PASSED [ 75%]
tests/test_section.py::SectionTest::test_section PASSED [ 76%]
tests/test_section.py::PlaneLine::test_planes PASSED [ 76%]
tests/test_section.py::SliceTest::test_slice PASSED [ 77%]
tests/test_segments.py::SegmentsTest::test_param PASSED [ 77%]
tests/test_simplify.py::SimplifyTest::test_simplify PASSED [ 78%]
tests/test_simplify.py::SimplifyTest::test_spline PASSED [ 78%]
tests/test_splines.py::SplineTests::test_bezier_example PASSED [ 79%]
tests/test_svg.py::ExportTest::test_layer PASSED [ 79%]
tests/test_svg.py::ExportTest::test_svg PASSED [ 80%]
tests/test_texture.py::TextureTest::test_fuze PASSED [ 80%]
tests/test_texture.py::TextureTest::test_uv_to_color PASSED [ 81%]
tests/test_thickness.py::ThicknessTest::test_known PASSED [ 81%]
tests/test_thickness.py::ThicknessTest::test_ray_reach PASSED [ 82%]
tests/test_thickness.py::ThicknessTest::test_ray_thickness PASSED [ 82%]
tests/test_thickness.py::ThicknessTest::test_sphere_reach PASSED [ 83%]
tests/test_thickness.py::ThicknessTest::test_sphere_thickness PASSED [ 83%]
tests/test_transformations.py::TransformTest::test_around PASSED [ 84%]
tests/test_transformations.py::TransformTest::test_doctest PASSED [ 84%]
tests/test_transformations.py::TransformTest::test_downstream PASSED [ 85%]
tests/test_transformations.py::TransformTest::test_rotation PASSED [ 85%]
tests/test_transformations.py::TransformTest::test_tiny PASSED [ 86%]
tests/test_triangles.py::TrianglesTest::test_barycentric PASSED [ 86%]
tests/test_triangles.py::TrianglesTest::test_closest PASSED [ 87%]
tests/test_triangles.py::TrianglesTest::test_degenerate PASSED [ 87%]
tests/test_units.py::UnitsTest::test_conversion PASSED [ 88%]
tests/test_units.py::UnitsTest::test_path PASSED [ 88%]
tests/test_units.py::UnitsTest::test_units PASSED [ 89%]
tests/test_util.py::VectorTests::test_align PASSED [ 89%]
tests/test_util.py::VectorTests::test_unitize_multi PASSED [ 90%]
tests/test_util.py::UtilTests::test_bounds_tree PASSED [ 90%]
tests/test_util.py::UtilTests::test_concat PASSED [ 91%]
tests/test_util.py::UtilTests::test_pairwise PASSED [ 91%]
tests/test_util.py::UtilTests::test_strips PASSED [ 92%]
tests/test_util.py::IOTest::test_dae PASSED [ 92%]
tests/test_util.py::ContainsTest::test_inside PASSED [ 93%]
tests/test_util.py::MassTests::test_mass PASSED [ 93%]
tests/test_util.py::IOWrapTests::test_file_hash PASSED [ 94%]
tests/test_util.py::IOWrapTests::test_io_wrap PASSED [ 94%]
tests/test_util.py::CompressTests::test_compress PASSED [ 95%]
tests/test_util.py::UniqueTests::test_unique PASSED [ 95%]
tests/test_validate.py::ValidTest::test_validate PASSED [ 96%]
tests/test_vector.py::SphericalTests::test_spherical PASSED [ 96%]
tests/test_vector.py::HemisphereTests::test_hemisphere PASSED [ 97%]
tests/test_vector.py::AlignTests::test_align PASSED [ 97%]
tests/test_vhacd.py::VHACDTest::test_vhacd PASSED [ 98%]
tests/test_voxel.py::VoxelTest::test_local PASSED [ 98%]
tests/test_voxel.py::VoxelTest::test_marching PASSED [ 99%]
tests/test_voxel.py::VoxelTest::test_points_to_from_indices PASSED [ 99%]
tests/test_voxel.py::VoxelTest::test_voxel PASSED [100%]
=================================== FAILURES ===================================
_________________________ PermutateTest.test_permutate _________________________
self = <tests.test_permutate.PermutateTest testMethod=test_permutate>
def test_permutate(self):
def close(a, b):
if len(a) == len(b) == 0:
return False
if a.shape != b.shape:
return False
return g.np.allclose(a, b)
def make_assertions(mesh, test, rigid=False):
if (close(test.face_adjacency,
mesh.face_adjacency) and
len(mesh.faces) > MIN_FACES):
raise ValueError(
'face adjacency of %s the same after permutation!',
mesh.metadata['file_name'])
if (close(test.face_adjacency_edges,
mesh.face_adjacency_edges) and
len(mesh.faces) > MIN_FACES):
raise ValueError(
'face adjacency edges of %s the same after permutation!',
mesh.metadata['file_name'])
assert not close(test.faces,
mesh.faces)
assert not close(test.vertices,
mesh.vertices)
assert not test.md5() == mesh.md5()
# rigid transforms don't change area or volume
if rigid:
assert g.np.allclose(mesh.area, test.area)
# volume is very dependent on meshes being watertight and sane
if (mesh.is_watertight and
test.is_watertight and
mesh.is_winding_consistent and
test.is_winding_consistent):
assert g.np.allclose(mesh.volume, test.volume, rtol=.05)
for mesh in g.get_meshes(5):
if len(mesh.faces) < MIN_FACES:
continue
# warp the mesh to be a unit cube
mesh.vertices /= mesh.extents
original = mesh.copy()
for i in range(5):
mesh = original.copy()
noise = g.trimesh.permutate.noise(mesh,
magnitude=mesh.scale / 50.0)
# make sure that if we permutate vertices with no magnitude
# area and volume remain the same
no_noise = g.trimesh.permutate.noise(mesh, magnitude=0.0)
transform = g.trimesh.permutate.transform(mesh)
tessellate = g.trimesh.permutate.tessellation(mesh)
make_assertions(mesh, noise, rigid=False)
> make_assertions(mesh, no_noise, rigid=True)
../tests/test_permutate.py:72:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
mesh = <trimesh.base.Trimesh object at 0x3ff879deb38>
test = <trimesh.base.Trimesh object at 0x3ff8c5f40f0>, rigid = True
def make_assertions(mesh, test, rigid=False):
if (close(test.face_adjacency,
mesh.face_adjacency) and
len(mesh.faces) > MIN_FACES):
raise ValueError(
'face adjacency of %s the same after permutation!',
mesh.metadata['file_name'])
if (close(test.face_adjacency_edges,
mesh.face_adjacency_edges) and
len(mesh.faces) > MIN_FACES):
raise ValueError(
'face adjacency edges of %s the same after permutation!',
> mesh.metadata['file_name'])
E ValueError: ('face adjacency edges of %s the same after permutation!', '1002_tray_bottom.STL')
../tests/test_permutate.py:34: ValueError
____________________________ RepairTests.test_multi ____________________________
self = <tests.test_repair.RepairTests testMethod=test_multi>
def test_multi(self):
"""
Try repairing a multibody geometry
"""
# create a multibody mesh with two cubes
a = g.get_mesh('unit_cube.STL')
b = a.copy()
b.apply_translation([2, 0, 0])
m = a + b
# should be a volume: watertight, correct winding
assert m.is_volume
# flip one face
m.faces[:1] = g.np.fliplr(m.faces[:1])
# flip every face
m.invert()
# not a volume
assert not m.is_volume
m.fix_normals(multibody=False)
# shouldn't fix inversion of one cube
> assert not m.is_volume
E AssertionError: assert not True
E + where True = <trimesh.base.Trimesh object at 0x3ff87c529b0>.is_volume
../tests/test_repair.py:120: AssertionError
=============================== warnings summary ===============================
trimesh/transformations.py:198
/builddir/build/BUILD/trimesh-2.36.13/trimesh/transformations.py:198: DeprecationWarning: invalid escape sequence \*
"""
trimesh/transformations.py:966
/builddir/build/BUILD/trimesh-2.36.13/trimesh/transformations.py:966: DeprecationWarning: invalid escape sequence \*
"""
trimesh/transformations.py:1079
/builddir/build/BUILD/trimesh-2.36.13/trimesh/transformations.py:1079: DeprecationWarning: invalid escape sequence \*
"""
trimesh/interfaces/scad.py:13
/builddir/build/BUILD/trimesh-2.36.13/trimesh/interfaces/scad.py:13: DeprecationWarning: invalid escape sequence \P
_search_path.append(os.path.normpath('C:\Program Files\OpenSCAD'))
trimesh/interfaces/scad.py:14
/builddir/build/BUILD/trimesh-2.36.13/trimesh/interfaces/scad.py:14: DeprecationWarning: invalid escape sequence \P
_search_path.append(os.path.normpath('C:\Program Files (x86)\OpenSCAD'))
trimesh/interfaces/blender.py:16
/builddir/build/BUILD/trimesh-2.36.13/trimesh/interfaces/blender.py:16: DeprecationWarning: invalid escape sequence \P
_search_path.append('C:\Program Files\Blender Foundation\Blender')
trimesh/interfaces/blender.py:17
/builddir/build/BUILD/trimesh-2.36.13/trimesh/interfaces/blender.py:17: DeprecationWarning: invalid escape sequence \P
_search_path.append('C:\Program Files (x86)\Blender Foundation\Blender')
trimesh/interfaces/vhacd.py:13
/builddir/build/BUILD/trimesh-2.36.13/trimesh/interfaces/vhacd.py:13: DeprecationWarning: invalid escape sequence \P
_search_path.append('C:\Program Files')
trimesh/interfaces/vhacd.py:14
/builddir/build/BUILD/trimesh-2.36.13/trimesh/interfaces/vhacd.py:14: DeprecationWarning: invalid escape sequence \P
_search_path.append('C:\Program Files (x86)')
/usr/lib/python3.7/site-packages/past/types/oldstr.py:5
/usr/lib/python3.7/site-packages/past/types/oldstr.py:5: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import Iterable
/usr/lib/python3.7/site-packages/past/builtins/misc.py:4
/usr/lib/python3.7/site-packages/past/builtins/misc.py:4: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import Mapping
/usr/lib/python3.7/site-packages/svg/path/path.py:3
/usr/lib/python3.7/site-packages/svg/path/path.py:3: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import MutableSequence
tests/test_color.py::VisualTest::test_conversion
tests/test_color.py::VisualTest::test_data_model
tests/test_curvature.py::CurvatureTest::test_gaussian_curvature
tests/test_curvature.py::CurvatureTest::test_vertex_defect
tests/test_html.py::ViewTest::test_JSHTML
/usr/lib64/python3.7/site-packages/lxml/html/_setmixin.py:1: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import MutableSet
tests/test_mesh.py::MeshTests::test_meshes
tests/test_mesh.py::MeshTests::test_none
tests/test_scene.py::SceneTests::test_scene
/usr/lib64/python3.7/site-packages/numpy/matrixlib/defmatrix.py:68: PendingDeprecationWarning: the matrix subclass is not the recommended way to represent matrices or deal with linear algebra (see https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html). Please adjust your code to use regular ndarray.
return matrix(data, dtype=dtype, copy=False)
tests/test_scene.py::GraphTests::test_forest
/usr/lib/python3.7/site-packages/networkx/algorithms/components/connected.py:86: DeprecationWarning: connected_component_subgraphs is deprecated and will be removedin 2.2. Use (G.subgraph(c).copy() for c in connected_components(G))
_warnings.warn(msg, DeprecationWarning)
-- Docs: https://docs.pytest.org/en/latest/warnings.html
===== 2 failed, 201 passed, 9 deselected, 5155 warnings in 185.02 seconds ======
Several duplicate DeprecationWarnings were removed.
Down to two, thanks for the logs!
The repair one seems like it was relying on implicit order, which I just changed to be more explicit. Not sure what's going on with the permutation not changing anything, but I added more log messages for when it happens again. Maybe they're all zero or something.
Down to one:
=================================== FAILURES ===================================
_________________________ PermutateTest.test_permutate _________________________
self = <tests.test_permutate.PermutateTest testMethod=test_permutate>
def test_permutate(self):
def close(a, b):
if len(a) == len(b) == 0:
return False
if a.shape != b.shape:
return False
return g.np.allclose(a, b)
def make_assertions(mesh, test, rigid=False):
if (close(test.face_adjacency,
mesh.face_adjacency) and
len(mesh.faces) > MIN_FACES):
g.log.error(
'face_adjacency unchanged: {}'.format(
str(test.face_adjacency)))
raise ValueError(
'face adjacency of %s the same after permutation!',
mesh.metadata['file_name'])
if (close(test.face_adjacency_edges,
mesh.face_adjacency_edges) and
len(mesh.faces) > MIN_FACES):
g.log.error(
'face_adjacency_edges unchanged: {}'.format(
str(test.face_adjacency_edges)))
raise ValueError(
'face adjacency edges of %s the same after permutation!',
mesh.metadata['file_name'])
assert not close(test.faces,
mesh.faces)
assert not close(test.vertices,
mesh.vertices)
assert not test.md5() == mesh.md5()
# rigid transforms don't change area or volume
if rigid:
assert g.np.allclose(mesh.area, test.area)
# volume is very dependent on meshes being watertight and sane
if (mesh.is_watertight and
test.is_watertight and
mesh.is_winding_consistent and
test.is_winding_consistent):
assert g.np.allclose(mesh.volume, test.volume, rtol=.05)
for mesh in g.get_meshes(5):
if len(mesh.faces) < MIN_FACES:
continue
# warp the mesh to be a unit cube
mesh.vertices /= mesh.extents
original = mesh.copy()
for i in range(5):
mesh = original.copy()
noise = g.trimesh.permutate.noise(mesh,
magnitude=mesh.scale / 50.0)
# make sure that if we permutate vertices with no magnitude
# area and volume remain the same
no_noise = g.trimesh.permutate.noise(mesh, magnitude=0.0)
transform = g.trimesh.permutate.transform(mesh)
tessellate = g.trimesh.permutate.tessellation(mesh)
make_assertions(mesh, noise, rigid=False)
> make_assertions(mesh, no_noise, rigid=True)
../tests/test_permutate.py:78:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
mesh = <trimesh.base.Trimesh object at 0x3ff74a047b8>
test = <trimesh.base.Trimesh object at 0x3ff74a04550>, rigid = True
def make_assertions(mesh, test, rigid=False):
if (close(test.face_adjacency,
mesh.face_adjacency) and
len(mesh.faces) > MIN_FACES):
g.log.error(
'face_adjacency unchanged: {}'.format(
str(test.face_adjacency)))
raise ValueError(
'face adjacency of %s the same after permutation!',
mesh.metadata['file_name'])
if (close(test.face_adjacency_edges,
mesh.face_adjacency_edges) and
len(mesh.faces) > MIN_FACES):
g.log.error(
'face_adjacency_edges unchanged: {}'.format(
str(test.face_adjacency_edges)))
raise ValueError(
'face adjacency edges of %s the same after permutation!',
> mesh.metadata['file_name'])
E ValueError: ('face adjacency edges of %s the same after permutation!', '1002_tray_bottom.STL')
../tests/test_permutate.py:40: ValueError
------------------------------ Captured log call -------------------------------
test_permutate.py 37 ERROR face_adjacency_edges unchanged: [[ 0 1]
[ 1 2]
[ 2 3]
...
[2201 2215]
[2208 2215]
[2214 2215]]
Another issue that came up in Fedora. We build packages on the first available builder and sometimes that's Big Endian (ppc64 on Fedora 28 or s390x anywhere). Apparently, the tests fail a lot on those.
Mos likely
load_stl_binary
is broken andload_stl_ascii
is called for binary STLs on Big Endian.failures.log