forest_gen_utils Module

Public API for forest_gen.

forest_gen_utils.asset_dist submodule

Submodule providing asset distribution generation

class forest_gen_utils.asset_dist.DistributionBuilder

Bases: object

Fluent builder for configuring a plant distribution simulation.

add_species(kind: str, species: Species) DistributionBuilder

Register a species.

Parameters:
  • kind (str) – Species group identifier.

  • species (Species) – Species specification.

Returns:

Builder instance.

Return type:

DistributionBuilder

build() DistributionGenerator

Construct the distribution generator.

Returns:

Configured distribution generator.

Return type:

DistributionGenerator

with_max_population(max_population: int | None) DistributionBuilder

Set a global population cap.

Parameters:

max_population (int or None) – Maximum allowed population or None.

Returns:

Builder instance.

Return type:

DistributionBuilder

with_size(size: tuple[float, float]) DistributionBuilder

Set the simulation area size.

Parameters:

size (tuple[float, float]) – Simulation area (width, height).

Returns:

Builder instance.

Return type:

DistributionBuilder

with_terrain_viability_layers(layers: Mapping[str, ndarray], resolution: float, combine: Callable[[Mapping[str, float]], float] | None = None) DistributionBuilder

Apply terrain-based viability modifiers.

Parameters:
  • layers (Mapping[str, numpy.ndarray]) – Named terrain layers sampled for viability.

  • resolution (float) – Spatial resolution of the layers.

  • combine (Callable[[Mapping[str, float]], float] or None) – Optional layer-combination function.

Returns:

Builder instance.

Return type:

DistributionBuilder

class forest_gen_utils.asset_dist.DistributionConfig(scene_density: float = 1.0, years: int = 0, max_population: int | None = None)

Bases: object

Configuration for running a plant distribution simulation.

max_population: int | None = None

Optional hard cap on total population size.

scene_density: float = 1.0

Global density scaling factor.

years: int = 0

Number of simulation steps (years).

class forest_gen_utils.asset_dist.DistributionGenerator(simulation: Simulation, *, max_population: int | None = None)

Bases: object

Orchestrates Simulation creation using a fluent builder interface.

generate(config: DistributionConfig) SimulationState

Run the simulation using the given configuration.

Parameters:

config (DistributionConfig) – Distribution simulation configuration.

Returns:

Final simulation state.

Return type:

SimulationState

class forest_gen_utils.asset_dist.GrassDistributor(terrain: Terrain, tree_positions: Iterable[tuple[float, float]] | None = None, patch_scale: float = 0.2, hard_radius: float = 2.0, falloff_radius: float = 6.0, *, max_age: int = 6, species_density: float = 0.35, reproduction_rate: int = 3, reproduction_radius: float = 2.5, radius: float = 0.6, patch_gamma: float = 0.7, species_floor: float = 0.15, terrain_floor: float = 0.35)

Bases: object

Distribute grass using the standard forest simulation pipeline.

generate(config: ForestConfig) SimulationState

Generate grass distribution for the given forest configuration.

Parameters:

config (ForestConfig) – Forest generation configuration.

Returns:

Resulting simulation state.

Return type:

SimulationState

class forest_gen_utils.asset_dist.Plant(coords: tuple[float, float], species: Species, age: int)

Bases: object

Individual plant instance in the simulation.

age: int

Plant age in simulation steps.

coords: tuple[float, float]

World-space coordinates.

seed() Iterable[Plant]

Generate offspring plants via random dispersal.

Returns:

Newly generated plants.

Return type:

Iterable[Plant]

species: Species

Species specification.

vt() float

Viability of the plant.

Returns:

Viability value in [0.0, 1.0].

Return type:

float

vt_prim(a: dict[Species, int], sum_a: int) float

Compute population-weighted viability.

Combines intrinsic viability, spatial viability, and relative population size.

Parameters:
  • a (dict[Species, int]) – Population counts per species.

  • sum_a (int) – Total population size.

