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.verts to 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() with relative=True to 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)
← Session 4A Next: Session 5A →