Expand description
immense describes 3D structures with simple composable rules and outputs them as Wavefront object files you can plug into your renderer of choice.
§Demo
Rule::new().push(vec![
Replicate::n(1, vec![Tf::saturation(0.8), Tf::hue(160.0)]),
Replicate::n(36, vec![Tf::rz(10.0), Tf::ty(0.1)]),
Replicate::n(36, vec![Tf::ry(10.0), Tf::tz(1.2), Tf::hue(3.4)]),
],
cube(),
)
§Table of Contents
§Intro
In immense, you create a Rule that describes your structure, which is ultimately composed of meshes. immense provides some builtin meshes, such as [cube][self::rule::builtin::cube], and you can create your own rules by using these builtins which you’ll see in the next section.
After you’ve built your Rule, you can export the meshes it expands to as a Wavefront object file for the next part of your workflow, whether that is rendering it in Blender, printing it in your 3D printer, or importing it into your game!
§Composing Rules
Let’s start with a cube. You probably want to write your meshes to a file and watch them in a viewer with autoreload. Meshlab is a great viewer (and much more) that can reload your meshes when changed. Check out ExportConfig to see what options you can set that will work best for your rendering or printing workflow.
use immense::*;
use std::fs::File;
let rule = cube();
let meshes = rule.generate();
let mut output_file = File::create("my_mesh.obj")?;
write_meshes(ExportConfig::default(), meshes, &mut output_file)?;
We can translate the cube with the Tf::t*
family of functions which generate translate
transforms. We’ll apply [Tf::tx][rule::transforms::Transform::tx] by creating our own rule and
invoking the cube rule with a transform.
let rule = Rule::new().push(Tf::tx(3.0), cube());
We can replicate transforms with [Replicate][rule::transforms::Replicate] which generates multiple invocations of a subrule, each with more applications of the same transform applied to it.
let rule = Rule::new().push(Replicate::n(3, Tf::ty(1.1)), cube());
Notice that our translation is 1.1 and that that is 0.1 more than the length of our cube. That’s no coincidence! All the built in meshes are 1 in length so that you can use convenient measurements like this, even when deep in a transform stack.
§Recursion
You can generate rules recursively with the api we’ve covered so far, but doing so would put your entire rule tree in memory at one time, which can become a problem. immense provides a trait, ToRule, so you can give it types that can instantiate rules when needed.
struct RecursiveTile {
depth_budget: usize,
}
impl ToRule for RecursiveTile {
fn to_rule(&self) -> Rule {
let rule = Rule::new()
.push(vec![Tf::t(0.25, 0.25, 0.0), Tf::s(0.4)], cube())
.push(vec![Tf::t(-0.25, -0.25, 0.0), Tf::s(0.4)], cube())
.push(vec![Tf::t(-0.25, 0.25, 0.0), Tf::s(0.4)], cube());
if self.depth_budget > 0 {
rule.push(
vec![Tf::t(0.25, -0.25, 0.0), Tf::s(0.4)],
RecursiveTile {
depth_budget: self.depth_budget - 1,
},
)
} else {
rule
}
}
}
let rule = RecursiveTile {
depth_budget: 3
}.to_rule();
§Randomness
Using ToRule to delay rule construction, we can sample some random values each time our type builds a rule.
struct RandCube;
impl ToRule for RandCube {
fn to_rule(&self) -> Rule {
Rule::new().push(
*thread_rng()
.choose(&[Tf::tx(0.1),
Tf::tx(-0.1),
Tf::tx(0.2),
Tf::tx(-0.2)])
.unwrap(),
cube(),
)
}
}
let rule = Rule::new().push(Replicate::n(4, Tf::ty(1.0)),
RandCube {});
§Color
immense can export some colors alongside your mesh, by linking the object file output to an mtl file (material library). Set the output mtl file in export_colors and immense will write out colors.
You can specify colors overrides and transforms in HSV color space using Ogeon’s palette. See [Tf::color][crate::rule::transforms::Transform::color], [Tf::hue][crate::rule::transforms::Transform::hue], [Tf::saturation][crate::rule::transforms::Transform::saturation], [Tf::value][crate::rule::transforms::Transform::value].
§Ergonomics Macros
immense provides two ergonomics macros that make defining rules and transform sequences a little
easier once you have an intuition for their semantics. They are rule!
and tf!
, which
help compose rules and transform sequences respectively.
They transform the demo code above into:
rule![
tf![
Tf::saturation(0.8),
Tf::hue(160.0),
Replicate::n(36, vec![Tf::rz(10.0), Tf::ty(0.1)]),
Replicate::n(36, vec![Tf::ry(10.0), Tf::tz(1.2), Tf::hue(3.4)]),
] => cube(),
]
§Custom Meshes
You can create meshes on your own and use them as rules by calling Mesh::from if you format your meshes according to object file format.
Meshes can be expensive to allocate. immense handles the primitives on your behalf, but if you introduce your own meshes you must be careful not to allocate them more than once. One million references to a sphere are fine, one million spheres will probably kill the process.
An example is the [sphere][self::rule::builtin::sphere] builtin which allows you to create a potentially expensive sphere estimation:
let sphere: Rc<Mesh> = sphere(/*resolution=*/4);
let rule = Rule::new().push(Tf::s(2.0), sphere);
Macros§
- rule
- An ergonomics macro for defining rules out of transformed subrule invocations.
- tf
- An ergonomics macro for listing transforms that will apply in order and branch on replications.
Structs§
- Export
Config - Configuration for Wavefront object file output.
- Hsv
- Linear HSV color space.
- Mesh
- A custom mesh definition described by a set of vertices, normals, and faces.
- Mesh
Iter - An iterator that iterates over a Rule’s generated meshes.
- Output
Mesh - An OutputMesh can be written out in an object file.
- Replicate
- Replicates a transform n times.
- RgbHue
- A hue type for the RGB family of color spaces.
- Rule
- A composition of subrules to expand until meshes are generated.
- Transform
- A Transform, when applied, modifies a mesh. When applied to a rule, it transforms all the meshes that rule eventually expands to. Transforms may be translations, scales, rotations, etc.
Enums§
- Error
- immense Error type.
- Mesh
Grouping - A policy for grouping meshes in the object file.
- Transform
Argument - A TransformArgument is a transform that should be applied to the invocation of a Rule.
Traits§
- ToRule
- A trait for types that can become rules.
Functions§
- cube
- A cube of size 1 whose center is at the origin.
- icosphere
- An icosphere of diameter 1.
- sphere
- A sphere of the given resolution. Produces 20 * 4 ^ resolution polygons to estimate the sphere.
- vertex
- Initializes a vertex for a custom mesh.
- write_
meshes - Writes out meshes as a Wavefront object file to the given Write sink.