Returns:

Modified viability value.

Return type:

float

class forest_gen_utils.asset_dist.Simulation(size: tuple[float, float], species: dict[str, set[Species]], seed: int | None = None)

Bases: object

Forest simulation initializer.

Generates an initial plant distribution based on species parameters and scene density, producing a populated SimulationState.

new_state(scene_density: float) SimulationState

Create a new initial simulation state.

Plants are placed using Poisson disk sampling per species, scaled by scene density and species-specific target density. Larger-radius species are placed first to reduce overlap.

Parameters:

scene_density (float) – Global density multiplier.

Returns:

Initialized simulation state.

Return type:

SimulationState

class forest_gen_utils.asset_dist.SimulationState(plants: Iterable[Plant], size: tuple[float, float], div: int = 10)

Bases: object

Mutable plant population state with spatial indexing.

Stores plants in a coarse grid to accelerate neighborhood queries and supports advancing the simulation in discrete yearly steps.

add(plant: Plant) None

Add a plant to the state.

Parameters:

plant (Plant) – Plant to add.

get_cell(coords: tuple[float, float]) tuple[int, int]

Map world coordinates to a grid cell index.

Parameters:

coords (tuple[float, float]) – World-space coordinates (x, y).

Returns:

Cell indices (cx, cy).

Return type:

tuple[int, int]

get_nearby(coords_or_plant: Plant | tuple[float, float], radius: float | None = None) chain[Plant]

Iterate plants in cells intersecting a neighborhood radius.

If a Plant is passed and radius is None, the plant’s species radius is used.

Parameters:
  • coords_or_plant (Plant | tuple[float, float]) – Plant or world-space coordinates.

  • radius (float or None) – Search radius (required when passing coordinates).

Returns:

Nearby plants (not distance-filtered).

Return type:

itertools.chain[Plant]

Raises:

TypeError – If coordinates are passed without radius.

get_nearby_plant(plant: Plant) chain[Plant]

Shortcut for neighborhood query around a plant.

Parameters:

plant (Plant) – Reference plant.

Returns:

Nearby plants.

Return type:

itertools.chain[Plant]

remove(plant: Plant) None

Remove a plant from the state.

Parameters:

plant (Plant) – Plant to remove.

run_state(num_years: int, max_population: int | None = None) None

Advance the simulation by a number of years.

Parameters:
  • num_years (int) – Number of years to simulate.

  • max_population (int or None) – Optional population cap.

class forest_gen_utils.asset_dist.Species(name: str, max_age: int, species_density: float = 0.02, reproduction_rate: int = 5, reproduction_radius: float = 20.0, radius: float = 0.5, viability_map: ~typing.Callable[[float, float], float] = <factory>, juvenile_mortality_depth: float = 0.4, juvenile_mortality_peak: float = 0.05, juvenile_mortality_width: float = 0.03, juvenile_recovery_age: float = 0.2, senescence_start: float = 0.7, senescence_plateau: float = 0.5, senescence_plateau_span: float = 0.15)

Bases: object

Specification describing biological parameters of a plant species.

juvenile_mortality_depth: float = 0.4

Peak early-life viability reduction.

juvenile_mortality_peak: float = 0.05

Normalized age of maximum juvenile mortality.

juvenile_mortality_width: float = 0.03

Spread of the juvenile mortality spike as a fraction of max age.

juvenile_recovery_age: float = 0.2

Normalized age by which viability recovers to its peak.

max_age: int

Maximum lifespan.

name: str
radius: float = 0.5

Radius needed for the plant to consider itself as clear of obstacles.

reproduction_radius: float = 20.0

Radius in which the seeds can be planted.

reproduction_rate: int = 5

Maximum number of seeds per year.

senescence_plateau: float = 0.5

Viability level maintained during senescence plateau.

senescence_plateau_span: float = 0.15

Duration of the senescence plateau as a fraction of lifespan.

