refactor(P1): M1 dead code removal + M3 blender_render.py split
M1 — dead code removed: - Delete blender-renderer/ and threejs-renderer/ source files - Remove PIL/Pillow fallback block from step_processor.py (_generate_thumbnail_placeholder, _finalise_image JPG path) - Remove stl_quality param from render_blender.py, render_still_task, render_turntable_task (was always "low"; hardcode deflection values) - render_turntable_task now reads scene_linear/angular_deflection from system_settings (consistent with export_glb.py pipeline) M3 — blender_render.py split from 263 → 68 lines: - _blender_args.py: parse_args() — all 25 positional + named args - _blender_scene_setup.py: setup_scene() — MODE A/B including USD import - _blender_render_config.py: configure_and_render() — engine + output Post-review fixes: - _db_engine.dispose() after settings read in render_turntable_task - _finalise_image() fmt param removed (always PNG; PIL never installed) - _blender_import.py committed together with new submodules to satisfy import_usd_file dependency Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
"""MODE A / MODE B scene setup for blender_render.py.
|
||||
|
||||
MODE A — factory settings (no template): auto-camera + auto-lights
|
||||
MODE B — template file: load .blend, import into named collection
|
||||
"""
|
||||
import time as _time
|
||||
from typing import Callable
|
||||
|
||||
import bpy # type: ignore[import]
|
||||
|
||||
from _blender_camera import setup_auto_camera, setup_auto_lights
|
||||
from _blender_import import import_glb, apply_rotation, import_usd_file
|
||||
from _blender_materials import (
|
||||
assign_failed_material,
|
||||
build_mat_map_lower,
|
||||
apply_material_library,
|
||||
)
|
||||
from _blender_scene import (
|
||||
ensure_collection,
|
||||
apply_smooth_batch,
|
||||
apply_sharp_edges_from_occ,
|
||||
setup_shadow_catcher,
|
||||
)
|
||||
|
||||
|
||||
def setup_scene(args, lap_fn: Callable[[str], None]) -> None:
|
||||
"""Set up the Blender scene according to args (MODE A or B).
|
||||
|
||||
Handles import, rotation, smooth shading, material assignment, shadow
|
||||
catcher, and auto-camera/lights. lap_fn is called with a label string
|
||||
at each timing checkpoint.
|
||||
"""
|
||||
if args.use_template:
|
||||
_setup_mode_b(args, lap_fn)
|
||||
else:
|
||||
_setup_mode_a(args)
|
||||
|
||||
|
||||
def _setup_mode_b(args, lap_fn: Callable[[str], None]) -> None:
|
||||
"""MODE B: Template-based render — load .blend, import into collection."""
|
||||
print(f"[blender_render] Opening template: {args.template_path}")
|
||||
bpy.ops.wm.open_mainfile(filepath=args.template_path)
|
||||
lap_fn("template_load")
|
||||
|
||||
target_col = ensure_collection(args.target_collection)
|
||||
if args.usd_path:
|
||||
parts = import_usd_file(args.usd_path)
|
||||
else:
|
||||
parts = import_glb(args.glb_path)
|
||||
lap_fn("glb_import")
|
||||
apply_rotation(parts, args.rotation_x, args.rotation_y, args.rotation_z)
|
||||
lap_fn("rotation")
|
||||
|
||||
for part in parts:
|
||||
for col in list(part.users_collection):
|
||||
col.objects.unlink(part)
|
||||
target_col.objects.link(part)
|
||||
|
||||
apply_smooth_batch(parts, args.smooth_angle)
|
||||
if not args.usd_path:
|
||||
_occ_pairs = args.mesh_attributes.get("sharp_edge_pairs") or []
|
||||
if _occ_pairs:
|
||||
apply_sharp_edges_from_occ(parts, _occ_pairs)
|
||||
lap_fn("smooth_shading")
|
||||
|
||||
if args.material_library_path and args.material_map:
|
||||
apply_material_library(
|
||||
parts, args.material_library_path,
|
||||
build_mat_map_lower(args.material_map), args.part_names_ordered,
|
||||
)
|
||||
else:
|
||||
for part in parts:
|
||||
assign_failed_material(part)
|
||||
lap_fn("material_assign")
|
||||
|
||||
if args.shadow_catcher:
|
||||
setup_shadow_catcher(parts)
|
||||
|
||||
needs_auto_camera = (
|
||||
(args.lighting_only and not args.shadow_catcher)
|
||||
or not bpy.context.scene.camera
|
||||
)
|
||||
if args.lighting_only and not args.shadow_catcher:
|
||||
print("[blender_render] lighting_only mode: using template World/HDRI, forcing auto-camera")
|
||||
elif needs_auto_camera:
|
||||
print("[blender_render] WARNING: template has no camera — will create auto-camera")
|
||||
|
||||
if not needs_auto_camera and bpy.context.scene.camera:
|
||||
bpy.context.scene.camera.data.clip_start = 0.001
|
||||
|
||||
print(f"[blender_render] template mode: {len(parts)} parts imported into collection '{args.target_collection}'")
|
||||
|
||||
if needs_auto_camera:
|
||||
setup_auto_camera(parts, args.width, args.height)
|
||||
|
||||
|
||||
def _setup_mode_a(args) -> None:
|
||||
"""MODE A: Factory settings — auto-camera + auto-lights."""
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
if args.usd_path:
|
||||
parts = import_usd_file(args.usd_path)
|
||||
else:
|
||||
parts = import_glb(args.glb_path)
|
||||
apply_rotation(parts, args.rotation_x, args.rotation_y, args.rotation_z)
|
||||
|
||||
_t = _time.time()
|
||||
apply_smooth_batch(parts, args.smooth_angle)
|
||||
if not args.usd_path:
|
||||
_occ_pairs = args.mesh_attributes.get("sharp_edge_pairs") or []
|
||||
if _occ_pairs:
|
||||
apply_sharp_edges_from_occ(parts, _occ_pairs)
|
||||
for part in parts:
|
||||
assign_failed_material(part)
|
||||
print(f"[blender_render] smooth+fallback-material: {len(parts)} parts ({_time.time()-_t:.2f}s)", flush=True)
|
||||
|
||||
if args.material_library_path and args.material_map:
|
||||
apply_material_library(
|
||||
parts, args.material_library_path,
|
||||
build_mat_map_lower(args.material_map), args.part_names_ordered,
|
||||
)
|
||||
|
||||
bbox_center, bsphere_radius = setup_auto_camera(parts, args.width, args.height)
|
||||
setup_auto_lights(bbox_center, bsphere_radius)
|
||||
world = bpy.data.worlds.new("World")
|
||||
bpy.context.scene.world = world
|
||||
world.use_nodes = True
|
||||
bg = world.node_tree.nodes["Background"]
|
||||
bg.inputs["Color"].default_value = (0.96, 0.96, 0.97, 1.0)
|
||||
bg.inputs["Strength"].default_value = 0.15
|
||||
Reference in New Issue
Block a user