Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release: Refactor Load Types #2241

Open
wants to merge 63 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
ed9de89
basic outline of return types
mikedh Jun 13, 2024
5df249f
resolver type hints
mikedh Jun 17, 2024
78567b7
3~BABMerge branch 'main' into refactor/loadtype
mikedh Jul 11, 2024
3553255
merge main and try lighter touch
mikedh Jul 11, 2024
9aa327d
merge main
mikedh Jul 11, 2024
30ca68b
merge
mikedh Sep 1, 2024
e5732dc
merge main
mikedh Oct 22, 2024
84b5565
wip
mikedh Oct 23, 2024
c73170c
Updated use of weights in procrustes analysis.
Oct 30, 2024
20dc9ed
Fix nearest.ipynb Typo
Tallerpie Dec 1, 2024
145ba83
Merge pull request #2313 from tillns/main
mikedh Dec 3, 2024
1ac2419
Merge pull request #2327 from Tallerpie/patch-1
mikedh Dec 3, 2024
6dedb95
update test_scenegraph to pytest style
mikedh Dec 3, 2024
209d0a5
codespell
mikedh Dec 3, 2024
52737d8
change test
mikedh Dec 3, 2024
4833682
Merge branch 'main' into refactor/loadtype
mikedh Dec 3, 2024
942ac83
pass test_minimal anyway
mikedh Dec 3, 2024
6d4e34e
pass test_loaded
mikedh Dec 3, 2024
a1e6877
move all fetching into WebResolver
mikedh Dec 3, 2024
6e7fd43
fix some metadata passing
mikedh Dec 3, 2024
9a8e969
hmm
mikedh Dec 3, 2024
f2f079a
metadata to every geometry
mikedh Dec 4, 2024
5d71ab1
try matching old behavior
mikedh Dec 4, 2024
9645641
fix more tests
mikedh Dec 4, 2024
75fd8cc
fix test_gltf
mikedh Dec 4, 2024
e76ce2b
off also return mesh
mikedh Dec 4, 2024
751ec61
match more old behavior
mikedh Dec 4, 2024
181dbcb
fix test_scene
mikedh Dec 5, 2024
a25082b
fix for #2330
mikedh Dec 15, 2024
f5b9b55
need a metadata policy
mikedh Dec 16, 2024
d608c3a
apply Jan25 resources.get deprecation
mikedh Dec 16, 2024
ff2a542
fix and test voxels in scenes
mikedh Dec 17, 2024
8d4693c
fix and test #2335
mikedh Dec 26, 2024
5b580b6
fix rounding issue in uv_to_color()
TooSchoolForCool Dec 27, 2024
c46eca1
Merge pull request #2336 from TooSchoolForCool/main
mikedh Jan 2, 2025
693081a
Merge pull request #2328 from mikedh/release/weight
mikedh Jan 2, 2025
a5ca023
fix and test divide-by-zero in visual.interpolate
mikedh Jan 2, 2025
08328c3
try tacking on load info as an attribute
mikedh Jan 2, 2025
6b5373e
deprecate Path3D.to_planar->Path3D.to_2D
mikedh Jan 9, 2025
f8dbf9a
fix test_gltf
mikedh Jan 9, 2025
273c92d
fix deprecation wrapper
mikedh Jan 9, 2025
381abe7
blender booleans
mikedh Jan 10, 2025
37b93e9
wrap _uri_to_bytes
mikedh Jan 12, 2025
94d35f5
fixed not loading point cloud colors from glb format files
henryzhengr Jan 14, 2025
f50e262
include a LoadSource for all geometry
mikedh Jan 14, 2025
eb4a088
run blender tests
mikedh Jan 14, 2025
13d1d65
make source available more easily
mikedh Jan 14, 2025
517fecb
should source really be optional
mikedh Jan 14, 2025
aa7e826
py38 syntax
mikedh Jan 14, 2025
90409b4
clean up and expand corpus and fix surfaced bugs
mikedh Jan 14, 2025
83425db
fix more tests
mikedh Jan 15, 2025
eb60b49
try adding in weights
mikedh Jan 15, 2025
63a92f6
some type fixes
mikedh Jan 15, 2025
24d2db1
add missing import
mikedh Jan 16, 2025
c3c858d
fix deepcopy override
mikedh Jan 16, 2025
fab9580
load_dict shenanigans
mikedh Jan 16, 2025
837270e
fix util type hint
mikedh Jan 16, 2025
780a572
run corpus again
mikedh Jan 16, 2025
eaa6004
remove dae until pycollada/pycollada/147 releases
mikedh Jan 16, 2025
ffdc7eb
add report logic
mikedh Jan 17, 2025
f72cef9
apply march 2024 deprecation of graph.smoothed
mikedh Jan 17, 2025
d0e0ac9
disable dae
mikedh Jan 17, 2025
a94c287
fixed not loading point cloud colors from glb format files (#2339)
mikedh Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
move all fetching into WebResolver
mikedh committed Dec 3, 2024
commit a1e68772198fe40974192d0c1f3de7b09d5694ce
3 changes: 2 additions & 1 deletion tests/test_loaded.py
Original file line number Diff line number Diff line change
@@ -11,8 +11,9 @@ def test_remote(self):
"""
# get a unit cube from localhost
with g.serve_meshes() as address:
mesh = g.trimesh.exchange.load.load_remote(url=address + "/unit_cube.STL")
scene = g.trimesh.exchange.load.load_remote(url=address + "/unit_cube.STL")

mesh = scene.to_mesh()
assert g.np.isclose(mesh.volume, 1.0)
assert isinstance(mesh, g.trimesh.Trimesh)

84 changes: 28 additions & 56 deletions trimesh/exchange/load.py
Original file line number Diff line number Diff line change
@@ -156,11 +156,12 @@ def load_scene(
Loaded geometry as trimesh classes
"""

arg = _parse_file_args(file_obj=file_obj, file_type=file_type, resolver=resolver)

if arg.is_remote:
if not allow_remote:
raise ValueError("URL passed with `allow_remote=False`")
arg = _parse_file_args(
file_obj=file_obj,
file_type=file_type,
resolver=resolver,
allow_remote=allow_remote,
)

try:
if arg.file_type in path_formats():
@@ -326,7 +327,7 @@ def _load_compressed(file_obj, file_type=None, resolver=None, mixed=False, **kwa
return result


def load_remote(url, **kwargs):
def load_remote(url, **kwargs) -> Scene:
"""
Load a mesh at a remote URL into a local trimesh object.
@@ -345,34 +346,7 @@ def load_remote(url, **kwargs):
loaded : Trimesh, Path, Scene
Loaded result
"""
# import here to keep requirement soft
import httpx

# download the mesh
response = httpx.get(url, follow_redirects=True)
response.raise_for_status()

# wrap as file object
file_obj = util.wrap_as_stream(response.content)

# so loaders can access textures/etc
resolver = resolvers.WebResolver(url)

try:
# if we have a bunch of query parameters the type
# will be wrong so try to clean up the URL
# urllib is Python 3 only
import urllib

# remove the url-safe encoding then split off query params
file_type = urllib.parse.unquote(url).split("?", 1)[0].split("/")[-1].strip()
except BaseException:
# otherwise just use the last chunk of URL
file_type = url.split("/")[-1].split("?", 1)[0]

# actually load the data from the retrieved bytes
loaded = load(file_obj=file_obj, file_type=file_type, resolver=resolver, **kwargs)
return loaded
return load_scene(file_obj=url, allow_remote=True, **kwargs)


def _load_kwargs(*args, **kwargs) -> Geometry:
@@ -516,14 +490,12 @@ class _FileArgs:
# a resolver for loading assets next to the file
resolver: resolvers.ResolverLike

# is this a remote url
is_remote: bool


def _parse_file_args(
file_obj: Loadable,
file_type: Optional[str],
resolver: Optional[resolvers.ResolverLike] = None,
allow_remote: bool = False,
**kwargs,
) -> _FileArgs:
"""
@@ -564,20 +536,12 @@ def _parse_file_args(
Returns
-----------
file_obj : file-like object
Contains data
file_type : str
Lower case of the type of file (eg 'stl', 'dae', etc)
metadata : dict
Any metadata gathered
opened : bool
Did we open the file or not
resolver : trimesh.visual.Resolver
Resolver to load other assets
args
Populated `_FileArg` message
"""

metadata = {}
opened = False
is_remote = False

if "metadata" in kwargs and isinstance(kwargs["metadata"], dict):
metadata.update(kwargs["metadata"])
@@ -593,8 +557,7 @@ def _parse_file_args(
try:
# os.path.isfile will return False incorrectly
# if we don't give it an absolute path
file_path = os.path.expanduser(file_obj)
file_path = os.path.abspath(file_path)
file_path = os.path.abspath(os.path.expanduser(file_obj))
exists = os.path.isfile(file_path)
except BaseException:
exists = False
@@ -615,13 +578,23 @@ def _parse_file_args(
opened = True
else:
if "{" in file_obj:
# if a dict bracket is in the string, its probably a straight
# JSON
# if a bracket is in the string it's probably straight JSON
file_type = "json"
elif "https://" in file_obj or "http://" in file_obj:
# we've been passed a URL, warn to use explicit function
# and don't do network calls via magical pipeline
raise ValueError(f"use load_remote to load URL: {file_obj}")
if not allow_remote:
raise ValueError("unable to load URL with `allow_remote=False`")

import urllib

# remove the url-safe encoding and query params
file_type = util.split_extension(
urllib.parse.unquote(file_obj).split("?", 1)[0].split("/")[-1].strip()
)
# create a web resolver to do the fetching and whatnot
resolver = resolvers.WebResolver(url=file_obj)
# fetch the base file
file_obj = util.wrap_as_stream(resolver.get_base())

elif file_type is None:
raise ValueError(f"string is not a file: {file_obj}")

@@ -656,7 +629,6 @@ def _parse_file_args(
metadata=metadata,
was_opened=opened,
resolver=resolver,
is_remote=is_remote,
)


23 changes: 23 additions & 0 deletions trimesh/resolvers.py
Original file line number Diff line number Diff line change
@@ -335,6 +335,11 @@ def __init__(self, url: str):
else:
# recombine into string ignoring any double slashes
path = "/".join(split)

# save the URL we were created with, i.e.
# `https://stuff.com/models/thing.glb`
self.url = url
# save the root url, i.e. `https://stuff.com/models`
self.base_url = (
"/".join(
i
@@ -382,6 +387,24 @@ def get(self, name: str) -> bytes:
# return the bytes of the response
return response.content

def get_base(self) -> bytes:
"""
Fetch the data at the full URL this resolver was
instantiated with, i.e. `https://stuff.com/hi.glb`
this will return the response.
Returns
--------
content
The value at `self.url`
"""
import httpx

# just fetch the url we were created with
response = httpx.get(self.url, follow_redirects=True)
response.raise_for_status()
return response.content

def namespaced(self, namespace: str) -> "WebResolver":
"""
Return a namespaced version of current resolver.