Geometry Node: Bisect #103904
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
8 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#103904
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Relevance
Bisect could be used for multiple purposes including: Boolean operations, Clipping/Geometry reduction, Contour lines (from terrain), etc.
Alternatives
Blender bool tools can be slow and/or unstable, primitive based bool tools can be simpler to use and yield better results.
Related Tasks
D14255 D13300 P2338
Limitations of the proposed solution(s)
Providing Bisect operation for all geometries through a single node will be an extensive PR and may not follow design of other operations.
Design Proposals
Bisect should operate on all geometries (excluding volume), to do so the possible operations will include:
Bisect will not do:
Preliminary layout for Bisect and related nodes (sorry for shitty hand drawing)
Pros
Cons
Changed status from 'Needs Triage' to: 'Needs Developer To Reproduce'
Added subscribers: @Osares, @HooglyBoogly
Added subscriber: @mod_moder
I think, to some extent, volume bisect would be the simplest operation... But for now, it's really best not to think about it.
It seems to fill the holes you need to be able to group all the vertices that
At the moment, this can't be done without complex and unstable hacks, so it makes sense, but it will still need work.
Added subscriber: @Dangry
Grouping connected elements would amount to computing the fill for each individual component, this would be the better behavior but even the current bisect operator does not do that (see image(s) below). It would probably be possible to extend the algorithm and let it take a connected element input. This could be done by combining a node computing a group ID integer for connected primitives (vertex/edge) and with a version of the fill node which could read the attribute and apply the fill algorithm on grouped elements instead. But I think that can be done later because:
Regarding volume I have not looked any part of the volume API so I have no idea of how it works. Bisecting a volume seems convoluted though since clipping voxels is one thing but representing the bisect plane might involve increasing the voxel resolution? To me it is not obvious what the result should be.
I might be missing something but that is why splitting the functionality in multiple parts is better because then those problems will not hold other things back (i.e. some of the nodes can be made available before everything is resolved).
Bisect operator examples
Bisect operator of three stacked cylinders (normals facing outward).
Same deal but normals facing the opposite direction.
Conclussion
Not sure why the face for the outer circle is split in two but it clearly does not consider connected parts neiter does the normals influence what is consider 'inner' and 'outer' part when filling the hole (it just affects the normal of the resulting face(s)). This behavior could be improved but I think we should keep the discussion to the bisect operator itself since this is a separate node in regard to this design.
Describing how to fill in the result, I considered individual nodes. That is:
So, almost everything, if you count hacks, can be done now. But on a good note, it all needs to be improved.
But it seems to me that this is a fairly clean variety of implementations of this function.
Therefore, the bisecting node should simply be able to bisecting and select.
About the volume: so far this is a very underdeveloped area. I myself have so far only learned a little about the basics of the structure. So, it was faster: there's just a bunch of elements in the array, we divide it in half by indexing when copying and that's it :).
So yes, it ~doesn't require complex topology work~ but I only said it in a way that someday it might be something to seriously think about.
Someday yes, but not today! It can wait, extending based on geometry type is decoupled so it should not be a problem! :)
Added subscriber: @FDesimpel
Having a seperate bisect node for each geo type doesn't seem to be too redundant, especially with the proposed plane equation node.
Also, this way the different nodes can release as they are ready, and have specific ux regarding outputs and (input)settings.
For instance, with pointclouds, no extra points would be made, only separated (trough selection boolean field) in half-spaces, some existing points could be exactly on the plane given an epsilon. And some option could be given on what to do with point radius. What else... two seperate 'epsilon' inputs for both sides, which could then also be used to have a plane thickness ( slice ) for point clouds for instance. For meshes this seems better done with two of the nodes. ( edit: see next comment too related to this )
For curves and volumes I can imagine there will be some specifics too. And i'd rather have mesh bisect soon rather then wait for all the other ones. Having only volume as a seperate one seems an arbitrary separation.
D13300 seems pretty close to ready for a Bisect_Mesh ?
Doesn't seem optional to me. Also the stuff on the plane. Also an epsilon input seems valuable here.
This on the other hand could be done with the existing delete node if we have selection outputs?
Though on the other hand, given this will be a performance critical node and the algorithms to do it go over the geo anyway, you could provide all selection and geo output / delete options ( given input flags ). Dunno if nodes will have dynamic outputs one day, those flags could set the node to only do / output what is asked.
Weird, given ...
... we could use all perf gain by having it in. The connectivity info is known at this point.
Having a seperate fill node is interesting too, but that seems a seperate issue/possibility. Regarding maintenance you could always include the relevant code in both nodes right? This way you could also have the additional seperate fill node have options for different fill algorithms/heuristics, and make them available in the bisect_mesh node later.
Just one geo output (can have the fill faces too), can delete/separate with the selection outputs and other nodes ?
Or again, have all options with multiple geo outputs.
Another thing i'm thinking about is maybe something can be done to have a multi/bisect. Could be a seperate node or a setting ( multiple plane inputs ) that uses these nodes logic internally to do slice / cube / frustum selections but with optimized algorithms running trough them at once if possible. Also for the height-lines use case.
The multiple plane inputs could be done with a field for this.
I'd suppose for instance checking distance per vertex to several aligned planes with different d, or maybe even perpendicular planes can be optimized ( like going trough all vertices once, buffering distances etc or even better. )
Splitting the node into versions for different types of components is a step backwards.
How so? As far as i'm aware, the node doesn't exist yet, so there's nothing to split. Conversely, you could always make a node later that has all component functionality in one.
I mean, the most extensible and unified thing would be to handle all the components with a single node. Like delete, join, transform, ... .
A lot of the work is already done except for mesh bisect, and as I understand it is where most of the interest are so likely mesh bisect will be delayed longer if they are not done as a single node (due to other nodes being done and tested first). Main purpose for this design thread is to determine if they should be a single node or multiple ones as it is not up to me to make that decision.
Regardless if there are multiple 'bisect' nodes the 'boolean operation' version of this node should support all geometry types in my opinion, an option to just 'clip all geometry by this plane' seems like a valid use case and it doesn't make sense to provide this function as four separate nodes to 'clip mesh' + 'clip curves' + 'clip point cloud' + 'clip volume'.
Pointcloud use case feels slightly niche for bisect but it feels like we are talking about a 'plane selection node' rather then a bisect node here. Selection should be 'possible' but to me there would be justification for a node purposely built for selecting things relative to a plane. For example when we are discussing 'epsilon' values those makes zero sense in relation to a bisect operation particularly if the end goal is to 'fill'. To me the original 'bisect' operator is fundamentally flawed due to providing an 'epsilon' input.
To my knowledge D13300 will never see the light of day, it's using BMesh functions which will not be approved by the devs. I haven't discussed it with Falk explicitly but it's over a year since any updates and the whole thing will have to be implemented from scratch.
To me it's optional since I believe it will be easy to extend the node with those options later and I didn't want to promise it in the first iteration even if I believe they should be provided.
Deletion has a greater performance impact if done in one pass, if say 'half' the mesh is 'deleted' the one only has to copy half the memory instead of copying 1.5 times the memory (copying the whole thing once to insert bisection and then deleting half). Deletion could be made fairly efficient though but I think Blender requires mesh primitives to be in continuous buffer(s).
It's not weird. It's explicitly stated to make the point of this design where the fill function is provided by a separate node. The performance issues will only affect very few use cases (very large geometries) as it will be still be efficient.
I think this is more effort then it seems. It is 'easy' if they are separated so that the fill algorithm creates a new mesh buffer from the output of the bisect operator, this would pretty much be equivalent to using two separate nodes and not bring any real performance benefits. If one wants to get the benefit by filling one mesh geometry once the implementation will be more messy and harder to maintain.
Maintainability is also a reason for me to provide the functionality in two nodes, it utilizes the node system to manage interchangeability between the functions. Blenders Mesh class is differentiated from the BMesh in this area as BMesh seems to have a defined interface for how parameters should be passed between chained operations/functions. For Mesh objects we pretty much have the geometry node system which to me is a very good argument for splitting the functionality in different nodes for this very reason. This is very development centric argument but from my POW it makes a lot of sense even if my understanding of the state of the Mesh class is likely incomplete.
Think we are only discussing one geo output here, there could be option for multiple selection outputs though (and as I said, those can be expanded later).
Summary
I think the points are valid but is missing some of the main points of this particular design. This design provides low level functionality in a clean usable way given the current geometry node context. If there are use cases that are limited by it one can easily iterate upon it by either by adding inputs and/or creating other specialized nodes for those use cases. To me making more specialized nodes is quite daunting as it would be like creating a simple version of an 'principled shader node' without having a good insight in what exactly the inputs/outputs should be.
I've thought a bit of about the idea of implementing some 'primitive' boolean operators for cubes/spheres/frustums. But one thing at a time, please :(
I've done this once before for a bisection with a fixed number of planes and it gets quite messy. It would take a lot of effort to design an algorithm that had any benefit compared to providing loop expressions and I don't see a value in it as it is seems more of a niche use case. Maybe one day but for now I want to keep things simple :)
Iff planes are parallel (so a field for the
d
value) it is not to complicated but to I would want to do that in an iteration rather then everything at once.Happy to hear that the other nodes are about ready, I thought it was the other way around.
With Bisecting a point cloud i mean separating into half-spaces, which indeed is more a selection thing.
Now I like the idea of having seperate selection nodes too, which could extend that idea to other components.
Like bisect is really cutting trough something, plane selection is something else and can be done later, needs a better name though... maybe select_halfspace ( and extend for other cases )
Thanks for the thorough reply, everything you said makes sense.
One more thing...
Would the bisect node also work on instances ?
I mean, do a coarse check ( like on it's bbox ) of the instances first,
then only do the actual mesh bisecting of those instances,
and actually having a way to just get the 'hit' instances,
without actually cutting them ?
Or would this also be something for another node / node group ?
Haven't thought much of instances in this context. Not sure what expected result should be since instances aren't geometry per see I but think one could treat them as bounding boxes and provide a selection for the ones intersecting the plane and option to cull either side of the plane. To get above behavior one could then:
Bisect -> realize intersected instances -> Bisect realization -> join instances on either side of the plane.
Of course it would be faster to provide everything in a single node but it would likely be quite a bit of extra code to maintain (and implement).
That's exactly the kind of nodegroup (noodle) I had in mind .
I think I agree with most things in the design so far, except the use of a new "Plane" socket type. I think that's a bit premature in this case, separate "Origin" and "Direction" vector inputs would probably be simpler for now.
I'm a bit worried that people will use the node in loops (real or workaround loops) to make many slices of a mesh for something like a topographic map. Since the node would output a separate mesh every time, it's really not optimized for that use case. Maybe it's worth having a plan for how that use case would be addressed, even if it's not with this node.
Inputing point cloud this positions and normal fields?
Analog of Instances on Points but for bisectiong simular on voronoi celing
Added subscriber: @sampotter
Yes I now realize it's not needed since "Origin" is not needed in the fill node (which was one reason it seemed interesting as it would reduce the number of sockets and prevent users from passing the wrong inputs as it will easily generate degenerate results).
Yes I can try to make/plan for the mesh bisection algorithm to support multiple parallel bisections but wont promise that it will be so. I think it would be better suited as a separate node though since it would just add to many redundant edge cases.
Not sure what you mean exactly.
Sorry for not replying faster.
BR
What is still holding this back, exactly ?
Googled for bisect in geomnodes and found this page... Would be cool to have it, boolean too slow for complicated geometry and plane-based bisect op sufficient for many tasks
Yeah my goal was to start this during the spring and finish it during the summer vacation. Right now it looks like it will be delayed however as I've been to busy at work and haven't been able to muster the energy to start properly working on it. Now the goal is to make progress during vacation and try to finish it early/mid autumn.
Any news on this?
Making some progress for the bisect node after christmas, hopefully I can finish it soon!
Right now i think its better to make
Mask
node as general version of bisect.While reasonable. Since one of the primary use cases is as a plane clip tool and how Mesh objects work in geo nodes (always copy if mesh is changed) the difference in implementation of not exposing a clipped mesh output is small (but not ingsignificantly so ofc). To me the optimization of returning a clipped mesh in this case is worth it due to avoiding an extra copy (of the whole mesh no less, not great when goal is to clip it).
It would be fine if only removing geometry without inserting a clean edge but I see those use cases as being slightly different (one is just primitive reduction while the other is to provide a specific viz effect). I see that outputs can be iterated slightly though.
Of course implementation should probably be shared with functions like masking in some way to avoid duplicating functionality.