senescence_start: float = 0.7

Normalized age when senescence effects start.

species_density: float = 0.02

Target density in plants per square meter used for the initial number of plants in the simulation.

viability_map: Callable[[float, float], float]

Spatial viability function.

class forest_gen_utils.asset_dist.TerrainViabilityMap(data: ndarray | Mapping[str, ndarray], resolution: float, combine: Callable[[Mapping[str, float]], float] | None = None)

Bases: object

Callable terrain-based viability lookup.

Samples one or more raster layers at world coordinates and combines the values into a single viability multiplier.

forest_gen_utils.asset_dist.grass_points(width: int, height: int, r: float) list[tuple[float, float]]

Generate Poisson-distributed grass points.

Intended for quick sampling or prototyping.

forest_gen_utils.asset_dist.remove_grass_near_tree(grass: list[tuple[float, float]], trees: Iterable[tuple[float, float]]) list[tuple[float, float]]

Filter grass points near trees using proximity masking.

forest_gen_utils.export submodule

Export strategies (GLB, PNG, etc.).

class forest_gen_utils.export.ExportFactory

Bases: object

Factory for creating ExportStrategy instances.

static create(fmt: Literal['glb', 'png', 'image'], **kwargs) ExportStrategy

Create an export strategy by format identifier.

Parameters:
  • fmt (Literal["glb", "png", "image"]) – Export format identifier.

  • kwargs (dict) – Keyword arguments forwarded to the exporter constructor.

Returns:

Export strategy instance.

Return type:

ExportStrategy

Raises:

ValueError – If the format is unknown.

class forest_gen_utils.export.ExportStrategy

Bases: ABC

Strategy interface for exporting terrain data.

Defines a common interface for exporting heightmaps to external representations (e.g. images, meshes).

abstractmethod export(heightmap: ndarray, path: str) None

Export a heightmap to the specified path.

Parameters:
  • heightmap (numpy.ndarray) – Heightmap array to export.

  • path (str) – Output file path.

class forest_gen_utils.export.GLBExporter(resolution: float = 1.0, max_elevation: float = 100.0, seed: int | None = None)

Bases: ExportStrategy

Concrete Strategy exporting terrain as a textured GLB mesh.

export(heightmap: ndarray, path: str) None

Export a heightmap as a GLB mesh with a generated texture.

Vertices are laid out on a regular grid using the configured resolution, heights are scaled by max_elevation, and a random RGB texture is generated for visualization.

Parameters:
  • heightmap (numpy.ndarray) – Heightmap array with values in [0.0, 1.0].

  • path (str) – Output .glb file path.

class forest_gen_utils.export.PNGExporter(max_elevation: float = 100.0)

Bases: ExportStrategy

Concrete Strategy exporting a heightmap as a grayscale PNG image.

export(heightmap: ndarray, path: str) None

Export a heightmap to a PNG file.

Parameters:
  • heightmap (numpy.ndarray) – Heightmap array with values in [0.0, 1.0].

  • path (str) – Output file path.

forest_gen_utils.forest submodule

class forest_gen_utils.forest.ForestBuilder

Bases: object

Fluent builder for constructing a ForestGenerator.

add_species(kind: str, species: Species) ForestBuilder

Register a species under a category.

Parameters:
  • kind (str) – Species group identifier.

  • species (Species) – Species specification.

Returns:

Builder instance.

Return type:

ForestBuilder

build()

Construct the configured forest generator.

Returns:

Forest generator instance.

Return type:

ForestGenerator

with_size(size: tuple[float, float]) ForestBuilder

Set the simulation area size.

Parameters:

size (tuple[float, float]) – Simulation area (width, height).

Returns:

Builder instance.

Return type:

ForestBuilder

with_terrain(terrain: Terrain) ForestBuilder

Attach a terrain used for viability sampling.

Parameters:

terrain (Terrain) – Terrain providing derived layers (e.g. slope, moisture).

Returns:

