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

Enhancement Ideas #199

mikedh opened this issue Jul 31, 2018 · 26 comments

Enhancement Ideas #199

mikedh opened this issue Jul 31, 2018 · 26 comments


Copy link

@mikedh mikedh commented Jul 31, 2018

I was pinged recently looking for some projects to help out with, here are some ideas. PR's are always appreciated!

Updated 7/27/2020

  • (docs) Figure out how to get the examples embedded in the actual docs webpage. Right now when you build docs, example ipynb files are rendered to HTML which is just linked to from the examples page. It would be really nice if each example was embedded in sphinx somehow, and kept the sidebar on the left so one could navigate around between examples and back to the docs.
  • (feature) Mesh simplification, either through creating a meshlabserver interface or through implementing a vectorized numpy version of quadratic edge collapse: #41
  • (feature) MSH support, as requested in #206. Probably via meshio
  • (feature) Color and line width in Path objects: #356
  • (feature) More 3MF tests. Trimesh has a 3MF importer, it would be great to put together a test corpus of various small- ish models (specifically interesting would be multibody assemblies with duplication) from various exporters.
  • (feature) Do whatever it takes to get pyinstaller to work with trimesh, as per #412
  • (infrastructure) Put all of Shapenet, Thingiverse 10k, GLTF samples, and all available meshes into an AWS S3 bucket, and continuously benchmark trimesh, pymesh, and assimp for percentage of files loaded and time. #510
  • (community) See if upstream numpy has interest in including TrackedArray or ndarray.crc #283
  • (speedup) Add broad-phase culling for mesh.slice_plane to speed up on large meshes: #630
  • (feature) Exact rather than approximate medial axis calculation as per #924
Copy link

@Marviel Marviel commented Aug 10, 2018

@mikedh awesome list, we'd all love to see some of these changes, stoked to know you're considering things like built-in mesh simplification, etc.

A convention I've seen in some other repos is to have each task listed as their own github issue, and give them an easy medium hard label applied to them, based on the perceived difficulty.

Also allows us to start threaded conversations on each of the tasks in your list.

Anyhow just a thought! Not sure the extent to which we want to use Issues here :)

Copy link
Owner Author

@mikedh mikedh commented Aug 13, 2018

Yeah it would be great to get some of this stuff! In the interest of avoiding a ton of immediately orphaned new issues the process I'd suggest initially would be:

  1. I'll update this list in- place with new ideas.
  2. If someone is interested in working on one of the ideas, they can open a new issue looking for advice before PR'ing.

Copy link

@mmatl mmatl commented Sep 10, 2018

@mikedh I'm going to try to tackle textures. Let me know if you have any thoughts -- I was also thinking a new TextureVisuals object. Loading the texture file itself will probably requireimageio -- are you okay with introducing that dep? It's really lightweight.

Copy link
Owner Author

@mikedh mikedh commented Sep 12, 2018

Sounds good, discussion for texture in #218

Copy link

@LinJiarui LinJiarui commented Sep 14, 2018

@mikedh Hey mike, it's great to see that you mentioned IFC, which I'm quite familiar with. I also used IfcOpenShell to get geometries from IFC file and then voxelize them with trimesh. That's why I found trimesh and created two PRs :) So, maybe I can help in IFC importing.

Copy link
Owner Author

@mikedh mikedh commented Sep 18, 2018

Hey @LinJiarui that would be great! I took a look at ifcopenshell-python briefly, and it looks like the biggest stumbling block would be packaging. As per IfcOpenShell/IfcOpenShell#146, you can't install it via pip, and it would be preferable to address that before adding it as a dependency.

CIbuildwheel might be a good solution, but is definitely a lot of work!

Copy link

@nschloe nschloe commented Mar 21, 2019

Perhaps optimesh is something for you, too.

(BTW I just added trimesh to the awesome list.)

Copy link

@FXXB FXXB commented Apr 16, 2019

@mikedh Thank you for your trimesh library. Just awesome.
I am rewriting my code which so far mainly deals with numpy.stl's. Since trimesh really does the job I am in the process of switching from numpy.stl to trimesh. So far I couldn´t find something to convert numpy.stl to trimesh.
Is there already a method to convert numpy.stl files to trimesh and vice versa. I would highly appreciate a hint on how to resolve.
Thank you and best regards

Copy link

@FXXB FXXB commented Apr 16, 2019

