Scripting for Animation and VFX: Week 4

 Scripting for Animation and VFX: Week 4

Functions and Creating Spheres 

For this weeks assignment we were working with functions using python in maya. The given code to work with and expand created randomly placed spheres and curves that connected them. 

Breaking down the given code:

import random
import maya.cmds as cmds

def create_random_sphere():
    # Generate random position
    x = random.uniform(-100, 100)
    y = random.uniform(-100, 100)
    z = random.uniform(-100, 100)

    # Create sphere
    sphere = cmds.polySphere() [0]

    # Move sphere to random position
    cmds.move(x, y, z, sphere)

    return sphere

def create_pipe(start, end):
    # Create a pipe between two objects
    curve = cmds.curve(degree=1, point=[cmds.xform(start, query=True, translation=True), cmds.xform(end, query=True, translation=True)])
    return curve

def create_shaders():
    black_shader = cmds.shadingNode('lambert', asShader=True, name="black")
    cmds.setAttr(black_shader + '.color', 0, 0, 0, type='double3')

    white_shader = cmds.shadingNode('lambert', asShader=True, name="white")
    cmds.setAttr(white_shader + '.color', 1, 1, 1, type='double3')
    
    return black_shader, white_shader
def create_spheres_and_pipes(num_spheres):
    # Create spheres
    spheres = []
    black_shader, white_shader = create_shaders()
    for i in range(num_spheres):
        sphere = create_random_sphere()
        spheres.append(sphere)
        if i % 2 == 0:
            cmds.select(sphere)
            cmds.hyperShade(assign=black_shader)
        else:
            cmds.select(sphere)
            cmds.hyperShade(assign=white_shader)

    # Connect spheres with pipes
    pipes = []
    for i in range(len(spheres) - 1):
        pipe = create_pipe(spheres[i], spheres[i + 1])
        pipes.append(pipe)

    # Connect last sphere with the first one
    pipe = create_pipe(spheres[-1], spheres[0])
    pipes.append(pipe)

    return spheres, pipes

def createrandspheres(num_spheres):
    # Create spheres and pipes
    spheres, pipes = create_spheres_and_pipes(num_spheres)

    # Create a circle curve
    circle = cmds.circle(normal=(0, 1, 0), radius=0.2)
    
    

    # Extrude the circle along the path curves
    for pipe in pipes:
        cmds.select(circle[0], pipe)
        cmds.extrude(et=2, upn=True, fpt=True, ucp=1)

The first two lines of code import the libraries that will be need in this function. 

import random and import cmds.maya as cmds


The next part of the code creates the first function, create_random_sphere. 

This function is what creates the random spheres in the scene. 

The first three lines generate a random position for the y x and z coordinates using the random.uniform function in the random library. 

The next line creates the sphere, and the following line moves the sphere to the randomly generated coordinates. 

The function returns the sphere.


The next function is create_pipe(start, end). 

This function creates the pipes that connect the spheres. 

curve = cmds.curve(degree=1, point=[cmds.xform(start, query=True, translation=True), cmds.xform(end, query=True, translation=True)])
    return curve

curve is a list that holds the information of the curve created. cmds.curve creates a curve. This maya function has parameters. We are creating a two point curve, this will make a straight line. 


The next function creates the shaders. create_shaders.

def create_shaders():
    black_shader = cmds.shadingNode('lambert', asShader=True, name="black")
    cmds.setAttr(black_shader + '.color', 0, 0, 0, type='double3')

    white_shader = cmds.shadingNode('lambert', asShader=True, name="white")
    cmds.setAttr(white_shader + '.color', 1, 1, 1, type='double3')

This function creates two shaders. One black one white. These shaders are lamberts

This function used the function cmds.shadingNode create a shading node in the hypershade. 

The function saves the shaders information in lists. the cmds.setAttr function is used to set what color each shader will be.


The next function uses the previously made functions to make the spheres and pipes. The firs line makes a list called spheres.

