From bf3e0a812ad3974bedc078c320e15940c61bce56 Mon Sep 17 00:00:00 2001 From: MayaTheShy Date: Sat, 8 Nov 2025 23:16:19 -0500 Subject: [PATCH] feat: streamline material creation and enhance export process for colored primitives --- tools/blender_export_primitives.py | 196 +++++++++++++---------------- 1 file changed, 85 insertions(+), 111 deletions(-) diff --git a/tools/blender_export_primitives.py b/tools/blender_export_primitives.py index 274a6e6..ec602e6 100644 --- a/tools/blender_export_primitives.py +++ b/tools/blender_export_primitives.py @@ -1,6 +1,9 @@ import bpy import os -import traceback + +print("="*60) +print("EXPORTING COLORED PRIMITIVES FOR STARWORLD") +print("="*60) # Clear existing objects bpy.ops.object.select_all(action='SELECT') @@ -9,125 +12,96 @@ bpy.ops.object.delete(use_global=False) # Output directory output_dir = os.path.expanduser("~/.cache/starworld/primitives") os.makedirs(output_dir, exist_ok=True) +print(f"Output directory: {output_dir}\n") def create_material(name, base_color): """Create a PBR material with the specified base color (RGBA)""" - try: - mat = bpy.data.materials.new(name=name) - mat.use_nodes = True - nodes = mat.node_tree.nodes - - # Find the Principled BSDF node (should be created by default) - bsdf = None - for node in nodes: - if node.type == 'BSDF_PRINCIPLED': - bsdf = node - break - - # If not found, create it - if not bsdf: - bsdf = nodes.new(type='ShaderNodeBsdfPrincipled') - - # Set material properties - bsdf.inputs['Base Color'].default_value = base_color - bsdf.inputs['Roughness'].default_value = 0.5 - bsdf.inputs['Metallic'].default_value = 0.1 - - print(f" Created material '{name}' with color {base_color}") - return mat - except Exception as e: - print(f"ERROR creating material: {e}") - traceback.print_exc() - return None + mat = bpy.data.materials.new(name=name) + mat.use_nodes = True + nodes = mat.node_tree.nodes + + # Find the Principled BSDF node + bsdf = None + for node in nodes: + if node.type == 'BSDF_PRINCIPLED': + bsdf = node + break + + if not bsdf: + bsdf = nodes.new(type='ShaderNodeBsdfPrincipled') + + # Set material properties + bsdf.inputs['Base Color'].default_value = base_color + bsdf.inputs['Roughness'].default_value = 0.5 + bsdf.inputs['Metallic'].default_value = 0.1 + + return mat -try: - print("Creating GREEN sphere...") - # Create and export UV Sphere with GREEN material - bpy.ops.mesh.primitive_uv_sphere_add(segments=32, ring_count=16, radius=0.5, location=(0, 0, 0)) - sphere = bpy.context.active_object - sphere.name = "Sphere" - sphere.select_set(True) - bpy.context.view_layer.objects.active = sphere - bpy.ops.object.shade_smooth() - - # Apply green material - green_mat = create_material("SphereMaterial", (0.2, 1.0, 0.2, 1.0)) # Green - if green_mat: - sphere.data.materials.append(green_mat) - - sphere_path = os.path.join(output_dir, "sphere.glb") - print(f" Exporting to {sphere_path}...") - bpy.ops.export_scene.gltf( - filepath=sphere_path, - export_format='GLB', - use_selection=True - ) - print(f"✓ Exported sphere.glb (GREEN)") -except Exception as e: - print(f"ERROR with sphere: {e}") - traceback.print_exc() +# ========== SPHERE (GREEN) ========== +print("1. Creating GREEN sphere...") +bpy.ops.mesh.primitive_uv_sphere_add(segments=32, ring_count=16, radius=0.5, location=(0, 0, 0)) +sphere = bpy.context.active_object +sphere.name = "Sphere" +bpy.ops.object.shade_smooth() -try: - print("\nCreating RED cube...") - # Delete sphere and create cube with RED material - bpy.ops.object.delete(use_global=False) - bpy.ops.mesh.primitive_cube_add(size=1.0, location=(0, 0, 0)) - cube = bpy.context.active_object - cube.name = "Cube" - cube.select_set(True) - bpy.context.view_layer.objects.active = cube - bpy.ops.object.shade_smooth() - - # Apply red material - red_mat = create_material("CubeMaterial", (1.0, 0.2, 0.2, 1.0)) # Red - if red_mat: - cube.data.materials.append(red_mat) - - cube_path = os.path.join(output_dir, "cube.glb") - print(f" Exporting to {cube_path}...") - bpy.ops.export_scene.gltf( - filepath=cube_path, - export_format='GLB', - use_selection=True - ) - print(f"✓ Exported cube.glb (RED)") -except Exception as e: - print(f"ERROR with cube: {e}") - traceback.print_exc() +green_mat = create_material("SphereMaterial", (0.2, 1.0, 0.2, 1.0)) +sphere.data.materials.append(green_mat) -try: - print("\nCreating BLUE icosphere...") - # Delete cube and create ico sphere for the "model" placeholder with BLUE material - bpy.ops.object.delete(use_global=False) - bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=2, radius=0.5, location=(0, 0, 0)) - ico = bpy.context.active_object - ico.name = "IcoSphere" - ico.select_set(True) - bpy.context.view_layer.objects.active = ico - bpy.ops.object.shade_smooth() - - # Apply blue material - blue_mat = create_material("IcoSphereMaterial", (0.2, 0.2, 1.0, 1.0)) # Blue - if blue_mat: - ico.data.materials.append(blue_mat) - - model_path = os.path.join(output_dir, "model.glb") - print(f" Exporting to {model_path}...") - bpy.ops.export_scene.gltf( - filepath=model_path, - export_format='GLB', - use_selection=True - ) - print(f"✓ Exported model.glb (BLUE)") -except Exception as e: - print(f"ERROR with icosphere: {e}") - traceback.print_exc() +bpy.ops.object.select_all(action='DESELECT') +sphere.select_set(True) + +sphere_path = os.path.join(output_dir, "sphere.glb") +bpy.ops.export_scene.gltf(filepath=sphere_path, use_selection=True) +print(f" ✓ Exported: {sphere_path}") + +# Clean up +bpy.ops.object.delete(use_global=False) + +# Clean up +bpy.ops.object.delete(use_global=False) + +# ========== CUBE (RED) ========== +print("\n2. Creating RED cube...") +bpy.ops.mesh.primitive_cube_add(size=1.0, location=(0, 0, 0)) +cube = bpy.context.active_object +cube.name = "Cube" +bpy.ops.object.shade_smooth() + +red_mat = create_material("CubeMaterial", (1.0, 0.2, 0.2, 1.0)) +cube.data.materials.append(red_mat) + +bpy.ops.object.select_all(action='DESELECT') +cube.select_set(True) + +cube_path = os.path.join(output_dir, "cube.glb") +bpy.ops.export_scene.gltf(filepath=cube_path, use_selection=True) +print(f" ✓ Exported: {cube_path}") + +# Clean up +bpy.ops.object.delete(use_global=False) + +# ========== ICOSPHERE (BLUE) ========== +print("\n3. Creating BLUE icosphere...") +bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=2, radius=0.5, location=(0, 0, 0)) +ico = bpy.context.active_object +ico.name = "IcoSphere" +bpy.ops.object.shade_smooth() + +blue_mat = create_material("IcoSphereMaterial", (0.2, 0.2, 1.0, 1.0)) +ico.data.materials.append(blue_mat) + +bpy.ops.object.select_all(action='DESELECT') +ico.select_set(True) + +model_path = os.path.join(output_dir, "model.glb") +bpy.ops.export_scene.gltf(filepath=model_path, use_selection=True) +print(f" ✓ Exported: {model_path}") print("\n" + "="*60) -print("✓ EXPORT COMPLETE!") +print("✓ ALL EXPORTS COMPLETE!") print("="*60) -print(f"Output directory: {output_dir}") +print(f"Files created in: {output_dir}") +print(" - sphere.glb (GREEN)") print(" - cube.glb (RED)") -print(" - sphere.glb (GREEN)") print(" - model.glb (BLUE)") print("="*60)