setzer22 / blackjack

A procedural, node-based modelling tool, made in rust 🦀
Mozilla Public License 2.0
1.42k stars 64 forks source link

Some usability issues #65

Open Zireael07 opened 2 years ago

Zireael07 commented 2 years ago

1) Can't figure out how to use bridge loops even on a simple cube, every edge I try ends up with a traceback saying it's not in a boundary 2) Can't subdivide/split a face or an edge, just the whole mesh (EDIT: I see we have cut_edge and divide_face implemented but they're not exposed to the UI) EDIT: The latter is now done in a PR I sent

3) Mesh view can't be zoomed or at least I haven't figured out to do so EDIT: seems that it's because I don't have a mouse, just a touchpad, so no mousewheel events here :P EDIT: solved, dummy me forgot how to do scrolling on a touchpad

4) Can't click on an edge to get its number/click on spreadsheet number to highlight edge - the only way I can figure out which is which for something more complex is the debug pane 5) Related, would be nice to be able to drag from spreadsheet to node to fill in the input box 6) Can't copy graph nodes

setzer22 commented 2 years ago

Thanks! This feedback is quite valuable :)

Can't figure out how to use bridge loops even on a simple cube, every edge I try ends up with a traceback saying it's not in a boundary

Here's a working example of bridge loops. Also showcases the "groups" feature you may find useful in case you didn't know it: image

Bridge loops is currently not as versatile as in Blender or Houdini. In particular, it can only bridge two chains of edges that are the same length, and both have to be either open, or closed, but you cannot mix.

Furthermore, a restriction underlying blackjack's mesh model that helps simplify everything else in the implementation is that meshes have to be manifolds with boundary, with boundary meaning that there can be holes (i.e. an edge with 0 or 1 adjacent faces). However, an important restriction of manifoldness is that you can't have an edge with more than two adjacent faces.

If you think about it, when you want to bridge the faces of two adjacent cubes like in the pic below, you would end up in such a situation, because the edges you're trying to bridge do not have either side in the boundary (or in other words, they do not have a hole), so the final mesh would have some vertices with three adjacent faces. image

The solution to fix that is to first remove the endpoint faces, and then call bridge loops. Unfortunately, there's no "delete primitives" node at the moment :sweat_smile:, but that should be an easy one to add. Could you please file an issue so we don't forget?

Can't subdivide/split a face or an edge, just the whole mesh (EDIT: I see we have cut_edge and divide_face implemented but they're not exposed to the UI)

The subdivision operation works in a way that is very fast (:rocket:!), but only works if you process the whole mesh with it. Here's a link to the paper in case you want to learn more about it: https://onrendering.com/data/papers/catmark/HalfedgeCatmullClark.pdf

A more versatile, but slower operation could be implemented in terms of cut face, divide edge and the other low-level operations. Although it may be a bit complicated to figure out all the corner cases of the implementation. If you're interested in subdividing a single quad, that might be easy enough, so maybe we should start there. I see no problem with exposing the lower level operations you mentions as nodes. Adding new nodes is one of the easiest ways to get started with blackjack, so let me know if you'd like to contribute with that :) Otherwise feel free to open a new issue :+1:

Mesh view can't be zoomed or at least I haven't figured out to do so