def create_spheres_and_pipes(num_spheres):
    # Create spheres
    spheres = []
    black_shader, white_shader = create_shaders()
    for i in range(num_spheres):
        sphere = create_random_sphere()
        spheres.append(sphere)
        if i % 2 == 0:
            cmds.select(sphere)
            cmds.hyperShade(assign=black_shader)
        else:
            cmds.select(sphere)
            cmds.hyperShade(assign=white_shader)

    # Connect spheres with pipes
    pipes = []
    for i in range(len(spheres) - 1):
        pipe = create_pipe(spheres[i], spheres[i + 1])
        pipes.append(pipe)

    # Connect last sphere with the first one
    pipe = create_pipe(spheres[-1], spheres[0])
    pipes.append(pipe)

    return spheres, pipes

The for in loop loops as many times in range of num_spheres. The loop creates a sphere using the create_random_sphere function, adds them to a list, and will assign the black sphere to every even number of sphere. This is done by having a condition and an if else branch, if the number of sphere equals 0 when divided by 2 then it is assigned the black shader. 

The next part of the function connects the spheres with the pipes. 

the list pipes is created, and a for in loop is used to create the pipes using the location of and sphere and the following sphere that is made, The for in range loop uses the length of the spheres[] list - 1. This means that the range is how many spheres are in the spheres list. 

pipe= create_pipe(spheres[i], spheres[i + 1]) 

This line creates a pipe that starts at the location of the sphere that is in the i position of the list sphere and ends at the next sphere in the list. 


The next function creates the spheres and pipe and also creates a circle curve that is extruded along the pipe curves.

def createrandspheres(num_spheres):
    # Create spheres and pipes
    spheres, pipes = create_spheres_and_pipes(num_spheres)

    # Create a circle curve
    circle = cmds.circle(normal=(0, 1, 0), radius=0.2)
    
    

    # Extrude the circle along the path curves
    for pipe in pipes:
        cmds.select(circle[0], pipe)
        cmds.extrude(et=2, upn=True, fpt=True, ucp=1)

 

Expanding the functions and code: 

So to expand on these functions and and code, I want to try to make the spheres make an interesting larger shape and include more and different shaders.

Right now the random generation of the spheres makes it so they form a cube shape. The random function that is used is uniform and is given the parameters -100 and 100 for x y and z. This makes is so the spheres form a cube shape. 

Because this code uses functions, one can change the code in one function instead of having to change the whole script. 

The shape I want to try to make is a helix. 

My fist thought was to make a large helix out of a curve that I could potentially make the spheres generate around. 

I used chatgpt to figure out where to start.

I entered the code and asked the program to write and addition to the script that would make the spheres form a helix shape. 

The ai suggested modifying the create_spheres-and_pipes(num_spheres) function to generate spheres in a helix arrangement. 

"To make the spheres form a helix shape, you can modify the create_spheres_and_pipes(num_spheres) function to generate the spheres in a helical arrangement. Here's how you can achieve that:

python
import math def create_spheres_and_pipes_helix(num_spheres, helix_radius, helix_height, num_turns): spheres = [] black_shader, white_shader = create_shaders() for i in range(num_spheres): angle = (i / num_spheres) * num_turns * 2 * math.pi x = helix_radius * math.cos(angle) z = helix_radius * math.sin(angle) y = (i / num_spheres) * helix_height sphere = cmds.polySphere()[0] cmds.move(x, y, z, sphere) spheres.append(sphere) if i % 2 == 0: cmds.select(sphere) cmds.hyperShade(assign=black_shader) else: cmds.select(sphere) cmds.hyperShade(assign=white_shader) pipes = [] for i in range(len(spheres) - 1): pipe = create_pipe(spheres[i], spheres[i + 1]) pipes.append(pipe) pipe = create_pipe(spheres[-1], spheres[0]) pipes.append(pipe) return spheres, pipes

