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

Add InstancedMeshVisual for faster and easier rendering of repeated meshes #2461

Merged
merged 15 commits into from
Apr 24, 2023

Conversation

brisvag
Copy link
Collaborator

@brisvag brisvag commented Mar 9, 2023

Followup from #2460: I implemented a full visual that inherits most of its logic from MeshVisual!

There are a few hacky workarounds, but overall the patching required is minimal. ShadingFilter unfortunately doesn't work as intended, I think because the light direction is computed on the non-rotated mesh... Probably possible to work around that too.

Otherwise, looks great, and should also work with textures and per-face colors (though I haven't tried that yet).

instanced_mesh_visual.mp4

@brisvag
Copy link
Collaborator Author

brisvag commented Mar 9, 2023

I got shading to work too! A bit hacky, but it shows that the changes needed are actually pretty small.

@brisvag
Copy link
Collaborator Author

brisvag commented Mar 10, 2023

Almost everything thaty works with meshes works here as well! I added some shortcuts to the exampel to test the functionality. The only exception is the MeshNormalVisual, which probably needs to be subclassed as well to account for instancing.

@jni
Copy link
Contributor

jni commented Mar 10, 2023

@brisvag
Copy link
Collaborator Author

brisvag commented Mar 10, 2023

@brisvag youtube.com/watch?v=SOucVPW4he4 joy

Ahah we're so close to that!

@brisvag
Copy link
Collaborator Author

brisvag commented Apr 18, 2023

@djhoese this would be nice to get in, but I don't know how to intepret that test failure. Something about discontinuous data being copied? How can I solve it?

Sorry, this was meant for #2460 :P

However, this one might be nice as well, though maybe a bit big to review now.

@djhoese
Copy link
Member

djhoese commented Apr 20, 2023

@brisvag if you fix the merge conflicts is this ready for re-review and merge?

@brisvag
Copy link
Collaborator Author

brisvag commented Apr 20, 2023

Ok, fixed some warnings in the example as well.

Copy link
Member

@djhoese djhoese left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good. I had a couple (mostly documentation) things I'd like updated, but otherwise I think this is pretty close to merging.

vispy/visuals/filters/mesh.py Show resolved Hide resolved
vispy/visuals/filters/mesh.py Outdated Show resolved Hide resolved
Comment on lines 53 to 109
class InstancedMeshVisual(MeshVisual):
"""Instanced Mesh visual.

Mostly identical to MeshVisual, but additionally takes arrays of
of positions and transforms (optionally colors) to create multiple
instances of the mesh.

Parameters
----------
vertices : array-like | None
The vertices.
faces : array-like | None
The faces.
vertex_colors : array-like | None
Colors to use for each vertex.
face_colors : array-like | None
Colors to use for each face.
color : instance of Color or ColorArray
The color to use.
vertex_values : array-like | None
The values to use for each vertex (for colormapping).
meshdata : instance of MeshData | None
The meshdata.
shading : str | None
Shading to use. This uses the
:class:`~vispy.visuals.filters.mesh.ShadingFilter`
filter introduced in VisPy 0.7. This class provides additional
features that are available when the filter is attached manually.
See 'examples/basics/scene/mesh_shading.py' for an example.
mode : str
The drawing mode.
**kwargs : dict
Keyword arguments to pass to `Visual`.

Notes
-----
Additional functionality is available through filters. Mesh-specific
filters can be found in the :mod:`vispy.visuals.filters.mesh` module.

This class emits a `data_updated` event when the mesh data is updated. This
is used for example by filters for synchronization.

Examples
--------
Create a primitive shape from a helper function:

>>> from vispy.geometry import create_sphere
>>> meshdata = create_sphere()
>>> mesh = MeshVisual(meshdata=meshdata)

Create a custom shape:

>>> # A rectangle made out of two triangles.
>>> vertices = [(0, 0, 0), (1, 0, 1), (1, 1, 1), (0, 1, 0)]
>>> faces = [(0, 1, 2), (0, 2, 3)]
>>> mesh = MeshVisual(vertices=vertices, faces=faces)
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update this docstring with the new keyword arguments and any usage examples that you think make sense (remove the existing ones that were copied from MeshVisual).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh a link to a site describing instanced rendering would be really nice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best example is the one in the gallery I think... Not sure if it's worth putting a big one in here. I don't really have a good link for instance rendering. I found this one maybe, but it's still a bit heavy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah maybe just a nice high-level human-readable description of what instanced rendering is would be nice. I'm basically imagining someone coming to VisPy and knowing very little about OpenGL, buffers, textures, or even only a little bit about what makes up a mesh and they question the difference between these two Visuals and why they should choose one over the other.

vispy/visuals/instanced_mesh.py Outdated Show resolved Hide resolved
Copy link
Member

@djhoese djhoese left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just realizing now, sorry, can we add at least one test to prove that the visual actually works beyond just the example?

brisvag and others added 3 commits April 20, 2023 17:01
Co-authored-by: David Hoese <david.hoese@ssec.wisc.edu>
Co-authored-by: David Hoese <david.hoese@ssec.wisc.edu>
@djhoese djhoese changed the title Instanced mesh visual Add InstancedMeshVisual for faster and easier rendering of repeated meshes Apr 20, 2023
@brisvag
Copy link
Collaborator Author

brisvag commented Apr 20, 2023

Just realizing now, sorry, can we add at least one test to prove that the visual actually works beyond just the example?

Definitely... however, do you know how to test gl+ stuff? I fear that it's not gonna work to just add it to the top of the file...

@djhoese
Copy link
Member

djhoese commented Apr 20, 2023

I think when you create the TestingCanvas or whatever you can specify a backend including a gl_backend or maybe it is gl="gl+" or something. I'd have to look through the code, but might not have time right now.

@djhoese
Copy link
Member

djhoese commented Apr 20, 2023

@brisvag Ok so I found one instance where it is just called under the Canvas context manager:

with Canvas():
gl.use_gl('gl2 debug')

But there is no indication that this resets on __exit__ of the context manager.

I also found:

def test_glplus():
"""Run glplus, check that mo names, set back, check exact set of names."""
gl.use_gl('gl+')
# Check that there are more names
fnames = set([name for name in dir(gl) if name.startswith('gl')])
assert len(fnames.difference(function_names).difference(['gl2'])) > 50
cnames = set([name for name in dir(gl) if name.startswith('GL')])
assert len(cnames.difference(constant_names)) > 50
gl.use_gl('gl2')
_test_function_names(gl)
_test_constant_names(gl)

where the module includes a teardown:

def teardown_module():
gl.use_gl() # Reset to default

So maybe a setup_module and teardown_module would be the clearest option?

@djhoese
Copy link
Member

djhoese commented Apr 20, 2023

Ok website seems good to go now.

@brisvag
Copy link
Collaborator Author

brisvag commented Apr 24, 2023

I need to fix a few things that popped up when working on tests; will update you soon!

@brisvag
Copy link
Collaborator Author

brisvag commented Apr 24, 2023

Ok, had to fix several bugs, but now it seems to work well. The test canvas is supposed to look like this:
image

@djhoese
Copy link
Member

djhoese commented Apr 24, 2023

The website failure I've fixed in #2472 and will merge it shortly.

@djhoese djhoese self-assigned this Apr 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants