Python Tools - Session 4B
Mesh Component Iteration
January 30, 2020
Session Navigation
Overview
This session demonstrates how to iterate over mesh components in Maya. You'll create a "spike" effect by placing randomly-scaled cones at every vertex of a ground plane. The session covers querying world-space vertex positions, generating random values with Python's random module, and using relative movement to offset geometry after initial placement.
Key Concepts
- Mesh vertex iteration — using
object.vertsto loop through every vertex on a mesh - World-space queries — getting vertex positions with
getPosition(space='world') - Random values — using
random.uniform()to generate variation in scale - Relative movement — using
pm.move()withrelative=Trueto offset from current position - Function arguments — passing vertex position data into a creation function
Code — Spike Creation
The main exercise: create randomly-scaled cone spikes at each vertex of a procedural ground plane.
"""
#############################################################################
filename session_4b_code_commented.py
author Matt Osbond
course CS115
Brief Description:
Session 4B - Thursday Jan 30th
Experimenting with iterating over a mesh's components
#############################################################################
"""
import pymel.core as pm
import random
# Make sure you always comment out the newFile when you're not iterating!
#pm.newFile(force=True)
def create_spike(position):
"""Spike creation function
Args: position
"""
# Create a spike object
new_spike = pm.polyCone(radius=0.5, height=5)[0]
# Move it to the provided position
pm.move(new_spike, position)
# Create a random scale, that is between 0.5 and 1.5
random_scale = random.uniform(0.5, 1.5)
# Uniformly scale the object
pm.scale(new_spike, [random_scale, random_scale, random_scale])
# Create a reasonable height by multiplying by a size factor
height = 5 * random_scale
# Move the spike again, this time RELATIVE to the current position
pm.move(new_spike, [0, (height / 2), 0], relative=True)
# Create a ground plane
ground = pm.polyPlane(width=20, height=20, subdivisionsX=10, subdivisionsY=10)[0]
# Iterate over each vertex
for vert in ground.verts:
# Get the world space position of the current vertex
vert_pos = vert.getPosition(space='world')
# Call the spike function, passing the current vert position through as an argument
create_spike(vert_pos)
Code — Spheres on Selection
A simpler variation: place a sphere at each vertex of the currently selected object.
# Create a polyPlane first. Scale it by 20 in every axis, and select it
import pymel.core as pm
# Grab the selected object and capture it in a variable called ground
ground = pm.ls(selection=True)[0]
# ground.verts returns a list, so we can iterate over this using a FOR loop
for vert in ground.verts:
# Create a sphere for each vertex
new_sphere = pm.polySphere(radius=1)[0]
# Get the position of the vertex in world space
vert_pos = vert.getPosition(space='world')
# Move the new sphere to the vertex position
pm.move(new_sphere, vert_pos)