tik.maya¶
Purpose¶
A disciplined, boring wrapper around Autodesk Maya.
What lives here¶
Node wrappers
DAG traversal
Attribute access
Scene interaction
OpenMaya integration
Maya-specific abstractions
Rules¶
May depend on
tik.coreMust not depend on Qt
Must not depend on tools or UI
Must mirror Maya behavior rather than reinterpret it
Should remain predictable and mechanical
Mental model¶
How things exist *inside Maya*. If it does not make sense without Maya, it belongs here.
Three Pillars inside tik.maya¶
┌─────────────────────────────────────────────────────────────┐
│ Constructs │
│ Orchestrate multiple nodes and roles │
│ (e.g., IK System, Space Switch) │
├─────────────────────────────────────────────────────────────┤
│ Roles │
│ What a node *means* semantically │
│ (e.g., Controller, Driver) │
├─────────────────────────────────────────────────────────────┤
│ Types │
│ What a node *is* in Maya │
│ (e.g., Transform, Mesh, Joint) │
└─────────────────────────────────────────────────────────────┘
Types¶
Types describe what a node *is*. Location: tik/maya/types/
A Type is a thin wrapper around a Maya node type. It maps 1:1 to Maya’s node classification.
Examples
TransformwrapstransformnodesMeshwrapsmeshshape nodesJointwrapsjointnodesCurvewrapsnurbsCurveshape nodes
Rules for Types
Each Type maps to exactly one Maya node type
Types are registered in the type registry via
@registerTypes expose low-level, structural behavior (transforms, attributes, geometry data)
Types never encode semantic meaning
A Type should answer
What attributes does this node have?
How do I create this node?
How do I query or manipulate its data?
A Type should NOT answer
What is this node used for?
What role does it play in a rig?
Is this a controller or a driver?
from tik.maya import Transform, Joint, Mesh
# Types tell you WHAT something is
cube = Transform.create(name="cube")
jnt = Joint.create(name="arm_jnt")
# Types provide node-specific operations
cube.freeze() # Transform method
cube.snap_to(target) # Transform method
mesh.vertices() # Mesh method
jnt.orient((0, 90, 0)) # Joint method
Roles¶
Roles describe what a node *means*. Location: tik/maya/roles/
A Role is a semantic overlay on top of an existing Type. It adds meaning and behavior without creating new Maya node types.
Examples
Controller— A transform that an animator interacts withDeformerDriver— A joint that drives deformationsSpaceSwitcher— A transform with space-switching capabilities
Rules for Roles
Roles are not Maya node types
Roles hold an existing Type instance internally (composition, not inheritance)
Roles validate that they hold a compatible base Type
Roles encode their identity in the scene (via attributes, metadata)
Roles never create new Maya node kinds
A Role should answer
What is this node’s purpose in the rig?
What high-level operations should this node support?
from tik.maya.roles.controller import Controller
# A Controller is a Role that wraps a Transform
ctrl = Controller.create(name="arm_ctrl", shape="circle")
# The Role adds semantic behavior
ctrl.set_shape("square", size=2.0)
ctrl.set_color((1, 0, 0)) # Red
# But you can still access the underlying Type
ctrl.transform.translate = (0, 5, 0)
Identity recovery¶
Roles must be recoverable from the scene. If you save and reload, you should be able to identify which transforms are Controllers by checking for role markers.
# Check if a node is a Controller
if Controller.is_controller(some_node):
ctrl = Controller.from_node(some_node)
Constructs¶
Constructs orchestrate multiple nodes and roles. Location: tik/maya/constructs/
A Construct coordinates several nodes and roles to represent a pattern or setup. It’s the “assembly” layer.
Examples
IK Chain — Multiple joints + IK handle + pole vector
Space Switch System — Transform + parent constraints + blend attributes
Ribbon Setup — Surface + follicles + joints
Panel — Model panel + camera display control
Rules for Constructs
Constructs manage collections of nodes and roles
Constructs define relationships and connections
Constructs may create and destroy nodes
Constructs provide high-level operations on the whole system
Note
The Constructs system is under development. As tik.maya matures, this will become the primary way to build complex rig systems.
Registry system¶
tik.maya uses a registry to map Maya node types to Python classes:
from tik.maya.core.registry import register, resolve
@register("myCustomNode")
class MyCustomNode(Node):
pass
# Now resolve() returns MyCustomNode for "myCustomNode" type nodes
node = resolve("myCustomNode1") # Returns MyCustomNode instance
The registry also handles inheritance. If no exact match exists, it walks the
Maya inheritance hierarchy to find the closest registered wrapper.
resolve is re-exported in tik.maya.__init__ so tik.maya.resolve
and tm.resolve() (after import tik.maya as tm) are equivalent.
Base classes¶
- Node
Base wrapper for all Maya dependency nodes. Provides:
UUID-based identity tracking
MObject handle caching with UUID verification and reconstruction
Name caching and resolution
Attribute access via
[]Lifecycle methods (
rename,delete,exists)
- DagNode (extends Node)
For DAG-capable nodes. Adds:
parent/childrenhierarchyvisibilitypropertyMDagPath integration
- ShapeNode (extends DagNode)
For shape nodes that live under transforms. Adds:
transformproperty (parent transform)Smart initialization (accepts transform or shape name)
- Transform (extends DagNode)
For transform nodes. Adds:
translate,rotate,scalepropertiesshapespropertyfreeze(),snap_to()methodsMatrix properties
- Type-specific classes (Mesh, Curve, Joint, etc.)
Extend the appropriate base with type-specific methods.
Design principles¶
- Scene as Source of Truth
tik.maya never caches state that could become stale. It validates cached
maya.api.OpenMaya.MObjecthandles by comparing UUIDs and re-resolves from the scene when handles become stale, keeping references both fast and safe.- Explicit Over Implicit
Methods that modify scene state are clearly named as actions. Properties return current state without side effects.
- Consistency Across Types
All Types follow the same patterns:
create()class method for creation[]for attribute accessStandard lifecycle methods
This means learning one Type teaches you all of them.