change material seems to be working now

This commit is contained in:
ahujasid 2025-03-08 01:07:37 +05:30
parent 31bce0dfbd
commit 962839ad57
2 changed files with 77 additions and 82 deletions

View File

@ -354,54 +354,87 @@ class BlenderMCPServer:
def set_material(self, object_name, material_name=None, create_if_missing=True, color=None): def set_material(self, object_name, material_name=None, create_if_missing=True, color=None):
"""Set or create a material for an object""" """Set or create a material for an object"""
obj = bpy.data.objects.get(object_name) try:
if not obj: # Get the object
raise ValueError(f"Object not found: {object_name}") obj = bpy.data.objects.get(object_name)
if not obj:
# If material_name is provided, try to find or create the material raise ValueError(f"Object not found: {object_name}")
if material_name:
mat = bpy.data.materials.get(material_name)
if not mat and create_if_missing:
mat = bpy.data.materials.new(name=material_name)
# Set material color if provided
if color and len(color) >= 3:
mat.use_nodes = True
bsdf = mat.node_tree.nodes.get('Principled BSDF')
if bsdf:
bsdf.inputs[0].default_value = (color[0], color[1], color[2], 1.0 if len(color) < 4 else color[3])
# Assign material to object # Make sure object can accept materials
if mat: if not hasattr(obj, 'data') or not hasattr(obj.data, 'materials'):
if obj.data.materials: raise ValueError(f"Object {object_name} cannot accept materials")
obj.data.materials[0] = mat
else:
obj.data.materials.append(mat)
return {"object": object_name, "material": material_name} # Create or get material
if material_name:
# If only color is provided, create a new material with the color mat = bpy.data.materials.get(material_name)
elif color: if not mat and create_if_missing:
# Create a new material with auto-generated name mat = bpy.data.materials.new(name=material_name)
mat_name = f"{object_name}_material" print(f"Created new material: {material_name}")
mat = bpy.data.materials.new(name=mat_name)
# Set material color
mat.use_nodes = True
bsdf = mat.node_tree.nodes.get('Principled BSDF')
if bsdf:
bsdf.inputs[0].default_value = (color[0], color[1], color[2], 1.0 if len(color) < 4 else color[3])
# Assign material to object
if obj.data.materials:
obj.data.materials[0] = mat
else: else:
obj.data.materials.append(mat) # Generate unique material name if none provided
mat_name = f"{object_name}_material"
mat = bpy.data.materials.get(mat_name)
if not mat:
mat = bpy.data.materials.new(name=mat_name)
material_name = mat_name
print(f"Using material: {mat_name}")
return {"object": object_name, "material": mat_name} # Set up material nodes if needed
if mat:
else: if not mat.use_nodes:
return {"error": "Either material_name or color must be provided"} mat.use_nodes = True
# Get or create Principled BSDF
principled = mat.node_tree.nodes.get('Principled BSDF')
if not principled:
principled = mat.node_tree.nodes.new('ShaderNodeBsdfPrincipled')
# Get or create Material Output
output = mat.node_tree.nodes.get('Material Output')
if not output:
output = mat.node_tree.nodes.new('ShaderNodeOutputMaterial')
# Link if not already linked
if not principled.outputs[0].links:
mat.node_tree.links.new(principled.outputs[0], output.inputs[0])
# Set color if provided
if color and len(color) >= 3:
principled.inputs['Base Color'].default_value = (
color[0],
color[1],
color[2],
1.0 if len(color) < 4 else color[3]
)
print(f"Set material color to {color}")
# Assign material to object if not already assigned
if mat:
if not obj.data.materials:
obj.data.materials.append(mat)
else:
# Only modify first material slot
obj.data.materials[0] = mat
print(f"Assigned material {mat.name} to object {object_name}")
return {
"status": "success",
"object": object_name,
"material": mat.name,
"color": color if color else None
}
else:
raise ValueError(f"Failed to create or find material: {material_name}")
except Exception as e:
print(f"Error in set_material: {str(e)}")
import traceback
traceback.print_exc()
return {
"status": "error",
"message": str(e),
"object": object_name,
"material": material_name if 'material_name' in locals() else None
}
def render_scene(self, output_path=None, resolution_x=None, resolution_y=None): def render_scene(self, output_path=None, resolution_x=None, resolution_y=None):
"""Render the current scene""" """Render the current scene"""

View File

@ -473,44 +473,6 @@ def set_material(
logger.error(f"Error setting material: {str(e)}") logger.error(f"Error setting material: {str(e)}")
return f"Error setting material: {str(e)}" return f"Error setting material: {str(e)}"
@mcp.tool()
def render_scene(
ctx: Context,
output_path: str = None,
resolution_x: int = None,
resolution_y: int = None
) -> str:
"""
Render the current scene and return the image.
Parameters:
- output_path: Optional path to save the rendered image
- resolution_x: Optional horizontal resolution
- resolution_y: Optional vertical resolution
"""
try:
# Get the global connection
blender = get_blender_connection()
params = {}
if output_path:
params["output_path"] = output_path
if resolution_x:
params["resolution_x"] = resolution_x
if resolution_y:
params["resolution_y"] = resolution_y
result = blender.send_command("render_scene", params)
if "image_path" in result:
# If we have an image path, we could potentially load and return the image
return f"Scene rendered to {result['image_path']}"
else:
return "Scene rendered successfully"
except Exception as e:
logger.error(f"Error rendering scene: {str(e)}")
return f"Error rendering scene: {str(e)}"
@mcp.tool() @mcp.tool()
def execute_blender_code(ctx: Context, code: str) -> str: def execute_blender_code(ctx: Context, code: str) -> str:
""" """