Compile¶
The compile function is responsible for converting a layer specification into a renderable scene.
This function is automatically called by hkw.render(), but can also be used directly for
advanced workflows or debugging.
Overview¶
The compilation process transforms the high-level declarative layer specification into a low-level scene representation that can be rendered by a backend. During compilation, Hakowan:
- Flattens the layer tree into individual views
- Applies all transforms to the data
- Processes channels and applies scales
- Generates geometry and attributes for rendering
- Computes the global scene transformation
Basic Usage¶
import hakowan as hkw
# Create a layer
layer = hkw.layer("mesh.obj").mark(hkw.mark.Surface)
# Compile the layer into a scene
scene = hkw.compile(layer)
# The scene can then be rendered
# (normally you would just call hkw.render() which does both)
When to Use Compile Directly¶
In most cases, you don't need to call compile() directly because hkw.render() does it
automatically. However, there are scenarios where direct compilation is useful:
Debugging and Inspection¶
You can compile a layer to inspect the resulting scene without rendering:
import hakowan as hkw
layer = hkw.layer("mesh.obj")
scene = hkw.compile(layer)
# Inspect the compiled scene
print(f"Number of views: {len(scene.views)}")
for i, view in enumerate(scene):
print(f"View {i}: {view.mark}, {view.data_frame.mesh.num_vertices} vertices")
Custom Rendering Workflows¶
If you're building a custom rendering pipeline or integrating Hakowan with other tools:
import hakowan as hkw
layer = hkw.layer("mesh.obj")
scene = hkw.compile(layer)
# Access the compiled mesh data
for view in scene:
mesh = view.data_frame.mesh
# Process mesh data with custom tools
# ...
Validation¶
Use hkw.validate() to check a layer before compiling or rendering it. The
result is structured and JSON-safe, so callers can display errors or feed them
back to an automated authoring system.
layer = hkw.layer("shape.obj").mark("Point").channel(size="radius")
report = hkw.validate(layer, backend="webgl", strict=True)
if not report.valid:
for error in report.errors:
print(error.code, error.path, error.message, error.hint)
# Raise one exception containing the complete report when desired.
report.raise_for_errors()
Intrinsic errors such as missing attributes are always errors. In strict mode,
backend fallbacks and mark/channel combinations that would be ignored are also
errors. With strict=False, those degradations are warnings. When static checks
find no errors, validation finishes with a real compile dry-run; compilation
deep-copies layer data, so validation does not mutate the input. Pass
compile_check=False for static-only, low-cost validation of expensive
procedural transforms.
The compile dry-run also checks output semantics that static schema validation cannot determine:
- transforms that leave a view with no renderable geometry;
- scenes entirely behind or outside an explicit Figure camera;
- geometry outside or intersecting near and far clipping planes; and
- surface layers that are entirely behind another layer covering their projected bounds.
Every finding has a stable code, exact path, and actionable hint. Occlusion
is intentionally reported as a warning: projected bounding coverage is a
conservative heuristic and cannot prove that an arbitrary surface is opaque.
Compilation Process¶
The compilation process consists of several stages:
-
Layer Tree Condensation: The layer tree is flattened into individual views, where each path from root to leaf becomes a view.
-
Transform Application: All transforms specified in each view are applied to the data frame.
-
Channel Preprocessing: Channels are preprocessed and default values are assigned.
-
Channel Processing: Channels are processed, scales are applied, and attributes are computed.
-
Data Frame Finalization: The data frame is finalized and prepared for rendering.
-
Global Transform Computation: The global scene transformation is computed.
Scene Object¶
The result of compilation is a Scene object that contains:
- views: A list of
Viewobjects, each representing a compiled layer - global_transform: The global transformation matrix applied to the entire scene
Each View object contains:
- data_frame: The processed mesh data and attributes
- mark: The mark type (Point, Curve, or Surface)
- channels: The processed channels
- material_channel: The material specification
- transform: The transform chain applied to this view
- global_transform: The global transformation for this view
Example: Multi-Layer Compilation¶
import hakowan as hkw
mesh = lagrange.io.load_mesh("shape.obj")
base = hkw.layer(mesh)
# Create multiple layers
surface = base.mark(hkw.mark.Surface)
wireframe = base.mark(hkw.mark.Curve).channel(size=0.01)
vertices = base.mark(hkw.mark.Point).channel(size=0.05)
# Combine layers
combined = surface + wireframe + vertices
# Compile - this creates 3 views
scene = hkw.compile(combined)
print(f"Total views: {len(scene.views)}")
# Output: Total views: 3