def box_exact_centered(size, center=(0, 0, 0)): """ A box with the given size, centered around the given point, with a Euclidean distance metric """ args = [ list([Shape.wrap(i) for i in size]), list([Shape.wrap(i) for i in center]) ] return Shape( stdlib.box_exact_centered(tvec3(*[a.ptr for a in args[0]]), tvec3(*[a.ptr for a in args[1]])))
def loft_between(a, b, lower, upper): """ Produces a blended loft between a (at lower.z) and b (at upper.z), with XY coordinates remapped to slide between lower.xy and upper.xy. a and b should be 2D shapes (i.e. invariant along the z axis) """ args = [Shape.wrap(a), Shape.wrap(b), list([Shape.wrap(i) for i in lower]), list([Shape.wrap(i) for i in upper])] return Shape(stdlib.loft_between( args[0].ptr, args[1].ptr, tvec3(*[a.ptr for a in args[2]]), tvec3(*[a.ptr for a in args[3]])))
def box_mitered_centered(size, center=(0, 0, 0)): """ A box with the given size and (optional) center, with edges that will stay sharp if offset. """ args = [ list([Shape.wrap(i) for i in size]), list([Shape.wrap(i) for i in center]) ] return Shape( stdlib.box_mitered_centered(tvec3(*[a.ptr for a in args[0]]), tvec3(*[a.ptr for a in args[1]])))
def scale_xyz(t, s, center=(0, 0, 0)): """ Scales a shape on all three axes, about 0 or an optional offset """ args = [ Shape.wrap(t), list([Shape.wrap(i) for i in s]), list([Shape.wrap(i) for i in center]) ] return Shape( stdlib.scale_xyz(args[0].ptr, tvec3(*[a.ptr for a in args[1]]), tvec3(*[a.ptr for a in args[2]])))
def rounded_box(a, b, r): """ Rounded box with the given bounds and radius (as a 0-1 fraction) """ args = [ list([Shape.wrap(i) for i in a]), list([Shape.wrap(i) for i in b]), Shape.wrap(r) ] return Shape( stdlib.rounded_box(tvec3(*[a.ptr for a in args[0]]), tvec3(*[a.ptr for a in args[1]]), args[2].ptr))
def cone_z(radius, height, base=(0, 0, 0)): """ A cone defined by its radius, height, and (optional) base location """ args = [ Shape.wrap(radius), Shape.wrap(height), list([Shape.wrap(i) for i in base]) ] return Shape( stdlib.cone_z(args[0].ptr, args[1].ptr, tvec3(*[a.ptr for a in args[2]])))
def half_space(norm, point=(0, 0, 0)): """ A plane which divides the world into inside and outside, defined by its normal and a single point on the plane """ args = [ list([Shape.wrap(i) for i in norm]), list([Shape.wrap(i) for i in point]) ] return Shape( stdlib.half_space(tvec3(*[a.ptr for a in args[0]]), tvec3(*[a.ptr for a in args[1]])))
def twirl_z(shape, amount, radius, center=(0, 0, 0)): """ Twirls the shape in the z axis about the (optional) center point """ args = [ Shape.wrap(shape), Shape.wrap(amount), Shape.wrap(radius), list([Shape.wrap(i) for i in center]) ] return Shape( stdlib.twirl_z(args[0].ptr, args[1].ptr, args[2].ptr, tvec3(*[a.ptr for a in args[3]])))
def rotate_z(t, angle, center=(0, 0, 0)): """ Rotate the given shape by an angle in radians The center of rotation is [0 0 0] or specified by the optional argument """ args = [ Shape.wrap(t), Shape.wrap(angle), list([Shape.wrap(i) for i in center]) ] return Shape( stdlib.rotate_z(args[0].ptr, args[1].ptr, tvec3(*[a.ptr for a in args[2]])))
def shear_x_y(t, base, height, offset, base_offset=0): """ Shears a shape on the x axis as a function of y offset = base-offset at base.y offset = offset = base.y + h """ args = [Shape.wrap(t), list([Shape.wrap(i) for i in base]), Shape.wrap(height), Shape.wrap(offset), Shape.wrap(base_offset)] return Shape(stdlib.shear_x_y( args[0].ptr, tvec2(*[a.ptr for a in args[1]]), args[2].ptr, args[3].ptr, args[4].ptr))
def triangle(a, b, c): """ A 2D triangle """ args = [ list([Shape.wrap(i) for i in a]), list([Shape.wrap(i) for i in b]), list([Shape.wrap(i) for i in c]) ] return Shape( stdlib.triangle(tvec2(*[a.ptr for a in args[0]]), tvec2(*[a.ptr for a in args[1]]), tvec2(*[a.ptr for a in args[2]])))
def taper_x_y(shape, base, h, scale, base_scale=1): """ Tapers a shape along the x axis as a function of y width = base-scale at base width = scale at base + [0 h] """ args = [Shape.wrap(shape), list([Shape.wrap(i) for i in base]), Shape.wrap(h), Shape.wrap(scale), Shape.wrap(base_scale)] return Shape(stdlib.taper_x_y( args[0].ptr, tvec2(*[a.ptr for a in args[1]]), args[2].ptr, args[3].ptr, args[4].ptr))
def rounded_rectangle(a, b, r): """ A rectangle with rounded corners """ args = [ list([Shape.wrap(i) for i in a]), list([Shape.wrap(i) for i in b]), Shape.wrap(r) ] return Shape( stdlib.rounded_rectangle(tvec2(*[a.ptr for a in args[0]]), tvec2(*[a.ptr for a in args[1]]), args[2].ptr))
def taper_xy_z(shape, base, height, scale, base_scale=1): """ Tapers a shape in the xy plane as a function of z width = base-scale at base width = scale at base + [0 0 height] """ args = [Shape.wrap(shape), list([Shape.wrap(i) for i in base]), Shape.wrap(height), Shape.wrap(scale), Shape.wrap(base_scale)] return Shape(stdlib.taper_xy_z( args[0].ptr, tvec3(*[a.ptr for a in args[1]]), args[2].ptr, args[3].ptr, args[4].ptr))
def attract_z(shape, locus, radius, exaggerate=1): """ Attracts the shape away from a XY plane based upon a radius r, with optional exaggeration """ args = [ Shape.wrap(shape), list([Shape.wrap(i) for i in locus]), Shape.wrap(radius), Shape.wrap(exaggerate) ] return Shape( stdlib.attract_z(args[0].ptr, tvec3(*[a.ptr for a in args[1]]), args[2].ptr, args[3].ptr))
def pyramid_z(a, b, zmin, height): """ A pyramid defined by its base rectangle, lower Z value, and height """ args = [ list([Shape.wrap(i) for i in a]), list([Shape.wrap(i) for i in b]), Shape.wrap(zmin), Shape.wrap(height) ] return Shape( stdlib.pyramid_z(tvec2(*[a.ptr for a in args[0]]), tvec2(*[a.ptr for a in args[1]]), args[2].ptr, args[3].ptr))
def repel(shape, locus, radius, exaggerate=1): """ Repels the shape away from a point based upon a radius r, with optional exaggeration """ args = [ Shape.wrap(shape), list([Shape.wrap(i) for i in locus]), Shape.wrap(radius), Shape.wrap(exaggerate) ] return Shape( stdlib.repel(args[0].ptr, tvec3(*[a.ptr for a in args[1]]), args[2].ptr, args[3].ptr))
def attract_xz(shape, locus, radius, exaggerate=1): """ Attracts the shape away from line parallel to the Y axis, with a particular radius and optional exaggeration """ args = [ Shape.wrap(shape), list([Shape.wrap(i) for i in locus]), Shape.wrap(radius), Shape.wrap(exaggerate) ] return Shape( stdlib.attract_xz(args[0].ptr, tvec3(*[a.ptr for a in args[1]]), args[2].ptr, args[3].ptr))
def symmetric_y(t): """ Clips the given shape at the y origin, then duplicates the remaining shape reflected on the other side of the origin """ args = [Shape.wrap(t)] return Shape(stdlib.symmetric_y( args[0].ptr))
def clearance(a, b, offset): """ Expands shape b by the given offset then subtracts it from shape a """ args = [Shape.wrap(a), Shape.wrap(b), Shape.wrap(offset)] return Shape(stdlib.clearance(args[0].ptr, args[1].ptr, args[2].ptr))
def offset(a, o): """ Expand or contract a given shape by an offset Positive offsets expand the shape; negative offsets shrink it """ args = [Shape.wrap(a), Shape.wrap(o)] return Shape(stdlib.offset(args[0].ptr, args[1].ptr))
def difference(a, b): """ Subtracts the second shape from the first """ args = [Shape.wrap(a), Shape.wrap(b)] return Shape(stdlib.difference(args[0].ptr, args[1].ptr))
def inverse(a): """ Returns a shape that's the inverse of the input shape """ args = [Shape.wrap(a)] return Shape(stdlib.inverse(args[0].ptr))
def intersection(a, b): """ Returns the intersection of two shapes """ args = [Shape.wrap(a), Shape.wrap(b)] return Shape(stdlib.intersection(args[0].ptr, args[1].ptr))
def union(a, b): """ Returns the union of two shapes """ args = [Shape.wrap(a), Shape.wrap(b)] return Shape(stdlib._union(args[0].ptr, args[1].ptr))
def blend_rough(a, b, m): """ Blends two shapes by the given amount, using a fast-but-rough CSG approximation that may not preserve gradients """ args = [Shape.wrap(a), Shape.wrap(b), Shape.wrap(m)] return Shape(stdlib.blend_rough(args[0].ptr, args[1].ptr, args[2].ptr))
def polygon(r, n, center=(0, 0)): """ A polygon with center-to-vertex distance r and n sides """ args = [Shape.wrap(r), n, list([Shape.wrap(i) for i in center])] return Shape( stdlib.polygon(args[0].ptr, args[1], tvec2(*[a.ptr for a in args[2]])))
def shell(a, offset): """ Returns a shell of a shape with the given offset """ args = [Shape.wrap(a), Shape.wrap(offset)] return Shape(stdlib.shell(args[0].ptr, args[1].ptr))
def blend_expt(a, b, m): """ Blends two shapes by the given amount using exponents """ args = [Shape.wrap(a), Shape.wrap(b), Shape.wrap(m)] return Shape(stdlib.blend_expt(args[0].ptr, args[1].ptr, args[2].ptr))
def morph(a, b, m): """ Morphs between two shapes. m = 0 produces a, m = 1 produces b """ args = [Shape.wrap(a), Shape.wrap(b), Shape.wrap(m)] return Shape(stdlib.morph(args[0].ptr, args[1].ptr, args[2].ptr))