generate_scene.py 从 1271 → 816 行 (-455)
P0: 纯函数搬家
- osmassets/osm.py: parse_osm / Projector / parse_height
- osmassets/geom.py: clip_polygon / point_in_polygon / distance_to_ring / sample_tree_row 等
- blender/tests/test_pure.py: 42 个 unittest (脱离 bpy 运行)
P1: 单一定义源
- osmassets/catalog.py: ROAD_LAYERS + MATERIALS (含 cesium 导出参数)
- 对接 osm2streets_scene_style.json 做图层一致性 warning
- 干掉 road_mats / layer_z / 材质参数三份副本
P2: 要素注册表
- osmassets/{water,grass,scrub}.py: 每个要素一个 assemble() 函数
- build() 中的 if/elif 链收缩为注册表调用
- 计数器集中到 counts 字典
P3: 材质契约化
- catalog.py 扩展 CESIUM_EXPORT 段 (tint/metallic/emission)
- 标记已发现的死条目 Office White Metal Facade (四表各一组)
校验:
- parity.js + scene_digest.py + glb-digest.js 三位一体
- control-1 vs p0/p1/p2a/p2b/p3-counts: 两区域全 PARITY OK
- 42 个纯 Python 测试全部通过
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
23 lines
783 B
Python
23 lines
783 B
Python
"""Grass feature assembly (`landuse=grass`) with optional tuft scattering."""
|
|
|
|
from osmassets.geom import clip_polygon
|
|
from osmassets.mesh import MeshBatch
|
|
|
|
|
|
def assemble(ring, way_id, scene_xmin, scene_xmax, scene_ymin, scene_ymax,
|
|
green_c, grass_mat, tuft_variants, add_grass_tufts_fn):
|
|
ring = clip_polygon(ring, scene_xmin, scene_xmax, scene_ymin, scene_ymax)
|
|
name = "Grass_" + str(way_id)
|
|
focus = list(ring)
|
|
if len(ring) < 3:
|
|
return 0, 0, focus
|
|
batch = MeshBatch(name, green_c, grass_mat)
|
|
batch.add_polygon(ring, 0.015)
|
|
obj = batch.finish()
|
|
tufts = 0
|
|
if tuft_variants:
|
|
tufts = add_grass_tufts_fn(name, ring, tuft_variants, green_c)
|
|
if obj:
|
|
obj["grass_tufts"] = tufts
|
|
return 1, tufts, focus
|