Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Demonstrates one approach to #30. Just parking this here for now, I'm not yet sure this is the way, or if it's even worthwhile to solve this. From the issue:
I think there's actually no speedup to be had as long as we're using Clipper (I would guess it uses equivalently fast spatial sorting internally)—but we can limit peak memory usage so we don't run out. Here we try the approach that KLayout takes: cover the geometry with tiles and do the operation on each tile. It's a pretty naive implementation, not doing anything clever: Build a spatial index (RTree) for each set of polygons, find the polygons touching each 1mm tile (~100 polygons per tile), intersect the polygons in each tile, then collect the results. To benchmark we create two sets of
n
circle polygons in a grid, offset from each other, then take their intersection. After compilation:Clipping 1 million pairs of circles directly would use too much memory for my laptop, but we can do it with tiles.
(Oops, big allocation at the end just for concatenating the results into a single array, which could be avoided.)
Hard to compare directly, but KLayout seems to do XOR at least 2x faster than our intersection (and Clipper XOR takes 25-50% longer than intersection here).
Tile size doesn't matter much but 100-1000 polygons per tile seems reasonable. Spatial indexing and querying are always much faster than clipping.
It seems Clipper isn't thread-safe so multithreading doesn't help, e.g.:
(If only we had pure Julia clipping... #35)
A simple multiprocessing version with
pmap
in place ofmap
does give a speedup for large enough batch size (I can get 2x with 2 cores, anyway), although you'd probably want to write it so that the workers can load only Clipper.Note on healing: Results of operations between polygons touching tile edges may be duplicated, so we also take the union of results touching tile edges if the user calls with
heal=true
. If such results don't themselves touch tile edges, they won't be healed (I think the KLayout implementation also has this issue). [Haven't tested healing in this initial demo.]I think the question is whether we even need this for realistic use cases (e.g. full-layout XOR) and if we do, whether we need to be able to do this in DeviceLayout rather than KLayout, which is faster.