nortikin / sverchok

Sverchok
http://nortikin.github.io/sverchok/
GNU General Public License v3.0
2.23k stars 232 forks source link

Viewer Draw node #4624

Open Durman opened 2 years ago

Durman commented 2 years ago

Problem statement

From Discord. I don't know, probably the node already using something like that, but if it's not it might help to improve its performance.

image

image

image

image

https://bartoszstyperek.gumroad.com/l/draw_xray

zeffii commented 2 years ago
  1. the stuff highlighted in the images reflect getting geometry from Blender meshes, the VD node doesn't do this. So this part of the suggestion is irrelevant to us.
  2. we already convert all incoming geometry to triangles and draw from the batch_shader, because that's the only way to do stuff in batch shader since Blender 2.8+.

our problem is that we need to support a wide variety of possible input, tris, quads, tris+quads, ngons, tris+ngons, quads+ngons, tris+quads+ngons. Anyone who's looked at the VD code sees there is a lot happening, it's slightly deceptive, but at runtime only a very limited sequence of executions are performed.

Could we do better? probably, the core of the problem is

we could offer modes that expect only triangle inputs, (indexed or non-indexed). or only quads (convex or concave) or if the user doesn't select those modes, we can run through essentially the current code.

we can do something faster for matrix multiplication here, if the input was np. https://github.com/nortikin/sverchok/blob/f6764818f4a83e77f505162c76f946b4d3976288/nodes/viz/viewer_draw_mk4.py#L443-L446

and certainly here too

https://github.com/nortikin/sverchok/blob/f6764818f4a83e77f505162c76f946b4d3976288/nodes/viz/viewer_draw_mk4.py#L856

it would be interesting to do a rewrite from scratch, but i would prefer it to be a separate node. "fast GL viewer" or something..

OR

is the suggestion that we convert incoming verts+edges+faces to a bpy.types.Mesh and from there extract everything as np data?

mifth commented 2 years ago

Good point about tris/quads only.

Can the Viewer separate tris and quads on its start? And as for ngons we can convert them to tris.
So, for example we have an input as Tris+Quads+NGons and the Viewer will convert them to Tris+Quads (Ngons will be converted to Tris). This conversion will be done once. Then we can run our shader.

Or we can convert everything to Tris and run a shader.

Also, the point is that a user could have a possiblitity to plug Numpy Arrays and Python Arrays. A viewer should work in both ways.

Also, probably there could be such situations like: Verts(Python Array), Polygons(Numpy Array).

zeffii commented 2 years ago

Or we can convert everything to Tris and run a shader

Not sure I understand this question, that's what it does already, i don't remember when the all_triangles was added. So anyone that uses that mode should already be seeing massive speedups.

https://github.com/nortikin/sverchok/blob/8eb88a3825fb5287da80f75e00b050e56e06e8a6/nodes/viz/viewer_draw_mk4.py#L311-L315

The internal complexity of the node is down to the difference between what the user can input, vs what the user can output . The more the display function is optimized for specific states, the more logic is required to create the those separate states.

zeffii commented 2 years ago

if we had a serious np contender for mathutils.geometry.tessellate_polygon then we'd have a reasonably good chance at creating a slightly faster routine.

zeffii commented 2 years ago

in facet mode i would like to offload the face-normal / color to the shader (but i never figured out how to do that, or if it's possible.. seems like it should be )

Durman commented 2 years ago

I just made a test with Python list and NumPy array (only vertices) and it appeared that with NumPy the node works quite slower (in both node execution and drawing).

image

It seems on the contrary we should avoid using NumPy arrays in the node since Blender seems does not expect such input.

mifth commented 2 years ago

@Durman does the Viewer node use the same code as X-Ray addon?

Durman commented 2 years ago

It seems does not have too much choice. It uses the same Blender API. https://github.com/nortikin/sverchok/blob/015081d94bcf3f45b9e48bc8ca30354d67ba3598/nodes/viz/viewer_draw_mk4.py#L188

zeffii commented 2 years ago

try passing 100's of thousands of verts to the x-ray callback :)

mifth commented 2 years ago

Alright, I didn't test it. I believe you. Probably we could add a numpy array conversion to a python array? The Viewer can convert an array on a start only.

Durman commented 2 years ago

Knowing other areas of Blender API I can say that the conversion really might give performance improvement.

zeffii commented 2 years ago

if the input is numpy, and a matrix is passed. then it makes sense to first multiply using numpy, before converting to python lists. for the shader

roughly.. (but i did test this :) )

if use_matrix:
    if isinstance(vecs, np.array):
        # use np to do matrix multiplications first.. then convert to python list
        xyzw_array = np.c_[vecs, np.ones(vecs.shape[0])]   # must add 4th column for 4*4 matrix multiplication 
        transformed = (mat @ xyzw_array.T).T
        v_path = transformed[:,:-1].tolist()          # [:,:-1]  drops last column to make xyz vectors
    else: 
        v_path = [(mat @ Vector(v))[:] for v in vecs] 
else: 
    v_path = vecs