Curve 2D Boolean Geometry Nodes

This is a much needed feature, specially for Text. Thank you for working on this.

1 Like

Unaware of your work on this I tried implementing 2D curve booleans yesterday with the Clipper library
If you’re interested in my code to try it out let me know in blender.chat (erik85)

12 Likes

Well, that’s inconvenient, but at least the functionality is there.
Who would have thought after all these years we’d have the same obscure idea at the same time .
Unless the performance of your library is particularly bad, I’m obviously calling this project off. I’ve so far ignored self intersection outright, so just based on your screenshot your solution appears superior.

This was just a quick test because I found that library yesterday and couldn’t not test it. I’m not planning to continue developing it (atleast not in the near future) so I think you should definitely continue, but maybe look at using Clipper. It also has a feature to offset curves that could be useful in other genometry nodes.

Ok.
I didn’t use any external dependencies because I didn’t feel I had the clout to get them into master. I was under the impression that they were frowned upon, but I’m not so sure anymore.

Yeah I’m not sure either, some core developer will have to answer that. But there are many small libs used in Blender and for something like this it should be fine I hope. It feels a bit unnecessary to reinvent the wheel.

After thinking about this for a while, here’s how I’m going to proceed forwards :

There are both pros and cons to using a library like Erik used.

Pros :

  • Easier
  • Cleaner
  • Inherently works well with all current and future curve types, since they are all turned into Poly Lines

Cons :

  • Result Curve is always a poly line, which makes the geometry node modifier “apply” operation less useful to users.
  • Intersections cannot be calculated at lower resolutions, then scaled back up again for rendering.
  • Attributes like radius get lost unless we massively modify the library.
  • An external library needs to be approved. It’s small (only ~250kb), but a lot of the code inside is redundant. And getting a patch approved is historically easier without external code.

My node currently has to convert splines to bezier curves, but it always returns easily-editable bezier curves. It doesn’t even support Poly-Lines at the moment, and therefore never even returns them. Useful for users, superfluous if raw evaluated curve data is what you’re after, which 99% of the time you would be.

But taking a step back from the Node itself, all these bezier boolean operations have uses outside of Geometry Nodes. They are in fact a basis on which vector graphic programs like Inkscape work. So even if the final Node uses a simpler Poly Line approach, the code could likely find its way into a set of edit mode operations. Which means my work thus far is likely not going to waste either way. Phew.

So for the time being I’m going to continue the node like before, implementing full bezier boolean operations. After that’s done, I’ll implement Poly Line support, which should use the same internal functions, and therefore be trivial to implement, by hand. A library would be overkill, and would always need to be modified to carry over curve attributes, but the fundamental idea of returning a poly line when that’s all that the following modifiers would use anyways has merit.

16 Likes

Bezier intersections are now fully functional.

You can find an up-to-date blender 3.0 with my changes here :

Make sure to only use curves without fill geometries (disable fill mode), as filled curves currently don’t work with most curve nodes, due to a bug.
Also keep in mind that currently, self intersection is not supported. If there’s an actual reason to have it, I’ll try to implement it at the very end, but for now, I can’t think of a good reason.

Performance has not been a priority thus far. But if you encounter performance issues, make sure to check whether Curve Fill or Curve To Mesh are at fault. In all my tests, those algorithms always performed worse than the actual boolean operation. Which is good. Because all of them should scale similarly well with the better line intersection algorithm I’ll be working on after all else is done.

EDIT : PolySpline support implemented. That went smooth as butter :slight_smile:

Next up I’ll implement a “Spline to Bezier” function. Then it’s on to optimization and cleanup.

25 Likes

I have thought of a workflow like this, to create face animation in a 2D view, but then projecting on top of a model and such.

Though it makes sense to use pixel boolean operations in the compositor, this way is kinda weak, because Blender currently missing, real time compositing capabilities (though there are talks to make this happen in the foreseable future). Pixel based operations work nicely provided that you exclude the real time factor.

So the most obvious solution is to model everything in 3D with the risk of loosing the 2D philosophy. But with your work so far I can see this idea becoming feasible once again.

Creating a 2D animated rig, with boolean operations and such, animated and fine-tuned properly right on the 3D view, with no intermediate steps.

Such as for example a typical use case is this:
anime-eye-blendshot

https://www.dropbox.com/s/sxyubry9wiq07q0/anime-eye.blend?dl=0

1 Like

Hey, what’s the status on this? It looks really cool. It would be nice if you could upload a patch to https://developer.blender.org (could include WIP in the name) so that it’s easier to try it.

Now that instances shouldn’t be realized by the nodes, maybe it could be possible to make this modify the instance references. If an instance is used multiple times it could duplicate the reference before modifying it.