In this modified version of the function, the spheres are positioned in a helical arrangement along the y-axis while rotating around the y-axis. The helix_radius parameter controls how far the spheres are from the y-axis (radius of the helix), the helix_height parameter controls the vertical distance between consecutive spheres, and the num_turns parameter controls how many turns the helix makes.

To use this modified function, call it with the desired parameters:

python
num_spheres = 20 helix_radius = 10.0 helix_height = 2.0 num_turns = 4.0 spheres, pipes = create_spheres_and_pipes_helix(num_spheres, helix_radius, helix_height, num_turns)

This will create a helical arrangement of spheres connected by pipes in the Maya scene. You can adjust the parameters to achieve the desired appearance of the helix."

 

I added the suggested changes to the code. 

The new create_spheres_and_pipes function now had more parameters that would be used to calculate the position the spheres needed to be moved to in order to make the helix. This new function required the math python library so that was imported at the top of the code. 

For each sphere that is created an angle is calculated using the i integer, and the angle is used to calculate the x and z coordinates of the sphere. 

I added the variables helix_radius, helix_height, and num_turns above the calling of the final function so that they can be easily accessible and modified. The variables are used to determine the radius height and amount of turns for the helix. 
 

Next I wanted to make a gradient with the shaders. I wanted it to go from dark to light blue up the helix. 

I asked ChatGPT to write another addition to the code. 

The ai suggested this:

"To create shaders that form a gradient from dark blue to light blue for the helical spheres, you can modify the create_spheres_and_pipes_helix function to interpolate the color values for each sphere along the gradient. Here's how you can achieve that:

python
def create_spheres_and_pipes_helix_gradient(num_spheres, helix_radius, helix_height, num_turns): spheres = [] dark_blue = (0.0, 0.0, 0.3) light_blue = (0.5, 0.5, 1.0) for i in range(num_spheres): angle = (i / num_spheres) * num_turns * 2 * math.pi x = helix_radius * math.cos(angle) z = helix_radius * math.sin(angle) y = (i / num_spheres) * helix_height sphere = cmds.polySphere()[0] cmds.move(x, y, z, sphere) spheres.append(sphere) # Interpolate color between dark blue and light blue based on y position t = y / helix_height color = ( dark_blue[0] + t * (light_blue[0] - dark_blue[0]), dark_blue[1] + t * (light_blue[1] - dark_blue[1]), dark_blue[2] + t * (light_blue[2] - dark_blue[2]) ) shader = cmds.shadingNode('lambert', asShader=True) shading_group = cmds.sets(renderable=True, noSurfaceShader=True, empty=True) cmds.setAttr(shader + '.color', color[0], color[1], color[2], type='double3') cmds.connectAttr(shader + '.outColor', shading_group + '.surfaceShader', force=True) cmds.select(sphere) cmds.hyperShade(assign=shader) pipes = [] for i in range(len(spheres) - 1): pipe = create_pipe(spheres[i], spheres[i + 1]) pipes.append(pipe) pipe = create_pipe(spheres[-1], spheres[0]) pipes.append(pipe) return spheres, pipes

In this version of the function, the color of each sphere's shader is interpolated between dark blue and light blue based on its vertical position (y) in the helix. The t value is used to control the interpolation, where t is in the range of 0 to 1, indicating the progress along the helical height.

You can use this modified function in a similar manner as before:

python
num_spheres = 20 helix_radius = 10.0 helix_height = 2.0 num_turns = 4.0 spheres, pipes = create_spheres_and_pipes_helix_gradient(num_spheres, helix_radius, helix_height, num_turns)

This will create a helical arrangement of spheres with shaders forming a gradient from dark blue to light blue along the helical height."

 I added the suggestions from the ai. 




 

Comments

Popular posts from this blog

Scripting for Animation and VFX: Week3

Final: Auto three point lighting set up

Scripting For Animation and VFX: Week 2