Builder instance.

Return type:

ForestBuilder

with_terrain_viability_layers(layers: Mapping[str, ndarray], combine: Callable[[Mapping[str, float]], float] | None = None) ForestBuilder

Provide additional terrain viability layers.

Parameters:
  • layers (Mapping[str, numpy.ndarray]) – Named raster layers sampled for viability.

  • combine (Callable[[Mapping[str, float]], float] or None) – Optional layer-combination function.

Returns:

Builder instance.

Return type:

ForestBuilder

class forest_gen_utils.forest.ForestConfig(scene_density: float = 1.0, years: int = 0)

Bases: object

Configuration for forest generation.

scene_density: float = 1.0

Global density multiplier for initial placement.

years: int = 0

Number of simulation years to run.

class forest_gen_utils.forest.ForestGenerator(size: tuple[float, float], species: dict[str, set[Species]], terrain: Terrain | None = None, terrain_layers: Mapping[str, ndarray] | None = None, layer_combiner: Callable[[Mapping[str, float]], float] | None = None)

Bases: object

High-level generator for forest plant distributions.

Wraps the distribution simulation pipeline and optionally integrates terrain-derived viability layers.

generate(config: ForestConfig) SimulationState

Generate a forest distribution.

Parameters:

config (ForestConfig) – Forest generation configuration.

Returns:

Resulting simulation state.

Return type:

SimulationState

forest_gen_utils.obstacles submodule

Obstacle generation module.

class forest_gen_utils.obstacles.Obstacle(kind: str, coords: tuple[float, float], radius: float)

Bases: object

Immutable representation of a navigational obstacle.

coords: tuple[float, float]

World-space coordinates (x, y).

kind: str

Obstacle type identifier.

radius: float

Obstacle influence radius.

class forest_gen_utils.obstacles.ObstacleBuilder

Bases: object

Fluent builder for configuring an ObstacleGenerator.

add_spec(spec: ObstacleSpec) ObstacleBuilder

Add a single obstacle specification.

Parameters:

spec (ObstacleSpec) – Obstacle specification.

Returns:

Builder instance.

Return type:

ObstacleBuilder

build() ObstacleGenerator

Construct the configured obstacle generator.

Returns:

Obstacle generator instance.

Return type:

ObstacleGenerator

with_seed(seed: int | None) ObstacleBuilder

Set the random seed.

Parameters:

seed (int or None) – Random seed or None.

Returns:

Builder instance.

Return type:

ObstacleBuilder

with_specs(specs: Iterable[ObstacleSpec]) ObstacleBuilder

Replace obstacle specifications.

Parameters:

specs (Iterable[ObstacleSpec]) – Obstacle specifications to use.

Returns:

Builder instance.

Return type:

ObstacleBuilder

class forest_gen_utils.obstacles.ObstacleConfig(size: tuple[float, float], density: float = 0.0025, min_distance: float = 2.0, seed: int | None = None, specs: tuple[ObstacleSpec, ...] | None = None)

Bases: object

Configuration for random obstacle generation.

property area: float
density: float = 0.0025

Obstacle density per unit area.

expected_obstacle_count() int
min_distance: float = 2.0

Minimum spacing between obstacles.

seed: int | None = None

Optional random seed.

size: tuple[float, float]

Generation area size (width, height).

specs: tuple[ObstacleSpec, ...] | None = None

Available obstacle specifications.

with_specs(specs: Iterable[ObstacleSpec]) ObstacleConfig

Return a copy of this config with custom obstacle specs.

Parameters:

specs (Iterable[ObstacleSpec]) – Obstacle specifications to use.

Returns:

New obstacle configuration.

Return type:

ObstacleConfig

class forest_gen_utils.obstacles.ObstacleGenerator(specs: tuple[~forest_gen_utils.obstacles.obstacle_config.ObstacleSpec, ...] | None = None, rng: ~random.Random = <factory>)

Bases: object

