Object Construction

Creation of complex objects from humble building blocks:

Box :
A simple box.
Cylinder :
A cylinder rotated around an origin and axis.
PolygonExtrusion :
Extrusion of a petrify.space.PlanarPolygon into a three-dimensional shape.
Spun :
A series of profiles spun around an axis and connected together.
Extrusion :
Complex layered objects with polygon slices.
Node :
Arbitrary construction of geometry via polygons.

All of the above classes subclass Node, which allows object joining via CSG union and difference operations.

class petrify.solid.Box(origin, size)[source]

Bases: petrify.solid.Extrusion

A simple three-dimensional box:

>>> cube = Box(Point3.origin, Vector3(1, 1, 1))
origin :
a petrify.space.Point3 defining the origin of this box.
size :
a petrify.space.Vector3 of the box’s size.
as_unit(unit)

Declare a unit for unitless geometry:

>>> Box(Point3(0, 0, 0), Vector3(1, 1, 1)).as_unit('inch').units
<Unit('inch')>
envelope()

Returns the axis-aligned bounding box for this shape:

>>> parallelogram = Polygon2([              Point2(0, 0),             Point2(0, 1),             Point2(1, 2),             Point2(1, 1)          ])
>>> extruded = PolygonExtrusion(                        PlanarPolygon(Basis.xy, parallelogram),             Vector3(0, 0, 1)                                 )
>>> extruded.envelope()
Box(Point3(0, 0, 0), Vector3(1, 2, 1))
generate_polygons()

Calculates all polygons for this shape.

render(**properties)

Create a pythreejs visualization of this geometry for use in interactive notebooks.

ring(bottom, top)

Builds a ring from two slices.

rotate(axis, theta)

Rotate this geometry around the given axis vector by theta radians.

rotate_at(origin, axis, theta)

Rotate this geometry about the given origin and axis by theta radians.

scale(scale)

Scale this geometry by the provided scale vector.

translate(delta)

Translate this geometry by the provided translate vector.

class petrify.solid.Collection(nodes)[source]

Bases: petrify.solid.Node

Collection of multiple objects. Self-intersection is unsupported, but lack of intersection is not enforced:

>>> c = Collection([         Box(Point3.origin, Vector3(1, 1, 1)),             Box(Point3(0, 5, 0), Vector3(1, 1, 1))        ])
as_unit(unit)

Declare a unit for unitless geometry:

>>> Box(Point3(0, 0, 0), Vector3(1, 1, 1)).as_unit('inch').units
<Unit('inch')>
envelope()

Returns the axis-aligned bounding box for this shape:

>>> parallelogram = Polygon2([              Point2(0, 0),             Point2(0, 1),             Point2(1, 2),             Point2(1, 1)          ])
>>> extruded = PolygonExtrusion(                        PlanarPolygon(Basis.xy, parallelogram),             Vector3(0, 0, 1)                                 )
>>> extruded.envelope()
Box(Point3(0, 0, 0), Vector3(1, 2, 1))
render(**properties)[source]

Create a pythreejs visualization of this geometry for use in interactive notebooks.

rotate(axis, theta)

Rotate this geometry around the given axis vector by theta radians.

rotate_at(origin, axis, theta)

Rotate this geometry about the given origin and axis by theta radians.

scale(scale)

Scale this geometry by the provided scale vector.

translate(delta)

Translate this geometry by the provided translate vector.

class petrify.solid.Cylinder(origin, axis, radius, segments=10)[source]

Bases: petrify.solid.PolygonExtrusion

A three-dimensional cylinder extruded along the given axis:

>>> axle = Cylinder(Point3.origin, Vector3.basis.y * 10, 1.0)

The actual cylinder is approximated by creating many segments of quads to simulate a circular shape.

origin :
a petrify.space.Point3 defining the origin of this cylinder.
axis :
a petrify.space.Vector3 that defines the axis the cylinder will be “spun about”. The magnitude of the axis is the height of the cylinder.
radius :
the radius of the cylinder.
segments :
the number of quads to use when approximating the cylinder.
as_unit(unit)

Declare a unit for unitless geometry:

>>> Box(Point3(0, 0, 0), Vector3(1, 1, 1)).as_unit('inch').units
<Unit('inch')>
envelope()

Returns the axis-aligned bounding box for this shape:

