Skip to main content
Glama

Maya MCP

create_advanced_model.py21.2 kB
from typing import Dict, List, Any, Optional def create_advanced_model( model_type: str, name: str = None, scale: float = 1.0, translate: List[float] = [0.0, 0.0, 0.0], rotate: List[float] = [0.0, 0.0, 0.0], color: List[float] = [0.5, 0.5, 0.5], parameters: Dict[str, Any] = None ) -> Dict[str, Any]: """Creates an advanced model in the Maya scene. Available model types: - car: Creates a simple car model with body, wheels, windows - tree: Creates a tree with trunk and foliage - building: Creates a simple building with windows - cup: Creates a cup/mug model - chair: Creates a simple chair model Parameters is a dictionary that can contain specific settings for each model type. Example parameters for car: {'wheels': 4, 'sporty': True, 'convertible': False} Example parameters for tree: {'branches': 3, 'leaf_density': 0.8, 'type': 'pine'} Scale applies a uniform scale to the entire model. Translate positions the model in world space. Rotate values are in degrees. Color applies an initial material color (RGB values between 0-1). """ import maya.cmds as cmds import random import math def _validate_vector3d(vec:List[float]): return isinstance(vec, list) and len(vec) == 3 and all([isinstance(v, float) for v in vec]) # Input validation if not _validate_vector3d(translate): raise ValueError("Invalid translate format. Must be a list of 3 float values.") if not _validate_vector3d(rotate): raise ValueError("Invalid rotate format. Must be a list of 3 float values.") if not _validate_vector3d(color): raise ValueError("Invalid color format. Must be a list of 3 float values between 0-1.") # Set default parameters dict if none provided if parameters is None: parameters = {} # Set default name if none provided if name is None: name = f"{model_type}_{int(random.random() * 1000)}" # Create a group for the entire model model_group = cmds.group(empty=True, name=name) # Create a Lambert material for the model mat_name = f"{name}_material" material = cmds.shadingNode('lambert', asShader=True, name=mat_name) cmds.setAttr(f"{mat_name}.color", color[0], color[1], color[2], type='double3') # Function to apply transformations to the entire model at the end def finalize_model(): # Apply scale to the group cmds.setAttr(f"{model_group}.scale", scale, scale, scale, type="double3") # Apply translate to the group cmds.setAttr(f"{model_group}.translate", translate[0], translate[1], translate[2], type="double3") # Apply rotate to the group cmds.setAttr(f"{model_group}.rotate", rotate[0], rotate[1], rotate[2], type="double3") return { "success": True, "name": model_group, "model_type": model_type, "components": components, "translate": translate, "rotate": rotate, "scale": scale } # Track components for return value components = [] # Create a simple car model if model_type.lower() == "car": # Get car-specific parameters with defaults wheels = parameters.get('wheels', 4) sporty = parameters.get('sporty', False) convertible = parameters.get('convertible', False) # Create car body if sporty: # Sporty car body - lower and sleeker body = cmds.polyCube(w=2.0, h=0.5, d=4.0, name=f"{name}_body")[0] cmds.move(0, 0.6, 0, body) # Make it more aerodynamic with a wedge shape cmds.select(f"{body}.f[1]") # Front face cmds.move(0, 0.2, 0, relative=True) else: # Standard car body body = cmds.polyCube(w=1.8, h=0.8, d=4.0, name=f"{name}_body")[0] cmds.move(0, 0.7, 0, body) components.append(body) cmds.parent(body, model_group) # Create cabin/roof unless it's a convertible if not convertible: cabin_height = 0.4 if sporty else 0.7 cabin_width = 1.6 if sporty else 1.7 cabin = cmds.polyCube(w=cabin_width, h=cabin_height, d=2.0, name=f"{name}_cabin")[0] cabin_y_pos = 1.15 if sporty else 1.6 cmds.move(0, cabin_y_pos, -0.2, cabin) components.append(cabin) cmds.parent(cabin, model_group) # Create wheels wheel_radius = 0.4 wheel_width = 0.2 wheel_positions = [] if wheels == 4: # Standard 4 wheels wheel_positions = [ [-0.9, wheel_radius, 1.5], # Front left [0.9, wheel_radius, 1.5], # Front right [-0.9, wheel_radius, -1.5], # Rear left [0.9, wheel_radius, -1.5] # Rear right ] elif wheels == 6: # 6 wheels (3 per side) wheel_positions = [ [-0.9, wheel_radius, 1.5], # Front left [0.9, wheel_radius, 1.5], # Front right [-0.9, wheel_radius, 0], # Middle left [0.9, wheel_radius, 0], # Middle right [-0.9, wheel_radius, -1.5], # Rear left [0.9, wheel_radius, -1.5] # Rear right ] for i, pos in enumerate(wheel_positions): wheel = cmds.polyCylinder(r=wheel_radius, h=wheel_width, ax=(1, 0, 0), name=f"{name}_wheel_{i}")[0] cmds.move(pos[0], pos[1], pos[2], wheel) components.append(wheel) cmds.parent(wheel, model_group) # Create windows (if not convertible) if not convertible: # Windshield windshield = cmds.polyCube(w=1.4, h=0.5, d=0.1, name=f"{name}_windshield")[0] windshield_y = 1.35 if sporty else 1.6 windshield_z = 0.6 if sporty else 0.7 cmds.move(0, windshield_y, windshield_z, windshield) cmds.rotate(45, 0, 0, windshield) # Rear window rear_window = cmds.polyCube(w=1.4, h=0.5, d=0.1, name=f"{name}_rear_window")[0] rear_window_y = 1.35 if sporty else 1.6 rear_window_z = -0.6 if sporty else -0.7 cmds.move(0, rear_window_y, rear_window_z, rear_window) cmds.rotate(-45, 0, 0, rear_window) components.append(windshield) components.append(rear_window) cmds.parent(windshield, model_group) cmds.parent(rear_window, model_group) # Side windows side_window_l = cmds.polyCube(w=0.1, h=0.4, d=1.4, name=f"{name}_side_window_l")[0] side_window_r = cmds.polyCube(w=0.1, h=0.4, d=1.4, name=f"{name}_side_window_r")[0] side_window_y = 1.3 if sporty else 1.5 cmds.move(-0.85, side_window_y, 0, side_window_l) cmds.move(0.85, side_window_y, 0, side_window_r) components.append(side_window_l) components.append(side_window_r) cmds.parent(side_window_l, model_group) cmds.parent(side_window_r, model_group) # Create headlights headlight_l = cmds.polyCylinder(r=0.2, h=0.1, ax=(1, 0, 0), name=f"{name}_headlight_l")[0] headlight_r = cmds.polyCylinder(r=0.2, h=0.1, ax=(1, 0, 0), name=f"{name}_headlight_r")[0] headlight_y = 0.7 if sporty else 0.8 cmds.move(-0.7, headlight_y, 2.0, headlight_l) cmds.move(0.7, headlight_y, 2.0, headlight_r) components.append(headlight_l) components.append(headlight_r) cmds.parent(headlight_l, model_group) cmds.parent(headlight_r, model_group) # Apply materials for comp in components: cmds.sets(comp, forceElement=cmds.sets(name=f"{mat_name}SG", renderable=True, noSurfaceShader=True)) elif model_type.lower() == "tree": # Get tree-specific parameters with defaults tree_type = parameters.get('type', 'oak') trunk_height = parameters.get('trunk_height', 5.0) trunk_radius = parameters.get('trunk_radius', 0.3) branches = parameters.get('branches', 5) leaf_density = parameters.get('leaf_density', 0.7) # Create trunk trunk = cmds.polyCylinder(r=trunk_radius, h=trunk_height, name=f"{name}_trunk")[0] cmds.move(0, trunk_height/2, 0, trunk) components.append(trunk) cmds.parent(trunk, model_group) # Create trunk material trunk_mat = cmds.shadingNode('lambert', asShader=True, name=f"{name}_trunk_material") cmds.setAttr(f"{trunk_mat}.color", 0.3, 0.2, 0.1, type='double3') cmds.sets(trunk, forceElement=cmds.sets(name=f"{trunk_mat}SG", renderable=True, noSurfaceShader=True)) # Create foliage based on tree type if tree_type.lower() in ('oak', 'maple', 'deciduous'): # Create a spherical foliage for deciduous trees foliage_radius = trunk_height * 0.4 * leaf_density foliage = cmds.polySphere(r=foliage_radius, name=f"{name}_foliage")[0] cmds.move(0, trunk_height + foliage_radius * 0.5, 0, foliage) # Add some variation to make it less perfect cmds.select(foliage) cmds.polySmooth(divisions=1) components.append(foliage) cmds.parent(foliage, model_group) elif tree_type.lower() in ('pine', 'conifer', 'evergreen'): # Create a cone-shaped foliage for coniferous trees layers = int(3 + leaf_density * 2) max_radius = trunk_height * 0.3 * leaf_density layer_height = trunk_height * 0.2 for i in range(layers): layer_radius = max_radius * (layers - i) / layers cone = cmds.polyCone(r=layer_radius, h=layer_height, name=f"{name}_foliage_{i}")[0] y_pos = trunk_height - (i * layer_height * 0.5) + (layers * layer_height * 0.5) cmds.move(0, y_pos, 0, cone) components.append(cone) cmds.parent(cone, model_group) elif tree_type.lower() in ('palm'): # Create a palm tree with a curved trunk and palm fronds # Curved trunk cmds.delete(trunk) # Remove straight trunk segments = 8 trunk = cmds.polyCylinder(r=trunk_radius, h=trunk_height/segments, subdivisionsHeight=1, name=f"{name}_trunk_base")[0] cmds.move(0, trunk_height/(segments*2), 0, trunk) components.append(trunk) # Create curved segments curve_direction = random.choice([-1, 1]) # Random curve direction for i in range(1, segments): segment = cmds.polyCylinder(r=trunk_radius * (1 - i * 0.05), h=trunk_height/segments, name=f"{name}_trunk_{i}")[0] y_pos = trunk_height * (i + 0.5) / segments x_offset = curve_direction * (math.sin(i / segments * math.pi * 0.5) * trunk_height * 0.15) cmds.move(x_offset, y_pos, 0, segment) # Rotate to follow curve angle = curve_direction * math.cos(i / segments * math.pi * 0.5) * 20 cmds.rotate(0, 0, angle, segment) components.append(segment) cmds.parent(segment, model_group) # Create palm fronds as cones frond_count = int(6 + leaf_density * 4) for i in range(frond_count): angle = i * (360 / frond_count) frond = cmds.polyCone(r=0.1, h=2.0, subdivisionsHeight=1, name=f"{name}_frond_{i}")[0] cmds.move(0, trunk_height, 0, frond) cmds.rotate(60, angle, 0, frond) components.append(frond) cmds.parent(frond, model_group) # Create leaf material leaf_mat = cmds.shadingNode('lambert', asShader=True, name=f"{name}_leaf_material") leaf_color = [0.0, 0.5, 0.0] # Default green # Adjust color based on tree type if tree_type.lower() in ('pine', 'conifer', 'evergreen'): leaf_color = [0.0, 0.3, 0.1] # Darker green for pine elif tree_type.lower() in ('maple'): # Could be green, red, or orange for maple season = parameters.get('season', 'summer') if season == 'fall': leaf_color = [0.8, 0.3, 0.0] # Orange/red for fall cmds.setAttr(f"{leaf_mat}.color", leaf_color[0], leaf_color[1], leaf_color[2], type='double3') # Apply leaf material to all foliage components except trunk foliage_components = [c for c in components if 'trunk' not in c] if foliage_components: cmds.sets(foliage_components, forceElement=cmds.sets(name=f"{leaf_mat}SG", renderable=True, noSurfaceShader=True)) elif model_type.lower() == "building": # Get building parameters with defaults width = parameters.get('width', 10.0) height = parameters.get('height', 15.0) depth = parameters.get('depth', 10.0) floors = parameters.get('floors', 3) windows_per_floor = parameters.get('windows_per_floor', 4) # Create building base building = cmds.polyCube(w=width, h=height, d=depth, name=f"{name}_main")[0] cmds.move(0, height/2, 0, building) components.append(building) cmds.parent(building, model_group) # Create roof roof = cmds.polyCube(w=width*1.1, h=height*0.1, d=depth*1.1, name=f"{name}_roof")[0] cmds.move(0, height + height*0.05, 0, roof) components.append(roof) cmds.parent(roof, model_group) # Create windows window_width = width * 0.15 window_height = height * 0.1 floor_height = height / floors # Calculate spacing front_window_spacing = width / (windows_per_floor + 1) side_window_spacing = depth / (windows_per_floor + 1) # Create windows on front side for floor in range(floors): for i in range(windows_per_floor): # Front windows window = cmds.polyCube(w=window_width, h=window_height, d=0.1, name=f"{name}_window_front_{floor}_{i}")[0] window_x = (i + 1) * front_window_spacing - width/2 window_y = (floor + 0.5) * floor_height cmds.move(window_x, window_y, depth/2, window) components.append(window) cmds.parent(window, model_group) # Back windows window = cmds.polyCube(w=window_width, h=window_height, d=0.1, name=f"{name}_window_back_{floor}_{i}")[0] cmds.move(window_x, window_y, -depth/2, window) components.append(window) cmds.parent(window, model_group) # Create windows on sides for floor in range(floors): for i in range(windows_per_floor): # Left side windows window = cmds.polyCube(w=0.1, h=window_height, d=window_width, name=f"{name}_window_left_{floor}_{i}")[0] window_z = (i + 1) * side_window_spacing - depth/2 window_y = (floor + 0.5) * floor_height cmds.move(-width/2, window_y, window_z, window) components.append(window) cmds.parent(window, model_group) # Right side windows window = cmds.polyCube(w=0.1, h=window_height, d=window_width, name=f"{name}_window_right_{floor}_{i}")[0] cmds.move(width/2, window_y, window_z, window) components.append(window) cmds.parent(window, model_group) # Create door door_width = width * 0.2 door_height = height * 0.2 door = cmds.polyCube(w=door_width, h=door_height, d=0.1, name=f"{name}_door")[0] cmds.move(0, door_height/2, depth/2, door) components.append(door) cmds.parent(door, model_group) # Apply materials building_mat = cmds.shadingNode('lambert', asShader=True, name=f"{name}_building_material") cmds.setAttr(f"{building_mat}.color", color[0], color[1], color[2], type='double3') cmds.sets([building, roof], forceElement=cmds.sets(name=f"{building_mat}SG", renderable=True, noSurfaceShader=True)) # Window material window_mat = cmds.shadingNode('lambert', asShader=True, name=f"{name}_window_material") cmds.setAttr(f"{window_mat}.color", 0.3, 0.7, 0.9, type='double3') # Get all window objects window_objects = [c for c in components if 'window' in c] if window_objects: cmds.sets(window_objects, forceElement=cmds.sets(name=f"{window_mat}SG", renderable=True, noSurfaceShader=True)) # Door material door_mat = cmds.shadingNode('lambert', asShader=True, name=f"{name}_door_material") cmds.setAttr(f"{door_mat}.color", 0.4, 0.2, 0.1, type='double3') cmds.sets(door, forceElement=cmds.sets(name=f"{door_mat}SG", renderable=True, noSurfaceShader=True)) elif model_type.lower() == "cup": # Get cup parameters radius = parameters.get('radius', 1.0) height = parameters.get('height', 2.0) handle = parameters.get('handle', True) # Create cup body cup = cmds.polyCylinder(r=radius, h=height, name=f"{name}_body")[0] cmds.move(0, height/2, 0, cup) # Create a hole in the cylinder to make it a cup inner_radius = radius * 0.8 inner_height = height * 0.9 inner = cmds.polyCylinder(r=inner_radius, h=inner_height, name=f"{name}_inner")[0] cmds.move(0, height/2 + (height - inner_height)/2, 0, inner) # Boolean the inner cylinder from the outer cup_final = cmds.polyCBoolOp(cup, inner, op=2, name=f"{name}_cup")[0] components.append(cup_final) cmds.parent(cup_final, model_group) # Create handle if requested if handle: # Create a curved handle using a torus handle = cmds.polyTorus(r=radius*0.8, sr=radius*0.1, twist=90, name=f"{name}_handle")[0] # Cut the torus to create a C-shaped handle cmds.select(f"{handle}.f[0:10]") # Select some faces to delete cmds.delete() # Position the handle cmds.move(radius, height/2, 0, handle) cmds.rotate(0, 90, 0, handle) components.append(handle) cmds.parent(handle, model_group) # Create a unified material cmds.sets([cup_final, handle], forceElement=cmds.sets(name=f"{mat_name}SG", renderable=True, noSurfaceShader=True)) else: # Apply material just to the cup cmds.sets(cup_final, forceElement=cmds.sets(name=f"{mat_name}SG", renderable=True, noSurfaceShader=True)) elif model_type.lower() == "chair": # Get chair parameters seat_width = parameters.get('seat_width', 2.0) seat_depth = parameters.get('seat_depth', 2.0) seat_height = parameters.get('seat_height', 1.5) back_height = parameters.get('back_height', 3.0) # Create seat seat = cmds.polyCube(w=seat_width, h=0.2, d=seat_depth, name=f"{name}_seat")[0] cmds.move(0, seat_height, 0, seat) components.append(seat) cmds.parent(seat, model_group) # Create back back = cmds.polyCube(w=seat_width, h=back_height, d=0.2, name=f"{name}_back")[0] cmds.move(0, seat_height + back_height/2, -seat_depth/2, back) components.append(back) cmds.parent(back, model_group) # Create legs leg_positions = [ [seat_width/2 - 0.1, seat_height/2, seat_depth/2 - 0.1], # Front right [-seat_width/2 + 0.1, seat_height/2, seat_depth/2 - 0.1], # Front left [seat_width/2 - 0.1, seat_height/2, -seat_depth/2 + 0.1], # Back right [-seat_width/2 + 0.1, seat_height/2, -seat_depth/2 + 0.1] # Back left ] for i, pos in enumerate(leg_positions): leg = cmds.polyCube(w=0.2, h=seat_height, d=0.2, name=f"{name}_leg_{i}")[0] cmds.move(pos[0], pos[1], pos[2], leg) components.append(leg) cmds.parent(leg, model_group) # Apply materials cmds.sets(components, forceElement=cmds.sets(name=f"{mat_name}SG", renderable=True, noSurfaceShader=True)) else: raise ValueError(f"Error: unknown model type {model_type}, use one of these types: car, tree, building, cup, chair") return finalize_model()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PatrickPalmer/MayaMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server