Utilities (.util)#

Code Statistics (.util.codestats)#

Module contents#

infinigen2.util.codestats.build_indexed_model(model) → dict[source]#

Reindex variables into topological order and convert branches to masks.

Parameters:

model (dict)

infinigen2.util.codestats.build_model_from_compute_graph(graph) → dict[source]#

Extract the compact branch-first model from a traced compute graph.

Parameters:

graph (ComputeGraph)

infinigen2.util.codestats.compute_stats(...) → dict[source]#

Extract the compact model and run either the tree or DP solver.

Parameters:
infinigen2.util.codestats.cyclomatic_complexity(choice_probs) → int[source]#

Cyclomatic complexity where only control flow is pf.control.hcoice Return 1 + sum(branch_count - 1) over discrete choices.

Parameters:

choice_probs (dict[int, list[float]])

infinigen2.util.codestats.solve_dp(indexed_model) → dict[source]#

Exact DP

Parameters:

indexed_model (dict)

infinigen2.util.codestats.solve_tree(indexed_model) → dict[source]#

Tree-style recursion.

child subtrees inside one branch are treated as disjoint and summed independently.

Parameters:

indexed_model (dict)

camera_projection#

infinigen2.util.camera_projection.adjust_camera_sensor(camera)[source]#
Parameters:

camera (CameraObject)

infinigen2.util.camera_projection.bpy_resolution() → tuple[int, int][source]#
infinigen2.util.camera_projection.get_calibration_matrix_K_from_blender(camera) → ndarray[source]#

Build intrinsic camera parameters from Blender camera data

Based on https://blender.stackexchange.com/questions/15102/what-is-blenders-camera-projection-matrix-model

Parameters:

camera (CameraObject) -- Blender camera object

Returns:

3x3 intrinsic camera matrix

Return type:

K

infinigen2.util.camera_projection.get_3x4_RT_matrix_from_blender(camera) → ndarray[source]#

Get camera rotation and translation matrices from Blender.

We return a camera matrix in the usual computer vision convention: +x is horizontal, +y is down, +z is forward.

This is different than blender’s camera typical convention, which is +x is horizontal, +y is up, -z is forward.

Parameters:

camera (CameraObject) -- Blender camera object

Returns:

3x4 camera matrix

Return type:

RT

infinigen2.util.camera_projection.get_3x4_P_matrix_from_blender(cam)[source]#
Parameters:

cam

infinigen2.util.camera_projection.project_points(camera, points_N3) → ndarray[source]#

Project points onto the camera image plane.

Parameters:
infinigen2.util.camera_projection.project_points_from_parameters(points_N3, K, camera_to_world) → ndarray[source]#

Project world points using K and an OpenCV-convention camera pose.

Parameters:
infinigen2.util.camera_projection.is_projection_within_image(projected, resolution=None) → ndarray[source]#

Check if the projection is within the image.

Parameters:
infinigen2.util.camera_projection.get_camera_parameters(camera, frame=None, use_dof=False) → dict[source]#
Parameters:
  • camera (CameraObject)

  • frame (int | None) -- (default: None)

  • use_dof (bool | None) -- (default: False)

curve#

class infinigen2.util.curve.CurveToMeshWithUvResult(mesh, vector)[source]#

Bases: NamedTuple

Fields: mesh: ProcNode[~MeshObject]; vector: ProcNode[Vector]

class infinigen2.util.curve.FilletMaskResult(...)[source]#

Bases: NamedTuple

Fields: curve: ProcNode[~CurveObject]; is_fillet_point: ProcNode[bool]; is_flat_point: ProcNode[bool]; orig_point_idx: ProcNode[int]

infinigen2.util.curve.curve_to_mesh_with_uv(...) → CurveToMeshWithUvResult[source]#
Parameters:
infinigen2.util.curve.curve_to_noncyclic(input) → pf.ProcNode[CurveObject][source]#
Parameters:

input (pf.ProcNode[CurveObject])

infinigen2.util.curve.fillet_mask(...) → FilletMaskResult[source]#
Parameters:

errors#

exception infinigen2.util.errors.RejectedScene[source]#

Bases: Exception

external_assets#

infinigen2.util.external_assets.distribution_from_asset_glob(folder)[source]#
Parameters:

folder (Path)

infinigen2.util.external_assets.pregenerated_asset_rand(relative_glob) → Callable[[pf.RNG], pf.MeshObject | None][source]#
Parameters:

relative_glob (str)

hardware_info#

infinigen2.util.hardware_info.get_hardware_info() → dict[source]#

import_utils#

Utilities for dynamic imports and finding generator functions.

infinigen2.util.import_utils.module_path()[source]#

instance#