>>> parallelogram = Polygon2([              Point2(0, 0),             Point2(0, 1),             Point2(1, 2),             Point2(1, 1)          ])
>>> extruded = PolygonExtrusion(                        PlanarPolygon(Basis.xy, parallelogram),             Vector3(0, 0, 1)                                 )
>>> extruded.envelope()
Box(Point3(0, 0, 0), Vector3(1, 2, 1))
generate_polygons()

Calculates all polygons for this shape.

height()[source]

The height of this cylinder along its axis.

render(**properties)

Create a pythreejs visualization of this geometry for use in interactive notebooks.

ring(bottom, top)

Builds a ring from two slices.

rotate(axis, theta)

Rotate this geometry around the given axis vector by theta radians.

rotate_at(origin, axis, theta)

Rotate this geometry about the given origin and axis by theta radians.

scale(scale)

Scale this geometry by the provided scale vector.

translate(delta)

Translate this geometry by the provided translate vector.

class petrify.solid.Extrusion(slices)[source]

Bases: petrify.solid.Node

A three-dimensional object built from rings of petrify.space.PlanarPolygon objects with the same number of points at each ring:

>>> parallelogram = Polygon2([          Point2(0, 0),         Point2(0, 1),         Point2(1, 2),         Point2(1, 1)      ])
>>> square = Polygon2([            Point2(0, 0),                  Point2(0, 1),                  Point2(1, 1),                  Point2(1, 0)               ])
>>> object = Extrusion([                                        PlanarPolygon(Basis.xy, parallelogram),                     PlanarPolygon(Basis.xy + Vector3(0, 0, 1), square),      ])

The rings must all have the same number of vertices. Quads are generated to connect each ring, and the bottom and top layers then complete the shape.

rings :
A list of petrify.space.PlanarPolygon objects defining each ring of the final shape.
as_unit(unit)

Declare a unit for unitless geometry:

>>> Box(Point3(0, 0, 0), Vector3(1, 1, 1)).as_unit('inch').units
<Unit('inch')>
envelope()

Returns the axis-aligned bounding box for this shape:

>>> parallelogram = Polygon2([              Point2(0, 0),             Point2(0, 1),             Point2(1, 2),             Point2(1, 1)          ])
>>> extruded = PolygonExtrusion(                        PlanarPolygon(Basis.xy, parallelogram),             Vector3(0, 0, 1)                                 )
>>> extruded.envelope()
Box(Point3(0, 0, 0), Vector3(1, 2, 1))
generate_polygons()[source]

Calculates all polygons for this shape.

render(**properties)

Create a pythreejs visualization of this geometry for use in interactive notebooks.

ring(bottom, top)[source]

Builds a ring from two slices.

rotate(axis, theta)

Rotate this geometry around the given axis vector by theta radians.

rotate_at(origin, axis, theta)

Rotate this geometry about the given origin and axis by theta radians.

scale(scale)

Scale this geometry by the provided scale vector.

translate(delta)

Translate this geometry by the provided translate vector.

class petrify.solid.Node(polygons)[source]

Bases: object

Convenience class for performing CSG operations on geometry.

All instances of this class can be added and subtracted via the built-in __add__ and __sub__ methods:

>>> a = Box(Point3(0, 0, 0), Vector3(1, 1, 1))
>>> b = Box(Point3(0, 0, 0.5), Vector3(1, 1, 1))
>>> union = a + b
>>> difference = a - b

All nodes also support scaling and translation via vectors:

>>> box = Box(Point3(0, 0, 0), Vector3(1, 1, 1))
>>> (box * Vector3(2, 1, 1)).envelope()
Box(Point3(0, 0, 0), Vector3(2, 1, 1))
>>> (box + Vector3(1, 0, 1)).envelope()
Box(Point3(1.0, 0.0, 1.0), Vector3(1.0, 1.0, 1.0))

To support unit operations via pint, multiplication and division by a scalar are also supported:

>>> (box * 2).envelope()
Box(Point3(0, 0, 0), Vector3(2, 2, 2))
>>> (box / 2).envelope()
Box(Point3(0.0, 0.0, 0.0), Vector3(0.5, 0.5, 0.5))
>>> from petrify import u
>>> (box * u.mm).units
<Unit('millimeter')>
as_unit(unit)[source]