You should be able to use the scroll wheel. Is that not working for you? I'm using it just fine, so in case it doesn't please file (yet another :sweat_smile:) issue describing your setup (OS, what you've tried...).

Can't click on an edge to get its number/click on spreadsheet number to highlight edge - the only way I can figure out which is which for something more complex is the debug pane

This is exactly the thing I'm starting to work on next. So... stay tuned! :smile:

Related, would be nice to be able to drag from spreadsheet to node to fill in the input box

Not sure I follow there. Do you mean, dragging the vertex id to add it to the list of elements in a selection?

Can't copy graph nodes

And that's precisely the next thing I have on my backlog right after the selections thing I mentioned above. Glad I'm on the right track with my plan :smile: Just a bit longer!

Zireael07 commented 2 years ago

Do you mean, dragging the vertex id to add it to the list of elements in a selection?

Yes

Since I have the source and Rust already :P I might as well try contributing when it comes to subdividing edges/quads but the new way of adding nodes is not documented yet it seems

PS image

One of the sides is missing but that should be easy to fix using create quad :P just learning :P

EDIT: I don't have a scroll wheel, just a trackpad, so nope. No way for it to work.

setzer22 commented 2 years ago

I want to make a guide for contributors describing how to add new nodes, but in the meantime check out my comment here: https://github.com/setzer22/blackjack/issues/60#issuecomment-1304563521. What you're trying to do is not exactly adding a new primitive, but adding a new operation should be very similar, only except of primitives.rs, you'd go to edit_ops.rs.

If this is something you'd like to tackle, please feel free to go ahead and don't hesitate to ask any questions! :smile:

One of the sides is missing but that should be easy to fix using create quad :P just learning :P

Nice! :smile: The "Create quad" node might not work as-is for this because it's hard-coded for 4-sided faces, but I'm almost sure the algorithm should generalize to any kind of n-gon. Needs a bit of work though.

In the long term, my plan is to make the extrude node have a a "fill bottom" option that would create the missing face. This would be far simpler than repurposing the create quad operation, which is far more versatile than this.

Zireael07 commented 2 years ago

In the long term, my plan is to make the extrude node have a a "fill bottom" option that would create the missing face. This would be far simpler than repurposing the create quad operation, which is far more versatile than this.

Probably!

I have a ton of notes from back when I attempted to generalize my project specific code in Godot, so hopefully I'll be able to pull off adding a new operation (Rust is great for that stuff, what with the Option preventing the usual nil/null shenanigans). And I think I have a general fill n-gon algorithm somewhere there too :P

Zireael07 commented 2 years ago

Was easier than I expected. I don't have time yet to make a proper fork (will likely do so tomorrow), but here's subdivide edge op (a zipped up .patch file) and a pic of it working.

image subdivide_edge.zip

setzer22 commented 2 years ago

Amazing! I'll wait for a PR so that you can take credit for the contribution :slightly_smiling_face:

Zireael07 commented 2 years ago

Made a PR.

In the meantime, another usability problem. Can't figure out how to use the Lua code node, it should likely come with a placeholder function demonstrating.

E.g. I tried to generate a 5x5 grid of points and no matter what I tried, it kept complaining that the format was wrong

setzer22 commented 2 years ago

Maybe I should rename the Lua Code node. It doesn't run anything, right now it's just a placeholder for a string which can be used to route Lua code to nodes that expect it, like Edit channels or Heightmap. Similar to how MakeScalar creates a scalar you can route to other nodes.

If you want to write custom Lua code, you can create your own node:

NodeLibrary:addNodes({ Playground = { label = "MyCustomNode", op = function(inputs) local cube = Primitives.cube(inputs.my_pos, inputs.size * inputs.scale) return { out_mesh = cube } end, inputs = { P.v3("pos", vector(0, 0, 0)), P.v3("size", vector(1, 1, 1)), P.scalar("scale", { default = 1, min = 0, soft_max = 10 }), }, outputs = { P.mesh("out_mesh"), }, returns = "out_mesh", }, })


That will make `MyCustomNode` available. You don't even need to restart blackjack, it will pick up changes every time you save it :+1:
Zireael07 commented 2 years ago

That Lua node definitely needs a rename AND a placeholder example then.

I'll try to make a Grid node then and likely send it as a PR whenever I get it done :P

setzer22 commented 2 years ago

Great! Looking forward to that :smile: I'll take note of the Lua Code node thing. I'll choose a clearer name like "Lua String" and provide a useful placeholder.

EDIT: seems that it's because I don't have a mouse, just a touchpad, so no mousewheel events here :P

By the way, two-finger scroll should be working on a touchpad (at least, works on my laptop). Can you confirm?

Zireael07 commented 2 years ago

Oh, right. Two finger gesture does work :)