Skip to content

linkcad.libgraph

High-performance boolean geometry engine for polygon operations. Wraps the native libgraph library.

from linkcad.v1.libgraph import (
ShapeProcessor, ShapeGroup, Operation, FillRule, HolesMode, Result,
boolean_and, boolean_or, boolean_xor, boolean_difference,
succeeded, failed,
)

Convenience Functions

For simple two-polygon operations, use these functions directly. Each accepts vertex lists as sequences of (x, y) tuples and returns a list of result polygons (each a list of (x, y) tuples). They raise RuntimeError if the operation fails.

from linkcad.v1.libgraph import boolean_and, boolean_or, boolean_xor, boolean_difference
square = [(0, 0), (10, 0), (10, 10), (0, 10)]
triangle = [(5, 5), (15, 5), (10, 15)]
result = boolean_and(square, triangle) # intersection
result = boolean_or(square, triangle) # union
result = boolean_xor(square, triangle) # exclusive OR
result = boolean_difference(square, triangle) # square minus triangle
FunctionDescription
boolean_and(vtx1, vtx2, fill_rule=FillRule.EvenOdd)Intersection of two polygons
boolean_or(vtx1, vtx2, fill_rule=FillRule.EvenOdd)Union of two polygons
boolean_xor(vtx1, vtx2, fill_rule=FillRule.EvenOdd)Symmetric difference of two polygons
boolean_difference(vtx1, vtx2, fill_rule=FillRule.EvenOdd)Difference — regions in vtx1 but not vtx2

Coordinates are integers. If your geometry is in database units, that is already the case.

ShapeProcessor

For multi-polygon operations, or when you need control over the fill rule and hole handling, use ShapeProcessor:

from linkcad.v1.libgraph import (
FillRule, HolesMode, Operation, ShapeGroup, ShapeProcessor, succeeded,
)
sp = ShapeProcessor()
sp.add_polygon(ShapeGroup.A, [(0, 0), (10, 0), (10, 10), (0, 10)])
sp.add_polygon(ShapeGroup.B, [(5, 5), (15, 5), (10, 15)])
result = sp.execute(Operation.And, FillRule.NonZero, HolesMode.Link)
if not succeeded(result):
raise RuntimeError(f"Boolean failed: {result}")
polygons = []
while sp.has_next_polygon():
poly = sp.get_next_polygon()
if poly is None:
break
polygons.append(poly)
Property / MethodDescription
ShapeProcessor(granularity=1)Create a new processor
sp.add_polygon(group, vertices, combine_with_previous=False)Add a polygon to group A, B, or AB. Returns an internal shape ID
sp.execute(operation, fill_mode=FillRule.NonZero, hole_mode=HolesMode.Link, process_vertically=False)Run the operation; returns a Result
sp.has_next_polygon()Whether more result polygons are available
sp.get_next_polygon()Next result polygon, or None when exhausted
sp.get_next_hole()Next hole of the current polygon, or None. Only meaningful with HolesMode.Extract
sp.clear()Discard all polygons and prepare for reuse
sp.emptyTrue if the processor holds no polygons
sp.set_license(license)Set a license key; returns True if valid

execute() returns a Result; there is no sp.result attribute. Test it with the module-level helpers:

FunctionDescription
succeeded(result)True for SuccessModified or SuccessNotModified
failed(result)True for any error result

Set combine_with_previous=True on add_polygon() to attach a sub-path — a hole, or a second contour — to the polygon added just before it.

Enums

ShapeGroup

Determines which operand a polygon belongs to.

ValueDescription
ShapeGroup.AFirst operand
ShapeGroup.BSecond operand
ShapeGroup.ABBelongs to both operands simultaneously

Operation

The boolean operation to perform.

ValueDescription
Operation.OrUnion (A ∪ B)
Operation.AndIntersection (A ∩ B)
Operation.XorSymmetric difference (A △ B)
Operation.AMinusBDifference (A − B)
Operation.BMinusADifference (B − A)
Operation.SplitOnBSplit the polygons in A along the boundary of B
Operation.NoopSimplify the polygons in A without combining them
Operation.KeepInternalEdgesUnion while keeping internal edges
Operation.OrNoMergeUnion without merging internal edges
Operation.AndNoMergeIntersection without merging internal edges
Operation.XorNoMergeXOR without merging internal edges
Operation.AMinusBNoMergeA − B without merging internal edges
Operation.BMinusANoMergeB − A without merging internal edges

FillRule

Controls how overlapping polygon edges determine “inside” versus “outside”.

ValueDescription
FillRule.NonZeroNon-zero winding rule
FillRule.EvenOddEven-odd rule (fastest)
FillRule.NonZeroGroupNon-zero winding rule applied per group
FillRule.EvenOddGroupEven-odd rule applied per group
FillRule.OuterGroupFill only the outermost area

HolesMode

Controls how holes in output polygons are represented.

ValueDescription
HolesMode.ExtractReturn holes separately, via get_next_hole()
HolesMode.LinkConnect holes to the outer boundary with zero-width bridges
HolesMode.SplitSplit the result into simple polygons with no holes
HolesMode.KeepKeep holes as separate polygons

Result

Status returned by ShapeProcessor.execute().

ValueDescription
Result.SuccessModifiedSucceeded; the geometry changed
Result.SuccessNotModifiedSucceeded; the geometry was already in the requested form
Result.FailedOperation failed
Result.CancelledOperation was cancelled
Result.NoLicenseInvalid license key
Result.InvalidFillRuleFill rule not valid for this operation
Result.InvalidHolesModeHoles mode not valid for this operation