Generate random navigational obstacles within a bounded area.

Obstacles are sampled according to obstacle specifications and placed with minimum distance constraints.

generate(config: ObstacleConfig) list[Obstacle]

Generate obstacles according to the given configuration.

Parameters:

config (ObstacleConfig) – Obstacle generation configuration.

Returns:

Generated obstacles.

Return type:

list[Obstacle]

rng: Random

Base random number generator.

specs: tuple[ObstacleSpec, ...] | None = None

Optional obstacle specifications overriding defaults.

class forest_gen_utils.obstacles.ObstacleSpec(name: str, radius: float, weight: float = 1.0)

Bases: object

Specification describing an obstacle type.

name: str

Obstacle type identifier.

radius: float

Collision radius used for spacing.

weight: float = 1.0

Relative sampling weight.

forest_gen_utils.obstacles.default_obstacle_specs() tuple[ObstacleSpec, ...]

Return the default obstacle specifications.

forest_gen_utils.terrain submodule

class forest_gen_utils.terrain.Terrain(config: TerrainConfig, heightmap: ndarray, flow: ndarray, slope: ndarray, aspect: ndarray, moisture: ndarray, materials_path: str = '../forest-gen/models/materials/Ground')

Bases: object

Container for generated terrain data and mesh export utilities.

Holds all terrain-derived fields (height, flow, slope, aspect, moisture) together with helper methods for sampling and mesh export.

aspect: ndarray

Aspect array in degrees.

config: TerrainConfig

Terrain generation configuration.

flow: ndarray

Flow accumulation array.

heightmap: ndarray

Terrain heightmap.

materials_path: str = '../forest-gen/models/materials/Ground'

Path to terrain material definitions.

moisture: ndarray

Moisture index array.

property size: tuple[float, float]

Terrain dimensions in units.

Returns:

(width, height).

Return type:

tuple[float, float]

slope: ndarray

Slope array in degrees.

to_mesh() trimesh.Trimesh

Convert the terrain heightmap to a single mesh.

Returns:

Terrain mesh.

Return type:

trimesh.Trimesh

to_meshes(classify: Callable[[float, float], str] | None = None) list[tuple[trimesh.Trimesh, list[tuple[str, str]]]]

Convert the terrain into multiple classified meshes.

Parameters:

classify (Callable[[float, float], str] or None) – Optional classifier mapping world coordinates to material identifiers.

Returns:

List of meshes with associated material assignments.

Return type:

list[tuple[trimesh.Trimesh, list[tuple[str, str]]]]

class forest_gen_utils.terrain.TerrainBuilder

Bases: object

Fluent builder for constructing a TerrainGenerator.

Provides a chainable API for selecting noise, microrelief, and moisture strategies before final assembly.

build() TerrainGenerator

Construct the configured TerrainGenerator.

Missing components are filled with default implementations.

Returns:

Terrain generator instance.

Return type:

TerrainGenerator

with_microrelief(enable: bool) TerrainBuilder

Enable or disable microrelief.

Parameters:

enable (bool) – Whether to apply microrelief.

Returns:

Builder instance.

Return type:

TerrainBuilder

with_moisture_model(weights: dict[str, float] | None = None) TerrainBuilder

Configure the moisture model.

Parameters:

weights (dict[str, float] or None) – Optional moisture weighting factors.

Returns:

Builder instance.

Return type:

TerrainBuilder

with_noise(name: Literal['fractal', 'simplex']) TerrainBuilder

Select the noise strategy.

Parameters:

name (Literal["fractal", "simplex"]) – Noise strategy identifier.

Returns:

Builder instance.

Return type:

TerrainBuilder

class forest_gen_utils.terrain.TerrainConfig(size: int, resolution: float = 1.0, scale: float = 50.0, octaves: int = 4, height_scale: float = 1.0, apply_microrelief: bool = True, moisture_weights: dict[str, float] = <factory>)

Bases: object

Configuration container for terrain generation parameters.

