Rock Generator 2.10.0: Quader als Grundform (Platten und Riegel)
Auf Wunsch des Users neben Wuerfel und Ico-Sphere eine Quader-Grundform mit frei einstellbaren Proportionen (X/Y/Z) plus Streuung je Stein. Damit entstehen flache Platten und langgestreckte Riegel - passt besonders zum Plattenlook der Genshin-Referenz, wo Felsen aus flachen Schichten bestehen. Wichtiges Detail: die Proportionen werden auf die MESH-DATEN angewendet (transform_apply), nicht auf das Objekt. Der Displace arbeitet mit globalen Texturkoordinaten - eine Objekt-Skalierung wuerde das Rauschen mitverzerren statt die Form zu aendern. Gemessen bei Proportion (2.0, 1.5, 0.35): 3.43 / 2.56 / 0.79 m (Z = 23 % von X), bei (2.2, 0.8, 0.9): 3.81 / 1.40 / 1.60 m. Der Zufalls-Button kennt die neue Form ebenfalls. Neuer Test tests/test_base_shapes.py. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import bpy, sys, importlib.util, mathutils
|
||||
spec=importlib.util.spec_from_file_location("srg", r"A:\eco\stylized_rock_generator\stylized_rock_generator.py")
|
||||
r=importlib.util.module_from_spec(spec); sys.modules["srg"]=r; spec.loader.exec_module(r)
|
||||
try: r.unregister()
|
||||
except Exception: pass
|
||||
r.register()
|
||||
fails=[]
|
||||
s=bpy.context.scene.rock_gen_settings
|
||||
s.batch_count=1; s.subsurf_levels=4; s.use_modal=False
|
||||
s.shading_mode='FLAT'; s.bake_vertex_cavity=True; s.set_origin_bottom=True
|
||||
s.randomize_transform=False # Proportionen isoliert messen
|
||||
mat=bpy.data.materials.new("P"); mat.use_nodes=True
|
||||
nt=mat.node_tree; nt.nodes.clear()
|
||||
o_=nt.nodes.new("ShaderNodeOutputMaterial"); b=nt.nodes.new("ShaderNodeBsdfPrincipled")
|
||||
c=nt.nodes.new("ShaderNodeVertexColor"); c.layer_name="Cavity"
|
||||
sep=nt.nodes.new("ShaderNodeSeparateColor"); nt.links.new(c.outputs["Color"], sep.inputs[0])
|
||||
t=nt.nodes.new("ShaderNodeRGB"); t.outputs[0].default_value=(0.66,0.64,0.60,1)
|
||||
mx=nt.nodes.new("ShaderNodeMixRGB"); mx.blend_type='MULTIPLY'; mx.inputs["Fac"].default_value=1.0
|
||||
nt.links.new(t.outputs[0],mx.inputs["Color1"]); nt.links.new(sep.outputs[0],mx.inputs["Color2"])
|
||||
nt.links.new(mx.outputs[0],b.inputs["Base Color"]); b.inputs["Roughness"].default_value=0.85
|
||||
nt.links.new(b.outputs[0],o_.inputs["Surface"])
|
||||
VARS=[("Wuerfel",'CUBE',None),
|
||||
("Platte",'BOX',(2.0,1.5,0.35)),
|
||||
("Riegel",'BOX',(2.2,0.8,0.9)),
|
||||
("Ico",'ICOSPHERE',None)]
|
||||
print("%-9s %-6s %s" % ("Variante","Form","Abmessungen X/Y/Z (m)"))
|
||||
keep=[]; x=0.0
|
||||
for name,shape,prop in VARS:
|
||||
for o in list(bpy.data.objects): bpy.data.objects.remove(o,do_unlink=True)
|
||||
s.base_shape=shape; s.box_variation=0.0
|
||||
if prop: s.box_proportions=prop
|
||||
s.seed=7
|
||||
bpy.ops.object.generate_rocks_batch()
|
||||
ob=[o for o in bpy.context.scene.objects if o.type=='MESH'][0]
|
||||
bb=ob.bound_box
|
||||
d=[max(v[i] for v in bb)-min(v[i] for v in bb) for i in range(3)]
|
||||
print("%-9s %-6s %.2f / %.2f / %.2f" % (name,shape,d[0],d[1],d[2]))
|
||||
if name=="Platte" and not (d[2] < d[0]*0.45): fails.append("platte_nicht_flach")
|
||||
if name=="Riegel" and not (d[0] > d[1]*1.5): fails.append("riegel_nicht_laenglich")
|
||||
cp=ob.copy(); cp.data=ob.data.copy(); keep.append((cp,x))
|
||||
x+=2.4
|
||||
for cp,px in keep:
|
||||
bpy.context.collection.objects.link(cp); cp.location=(px,0,0)
|
||||
cp.data.materials.clear(); cp.data.materials.append(mat)
|
||||
for o in list(bpy.context.scene.objects):
|
||||
if o.type=='MESH' and o not in [k[0] for k in keep]: bpy.data.objects.remove(o,do_unlink=True)
|
||||
cam_d=bpy.data.cameras.new("C"); cam=bpy.data.objects.new("C",cam_d)
|
||||
bpy.context.scene.collection.objects.link(cam); bpy.context.scene.camera=cam
|
||||
cam.location=(3.6,-9.0,2.6)
|
||||
d=mathutils.Vector((3.6,0,0.5))-cam.location
|
||||
cam.rotation_euler=d.to_track_quat('-Z','Y').to_euler()
|
||||
sun=bpy.data.objects.new("S", bpy.data.lights.new("S",'SUN'))
|
||||
bpy.context.scene.collection.objects.link(sun); sun.rotation_euler=(0.9,0.2,0.7); sun.data.energy=3.5
|
||||
sc=bpy.context.scene; sc.render.engine='CYCLES'; sc.cycles.samples=18
|
||||
sc.render.resolution_x=1250; sc.render.resolution_y=470
|
||||
sc.render.filepath=r"C:\Users\az319\AppData\Local\Temp\claude\A--eco-EcoGame--claude-worktrees-rock-generator-hardening-3d5f61\cf805d69-059c-4821-ac92-afae28022987\scratchpad\formen.png"
|
||||
bpy.ops.render.render(write_still=True)
|
||||
r.unregister()
|
||||
print("ERGEBNIS:", "ALLE CHECKS OK" if not fails else "FEHLER: "+", ".join(fails))
|
||||
Reference in New Issue
Block a user