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

Closed
mikedh opened this issue Jul 31, 2018 · 27 comments
Closed

Enhancement Ideas #199

mikedh opened this issue Jul 31, 2018 · 27 comments

Comments

@mikedh
Copy link
Owner

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

@Marviel
Copy link
Contributor

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 :)

@mikedh
Copy link
Owner Author

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.

@mmatl
Copy link
Contributor

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.

@mikedh
Copy link
Owner Author

mikedh commented Sep 12, 2018

Sounds good, discussion for texture in #218

@LinJiarui
Copy link
Contributor

@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.

@mikedh
Copy link
Owner Author

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!

@nschloe
Copy link
Contributor

nschloe commented Mar 21, 2019

Perhaps optimesh is something for you, too.

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

@FXXB
Copy link

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

@FXXB
Copy link

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 (numpy-stl.data)
I wondered if this direct conversion between numpy-stl and trimesh already exists...
Sorry for the confusion

@FXXB
Copy link

FXXB commented Apr 16, 2019

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

@mikedh
Copy link
Owner Author

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]: r.data
Out[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)

@FXXB
Copy link

FXXB commented Apr 17, 2019

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

@science-code
Copy link

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

@sklausing
Copy link

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.

@nschloe
Copy link
Contributor

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.

@mikedh
Copy link
Owner Author

mikedh commented Feb 13, 2020

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

@FreakTheMighty
Copy link
Contributor

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))
    om_mesh.add_faces(np.array(mesh.faces))
    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)
    decimator.add(mod)
    mod = decimator.module(mod)
    mod.set_binary(False)
    mod.set_max_err(4)
    decimator.initialize()
    decimator.decimate_to(to)
    om_mesh.garbage_collection()

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

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

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

Greatings

Kristof S.

@FreakTheMighty
Copy link
Contributor

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),
                       node_target)
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

@jannessm
Copy link

@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.

@mikedh
Copy link
Owner Author

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.

@Kramer84
Copy link

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.

@FreakTheMighty
Copy link
Contributor

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

@Kramer84
Copy link

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

@tpank
Copy link
Contributor

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).

@mikedh
Copy link
Owner Author

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!

@mikedh
Copy link
Owner Author

mikedh commented Apr 7, 2022

Closing in favor of the updated issue #1557

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests