Skip to content

Commit

Permalink
fix and test #2335
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedh committed Dec 26, 2024
1 parent ff2a542 commit 8d4693c
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 16 deletions.
15 changes: 15 additions & 0 deletions tests/test_obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ def test_no_img(self):
rec = g.roundtrip(m.export(file_type="obj"), file_type="obj")
assert g.np.isclose(m.area, rec.area)

def test_keep_unreferenced(self):
# try loading a short mesh with 2 vertices, one of which is referenced
m = g.trimesh.load(
g.trimesh.util.wrap_as_stream("o mesh\nv 1 1 1\nv 1 1 2\nf 1 1 1"),
file_type="obj",
process=False,
maintain_order=True,
)

assert g.np.allclose(m.faces[0], [0, 0, 0])
assert g.np.allclose(m.vertices, [[1, 1, 1], [1, 1, 2]])

def test_trailing(self):
# test files with texture and trailing slashes
m = g.get_mesh("jacked.obj")
Expand Down Expand Up @@ -335,6 +347,9 @@ def test_mtl_color_roundtrip(self):

def test_scene_export_material_name(self):
s = g.get_mesh("fuze.obj", force="scene")

g.log.warning(s.geometry)

dummy = "fuxx"
s.geometry["fuze.obj"].visual.material.name = dummy

Expand Down
28 changes: 22 additions & 6 deletions trimesh/exchange/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ def load(
**kwargs,
) -> Geometry:
"""
Load a mesh or vectorized path into objects like
Trimesh, Path2D, Path3D, Scene
For new code the typed load functions `trimesh.load_scene` or `trimesh.load_mesh`
are recommended over `trimesh.load` which is a backwards-compatibility wrapper
that mimics the behavior of the old function and can return any geometry type.
Parameters
-----------
Expand All @@ -103,6 +105,7 @@ def load(
Loaded geometry as trimesh classes
"""

# call the most general loading case into a `Scene`.
loaded = load_scene(
file_obj=file_obj,
file_type=file_type,
Expand All @@ -111,12 +114,25 @@ def load(
**kwargs,
)

# combine a scene into a single mesh
if force == "mesh":
# new code should use `load_mesh` for this
log.debug(
"`trimesh.load_mesh` does the same thing as `trimesh.load(force='mesh')`"
"`trimesh.load(force='mesh')` is a compatibility wrapper for `trimesh.load_mesh`"
)
return loaded.to_mesh()
elif force == "scene":
# new code should use `load_scene` for this
log.debug(
"`trimesh.load(force='scene')` is a compatibility wrapper for `trimesh.load_scene`"
)
return loaded

# else:
# log.debug(
# "For new code the typed load functions `trimesh.load_scene` or `trimesh.load_mesh` "
# + "are recommended over `trimesh.load` which is a backwards-compatibility wrapper "
# + "that mimics the behavior of the old function and can return any geometry type."
# )

###########################################
# we are matching deprecated behavior here!
Expand Down Expand Up @@ -232,8 +248,8 @@ def load_scene(
loaded = Scene(loaded)

# add the "file_path" information to the overall scene metadata
# if 'metadata' not in kwargs:
# loaded.metadata.update(arg.metadata)
if "metadata" not in kwargs:
loaded.metadata.update(arg.metadata)
# add the load path metadata to every geometry
# [g.metadata.update(arg.metadata) for g in loaded.geometry.values()]

Expand Down
20 changes: 10 additions & 10 deletions trimesh/exchange/obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,12 @@ def load_obj(
log.debug("faces have mixed data: using slow fallback!")
faces, faces_tex, faces_norm = _parse_faces_fallback(face_lines)

if group_material:
if group_material and len(materials) > 1:
name = material
else:
elif current_object is not None:
name = current_object
else:
name = kwargs.get("metadata", {}).get("file_name", "geometry")

# ensure the name is always unique
name = util.unique_name(name, geometry)
Expand Down Expand Up @@ -218,9 +220,13 @@ def load_obj(
faces, faces_norm, maintain_faces=maintain_order
)
else:
# face_tex is None and
# generate the mask so we only include
# referenced vertices in every new mesh
mask_v = np.zeros(len(v), dtype=bool)
if maintain_order:
mask_v = np.ones(len(v), dtype=bool)
else:
mask_v = np.zeros(len(v), dtype=bool)
mask_v[faces] = True

# reconstruct the faces with the new vertex indices
Expand Down Expand Up @@ -269,17 +275,11 @@ def load_obj(
# store geometry by name
geometry[name] = mesh

if len(geometry) == 1:
# TODO : should this be removed to always return a scene?
return next(iter(geometry.values()))

# add an identity transform for every geometry
graph = [{"geometry": k, "frame_to": k} for k in geometry.keys()]

# convert to scene kwargs
result = {"geometry": geometry, "graph": graph}

return result
return {"geometry": geometry, "graph": graph}


def parse_mtl(mtl, resolver=None):
Expand Down

0 comments on commit 8d4693c

Please sign in to comment.