Declare a unit for unitless geometry:

>>> Box(Point3(0, 0, 0), Vector3(1, 1, 1)).as_unit('inch').units
<Unit('inch')>
envelope()[source]

Returns the axis-aligned bounding box for this shape:

>>> parallelogram = Polygon2([              Point2(0, 0),             Point2(0, 1),             Point2(1, 2),             Point2(1, 1)          ])
>>> extruded = PolygonExtrusion(                        PlanarPolygon(Basis.xy, parallelogram),             Vector3(0, 0, 1)                                 )
>>> extruded.envelope()
Box(Point3(0, 0, 0), Vector3(1, 2, 1))
render(**properties)[source]

Create a pythreejs visualization of this geometry for use in interactive notebooks.

rotate(axis, theta)[source]

Rotate this geometry around the given axis vector by theta radians.

rotate_at(origin, axis, theta)[source]

Rotate this geometry about the given origin and axis by theta radians.

scale(scale)[source]

Scale this geometry by the provided scale vector.

translate(delta)[source]

Translate this geometry by the provided translate vector.

class petrify.solid.PolygonExtrusion(footprint, direction)[source]

Bases: petrify.solid.Extrusion

Extrusion of a simple two-dimensional polygon into three-dimensional space:

>>> triangle = Polygon2([          Point2(0, 0),                 Point2(0, 2),                 Point2(1, 1)              ])
>>> planar = PlanarPolygon(Basis.xy, triangle)
>>> extruded = PolygonExtrusion(planar, Vector3(0, 0, 1))
footprint :
a petrify.space.PlanarPolygon object describing a the polygon that will be extruded in the given direction
direction :
A petrify.space.Vector3 defining which direction the polygon will be linearly extruded into.
as_unit(unit)

Declare a unit for unitless geometry:

>>> Box(Point3(0, 0, 0), Vector3(1, 1, 1)).as_unit('inch').units
<Unit('inch')>
envelope()

Returns the axis-aligned bounding box for this shape:

>>> parallelogram = Polygon2([              Point2(0, 0),             Point2(0, 1),             Point2(1, 2),             Point2(1, 1)          ])
>>> extruded = PolygonExtrusion(                        PlanarPolygon(Basis.xy, parallelogram),             Vector3(0, 0, 1)                                 )
>>> extruded.envelope()
Box(Point3(0, 0, 0), Vector3(1, 2, 1))
generate_polygons()

Calculates all polygons for this shape.

render(**properties)

Create a pythreejs visualization of this geometry for use in interactive notebooks.

ring(bottom, top)

Builds a ring from two slices.

rotate(axis, theta)

Rotate this geometry around the given axis vector by theta radians.

rotate_at(origin, axis, theta)

Rotate this geometry about the given origin and axis by theta radians.

scale(scale)

Scale this geometry by the provided scale vector.

translate(delta)

Translate this geometry by the provided translate vector.

class petrify.solid.Spun(axis, start, turns)[source]

Bases: petrify.solid.Node

A three-dimensional object built from two-dimensional profiles rotated uniformly around an axis:

>>> axis = Vector3.basis.z
>>> start = Vector3.basis.y
>>> tri = Polygon2([           Point2(0, 0),              Point2(1, 1),              Point2(0, 2)           ])
>>> spun = Spun(axis, start, [tri] * 5)

The y-axis of the profile is used as the rotational axis when building the solid.

as_unit(unit)

Declare a unit for unitless geometry:

>>> Box(Point3(0, 0, 0), Vector3(1, 1, 1)).as_unit('inch').units
<Unit('inch')>
envelope()

Returns the axis-aligned bounding box for this shape:

>>> parallelogram = Polygon2([              Point2(0, 0),             Point2(0, 1),             Point2(1, 2),             Point2(1, 1)          ])
>>> extruded = PolygonExtrusion(                        PlanarPolygon(Basis.xy, parallelogram),             Vector3(0, 0, 1)                                 )
>>> extruded.envelope()
Box(Point3(0, 0, 0), Vector3(1, 2, 1))
generate_polygons()[source]

Calculates all polygons for this shape.

render(**properties)

Create a pythreejs visualization of this geometry for use in interactive notebooks.

rotate(axis, theta)

Rotate this geometry around the given axis vector by theta radians.

