K3D-tools / K3D-jupyter

K3D lets you create 3D plots backed by WebGL with high-level API (surfaces, isosurfaces, voxels, mesh, cloud points, vtk objects, volume renderer, colormaps, etc). The primary aim of K3D-jupyter is to be easy for use as stand alone package like matplotlib, but also to allow interoperation with existing libraries as VTK.
MIT License
942 stars 123 forks source link

[Feature request] Add groups to front-end / plot #327

Closed sataset closed 2 years ago

sataset commented 2 years ago

It would have been perfect to see groups (k3d.objects.Group) in plot controls instead of all meshes it contain.

In example below I have added 2 groups containing 13 elements each.

Spoiler ![image](https://user-images.githubusercontent.com/28687456/150962408-84133594-3ab7-4c87-b21a-18937e26ffe6.png)

292

tgandor commented 2 years ago

I think this is an interesting feature request, but possibly quite heavyweight on the JS side of K3D (@artur-trzesiok ?). It would require also handling some corner cases (multiple group membership of objects, groups within groups, possible infinite recursion -- what happens if we try to add a group to itself, a.k.a. Russel's paradox...).

Right now, k3d.objects.Group is a little more than an improved Python list() object, and the JS frontend (thus, also the UI) has no information about its existence.

sataset commented 2 years ago

Thank you for your comment.

I have read comment from previous issue and understand that JS front-end has no information about its existence.

However I think it is possible to simplify current implementation towards constant structure or make a new one specifically for that case. E.g. provide front-end with a UIGroup that wraps all objects and checks if these groups intersect between each other (by checking their references or objects unique ids). And in case if they do just throw error and cancel plotting until user handle this.

I know that specified description does not play well with the rest of k3d but as far it will be needed only for visuals it should be okay?

artur-trzesiok commented 2 years ago

I think this is an interesting feature request, but possibly quite heavyweight on the JS side of K3D (@artur-trzesiok ?)

Not on js side but Python + concept level. plot.objects and plot.object_ids will be no longer a plain list. So a lot of question will rise: can we have the same object in two places of lists ? Do we want have a feature to remove whole branch of tree from plot? What is the limit od depth of three? Can we have empty group with only a name? Where will be added by default a new element via plot += obj?

What library should we use to handle that? anytree ? Do we want to add model_matrix per group?

I would rather see solution in something much simpler like hardcoded one-level hierarchy done by convetion with names eg.

earth = k3d.mesh(...., name="Earth", group="Planet");
mars = k3d.mesh(...., name="Mars", group="Planet");
pluto = k3d.mesh(...., name="Pluto", group="Planet");

alternative:

earth = k3d.mesh(...., name="Planet | Earth");
mars = k3d.mesh(...., name="Planet | Mars ");
pluto = k3d.mesh(...., name="Planet | Pluto");

And that will be interpreted by js side as group "Planet". @sataset @tgandor do you think that this will be good enough? I want to keep k3d simple as I can. So I would like to avoid adding anytree-like solution.

@marcinofulus please look at this too.

artur-trzesiok commented 2 years ago

https://github.com/K3D-tools/K3D-jupyter/blob/devel/examples/objects_groups.ipynb

tgandor commented 2 years ago

I think the "structure by materialized-path naming convention" is a great idea. This would be even more than "single level group" OP asked about, but probably quite complicated (grouping by common prefix -- "path compression" like in VS Code filesystem tree).

Anyway, the current approach -- group as an optional traitlet -- looks fine!