Refactor fountain assembly module
This commit is contained in:
@@ -54,11 +54,11 @@ from osmassets.mesh import ( # noqa: E402
|
||||
add_polyline,
|
||||
add_roof,
|
||||
add_wall_panel,
|
||||
link_object_to_collection,
|
||||
make_prism,
|
||||
new_collection,
|
||||
)
|
||||
from osmassets.osm import Projector, parse_height, parse_osm # noqa: E402
|
||||
from osmassets import fountain as _fountain # noqa: E402
|
||||
from osmassets import water as _water # noqa: E402
|
||||
from osmassets import grass as _grass # noqa: E402
|
||||
from osmassets import scrub as _scrub # noqa: E402
|
||||
@@ -67,8 +67,8 @@ from osmassets import tree as _tree # noqa: E402
|
||||
|
||||
# Building assembly stays in this file because it needs make_prism, add_roof,
|
||||
# add_wall_panel, and add_building_details — Blender geometry helpers that
|
||||
# live a few lines above. The other features moved to osmassets/{water,grass,
|
||||
# scrub}.py and take only pure-geometry primitives (MeshBatch / clip_polygon).
|
||||
# live a few lines above. The other feature assembly code lives under
|
||||
# osmassets/ and keeps build() focused on data dispatch, materials, and counts.
|
||||
def _assemble_building(ring, way_id, tag, args, buildings_c, building_mats):
|
||||
industrial = (tag.get("building") == "industrial" and
|
||||
way_id not in args["office_overrides"])
|
||||
@@ -636,48 +636,6 @@ def sample_scrub_interior_trees(ring, way_id):
|
||||
return trees
|
||||
|
||||
|
||||
def add_fountain(name, x, y, collection, materials):
|
||||
def cylinder(part_name, radius, depth, z, material, vertices=48):
|
||||
bpy.ops.mesh.primitive_cylinder_add(
|
||||
vertices=vertices, radius=radius, depth=depth,
|
||||
location=(x, y, z))
|
||||
obj = bpy.context.object
|
||||
obj.name = name + "_" + part_name
|
||||
link_object_to_collection(obj, collection)
|
||||
obj.data.materials.append(material)
|
||||
for polygon in obj.data.polygons:
|
||||
polygon.use_smooth = True
|
||||
return obj
|
||||
|
||||
basin = cylinder("Basin", 3.0, 0.32, 0.16,
|
||||
materials["fountain_stone"])
|
||||
basin["osm_feature"] = "amenity=fountain"
|
||||
cylinder("Water", 2.52, 0.045, 0.335,
|
||||
materials["fountain_water"])
|
||||
cylinder("Pedestal", 0.30, 0.78, 0.72,
|
||||
materials["fountain_stone"], vertices=32)
|
||||
|
||||
bpy.ops.mesh.primitive_uv_sphere_add(
|
||||
segments=20, ring_count=10, radius=0.22,
|
||||
location=(x, y, 1.30))
|
||||
crown = bpy.context.object
|
||||
crown.name = name + "_Water_Crown"
|
||||
link_object_to_collection(crown, collection)
|
||||
crown.data.materials.append(materials["fountain_spray"])
|
||||
for index in range(8):
|
||||
angle = math.tau * index / 8.0
|
||||
radius = 0.50
|
||||
bpy.ops.mesh.primitive_uv_sphere_add(
|
||||
segments=12, ring_count=6, radius=0.075,
|
||||
location=(x + math.cos(angle) * radius,
|
||||
y + math.sin(angle) * radius,
|
||||
1.02 + 0.10 * math.sin(angle * 2.0)))
|
||||
droplet = bpy.context.object
|
||||
droplet.name = name + "_Droplet_" + str(index + 1)
|
||||
link_object_to_collection(droplet, collection)
|
||||
droplet.data.materials.append(materials["fountain_spray"])
|
||||
|
||||
|
||||
def look_at(obj, target):
|
||||
obj.rotation_euler = (Vector(target) - obj.location).to_track_quat("-Z", "Y").to_euler()
|
||||
|
||||
@@ -898,8 +856,8 @@ def build(args):
|
||||
if not projector.inside(feature["coord"]):
|
||||
continue
|
||||
fx, fy = projector.xy(feature["coord"])
|
||||
add_fountain("Fountain_" + str(feature["id"]), fx, fy,
|
||||
props_c, fountain_mats)
|
||||
_fountain.assemble("Fountain_" + str(feature["id"]), fx, fy,
|
||||
props_c, fountain_mats)
|
||||
counts["fountain_count"] += 1
|
||||
|
||||
bpy.ops.object.light_add(type="SUN", location=(0, 0, 500))
|
||||
|
||||
49
blender/osmassets/fountain.py
Normal file
49
blender/osmassets/fountain.py
Normal file
@@ -0,0 +1,49 @@
|
||||
"""Fountain feature assembly (`amenity=fountain`)."""
|
||||
|
||||
import math
|
||||
|
||||
import bpy
|
||||
|
||||
from osmassets.mesh import link_object_to_collection
|
||||
|
||||
|
||||
def assemble(name, x, y, collection, materials):
|
||||
def cylinder(part_name, radius, depth, z, material, vertices=48):
|
||||
bpy.ops.mesh.primitive_cylinder_add(
|
||||
vertices=vertices, radius=radius, depth=depth,
|
||||
location=(x, y, z))
|
||||
obj = bpy.context.object
|
||||
obj.name = name + "_" + part_name
|
||||
link_object_to_collection(obj, collection)
|
||||
obj.data.materials.append(material)
|
||||
for polygon in obj.data.polygons:
|
||||
polygon.use_smooth = True
|
||||
return obj
|
||||
|
||||
basin = cylinder("Basin", 3.0, 0.32, 0.16,
|
||||
materials["fountain_stone"])
|
||||
basin["osm_feature"] = "amenity=fountain"
|
||||
cylinder("Water", 2.52, 0.045, 0.335,
|
||||
materials["fountain_water"])
|
||||
cylinder("Pedestal", 0.30, 0.78, 0.72,
|
||||
materials["fountain_stone"], vertices=32)
|
||||
|
||||
bpy.ops.mesh.primitive_uv_sphere_add(
|
||||
segments=20, ring_count=10, radius=0.22,
|
||||
location=(x, y, 1.30))
|
||||
crown = bpy.context.object
|
||||
crown.name = name + "_Water_Crown"
|
||||
link_object_to_collection(crown, collection)
|
||||
crown.data.materials.append(materials["fountain_spray"])
|
||||
for index in range(8):
|
||||
angle = math.tau * index / 8.0
|
||||
radius = 0.50
|
||||
bpy.ops.mesh.primitive_uv_sphere_add(
|
||||
segments=12, ring_count=6, radius=0.075,
|
||||
location=(x + math.cos(angle) * radius,
|
||||
y + math.sin(angle) * radius,
|
||||
1.02 + 0.10 * math.sin(angle * 2.0)))
|
||||
droplet = bpy.context.object
|
||||
droplet.name = name + "_Droplet_" + str(index + 1)
|
||||
link_object_to_collection(droplet, collection)
|
||||
droplet.data.materials.append(materials["fountain_spray"])
|
||||
Reference in New Issue
Block a user