apply_microrelief: bool = True

Whether microrelief should be applied to the terrain.

property cols: int
height_scale: float = 1.0

Global height scaling factor.

moisture_weights: dict[str, float]

Default weighting factors for moisture computation.

octaves: int = 4

Number of noise octaves for multi-scale generation.

resolution: float = 1.0

Spatial resolution (units per grid cell).

property rows: int
scale: float = 50.0

Base noise scale controlling feature size.

size: int

Terrain size.

transform(x: float) int

Convert a ws coordinate to grid-space.

Parameters:

x (float) – Coordinate in world units.

Returns:

Grid index.

Return type:

int

class forest_gen_utils.terrain.TerrainGenerator(noise: NoiseStrategy, micro: MicroreliefStrategy, moisture_model: MoistureModel)

Bases: object

High-level terrain generation orchestrator.

Coordinates noise generation, optional microrelief, hydrology, slope/aspect analysis, and moisture computation to produce a complete Terrain.

generate(config: TerrainConfig) Terrain

Generate a terrain from the given configuration.

Parameters:

config (TerrainConfig) – Terrain generation configuration.

Returns:

Generated terrain data container.

Return type:

Terrain

micro: MicroreliefStrategy
moisture_model: MoistureModel
noise: NoiseStrategy

forest_gen_utils.traversability submodule

class forest_gen_utils.traversability.TraversabilityConfig(resolution_factor: int = 3, max_slope_deg: float = 30.0, obstacle_influence_radius: float = 7.0, obstacle_penalty: float = 0.45)

Bases: object

Configuration parameters for traversability computation.

max_slope_deg: float = 30.0

Maximum traversable slope in degrees.

obstacle_influence_radius: float = 7.0

Radius of obstacle influence.

obstacle_penalty: float = 0.45

Maximum traversability penalty per obstacle.

resolution_factor: int = 3

Upsampling factor relative to terrain resolution.

class forest_gen_utils.traversability.TraversabilityMapBuilder(terrain: Terrain, resolution_factor: int = 2, max_slope_deg: float = 30.0)

Bases: object

Build a high-resolution traversability map from terrain data.

add_obstacle_score(obstacles: list[tuple[float, float]], obstacle_influence_radius: float = 10.0, obstacle_penalty: float = 0.5) None

Apply obstacle-based penalties to the traversability map.

Each obstacle reduces traversability within a given radius, with penalty decreasing linearly with distance.

Parameters:
  • obstacles (list[tuple[float, float]]) – Obstacle positions as (x, y) coordinates.

  • obstacle_influence_radius (float) – Radius of obstacle influence.

  • obstacle_penalty (float) – Maximum penalty applied near obstacles.

get_score() ndarray

Return the final traversability score map.

Returns:

Traversability values in [0.0, 1.0].

Return type:

numpy.ndarray

forest_gen_utils.traversability.compute_slope_per_vertex(mesh: trimesh.Trimesh) ndarray

Compute per-vertex slope angles from a mesh.

Slope is derived from the Z component of vertex normals.

Parameters:

mesh (trimesh.Trimesh) – Terrain mesh.

Returns:

Slope angles in radians.

Return type:

numpy.ndarray

forest_gen_utils.vis submodule

Visualization subpackage initializer inside temp.

class forest_gen_utils.vis.FlowVisualizer

Bases: Visualizer

visualize(data, title='Flow Accumulation')
class forest_gen_utils.vis.HeightmapVisualizer

Bases: Visualizer

visualize(data, title='Heightmap')
class forest_gen_utils.vis.MoistureVisualizer(dry_thresh=0.33, wet_thresh=0.66)

Bases: Visualizer

visualize(moisture, title='Moisture Classes')
class forest_gen_utils.vis.Visualizer

Bases: ABC

Strategy interface: render a single 2-D array with a title. Matches UML — only one abstract method.

abstractmethod visualize(data: ndarray, title: str) None