infinigen2.util.instance.instances_on_line(...) → pf.ProcNode[pf.MeshObject][source]#
Parameters:
infinigen2.util.instance.instance(...) → pf.ProcNode[source]#
Parameters:
infinigen2.util.instance.instanced_objects(...) → list[pf.MeshObject][source]#
Parameters:

math#

infinigen2.util.math.offset_spacing(...) → pf.ProcNode[float][source]#
Parameters:

mesh#

class infinigen2.util.mesh.ExtrudeSeamlessResult(mesh, top, side)[source]#

Bases: NamedTuple

Fields: mesh: ProcNode[~MeshObject]; top: ProcNode[bool]; side: ProcNode[bool]

class infinigen2.util.mesh.LoftingResult(...)[source]#

Bases: NamedTuple

Fields: geometry: ProcNode[~CurveObject]; top: ProcNode[bool]; side: ProcNode[bool]; bottom: ProcNode[bool]

class infinigen2.util.mesh.WallCutoutResult(wall, sill, lightblocker)[source]#

Bases: NamedTuple

Fields: wall: ProcNode[~MeshObject]; sill: ProcNode[~MeshObject]; lightblocker: ProcNode[~MeshObject]

infinigen2.util.mesh.box(...) → pf.ProcNode[pf.MeshObject][source]#

Create a box with location at its normalized anchor point.

Parameters:
infinigen2.util.mesh.box_with_support_loops(...) → pf.ProcNode[pf.MeshObject][source]#

Create a support-loop box with the same placement contract as box.

Parameters:
infinigen2.util.mesh.center_footprint(obj)[source]#

Shift geometry so its bounding box is centered on x/y, leaving z alone.

Storage carcasses are built into the positive octant while tables are built centered on their footprint; placement code sets a location expecting the latter, so a carcass used as a table has to be recentered first.

Parameters:

obj (pf.MeshObject)

infinigen2.util.mesh.crease_all_edges(obj)[source]#
Parameters:

obj (pf.MeshObject)

infinigen2.util.mesh.crease_by_angle(
mesh,
threshold_degrees,
softness_degrees,
) → pf.ProcNode[pf.MeshObject][source]#
Parameters:
infinigen2.util.mesh.crease_sharp(
mesh,
threshold_degrees,
) → pf.ProcNode[pf.MeshObject][source]#
Parameters:
infinigen2.util.mesh.evaluated_world_bbox(obj) → tuple[ndarray, ndarray][source]#
Parameters:

obj (pf.MeshObject)

infinigen2.util.mesh.extrude_mesh_seamless_uvs(...) → ExtrudeSeamlessResult[source]#

Extrude faces along their normals and continue source UVs seamlessly.

Each side corner gets uv0 plus a perpendicular offset proportional to its extrusion depth. The boundary edge driving that offset is found per corner via its own next-corner edge (the one with both ends on the depth-0 ring), then broadcast across the side face with accumulate_field.

Parameters:
infinigen2.util.mesh.extrude_mesh_seamless_uvs_along(...) → ExtrudeSeamlessResult[source]#

Continue source UVs while extruding along an explicit offset.

Parameters:
infinigen2.util.mesh.face_selection_boundary_curve(
mesh,
selection,
) → pf.ProcNode[CurveObject][source]#

Extract the edge loops separating selected from unselected faces as curves.

Curve normals are set to the inward surface direction (-mesh normal), matching the skirting sweep convention: a profile authored in -X/-Y swept along the result protrudes out the front of the surface.

Parameters:
infinigen2.util.mesh.fill_between_curves(...) → pf.ProcNode[pf.MeshObject][source]#

Ruled surface bridging two curves: resample both to n_points, then lerp an n_rows x n_points grid between the sample positions. n_rows > 2 keeps faces small and near-planar so downstream bevel/warp modifiers behave.

Stores metric UVs with U along the curves and V between them.

Parameters:
infinigen2.util.mesh.grid_from_corners(...) → pf.ProcNode[source]#
Parameters:
infinigen2.util.mesh.lofting(...) → LoftingResult[source]#

Loft a tube surface through a stack of cross-section profile curves.

profile_curves is a single geometry holding N separate profile splines, one per cross-section ordered along the loft (spline 0 = bottom rim … spline N-1 = top rim). Each profile is resampled to u_resolution points and the N profiles are interpolated (Catmull-Rom, or NURBS if use_nurb) into v_resolution rows, yielding a u_resolution x v_resolution cylinder-topology mesh. Returns the lofted geometry plus the cylinder’s top/side/bottom masks.

Parameters:
infinigen2.util.mesh.mesh_from_corners(corners, sizes, uvs) → pf.MeshObject[source]#

Shared-vertex mesh from flat (N, 3) face corners, per-face corner counts and (N, 2) UVs.