Hi @bbarroqueiro Thank you for your quick response.
Yes, of course, I can save the numpy.stl representation as *.stl and reload it as *.stl in the trimesh representation, but I would prefer to do the job without export/import. Something like
trimesh.load (
I wondered if this direct conversion between numpy-stl and trimesh already exists...
Sorry for the confusion

Copy link

@FXXB FXXB commented Apr 16, 2019

Hi @bbarroqueiro
Thank you for your assistance. I will give it a try and let you know.
Best regards

Copy link
Owner Author

@mikedh mikedh commented Apr 16, 2019

Oh numpy-stl from pypi? It looks like they just use a custom dtype, you can probably access the data directly:

In [1]: import trimesh

In [2]: from stl import Mesh

In [3]: r = Mesh.from_file('models/featuretype.STL')

In [4]:
array([([ 0.        , -0.        ,  0.01694411], [[ 1.8933141 ,  0.5625    ,  1.        ], [ 1.8952131 ,  0.58420604,  1.        ], [ 1.125     ,  0.703125  ,  1.        ]], [0]),
       ([ 0.        , -0.        ,  0.01688094], [[ 1.8952131 ,  0.58420604,  1.        ], [ 1.9008526 ,  0.60525256,  1.        ], [ 1.125     ,  0.703125  ,  1.        ]], [0]),
       ([ 0.        ,  0.        ,  0.01622234], [[ 1.125     ,  0.703125  ,  1.        ], [ 1.9008526 ,  0.60525256,  1.        ], [ 1.9100609 ,  0.625     ,  1.        ]], [0]),
       ([ 0.        ,  0.0625    ,  0.        ], [[ 1.75      , -0.25      ,  1.        ], [ 1.25      , -0.25      ,  0.875     ], [ 1.25      , -0.25      ,  1.        ]], [0]),
       ([ 0.        , -0.        ,  0.25      ], [[ 1.75      , -0.25      ,  0.875     ], [ 1.75      ,  0.25      ,  0.875     ], [ 1.25      , -0.25      ,  0.875     ]], [0]),
       ([ 0.        ,  0.        ,  0.25      ], [[ 1.25      , -0.25      ,  0.875     ], [ 1.75      ,  0.25      ,  0.875     ], [ 1.25      ,  0.25      ,  0.875     ]], [0])],
      dtype=[('normals', '<f4', (3,)), ('vectors', '<f4', (3, 3)), ('attr', '<u2', (1,))])

In [5]: r.vectors.shape
Out[5]: (3476, 3, 3)

In [6]: m = trimesh.Trimesh(**trimesh.triangles.to_kwargs(r.vectors))

In [7]: m.faces.shape
Out[7]: (3476, 3)

Copy link

@FXXB FXXB commented Apr 17, 2019

Thank you so much. That's it. I must have missed the .to_kwargs method. Thanks again

Copy link

@science-code science-code commented Oct 24, 2019

Hello! Was there any progress on mesh simplification/decimation with Trimesh?

Copy link

@sklausing sklausing commented Feb 7, 2020

Hello there everyone, my first ever comment on github haha! I think it would be nice to specify dtype for several functions when passing in arrays of points (not always converting to float64 when checking appropriate 3-dimensional). Constantly running into a memory issue when using ray.contains_points. I did see a comment that suggested iterating through, perhaps on the Z axis to avoid this issue, although i do think it could help having the option to use float16 or float 32.

Copy link

@nschloe nschloe commented Feb 11, 2020

meshio author here. I think handling the I/O via meshio would be a good idea here. If you're interested I could cook up a PR.

Copy link
Owner Author

@mikedh mikedh commented Feb 13, 2020

Hey @nschloe that would be awesome! Super open to PR's!

Copy link

@FreakTheMighty FreakTheMighty commented Mar 15, 2020

OpenMesh has python bindings and decimation. Its not the lightest dependency, but it could provide mesh simplification.

Roughly, you can go back and forth between OpenMesh and trimesh like so:

def tri_to_om(mesh):
    om_mesh = om.TriMesh(np.array(mesh.vertices))
    return om_mesh

def om_to_tri(om_mesh):
    mesh = trimesh.Trimesh()
    mesh.vertices = om_mesh.points()
    mesh.faces = om_mesh.face_vertex_indices()
    mesh.face_normals = om_mesh.face_normals()
    mesh.vertex_normals = om_mesh.vertex_normals()
    return mesh

Decimation looks something like. I find their interface pretty confusing. It took a while for me to make sense of it at all.

    mod = om.TriMeshModQuadricHandle()
    decimator = om.TriMeshDecimater(om_mesh)
    mod = decimator.module(mod)

Its also possible to lock edges to preserve them during decimation.

@mikedh mikedh mentioned this issue Mar 25, 2020
Copy link

@Kramer84 Kramer84 commented Apr 25, 2020

Hi Mike

I have seen the issue concerning quadric edge decimation and the potential enhancement using sp4cerat's fast quadric edge decimation. For now I am trying to learn how to do the bindings using Cython, but I am running into some issues, mainly concerning the conversion of numpy arrays into the custom object vec3f defined in sp4cerat's code. (As I have little to no experience with C++)

The easiest way to proceed would, in my opinion, to export the mesh as a temporary .OBJ file, doing the reduction using a simple cython wrapper, and loading the new file into trimesh again, but this solution is not elegant at all, and a lot of time would be lost from the conversion, the savings and the loading of objects... On the other hand, this would require the least modifications in the original code.
But still, not elegant.

An other idea would to pass the OBJ string directly as an argument into the code, but then I struggle to know if the type of the string in the new function used to pass the OBJ string should be *char ** or stdin or a FILE Stream , and there would still be time spent for the OBJ conversion.

But the best way to proceed would be to convert the numpy arrays into the custom type defined by sp4cerat and setting the variables through a new C++ function, but this would be a lot of work and research.

I would like to know if you have any ideas about how to do this (or some interesting articles about this topic) or if you have already begun this implementation. I have begun some analysis and will soon begin some testing here


Kristof S.

Copy link

@FreakTheMighty FreakTheMighty commented Sep 17, 2020

@mikedh I've been using this library for quadratic mesh simplification. I think this could be the perfect library for integrating into trimesh.

Its got a lot going for it:

  • The library is clean and simple. It only does one thing, (quadratic mesh simplification)
  • Has a bunch of useful options
    • Target vertex count
    • A valid pairs threshold
    • Maximum allowed error threshold
    • It might support tracking other vertex attributes (I'm a little unclear about this feature)
  • Its just been added to pip, so its can be simply pip installed
simplified = simplify_mesh(np.array(mesh.vertices),
                       np.array(mesh.faces, dtype=np.uint32),
decimated= trimesh.Trimesh(vertices=simplified[0], faces=simplified[1])

I believe it should be cross platform, but there is an outstanding issue on windows that I wasn't able to offer a pull request for. Perhaps someone in this community would be able to address it jannessm/quadric-mesh-simplification#2

CC @jannessm

Copy link

@jannessm jannessm commented Sep 17, 2020

@FreakTheMighty: thanks for your support.

regarding the vertex attributes. I have implemented this library to use it in the context of geometric deep learning. therefore, I needed an interpolation of feature vectors assigned to vertices. But as @FreakTheMighty mentioned, it can be used very easily for quadric mesh simplification without features.

Currently, I am quite busy. Therefore, I would be very glad, if I receive some support for the mentioned issue.

Copy link
Owner Author

@mikedh mikedh commented Oct 1, 2020

hey @jannessm that looks awesome! I really like how self contained it is. If I get some cycles I'd love to help get cibuildwheel set up, although unfortunately I'm also kind of slammed this season. I'll try to look at it once I drag Toblerity/rtree#163 over the finish line.

Copy link

@Kramer84 Kramer84 commented Oct 24, 2020

Hi @mikedh , even if now this issue seems to be solved i managed to wrap Sp4cerat's Fast-Quadric-Mesh-Algorithm in C++ with Cython
It works well enough on stanfords bunny sample for simplifying it down from 112402 to 1000 in less then a second.
The algorithm is only composed of two scripts.
The simplification is also possible on non watertight meshes and does not change open triangle borders.

repo: PySimplify

usage is similar:

>>> from simplify import pySimplify
>>> import trimesh as tr
>>> bunny = tr.load_mesh('Stanford_Bunny_sample.stl)
>>> bunny
<trimesh.Trimesh(vertices.shape=(56203, 3), faces.shape=(112402, 3))>
>>> simplify = pySimplifyy()
>>> simplify.setMesh(bunny)
>>> simplify.simplify_mesh(target_count = 1000, aggressiveness=7, verbose=10)
iteration 0 - triangles 112402 threshold 2.187e-06
iteration 5 - triangles 62674 threshold 0.00209715
iteration 10 - triangles 21518 threshold 0.0627485
iteration 15 - triangles 9086 threshold 0.61222
iteration 20 - triangles 4692 threshold 3.40483
iteration 25 - triangles 2796 threshold 13.4929
iteration 30 - triangles 1812 threshold 42.6184
iteration 35 - triangles 1262 threshold 114.416
simplified mesh in 0.2254 seconds from 112402 to 1000 triangles
>>> smallBunny = simplify.getMesh()
>>> smallBunny
<trimesh.Trimesh(vertices.shape=(502, 3), faces.shape=(1000, 3))>

The tracking of the color and material attributes is not yet implemented, but as it is already implemented in the c++ code it is just a mater of wrapping one more function.

I can help to integrating it into trimesh if you plan not to use it as an external dependency.

Copy link

@FreakTheMighty FreakTheMighty commented Oct 26, 2020

@Kramer84, thank you for doing this work! It seems like Issues are not enabled on that repo, is that intentional?

Copy link

@Kramer84 Kramer84 commented Oct 26, 2020

@FreakTheMighty I forgot it, the issues are now enabled, thanks!

Copy link

@tpank tpank commented Feb 10, 2021

Hi @mikedh ,

thank you for this awesome library!
Would it be possible to include the option for a multi-dimensional pitch in Path2d.rasterize?
This would only require to remove the current input checks that enforce the user to provide a uniform spacing for all directions.
The same is already possible in trimesh.voxel.creation.voxelize (even though its not in the documentation and possibly not intended).

Copy link
Owner Author

@mikedh mikedh commented Feb 10, 2021

Hey @tpank if it's just removing a check and adding a unit test absolutely! Happy to take PR's!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet