14. API - Rendering¶
The render module defines a series of classes for interpreting and rendering models in the Wavefront object format.
Note
All items in this module are available from the picraft
namespace
without having to import picraft.render
directly.
The following items are defined in the module:
14.1. Model¶
-
class
picraft.render.
Model
(source, swap_yz=False)[source]¶ Represents a three-dimensional model parsed from an Alias|Wavefront object file (.obj extension). The constructor accepts a source parameter which can be a filename or file-like object (in the latter case, this must be opened in text mode such that it returns unicode strings rather than bytes in Python 3).
The optional swap_yz parameter specifies whether the Y and Z coordinates of each vertex in the model will be swapped; some models require this to render correctly in Minecraft, some do not.
The
faces
attribute provides access to all object faces extracted from the file’s content. Thematerials
property enumerates all material names used by the object. Thegroups
mapping maps group names to subsets of the available faces. Thebounds
attribute provides a range describing the bounding box of the unscaled model.Finally, the
render()
method can be used to easily render the object in the Minecraft world at the specified scale, and with a given material mapping.-
render
(scale=1.0, materials=None, groups=None)[source]¶ Renders the model as a
dict
mapping vectors to block types. Effectively this rounds the vertices of each face to integers (after applying the scale multiplier, which defaults to 1.0), then callsfilled()
andlines()
to obtain the complete coordinates of each face.Each coordinate then needs to be mapped to a block type. By default the material name is simply passed to the
Block
constructor. This assumes that material names are valid Minecraft block types (seeNAMES
).You can override this mechanism with the materials parameter. This can be set to a mapping (e.g. a
dict
) which maps material names toBlock
instances. For example:from picraft import Model, Block m = Model('airboat.obj') d = m.render(materials={ 'bluteal': Block('diamond_block'), 'bronze': Block('gold_block'), 'dkdkgrey': Block((64, 64, 64)), 'dkteal': Block('#000080'), 'red': Block('#ff0000'), 'silver': Block.from_color('#ffffff'), 'black': Block(id=35, data=15), None: Block('stone'), })
Note
Some object files may include faces with no associated material. In this case you will need to map
None
to a block type, as in the example above.Alternatively, materials can be a callable which will be called with the
ModelFace
being rendered, which should return a block type. The following is equivalent to the default behaviour:from picraft import Model, Block m = Model('airboat.obj') d = m.render(materials=lambda f: Block(f.material))
If you simply want to preview a shape without bothering with any material mapping you can use this method to map any face to a single material (in this case stone):
from picraft import Model, Block m = Model('airboat.obj') d = m.render(materials=lambda f: Block('stone'))
If the materials mapping or callable returns
None
instead of aBlock
instance, the corresponding blocks will not be included in the result. This is a simple mechanism for excluding parts of a model. The other mechanism for achieving this is the groups parameter which specifies which sub-components of the model should be rendered. This can be specified as a string (indicating that only that sub-component should be rendered) or as a sequence of strings (indicating that all specified sub-components should be rendered).The result is a mapping of
Vector
toBlock
instances. Rendering the result in the main world should be as trivial as the following code:from picraft import World, Model w = World() m = Model('airboat.obj').render(scale=2.0) with w.connection.batch_start(): for v, b in m.items(): w.blocks[v] = b
Of course, you may choose to further transform the result first. This can be accomplished by modifying the vectors as you set them:
from picraft import World, Model, Y w = World() m = Model('airboat.obj').render(scale=2.0) with w.connection.batch_start(): for v, b in m.items(): w.blocks[v + 10*Y] = b
Alternatively you may choose to use a dict-comprehension:
from picraft import Model, Vector m = Model('airboat.obj').render(scale=2.0) offset = Vector(y=10) m = {v + offset: b for v, b in m.items()}
Note that the Alias|Wavefront object file format is a relatively simple text based format that can be constructed by hand without too much difficulty. Combined with the default mapping of material names to block types, this enables another means of constructing objects in the Minecraft world. For example, see Models.
-
bounds
¶ Returns a vector range which completely encompasses the model at scale 1.0. This can be useful for determining scaling factors when rendering.
Note
The bounding box returned is axis-aligned and is not guaranteed to be the minimal bounding box for the model.
-
faces
¶ Returns the sequence of faces that make up the model. Each instance of this sequence is a
ModelFace
instance which provides details of the coordinates of the face vertices, the face material, etc.
-
14.2. ModelFace¶
-
class
picraft.render.
ModelFace
(vectors, material, groups)[source]¶ Represents a face belonging to a
Model
. A face consists of three or morevectors
which are all coplanar (belonging to the same two-dimensional plane within the three-dimensional space).A face also has a
material
. As Minecraft’s rendering is relatively crude this is simply stored as the name of the material; it is up to the user to map this to a meaningful block type. Finally each face belongs to zero or moregroups
which can be used to distinguish components of a model from each other.-
groups
¶ The set of groups that the face belongs to. By default all faces belong to a
Model
. However, in additionl to this a face can belong to zero or more “groups” which are effectively components of the model. This facility can be used to render particular parts of a model.
-
material
¶ The material assigned to the face. This is simply stored as the name of the material as it would be ridiculous to even attempt to emulate the material model of a full ray-tracer as Minecraft blocks.
The
Model.render()
method provides a simple means for mapping a material name to a block type in Minecraft.
-