Parameters:
infinigen2.util.mesh.mesh_from_quads(corners, uvs) → pf.MeshObject[source]#
Parameters:
infinigen2.util.mesh.metric_box_uv(geometry) → pf.ProcNode[source]#

Store metric box-projection UVs computed from the current positions.

Per face, picks the two in-plane position axes (U/V in meters) and puts V on the axis with the larger board extent so woodgrain runs along the board’s long dimension, then writes them as a CORNER “UVMap”.

Parameters:

geometry (pf.ProcNode)

infinigen2.util.mesh.metric_cylinder_uv(obj)[source]#

Project sides at the widest circumference, with metric Z and planar caps.

Parameters:

obj (pf.MeshObject)

infinigen2.util.mesh.quad_cap(
profile,
insets=1,
scale=0.55,
) → pf.ProcNode[pf.MeshObject][source]#

Fill a closed profile with concentric quad rings around a centre face.

A cap filled as one bare ngon shares its vertices with the rim, so a rim crease drags on the whole face; a single inset ring isolates the two and the subdivided cap comes out flat. Ring vertices inherit the profile’s angular spacing, which is what keeps the subdivided silhouette round.

Parameters:
infinigen2.util.mesh.quad_cylinder(...) → pf.ProcNode[pf.MeshObject][source]#

Cylinder capped by quad rings, centred on the origin like mesh_cylinder.

mesh_cylinder caps each end with a bare ngon whose vertices are the creased rim itself, which tilts the subdivided face; this sweeps the same circle for the wall and caps it with quad_cap instead.

Parameters:
infinigen2.util.mesh.quad_disc(
radius=1.0,
resolution=20,
insets=1,
) → pf.ProcNode[pf.MeshObject][source]#

Disc of concentric quad rings, uniformly spaced around the rim.

Parameters:
infinigen2.util.mesh.refine_lattice_cage(obj, max_cell) → pf.MeshObject[source]#

Split oversized cells of a quad cage whose faces are axis-aligned UV rectangles.

New lines go only inside UV gaps wider than max_cell metres, so small faces (chamfers, reveals) stay untouched and no T-junctions appear. Returns obj unchanged if any face is not a UV rectangle or nothing needs splitting.

Parameters:
infinigen2.util.mesh.reversed_faces(sizes) → ndarray[source]#

Corner permutation that reverses the winding of every face in a flat layout.

Parameters:

sizes (ndarray)

infinigen2.util.mesh.split_gaps(lines, max_cell) → ndarray[source]#

Sorted lines plus evenly spaced extras so no gap exceeds max_cell.

Parameters:
infinigen2.util.mesh.uv_winding_sign(obj) → float[source]#

Sign of the first face’s UV winding (+1/-1), for un-mirrored continuation.

Parameters:

obj (pf.MeshObject)

infinigen2.util.mesh.wall_cutout_split(...) → WallCutoutResult[source]#

Split a flat cutout_sel-tagged surface into holed wall, sill tunnels, and lightblocker backing.

The mouth of each hole gets a chamfer-wide angled lip, kept on the wall (it reads as a bevel of the wall surface around the opening); the sill is just the deep reveal tunnel. The footprint must be pre-expanded by chamfer (see face_expand_margin) so the inner opening lands at the originally-intended size.

Parameters:

polycount#

infinigen2.util.polycount.estimated_eval_tricount(objects) → tuple[int, list[tuple[Object, int]]][source]#

Estimate total and ascending per-object render-level triangle counts.

Modifier-free objects sharing mesh data are instanced by Cycles, so the total counts their geometry once; objects with modifiers evaluate separately and each count.

Parameters:

objects (list[Object])

render_metadata#

infinigen2.util.render_metadata.time_step(times, name) → Iterator[None][source]#
Parameters:
infinigen2.util.render_metadata.write_render_metadata(...) → dict[source]#

Write metadata.json, which ships verbatim in datareleases.

Nothing here may identify the machine or user that rendered the scene, and export paths are relative to output so they do not leak the render tree’s layout.

Parameters:

scene_cleanup#

infinigen2.util.scene_cleanup.cleanup_except(keep) → list[str][source]#

Delete every bpy.data.objects entry not in keep.

Placement helpers (e.g. repeat_attempts) leave failed-placement objects in the scene. They are excluded from the returned all_objects lists but still live in the blend and would otherwise be rendered. Pass the union of objects/cameras/lights you want kept and this removes the rest.

Parameters:

keep (Iterable[Object])

infinigen2.util.scene_cleanup.delete_object(obj)[source]#
Parameters:

obj (Object)

infinigen2.util.scene_cleanup.delete_objects(objs)[source]#
Parameters:

objs (Iterable[Object])

Module contents#