Python Tools - Session 3A

Image-Based Mosaic

January 21, 2020

Session Navigation

Overview

This session introduces image-based 3D mosaic creation in Maya using PyMEL. You'll learn how to load an image texture, read its resolution, and use nested FOR loops to create a grid of cubes that tiles out to match the source image dimensions. This forms the foundation for the more advanced height-mapped mosaic in Session 3B.

Key Concepts

  • File nodes — creating texture nodes in Maya to read image properties like resolution
  • Nested FOR loops — iterating over X and Y axes to build a 2D grid of objects
  • Tile sizing — dividing image resolution by tile size to calculate grid dimensions
  • Position tracking — incrementing variables outside the loop to track placement coordinates
  • List indexing — using [0] to get the transform node from Maya's returned list

Code

This script creates a file node from a source image, calculates the grid dimensions, then uses nested loops to place cubes in a mosaic pattern.

# Import the PyMel module, and create the alias "pm" for it to save on typing later
import pymel.core as pm

# Create the variables that we may want to change
# The path to the image - change this to a path on your local drive
image_file = r"C:\path\to\your\image.jpg"
# This is the size of each tile in the mosaic
tile_size = 20

# Create a file node inside Maya for us to use
file_node = pm.createNode('file')

# Set the image path to be the image set above
file_node.fileTextureName.set(image_file)

# Now we calculate the number of tiles in each direction
# We do this by getting the resolution of the texture from the file node
# .. and dividing it by the tile size
# i.e. a resolution of 400, with tiles of 10 units, will create 40 tiles
width_count = int(file_node.outSizeX.get() / tile_size)
height_count = int(file_node.outSizeY.get() / tile_size)

# Print them out to make sure we get good values
print width_count, height_count

# Now we start the FOR loops
# Because we are counting along each axis as we go..
# .. we need to create a variable outside the loop to increment
x_pos = 0.0
for x in xrange(0, width_count):
    # here we add "tile_size" to the x_pos of the current iteration
    # += is short hand - the long form of this would be
    # x_pos = x_pos + tile_size
    x_pos += tile_size

    # Same here for the Y axis
    y_pos = 0.0
    for y in xrange(0, height_count):
        y_pos += tile_size

        # Create a poly cube, setting the width, depth and height to be the size of the tile
        # REMEMBER - creating most objects in Maya returns a list
        # This contains both the Transform and the Shape
        # We only want the transform - the first element
        # We access the first element by using "[0]", the "zeroth" element in the list
        tile = pm.polyCube(width=tile_size, depth=tile_size, height=tile_size)[0]

        # Move the transform node to our new coordinates
        pm.move(tile, [x_pos, 0, y_pos])
← Session 2B Session 3B →