mikedh / trimesh

Python library for loading and using triangular meshes.
https://trimesh.org
MIT License
3k stars 580 forks source link

Big Endian failures #249

Closed hroncok closed 5 years ago

hroncok commented 5 years ago

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 and load_stl_ascii is called for binary STLs on Big Endian.

+ /usr/bin/python3 -m pytest -v -k 'not test_export and not test_remote'
============================= test session starts ==============================
platform linux -- Python 3.6.6, pytest-3.4.2, py-1.5.4, pluggy-0.6.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /builddir/build/BUILD/trimesh-2.35.24, inifile:
collecting ... collected 193 items
tests/test_boolean.py::BooleanTest::test_boolean PASSED                  [  0%]
tests/test_boolean.py::BooleanTest::test_multiple PASSED                 [  1%]
tests/test_bounds.py::BoundsTest::test_2D FAILED                         [  1%]
tests/test_bounds.py::BoundsTest::test_cylinder FAILED                   [  2%]
tests/test_bounds.py::BoundsTest::test_obb_mesh FAILED                   [  2%]
tests/test_bounds.py::BoundsTest::test_obb_order FAILED                  [  3%]
tests/test_bounds.py::BoundsTest::test_obb_points FAILED                 [  3%]
tests/test_cache.py::CacheTest::test_contiguous PASSED                   [  4%]
tests/test_cache.py::CacheTest::test_hash FAILED                         [  4%]
tests/test_cache.py::CacheTest::test_track 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_convex.py::ConvexTest::test_convex FAILED                     [  7%]
tests/test_convex.py::ConvexTest::test_primitives PASSED                 [  8%]
tests/test_convex.py::ConvexTest::test_projections FAILED                [  8%]
tests/test_creation.py::CreationTest::test_annulus PASSED                [  9%]
tests/test_creation.py::CreationTest::test_path_sweep PASSED             [  9%]
tests/test_creation.py::CreationTest::test_soup PASSED                   [ 10%]
tests/test_creation.py::CreationTest::test_triangulate PASSED            [ 10%]
tests/test_creation.py::CreationTest::test_triangulate_plumbing PASSED   [ 11%]
tests/test_creation.py::CreationTest::test_uv PASSED                     [ 12%]
tests/test_curvature.py::CurvatureTest::test_gaussian_curvature FAILED   [ 12%]
tests/test_curvature.py::CurvatureTest::test_mean_curvature PASSED       [ 13%]
tests/test_curvature.py::CurvatureTest::test_vertex_defect PASSED        [ 13%]
tests/test_decomposition.py::DecompositionTest::test_convex_decomposition PASSED [ 14%]
tests/test_dxf.py::DXFTest::test_bulge PASSED                            [ 14%]
tests/test_dxf.py::DXFTest::test_dxf PASSED                              [ 15%]
tests/test_dxf.py::DXFTest::test_spline PASSED                           [ 15%]
tests/test_dxf.py::DXFTest::test_versions PASSED                         [ 16%]
tests/test_facets.py::FacetTest::test_facet FAILED                       [ 16%]
tests/test_gltf.py::GLTFTest::test_duck FAILED                           [ 17%]
tests/test_gltf.py::GLTFTest::test_units FAILED                          [ 18%]
tests/test_graph.py::GraphTest::test_components FAILED                   [ 18%]
tests/test_graph.py::GraphTest::test_engine_time FAILED                  [ 19%]
tests/test_graph.py::GraphTest::test_engines PASSED                      [ 19%]
tests/test_graph.py::GraphTest::test_smoothed PASSED                     [ 20%]
tests/test_graph.py::GraphTest::test_soup FAILED                         [ 20%]
tests/test_graph.py::GraphTest::test_traversals PASSED                   [ 21%]
tests/test_graph.py::GraphTest::test_vertex_adjacency_graph FAILED       [ 21%]
tests/test_graph.py::GraphTest::test_watertight PASSED                   [ 22%]
tests/test_grouping.py::GroupTests::test_blocks PASSED                   [ 22%]
tests/test_grouping.py::GroupTests::test_boolean_rows PASSED             [ 23%]
tests/test_grouping.py::GroupTests::test_cluster PASSED                  [ 24%]
tests/test_grouping.py::GroupTests::test_group_rows PASSED               [ 24%]
tests/test_grouping.py::GroupTests::test_group_vector PASSED             [ 25%]
tests/test_grouping.py::GroupTests::test_runs PASSED                     [ 25%]
tests/test_grouping.py::GroupTests::test_unique_float PASSED             [ 26%]
tests/test_grouping.py::GroupTests::test_unique_rows PASSED              [ 26%]
tests/test_html.py::ViewTest::test_JSHTML FAILED                         [ 27%]
tests/test_html.py::ViewTest::test_inNB PASSED                           [ 27%]
tests/test_identifier.py::IdentifierTest::test_identifier FAILED         [ 28%]
tests/test_identifier.py::IdentifierTest::test_scene_id PASSED           [ 28%]
tests/test_inertia.py::InertiaTest::test_inertia FAILED                  [ 29%]
tests/test_inertia.py::InertiaTest::test_primitives PASSED               [ 30%]
tests/test_integrate.py::IntegrateTest::test_integrate FAILED            [ 30%]
tests/test_loaded.py::LoaderTest::test_3MF PASSED                        [ 31%]
tests/test_loaded.py::LoaderTest::test_obj_compressed PASSED             [ 31%]
tests/test_loaded.py::LoaderTest::test_obj_groups PASSED                 [ 32%]
tests/test_loaded.py::LoaderTest::test_obj_multiobj PASSED               [ 32%]
tests/test_loaded.py::LoaderTest::test_obj_quad PASSED                   [ 33%]
tests/test_loaded.py::LoaderTest::test_obj_simple_order PASSED           [ 33%]
tests/test_loaded.py::LoaderTest::test_obj_split_attributes PASSED       [ 34%]
tests/test_loaded.py::LoaderTest::test_stl PASSED                        [ 34%]
tests/test_mesh.py::MeshTests::test_meshes FAILED                        [ 35%]
tests/test_mesh.py::MeshTests::test_vertex_neighbors PASSED              [ 36%]
tests/test_normals.py::NormalsTest::test_face_normals PASSED             [ 36%]
tests/test_normals.py::NormalsTest::test_vertex_normal PASSED            [ 37%]
tests/test_nsphere.py::NSphereTest::test_isnsphere PASSED                [ 37%]
tests/test_nsphere.py::NSphereTest::test_minball FAILED                  [ 38%]
tests/test_packing.py::PackingTest::test_obb PASSED                      [ 38%]
tests/test_packing.py::PackingTest::test_paths PASSED                    [ 39%]
tests/test_paths.py::VectorTests::test_discrete PASSED                   [ 39%]
tests/test_paths.py::VectorTests::test_edges FAILED                      [ 40%]
tests/test_paths.py::VectorTests::test_poly PASSED                       [ 40%]
tests/test_paths.py::VectorTests::test_random_polygon PASSED             [ 41%]
tests/test_paths.py::VectorTests::test_sample PASSED                     [ 42%]
tests/test_paths.py::ArcTests::test_center PASSED                        [ 42%]
tests/test_paths.py::ArcTests::test_center_random PASSED                 [ 43%]
tests/test_paths.py::ArcTests::test_multiroot PASSED                     [ 43%]
tests/test_paths.py::SplitTest::test_split PASSED                        [ 44%]
tests/test_paths.py::ExportTest::test_svg PASSED                         [ 44%]
tests/test_paths.py::SectionTest::test_section PASSED                    [ 45%]
tests/test_paths.py::CreationTests::test_circle PASSED                   [ 45%]
tests/test_paths.py::CreationTests::test_rect PASSED                     [ 46%]
tests/test_permutate.py::PermutateTest::test_base PASSED                 [ 46%]
tests/test_permutate.py::PermutateTest::test_permutate FAILED            [ 47%]
tests/test_permutate.py::PermutateTest::test_tesselation FAILED          [ 48%]
tests/test_points.py::PointsTest::test_kmeans PASSED                     [ 48%]
tests/test_points.py::PointsTest::test_plane PASSED                      [ 49%]
tests/test_points.py::PointsTest::test_pointcloud PASSED                 [ 49%]
tests/test_points.py::PointsTest::test_tsp PASSED                        [ 50%]
tests/test_points.py::PointsTest::test_vertex_only PASSED                [ 50%]
tests/test_poses.py::PosesTest::test_multiple FAILED                     [ 51%]
tests/test_poses.py::PosesTest::test_nonsampling_poses PASSED            [ 51%]
tests/test_poses.py::PosesTest::test_round PASSED                        [ 52%]
tests/test_primitives.py::PrimitiveTest::test_box PASSED                 [ 53%]
tests/test_primitives.py::PrimitiveTest::test_extrusion PASSED           [ 53%]
tests/test_primitives.py::PrimitiveTest::test_primitives PASSED          [ 54%]
tests/test_primitives.py::PrimitiveTest::test_sample PASSED              [ 54%]
tests/test_proximity.py::NearestTest::test_acute_edge_case PASSED        [ 55%]
tests/test_proximity.py::NearestTest::test_coplanar_signed_distance FAILED [ 55%]
tests/test_proximity.py::NearestTest::test_edge_case FAILED              [ 56%]
tests/test_proximity.py::NearestTest::test_helper FAILED                 [ 56%]
tests/test_proximity.py::NearestTest::test_naive PASSED                  [ 57%]
tests/test_proximity.py::NearestTest::test_nearest_naive PASSED          [ 57%]
tests/test_raster.py::RasterTest::test_rasterize PASSED                  [ 58%]
tests/test_ray.py::RayTests::test_box FAILED                             [ 59%]
tests/test_ray.py::RayTests::test_contain_single FAILED                  [ 59%]
tests/test_ray.py::RayTests::test_contains FAILED                        [ 60%]
tests/test_ray.py::RayTests::test_multiple_hits PASSED                   [ 60%]
tests/test_ray.py::RayTests::test_on_edge FAILED                         [ 61%]
tests/test_ray.py::RayTests::test_on_vertex PASSED                       [ 61%]
tests/test_ray.py::RayTests::test_rays FAILED                            [ 62%]
tests/test_ray.py::RayTests::test_rps FAILED                             [ 62%]
tests/test_registration.py::RegistrationTest::test_icp_mesh PASSED       [ 63%]
tests/test_registration.py::RegistrationTest::test_icp_points PASSED     [ 63%]
tests/test_registration.py::RegistrationTest::test_mesh PASSED           [ 64%]
tests/test_registration.py::RegistrationTest::test_procrustes PASSED     [ 65%]
tests/test_remesh.py::SubDivideTest::test_subdivide FAILED               [ 65%]
tests/test_render.py::RenderTest::test_args FAILED                       [ 66%]
tests/test_repair.py::RepairTests::test_fill_holes FAILED                [ 66%]
tests/test_repair.py::RepairTests::test_fix_normals FAILED               [ 67%]
tests/test_repair.py::RepairTests::test_multi FAILED                     [ 67%]
tests/test_repair.py::RepairTests::test_winding FAILED                   [ 68%]
tests/test_sample.py::SampleTest::test_sample FAILED                     [ 68%]
tests/test_scene.py::SceneTests::test_3DXML PASSED                       [ 69%]
tests/test_scene.py::SceneTests::test_doubling PASSED                    [ 69%]
tests/test_scene.py::SceneTests::test_dupe PASSED                        [ 70%]
tests/test_scene.py::SceneTests::test_empty PASSED                       [ 71%]
tests/test_scene.py::SceneTests::test_scaling PASSED                     [ 71%]
tests/test_scene.py::SceneTests::test_scene PASSED                       [ 72%]
tests/test_scene.py::SceneTests::test_zipped PASSED                      [ 72%]
tests/test_scene.py::GraphTests::test_forest PASSED                      [ 73%]
tests/test_section.py::SectionTest::test_section FAILED                  [ 73%]
tests/test_section.py::PlaneLine::test_planes PASSED                     [ 74%]
tests/test_section.py::SliceTest::test_slice PASSED                      [ 74%]
tests/test_segments.py::SegmentsTest::test_param PASSED                  [ 75%]
tests/test_simplify.py::SimplifyTest::test_simplify PASSED               [ 75%]
tests/test_simplify.py::SimplifyTest::test_spline PASSED                 [ 76%]
tests/test_splines.py::SplineTests::test_bezier_example PASSED           [ 77%]
tests/test_thickness.py::ThicknessTest::test_known PASSED                [ 77%]
tests/test_thickness.py::ThicknessTest::test_ray_reach PASSED            [ 78%]
tests/test_thickness.py::ThicknessTest::test_ray_thickness PASSED        [ 78%]
tests/test_thickness.py::ThicknessTest::test_sphere_reach PASSED         [ 79%]
tests/test_thickness.py::ThicknessTest::test_sphere_thickness PASSED     [ 79%]
tests/test_transformations.py::TransformTest::test_around PASSED         [ 80%]
tests/test_transformations.py::TransformTest::test_doctest PASSED        [ 80%]
tests/test_transformations.py::TransformTest::test_downstream PASSED     [ 81%]
tests/test_transformations.py::TransformTest::test_rotation PASSED       [ 81%]
tests/test_transformations.py::TransformTest::test_tiny PASSED           [ 82%]
tests/test_triangles.py::TrianglesTest::test_barycentric FAILED          [ 83%]
tests/test_triangles.py::TrianglesTest::test_closest PASSED              [ 83%]
tests/test_triangles.py::TrianglesTest::test_degenerate PASSED           [ 84%]
tests/test_units.py::UnitsTest::test_conversion FAILED                   [ 84%]
tests/test_units.py::UnitsTest::test_path PASSED                         [ 85%]
tests/test_units.py::UnitsTest::test_units FAILED                        [ 85%]
tests/test_utility.py::VectorTests::test_align PASSED                    [ 86%]
tests/test_utility.py::VectorTests::test_unitize_multi PASSED            [ 86%]
tests/test_utility.py::UtilTests::test_bounds_tree PASSED                [ 87%]
tests/test_utility.py::UtilTests::test_concat PASSED                     [ 87%]
tests/test_utility.py::UtilTests::test_pairwise PASSED                   [ 88%]
tests/test_utility.py::UtilTests::test_strips PASSED                     [ 89%]
tests/test_utility.py::IOTest::test_dae PASSED                           [ 89%]
tests/test_utility.py::ContainsTest::test_inside PASSED                  [ 90%]
tests/test_utility.py::MassTests::test_mass FAILED                       [ 90%]
tests/test_utility.py::IOWrapTests::test_file_hash PASSED                [ 91%]
tests/test_utility.py::IOWrapTests::test_io_wrap PASSED                  [ 91%]
tests/test_utility.py::CompressTests::test_compress PASSED               [ 92%]
tests/test_validate.py::ValidTest::test_validate FAILED                  [ 92%]
tests/test_vector.py::SphericalTests::test_spherical PASSED              [ 93%]
tests/test_vector.py::HemisphereTests::test_hemisphere PASSED            [ 93%]
tests/test_vhacd.py::VHACDTest::test_vhacd PASSED                        [ 94%]
tests/test_visual.py::VisualTest::test_concatenate PASSED                [ 95%]
tests/test_visual.py::VisualTest::test_conversion PASSED                 [ 95%]
tests/test_visual.py::VisualTest::test_data_model FAILED                 [ 96%]
tests/test_visual.py::VisualTest::test_interpolate PASSED                [ 96%]
tests/test_visual.py::VisualTest::test_smooth FAILED                     [ 97%]
tests/test_visual.py::VisualTest::test_vertex FAILED                     [ 97%]
tests/test_visual.py::VisualTest::test_visual FAILED                     [ 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_voxel FAILED                        [100%]
============================= 10 tests deselected ==============================
============ 53 failed, 130 passed, 10 deselected in 124.47 seconds ============

failures.log

hroncok commented 5 years ago

I have a patch ready, will test.

mikedh commented 5 years ago

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!

hroncok commented 5 years ago

Well i have basically the same commit, running trough Fedora buildsystem.

mikedh commented 5 years ago

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.

hroncok commented 5 years ago

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')
hroncok commented 5 years ago

load_glb mostly

hroncok commented 5 years ago

BTW AFAIK PLY is textual so the endianness should not matter

hroncok commented 5 years ago
=================================== 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
hroncok commented 5 years ago

WIP in https://github.com/mikedh/trimesh/pull/250

Still the failures above, but I have to go now. Will revisit later.

hroncok commented 5 years ago

@mikedh any hints where to look for clues for the last remaining failing tests?

mikedh commented 5 years ago

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?

hroncok commented 5 years ago

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.

mikedh commented 5 years ago

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.

mikedh commented 5 years ago

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!

hroncok commented 5 years ago

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.

mikedh commented 5 years ago

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.

hroncok commented 5 years ago

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]]