rotate_at(origin, axis, theta)

Rotate this geometry about the given origin and axis by theta radians.

rotation(a, b)[source]

Builds a ring from two slices.

scale(scale)

Scale this geometry by the provided scale vector.

translate(delta)

Translate this geometry by the provided translate vector.

class petrify.solid.Transformed(prior, matrix)[source]

Bases: petrify.solid.Node

Geometry that has had a matrix transform applied to it.

You probably should use methods on Node instead of instantiating this class directly.

as_unit(unit)

Declare a unit for unitless geometry:

>>> Box(Point3(0, 0, 0), Vector3(1, 1, 1)).as_unit('inch').units
<Unit('inch')>
envelope()

Returns the axis-aligned bounding box for this shape:

>>> parallelogram = Polygon2([              Point2(0, 0),             Point2(0, 1),             Point2(1, 2),             Point2(1, 1)          ])
>>> extruded = PolygonExtrusion(                        PlanarPolygon(Basis.xy, parallelogram),             Vector3(0, 0, 1)                                 )
>>> extruded.envelope()
Box(Point3(0, 0, 0), Vector3(1, 2, 1))
render(**properties)

Create a pythreejs visualization of this geometry for use in interactive notebooks.

rotate(axis, theta)

Rotate this geometry around the given axis vector by theta radians.

rotate_at(origin, axis, theta)

Rotate this geometry about the given origin and axis by theta radians.

scale(scale)

Scale this geometry by the provided scale vector.

translate(delta)

Translate this geometry by the provided translate vector.

class petrify.solid.Union(parts)[source]

Bases: petrify.solid.Node

Defines a union of a list of parts:

>>> many = Union([                                 Box(Point3(0, 0, 0), Vector3(10, 1, 1)),         Box(Point3(0, 0, 0), Vector3(1, 10, 1)),         Box(Point3(0, 0, 0), Vector3(1, 1, 10)),     ])
as_unit(unit)

Declare a unit for unitless geometry:

>>> Box(Point3(0, 0, 0), Vector3(1, 1, 1)).as_unit('inch').units
<Unit('inch')>
envelope()

Returns the axis-aligned bounding box for this shape:

>>> parallelogram = Polygon2([              Point2(0, 0),             Point2(0, 1),             Point2(1, 2),             Point2(1, 1)          ])
>>> extruded = PolygonExtrusion(                        PlanarPolygon(Basis.xy, parallelogram),             Vector3(0, 0, 1)                                 )
>>> extruded.envelope()
Box(Point3(0, 0, 0), Vector3(1, 2, 1))
render(**properties)

Create a pythreejs visualization of this geometry for use in interactive notebooks.

rotate(axis, theta)

Rotate this geometry around the given axis vector by theta radians.

rotate_at(origin, axis, theta)

Rotate this geometry about the given origin and axis by theta radians.

scale(scale)

Scale this geometry by the provided scale vector.

translate(delta)

Translate this geometry by the provided translate vector.

class petrify.solid.View(node, **data)[source]

Bases: petrify.solid.Node

Apply view properties to geometry.

>>> v = View(Box(Point3.origin, Vector3(1, 1, 1)), wireframe=True)
as_unit(unit)

Declare a unit for unitless geometry:

>>> Box(Point3(0, 0, 0), Vector3(1, 1, 1)).as_unit('inch').units
<Unit('inch')>
envelope()

Returns the axis-aligned bounding box for this shape:

>>> parallelogram = Polygon2([              Point2(0, 0),             Point2(0, 1),             Point2(1, 2),             Point2(1, 1)          ])
>>> extruded = PolygonExtrusion(                        PlanarPolygon(Basis.xy, parallelogram),             Vector3(0, 0, 1)                                 )
>>> extruded.envelope()
Box(Point3(0, 0, 0), Vector3(1, 2, 1))
render(**properties)

Create a pythreejs visualization of this geometry for use in interactive notebooks.

rotate(axis, theta)

Rotate this geometry around the given axis vector by theta radians.

rotate_at(origin, axis, theta)

Rotate this geometry about the given origin and axis by theta radians.

scale(scale)

Scale this geometry by the provided scale vector.

translate(delta)

Translate this geometry by the provided translate vector.

petrify.solid.perpendicular(axis)[source]

Return a vector that is perpendicular to the given axis.