added polyhaven checkbox

This commit is contained in:
ahujasid 2025-03-13 17:02:04 +05:30
parent 40a8334b97
commit 36c05e7196
3 changed files with 80 additions and 60 deletions

View File

@ -80,8 +80,8 @@ uvx blender-mcp
1. In Blender, go to the 3D View sidebar (press N if not visible)
2. Find the "BlenderMCP" tab
3. Set the port number (default: 9876)
4. Click "Start MCP Server"
3. Turn on the Poly Haven checkbox if you want assets from their API (optional)
4. Click "Connect to Claude"
5. Make sure the MCP server is running in your terminal
### Using with Claude

View File

@ -148,14 +148,12 @@ class BlenderMCPServer:
cmd_type = command.get("type")
params = command.get("params", {})
# Add a simple ping handler
if cmd_type == "ping":
print("Handling ping command")
return {"status": "success", "result": {"pong": True}}
# Add a handler for checking PolyHaven status
if cmd_type == "get_polyhaven_status":
return {"status": "success", "result": self.get_polyhaven_status()}
# Base handlers that are always available
handlers = {
"ping": lambda **kwargs: {"pong": True},
"get_simple_info": self.get_simple_info,
"get_scene_info": self.get_scene_info,
"create_object": self.create_object,
"modify_object": self.modify_object,
@ -163,13 +161,18 @@ class BlenderMCPServer:
"get_object_info": self.get_object_info,
"execute_code": self.execute_code,
"set_material": self.set_material,
"render_scene": self.render_scene,
# Add Polyhaven handlers
"get_polyhaven_status": self.get_polyhaven_status,
}
# Add Polyhaven handlers only if enabled
if bpy.context.scene.blendermcp_use_polyhaven:
polyhaven_handlers = {
"get_polyhaven_categories": self.get_polyhaven_categories,
"search_polyhaven_assets": self.search_polyhaven_assets,
"download_polyhaven_asset": self.download_polyhaven_asset,
"set_texture": self.set_texture,
}
handlers.update(polyhaven_handlers)
handler = handlers.get(cmd_type)
if handler:
@ -1137,6 +1140,19 @@ class BlenderMCPServer:
traceback.print_exc()
return {"error": f"Failed to apply texture: {str(e)}"}
def get_polyhaven_status(self):
"""Get the current status of PolyHaven integration"""
enabled = bpy.context.scene.blendermcp_use_polyhaven
if enabled:
return {"enabled": True, "message": "PolyHaven integration is enabled and ready to use."}
else:
return {
"enabled": False,
"message": """PolyHaven integration is currently disabled. To enable it:
1. In the 3D Viewport, find the BlenderMCP panel in the sidebar (press N if hidden)
2. Check the 'Use assets from Poly Haven' checkbox
3. Restart the connection to Claude"""
}
# Blender UI Panel
class BLENDERMCP_PT_Panel(bpy.types.Panel):
@ -1151,6 +1167,7 @@ class BLENDERMCP_PT_Panel(bpy.types.Panel):
scene = context.scene
layout.prop(scene, "blendermcp_port")
layout.prop(scene, "blendermcp_use_polyhaven", text="Use assets from Poly Haven")
if not scene.blendermcp_server_running:
layout.operator("blendermcp.start_server", text="Start MCP Server")
@ -1161,7 +1178,7 @@ class BLENDERMCP_PT_Panel(bpy.types.Panel):
# Operator to start the server
class BLENDERMCP_OT_StartServer(bpy.types.Operator):
bl_idname = "blendermcp.start_server"
bl_label = "Start BlenderMCP Server"
bl_label = "Connect to Claude"
bl_description = "Start the BlenderMCP server to connect with Claude"
def execute(self, context):
@ -1180,8 +1197,8 @@ class BLENDERMCP_OT_StartServer(bpy.types.Operator):
# Operator to stop the server
class BLENDERMCP_OT_StopServer(bpy.types.Operator):
bl_idname = "blendermcp.stop_server"
bl_label = "Stop BlenderMCP Server"
bl_description = "Stop the BlenderMCP server"
bl_label = "Stop the connection to Claude"
bl_description = "Stop the connection to Claude"
def execute(self, context):
scene = context.scene
@ -1210,6 +1227,12 @@ def register():
default=False
)
bpy.types.Scene.blendermcp_use_polyhaven = bpy.props.BoolProperty(
name="Use Poly Haven",
description="Enable Poly Haven asset integration",
default=False
)
bpy.utils.register_class(BLENDERMCP_PT_Panel)
bpy.utils.register_class(BLENDERMCP_OT_StartServer)
bpy.utils.register_class(BLENDERMCP_OT_StopServer)
@ -1228,6 +1251,7 @@ def unregister():
del bpy.types.Scene.blendermcp_port
del bpy.types.Scene.blendermcp_server_running
del bpy.types.Scene.blendermcp_use_polyhaven
print("BlenderMCP addon unregistered")

