zcbot/windows-node/adapters/blender.scene.author@v3/rotary_kiln.py

140 lines
5.1 KiB
Python

"""Built-in rotary-kiln generator for the generic Scene Recipe compiler."""
from __future__ import annotations
import math
from typing import Any
def build_rotary_kiln(
builder: Any,
root: Any,
prefix: str,
parameters: dict[str, Any],
) -> None:
length = float(parameters["length_m"])
diameter = float(parameters["outer_diameter_m"])
radius = diameter / 2
slope_angle = math.degrees(math.atan(float(parameters["slope_percent"]) / 100))
stations = int(parameters["support_stations"])
shell = builder.generated_material(prefix + "_shell", "#707780", 0.65, 0.3)
metal = builder.generated_material(prefix + "_metal", "#303840", 0.8, 0.22)
lining = builder.generated_material(prefix + "_lining", "#B56A3B", 0.0, 0.75)
concrete = builder.generated_material(prefix + "_concrete", "#8D9398", 0.0, 0.9)
material = builder.generated_material(prefix + "_bed", "#D35B26", 0.0, 0.8)
builder.add_generated_geometry(
prefix + "_shell_body",
{"type": "cylinder", "radius": radius, "depth": length, "vertices": 96},
parent=root,
material=shell,
rotation_deg=(0, 90 + slope_angle, 0),
)
builder.add_generated_geometry(
prefix + "_lining_body",
{
"type": "cylinder",
"radius": max(0.05, radius - float(parameters["shell_thickness_m"])),
"depth": length * 0.995,
"vertices": 96,
},
parent=root,
material=lining,
rotation_deg=(0, 90 + slope_angle, 0),
)
if parameters.get("material_bed", True):
builder.add_generated_geometry(
prefix + "_material_bed",
{
"type": "cylinder",
"radius": max(
0.03,
radius
- float(parameters["shell_thickness_m"])
- float(parameters["lining_thickness_m"]),
),
"depth": length * 0.97,
"vertices": 64,
},
parent=root,
material=material,
position=(0, 0, -radius * 0.25),
rotation_deg=(0, 90 + slope_angle, 0),
)
usable = length * 0.7
for index in range(stations):
x = -usable / 2 + usable * index / (stations - 1)
z = -x * math.tan(math.radians(slope_angle))
builder.add_generated_geometry(
f"{prefix}_tyre_{index + 1:02d}",
{
"type": "torus",
"major_radius": radius + diameter * 0.035,
"minor_radius": max(0.04, diameter * 0.055),
"major_segments": 64,
"minor_segments": 16,
},
parent=root,
material=metal,
position=(x, 0, z),
rotation_deg=(0, 90 + slope_angle, 0),
)
builder.add_generated_geometry(
f"{prefix}_foundation_{index + 1:02d}",
{"type": "box", "size": [diameter * 0.7, diameter * 1.8, radius * 0.8]},
parent=root,
material=concrete,
position=(x, 0, z - radius * 1.25),
)
if parameters.get("drive_system", True):
builder.add_generated_geometry(
prefix + "_girth_gear",
{
"type": "torus",
"major_radius": radius + diameter * 0.08,
"minor_radius": max(0.05, diameter * 0.07),
"major_segments": 72,
"minor_segments": 16,
},
parent=root,
material=metal,
position=(-length * 0.18, 0, length * 0.18 * math.tan(math.radians(slope_angle))),
rotation_deg=(0, 90 + slope_angle, 0),
)
builder.add_generated_geometry(
prefix + "_drive_motor",
{"type": "box", "size": [diameter * 0.55, diameter * 0.4, diameter * 0.4]},
parent=root,
material=metal,
position=(-length * 0.18, -radius * 1.45, -radius * 0.7),
)
if parameters.get("hoods", True):
for name, x in (("tail_hood", -length * 0.54), ("head_hood", length * 0.54)):
builder.add_generated_geometry(
prefix + "_" + name,
{"type": "box", "size": [diameter * 0.65, diameter * 1.4, diameter * 1.55]},
parent=root,
material=metal,
position=(x, 0, -x * math.tan(math.radians(slope_angle))),
)
if parameters.get("burner", True):
builder.add_generated_geometry(
prefix + "_burner",
{"type": "cylinder", "radius": max(0.03, diameter * 0.055), "depth": diameter * 2.2, "vertices": 32},
parent=root,
material=metal,
position=(length * 0.57, 0, -length * 0.57 * math.tan(math.radians(slope_angle))),
rotation_deg=(0, 90 + slope_angle, 0),
)
if parameters.get("inspection_platform", True):
builder.add_generated_geometry(
prefix + "_inspection_platform",
{"type": "box", "size": [diameter * 1.6, diameter * 0.9, 0.12]},
parent=root,
material=metal,
position=(length * 0.35, -radius * 1.2, -radius * 0.2),
)