-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add 2D polygon boolean operations in Geometry singleton #28987
Conversation
As discussed in PR meeting today, the added feature seems good. #29003 needs to be solved first, and then this PR should be rebased to squash commits, but otherwise it should be good to merge. |
#29003 is merged, so you can eventually rebase on top of it/master to fix the build. |
Clipper 6.4.2 is used internally to perform polypaths clipping, as well as inflating/deflating polypaths. The following methods were added: ``` Geometry.merge_polygons_2d(poly_a, poly_b) # union Geometry.clip_polygons_2d(poly_a, poly_b) # difference Geometry.intersect_polygons_2d(poly_a, poly_b) # intersection Geometry.exclude_polygons_2d(poly_a, poly_b) # xor Geometry.clip_polyline_with_polygon_2d(poly_a, poly_b) Geometry.intersect_polyline_with_polygon_2d(poly_a, poly_b) Geometry.offset_polygon_2d(polygon, delta) # inflate/deflate Geometry.offset_polyline_2d(polyline, delta) # returns polygons // This one helps to implement CSG-like behaviour: Geometry.transform_points_2d(points, transform) ``` All the methods return an array of polygons/polylines. The resulting polygons could possibly be holes which could be checked with `Geometry.is_polygon_clockwise()` which was exposed to scripting as well.
I wanted to add some more input validation, but seems like Clipper can handle most input without throwing errors (the API is exposed in such a way that misuse is kept to a minimum, or eliminated completely), so I'm satisfied with it. |
Thanks for the awesome features! |
Many thanks |
Is there a way to merge a list of polygons? So is this a possible missing feature? Or am Doing things wrong? |
|
Was wondering the same, but haven't had to approach the problem yet myself. I imagine it might be worked around by tacking on a point to one polygon that would create intersection before performing the union. My near term use cases would mainly be on the tool end. Merging polygon geometries for colliders and such, as part of an offline optimization. Not there yet though, but my intuition is that it would be useful sometimes to have a direct method that would merge/union polygons that don't intersect. I have designs for a much further out project (12-14 months) that would do many things with dynamic 2D geometry with polygons. So these 2D geometric additions so far are quite nice. 👍 When or if a more concrete need emerges I'll be sure to give you ping on it, or append it to any existing issue. |
To be honest, these features are much more powerful than I thought, ♥thank you very much♥ |
Thank you for the new features!! Wondering did something happen to Geometry.transform_points_2d()? Wanted to use it to convert from local -> global coordinates on v3.2 Beta2: EDIT: Just found PR #31865 where you removed this function and suggested the use of xform() from Transform2D. Thanks! |
@Xrayez Hi, sorry for disturbing you, I am using these APIs, I would like to ask if the arrays returned by these APIs are distributed in a tree structure (like this: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/PolyTree/_Body.htm) |
@Jiaming00 the internal implementation does use You'll have better luck by checking out godot-clipper module if you need more control over the many parameters which Clipper provides. |
is there any documentation of how i can get back the data you would have from a boolean as in a list of polygons that now represent the original shape with a hole in it? I can't seem to find documentation on how to use this i'm trying to get triangles back to draw csv data... so if i could define a 2D shape, then cut a hole in it resulting in triangles i can use as a mesh |
@RichardEllicott Godot only provides core support for geometry operations. I think you're looking for a method for decomposing polygons with holes into triangles/convex. Unfortunately, Godot does not have robust methods to deal with such input (yet?). If you're comfortable compiling the engine from source, you can look at the Goost project which provides more functionality revolving around geometry operations (and more). You may also consider opening a thread in Goost for discussion purposes, regardless of whether you're planning to use Goost.
I've recently implemented boolean nodes in 2D which are equivalent to CSG in Godot if you'd like to take a look: goostengine/goost#39. That includes In any case, consider documenting your use case at godotengine/godot-proposals#913 as well if you'd like to see those features to be implemented in Godot. EDIT: you can also download precompiled Godot+Goost binaries if you'd like to give those classes a try. |
okay thanks for your reply and advice, i will take a look, i will post my reason why in the suggested proposal |
Hi, sorry to bother you. I was looking back at this old project that was stuck needing a boolean. Nothing in the goost libarary seems to fit the bill. What you say "I think you're looking for a method for decomposing polygons with holes into triangles/convex" ...... that sounds logical i get that, i mean even decompose a polygon and a hole into concave shapes is also fine i can't seem to find this, not aware of any other libraries? If we found it, it really should go in the engine as this is a task like triangulation, people don't want to do this manually i'm reading this document, page 9, https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf so i just wanted to run that by you in case you had anything to add, cheers |
@RichardEllicott hi, I'm glad that you're still interested in this! As I said, feel free to ask a question at Goost discussions, I'd appreciate this, because Godot is not currently capable of doing this kind of triangulation. And this PR is not really the place for providing complex solutions. But you're probably looking for If you need a more elaborate response, again feel free to ask a question.
I share your vision and desire, but unlike in Goost, I cannot decide what goes into Godot core. |
Important prerequisite: #29003 ✔️
Supercedes #23559.
Closes #22275.
This is a more compact, easy to use implementation for boolean polygon/polyline operations:
Boolean polygon vs polygon operations
Boolean polyline vs polygon operations
Polyline/Polygon grow/shrink operations
All the methods return an array of polygons/polylines. The resulting polygons could possibly be holes which could be checked with
Geometry.is_polygon_clockwise()
.Could be easily used both within engine and via scripting, so that it can be useful for improving other areas like navigation and path finding.
Clipper 6.4.2 is used internally to perform polypaths clipping, as well as inflating/deflating polypaths.
The implementation is mostly forward compatible with Clipper 10.0.0.
Issues
#17319 - currently prevents Clipper from being compiled in release mode, Clipper should be patched to optionally disable exceptions (see #29003),which should help #25262fixed by #29032.Test project
geometry-clipper-test.zip