View File

@ -196,17 +196,19 @@ mcp = FastMCP(
# Global connection for resources (since resources can't access context)
_blender_connection = None
_polyhaven_enabled = False # Add this global variable
def get_blender_connection():
"""Get or create a persistent Blender connection"""
global _blender_connection
global _blender_connection, _polyhaven_enabled # Add _polyhaven_enabled to globals
# If we have an existing connection, check if it's still valid
if _blender_connection is not None:
# Test if the connection is still alive with a simple ping
try:
# Just try to send a small message to check if the socket is still connected
_blender_connection.sock.sendall(b'')
# First check if PolyHaven is enabled by sending a ping command
result = _blender_connection.send_command("get_polyhaven_status")
# Store the PolyHaven status globally
_polyhaven_enabled = result.get("enabled", False)
return _blender_connection
except Exception as e:
# Connection is dead, close it and create a new one
@ -260,33 +262,7 @@ def get_object_info(ctx: Context, object_name: str) -> str:
logger.error(f"Error getting object info from Blender: {str(e)}")
return f"Error getting object info: {str(e)}"
# Tool endpoints
@mcp.tool()
@mcp.tool()
def set_object_property(
ctx: Context,
name: str,
property: str,
value: Any
) -> str:
"""
Set a single property of an object.
Parameters:
- name: Name of the object
- property: Property to set (location, rotation, scale, color, visible)
- value: New value for the property
"""
try:
blender = get_blender_connection()
params = {"name": name, property: value}
result = blender.send_command("modify_object", params)
return f"Set {property} of {name} to {value}"
except Exception as e:
return f"Error setting property: {str(e)}"
@mcp.tool()
def create_object(
@ -447,11 +423,11 @@ def get_polyhaven_categories(ctx: Context, asset_type: str = "hdris") -> str:
Parameters:
- asset_type: The type of asset to get categories for (hdris, textures, models, all)
Returns a list of categories with the count of assets in each category.
"""
try:
blender = get_blender_connection()
if not _polyhaven_enabled:
return "PolyHaven integration is disabled. Select it in the sidebar in BlenderMCP, then run it again."
result = blender.send_command("get_polyhaven_categories", {"asset_type": asset_type})
if "error" in result:
@ -632,25 +608,45 @@ def set_texture(
logger.error(f"Error applying texture: {str(e)}")
return f"Error applying texture: {str(e)}"
@mcp.tool()
def get_polyhaven_status(ctx: Context) -> str:
"""
Check if PolyHaven integration is enabled in Blender.
Returns a message indicating whether PolyHaven features are available.
"""
try:
blender = get_blender_connection()
result = blender.send_command("get_polyhaven_status")
enabled = result.get("enabled", False)
message = result.get("message", "")
return message
except Exception as e:
logger.error(f"Error checking PolyHaven status: {str(e)}")
return f"Error checking PolyHaven status: {str(e)}"
@mcp.prompt()
def asset_creation_strategy() -> str:
"""Defines the preferred strategy for creating assets in Blender"""
return """When creating 3D content in Blender, follow these priorities:
return """When creating 3D content in Blender, always start by checking if PolyHaven is available:
1. First, try to find and use appropriate PolyHaven assets:
0. Before anything, always check the scene from get_scene_info()
1. First use get_polyhaven_status() to verify if PolyHaven integration is enabled.
2. If PolyHaven is enabled:
- For objects/models: Use download_polyhaven_asset() with asset_type="models"
- For materials/textures: Use download_polyhaven_asset() with asset_type="textures"
- For environment lighting: Use download_polyhaven_asset() with asset_type="hdris"
2. Only fall back to basic creation tools when:
3. If PolyHaven is disabled or when falling back to basic tools:
- create_object() for basic primitives (CUBE, SPHERE, CYLINDER, etc.)
- set_material() for basic colors and materials
Only fall back to basic creation tools when:
- PolyHaven is disabled
- A simple primitive is explicitly requested
- No suitable PolyHaven asset exists
- The task specifically requires a basic material/color
- Time or resource constraints make downloading assets impractical
Basic creation tools to use as fallback:
- create_object() for basic primitives
- set_material() for basic colors and materials
"""
# Main execution