I also thought about the possibility of reusing some of this code for a separate “Slice Curves” node that takes a 2d curve or 2d curve instances as input together with parameters like slice direction, width and padding and then outputs all slices as instances. This would be quite useful together with the text nodes I’m working on. What do you think?

Here’s an example of what I mean by slicing, made with the current boolean node:

8 Likes

There you go
https://developer.blender.org/D12753

I have no idea what this instancing is all about. I’ve briefly seen people talk about it in the chat, and nothing more. Is there a doc I can look up?

As for slicing, you should be able to use most of the boolean functions for that. They can generate a mesh containing all intersection points for you, which you then just need to walk along / trace correctly. I can’t guarantee the relevant code won’t change anymore, but it should stay mostly the same.

Might be much easier to just generate very thin boxes and use boolean subtraction instead though.

3 Likes

I haven’t had time to look at your code so I could be wrong, but generally what you do to support instances is not realize instances but instead run the code for each geometry set inside the input, using geometry_set.modify_geometry_sets. It would take a bit more work in this case though I guess as instance position has to be taken into account, and if the instance reference is used multiple times the cut version would have to be a copy of the original.

I just realized as this is in 2D I wonder how instances should be treated if they are not on the same plane?

1 Like

Is there life in the project, or has it faded into the background?

I’m unfortunately a bit stuck. An update changed how curves are stored internally, and I can’t turn that new representation into a linked list and back without inevitably running into an exception somewhere down the line.
I currently don’t have the time to spend days debugging this, so unless someone else can jump in and implement that part, I’ll have to put the project on hiatus until I have excessive free time again.

1 Like

Where can I see the latest version?

Edit:
Maybe I’ll take a look at it. Although, if the latest version was uploaded a year ago, it would be trumpet…

1 Like

I’ll upload a new version soon. Need to strip out all the experimental messes first :wink:

2 Likes

Here’s an up-to-date version of blender with the base parts of the Curve Bool Modifier only. Meaning the modifier should show up in Blender, but not do anything.
The modifier is implemented in source/blender/nodes/geometry/nodes/node_geo_curve_bool.cc

The short term goal is to take data from CurvesGeometry, turn it into a double linked list (such as CurvePoint), storing all relevant point data, and then turn it back into a CurvesGeometry output, without crashing Blender.

Just copying CurveGeometry was supposed to be an even more simplified step. I’ve copied in a function from subdivide_curves.cc that’s supposed to copy existing curve data, but it causes a segfault. That one had me stumped last time I looked into it. The segfault happens outside of the node’s logic, probably during the update or draw call. If we can’t even copy the data, it’s hard to see how we can create new data from the linked list representation later. So that’s probably a good place to start.

Once we can turn the data from CurveGeometry to a linked list and back again, most of the old code should work again.

If you find a solution, that’d be wonderful. If you can’t , no worries, I’ll just have to pester the curve developer :smiley: . It’s time to finish this either way.

6 Likes

Hello. Sorry for bringing up a dead topic. It’s just that some time ago I made some progress in learning blender and now, remembering this project, I see that it requires a complete census.
That is a good concept. We need this tool.
But from an implementation point of view, the following design needs to be considered:

  1. BVHTree for imaginary curve edges (Support curve component in attribute proximity and attribute transfer nodes).
  2. Bounding box and convex surface curve for curve (contour without self-intersection).
  3. Search or sampling of the closest: curve index, curve segment factor.
  4. Number of self-intersections of the curve field input.
  5. Sample intersection data by curve index and: Closest self-intersection to factor/length. Self-intersection by number in order by length.
  6. Intersection of curves (as in this project now Geometry Node: Curve Intersections)
  7. And finally, after solving all the questions about the behavior of the curves, it is possible, based on all the algorithms tested above, to design this node.
    This is at least to make an implementation of o = N^2 → 2log(n). Right now it meah what for 1000 x 1000 points we need do 10000000 tests. For join 10 curves by 1000 points … oh god … (1000 * 500 * 500 * 500 ... ( 1000 / 2 = 500 just for delete points in intersection area lol)). And of course, you can somehow optimize this so as not to check points that do not exactly intersect. But that’s the point BVHTree

I don’t have time for this (because of my studies and other projects), so these are just notes for the future.

5 Likes

Any update? This is a very needed feature, It would open so many possibilities for modeling by layout.
(and will solve some annoying semi-functional workarounds I am using)

2 Likes

Little piece of my long WIP, I probably wouldn’t be able to share more pics anytime soon.
a 2D boolean would make this thing much more stable…

3 Likes