change material seems to be working now
This commit is contained in:
parent
31bce0dfbd
commit
962839ad57
@ -354,54 +354,87 @@ class BlenderMCPServer:
|
||||
|
||||
def set_material(self, object_name, material_name=None, create_if_missing=True, color=None):
|
||||
"""Set or create a material for an object"""
|
||||
try:
|
||||
# Get the object
|
||||
obj = bpy.data.objects.get(object_name)
|
||||
if not obj:
|
||||
raise ValueError(f"Object not found: {object_name}")
|
||||
|
||||
# If material_name is provided, try to find or create the material
|
||||
# Make sure object can accept materials
|
||||
if not hasattr(obj, 'data') or not hasattr(obj.data, 'materials'):
|
||||
raise ValueError(f"Object {object_name} cannot accept materials")
|
||||
|
||||
# Create or get material
|
||||
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
|
||||
if mat:
|
||||
if obj.data.materials:
|
||||
obj.data.materials[0] = mat
|
||||
print(f"Created new material: {material_name}")
|
||||
else:
|
||||
obj.data.materials.append(mat)
|
||||
|
||||
return {"object": object_name, "material": material_name}
|
||||
|
||||
# If only color is provided, create a new material with the color
|
||||
elif color:
|
||||
# Create a new material with auto-generated name
|
||||
# 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}")
|
||||
|
||||
# Set material color
|
||||
# Set up material nodes if needed
|
||||
if mat:
|
||||
if not mat.use_nodes:
|
||||
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:
|
||||
# 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)
|
||||
|
||||
return {"object": object_name, "material": mat_name}
|
||||
|
||||
else:
|
||||
return {"error": "Either material_name or color must be provided"}
|
||||
# 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):
|
||||
"""Render the current scene"""
|
||||
|
||||
@ -473,44 +473,6 @@ def set_material(
|
||||
logger.error(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()
|
||||
def execute_blender_code(ctx: Context, code: str) -> str:
|
||||
"""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user