mikedh / trimesh

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

Can't export empty scenes #2294

Closed DanCardin closed 1 month ago

DanCardin commented 1 month ago

Hi, loving the library so far!

I'm currently using it in service of rendering abitrary stl/3mf/obj files for 3d printing to html (and it's been by far the most compelling option i've encountered!). I'm noticing that:

  File "./.venv/lib/python3.11/site-packages/trimesh/exchange/export.py", line 242, in export_scene
    raise ValueError("Can't export empty scenes!")

The code being run for all types is:

import trimesh
import trimesh.viewer

scene = cast(trimesh.Scene, trimesh.load(self.path, force="scene"))
result = trimesh.viewer.scene_to_html(scene)

I did try to do some sleuthing, and it just seems like various paths you're looking for in the 3mf code doesn't translate match to the ones that are practically in any of these files. But you clearly know about the file formats and I dont, so i can't speculate more than that.

Taking some random example off the homepage of https://makerworld.com/en: https://makerworld.com/en/models/633969#profileId-561565. Downloading the 3mf here results in this behavior, if that's at all helpful.

Thanks!

mikedh commented 1 month ago

Hey, yeah it's possible the scene instances aren't translating correctly. That being said every 3MF file in that pumpkin loads some geometry for me and doesn't crash scene_to_html. I'd maybe try running with trimesh.util.attach_to_log() and see if it's printing any errors? If you can find a smaller open-license model we could add to tests that reproduces that would be helpful too!

import os
import trimesh
from pyinstrument import Profiler

from trimesh.viewer import scene_to_html

if __name__ == '__main__':
    trimesh.util.attach_to_log()

    root = 'Halloween+Pumpkin+(tealight+compatible)'
    meshes = {}

    for name in os.listdir(root):
    meshes[name] = trimesh.load(os.path.join(root, name), force='scene')
        scene_to_html(meshes[name])

Results in:

<trimesh.Scene(len(geometry)=1, name=`Pumpkin 60% scale (thicker walls for printing).3mf`)>
<trimesh.Scene(len(geometry)=1, name=`Pumpkin body.3mf`)>
<trimesh.Scene(len(geometry)=1, name=`Pumpkin .3mf`)>
<trimesh.Scene(len(geometry)=1, name=`Pumpkin stem.3mf`)>
DanCardin commented 1 month ago

This is, perhaps a simpler model that also exhibits the behavior: https://makerworld.com/en/models/511710?from=search#profileId-427769

I get (on linux, with latest trimesh)

DEBUG           threemf.py:160   id 1 included but not defined!
DEBUG           load.py:217   loaded <trimesh.Scene(len(geometry)=0)> using `load_3MF` in 0.0086s
INFO               test.py:10   Can't export empty scenes! <-- my code catching your exception
mikedh commented 1 month ago

Oh yeah it looks like this is that we don't currently support meshes referenced in other files (vs in-line), i.e. :

<resources>
  <object id="2" p:UUID="00000001-61cb-4c03-9d28-80fed5dfa1dc" type="model">
    <components>
    <component p:path="/3D/Objects/object_1.model" objectid="1" p:UUID="00010000-b206-40ff-9872-83e8017abed1" transform="1 0 0 0 1 0 0 0 1 0 0 0"/>
    </components>
  </object>
</resources>

It looks pretty easy to support, here's a lightly broken rough draft that loads "something" on that example file: https://github.com/mikedh/trimesh/commit/ac3bebb825f269fa55114b7a60b1dd9e774b1840

Thanks for the report!

DanCardin commented 1 month ago

for what it's worth, I still get an empty scene error with that file, on that branch. I did try running it on my arm mac, and it segfaults, so it's odd that you're reporting it loading geometry on some files (even the pumpkin) that I'm seeing no geometry on.

I installed with pip install 'trimesh[easy] @ git+https://github.com/mikedh/trimesh@feat/3mfextra' in python3.11 if that's at all helpful.

DanCardin commented 1 month ago

I tested about a dozen of the previously not loading 3mf files, and they all render now! Thanks!