Bases: object
Constructive Solid Geometry (CSG) is a modeling technique that uses Boolean operations like union and intersection to combine 3D solids. This library implements CSG operations on meshes elegantly and concisely using BSP trees, and is meant to serve as an easily understandable implementation of the algorithm. All edge cases involving overlapping coplanar polygons in both solids are correctly handled.
Example usage:
from csg.core import CSG
cube = CSG.cube();
sphere = CSG.sphere({'radius': 1.3});
polygons = cube.subtract(sphere).toPolygons();
## Implementation Details
All CSG operations are implemented in terms of two functions, clipTo() and invert(), which remove parts of a BSP tree inside another BSP tree and swap solid and empty space, respectively. To find the union of a and b, we want to remove everything in a inside b and everything in b inside a, then combine polygons from a and b into one solid:
a.clipTo(b);
b.clipTo(a);
a.build(b.allPolygons());
The only tricky part is handling overlapping coplanar polygons in both trees. The code above keeps both copies, but we need to keep them in one tree and remove them in the other tree. To remove them from b we can clip the inverse of b against a. The code for union now looks like this:
a.clipTo(b);
b.clipTo(a);
b.invert();
b.clipTo(a);
b.invert();
a.build(b.allPolygons());
Subtraction and intersection naturally follow from set operations. If union is A | B, subtraction is A - B = ~(~A | B) and intersection is A & B = ~(~A | ~B) where ~ is the complement operator.
## License
Copyright (c) 2011 Evan Wallace (http://madebyevan.com/), under the MIT license.
Python port Copyright (c) 2012 Tim Knip (http://www.floorplanner.com), under the MIT license.
Construct an axis-aligned solid cuboid. Optional parameters are center and radius, which default to [0, 0, 0] and [1, 1, 1]. The radius can be specified using a single number or a list of three numbers, one for each axis.
Example code:
cube = CSG.cube(
center=[0, 0, 0],
radius=1
)
Returns a cylinder.
start (list): Start of cylinder, default [0, -1, 0].
end (list): End of cylinder, default [0, 1, 0].
radius (float): Radius of cylinder, default 1.0.
slices (int): Number of slices, default 16.
Return a new CSG solid representing space both this solid and in the solid csg. Neither this solid nor the solid csg are modified.:
A.intersect(B)
+-------+
| |
| A |
| +--+----+ = +--+
+----+--+ | +--+
| B |
| |
+-------+
Return a new CSG solid with solid and empty space switched. This solid is not modified.
Returns a sphere.
center (list): Center of sphere, default [0, 0, 0].
radius (float): Radius of sphere, default 1.0.
slices (int): Number of slices, default 16.
stacks (int): Number of stacks, default 8.
Return a new CSG solid representing space in this solid but not in the solid csg. Neither this solid nor the solid csg are modified.:
A.subtract(B)
+-------+ +-------+
| | | |
| A | | |
| +--+----+ = | +--+
+----+--+ | +----+
| B |
| |
+-------+
Return a new CSG solid representing space in either this solid or in the solid csg. Neither this solid nor the solid csg are modified.:
A.union(B)
+-------+ +-------+
| | | |
| A | | |
| +--+----+ = | +----+
+----+--+ | +----+ |
| B | | |
| | | |
+-------+ +-------+