Growing Ivy with a little script

Hi there,

I just finished my first script today.

I’ve wanted to find a way to get ivy branches to grow nice and gradually for some time (or sapling trees, or anything really), and no simple method satisfied me (using a simple Build modifier, using arrays with curves or animating transparency).

So I came up with a build-per-branch method which would have been too tiresome and tedious without scripting.

Essentially, it takes an ivy which was created with the ivy generator, then converted into a mesh and separated to different objects by loose parts, and assigns Build modifier start frame and duration values that make all branches grow gradually.

This is the code I used:




- import bpy

import re

 

modifier_type = "Build"

base_name     = 'IVY_Curve'

 

frame_per_face        = 1 / 4   # how to allocate a total build animation length according to the number of faces on a branch

build_interval        = 15      # how many frames to wait until starting to build 2nd branch

wait_between_branches = 4       # how many frames to wait between branches

build_start_frame     = 1       # Build animation start frame for the first ivy branch

 

ivy_objects = []

 

for current_obj in bpy.data.objects:  # browse all objects and filter out ivy branches

    if re.search(base_name, current_obj.name):          # if the object name contains the base_name

        current_obj.data.update(calc_tessface=True)     # calculate face data so that...

        face_count = len(current_obj.data.tessfaces)    # we can obtain the total number of faces

        

        ivy_objects.append( { "name" : current_obj.name, "facecount" : face_count } ) # add ivy object to list, include name and face count

 

biggest_obj = ""

most_faces  = 0

 

# Find the biggest object (highest face count)

for obj in ivy_objects:

    if obj["facecount"] > most_faces:   # if this object's facecount is larger than the previous highscore,
        most_faces  = obj["facecount"]  # then make this facecount one the new max
        biggest_obj = obj["name"]       # and update the biggest object's name
 
# set base build animation length according to the biggest object's size
base_build_length = int( most_faces * frame_per_face )
 
count = 0
 
# set animation length and start frames to all objects in list
for obj in ivy_objects:
    name = obj["name"]
    current_object = bpy.data.objects[name]
 
    # set the start frame of each object's build anim. by the order of names (which corresponds to order of creation)
    if count != 0: # Set build start for all the branches after the first one:
        bpy.data.objects[name].modifiers[modifier_type].frame_start = int( build_start_frame + build_interval + count * wait_between_branches )
    else:   # Set when the first branch starts to build
        bpy.data.objects[name].modifiers[modifier_type].frame_start = int( build_start_frame )
    
    # Set build length in proportion to face count
    ratio = obj["facecount"] / most_faces
    bpy.data.objects[name].modifiers[modifier_type].frame_duration = int( ratio * base_build_length )
 
    count += 1 



This is the pastebin link for the code, much more readable here.

There’s some more info in my blog, if anyone’s interested.

And here’s a little video demo showing the kind of growth this produces:

great stuff, it looks really cool :slight_smile:

I’m working at understanding how to use your script…

So, I create an object, such as a cube, and name the cube IVY_curve and your script will grow ivy on it?

Not exactly,
I used the Ivy Generator add on to create the Ivy. You can see a nice tutorial about using it on BlenderNerd.

This script is used to animate the growth of the ivy, and for it to work you need a ready-made ivy, which has been:

  1. converted into a mesh (Alt + C)
  2. sorted (in edit mode select all faces, then press Ctrl + F to open the faces menu and select “Sort Faces”).
  3. added a Build modifier.
  4. separated into branches (in edit mode, press P to separate, then select “by loose parts”).

Then you can use the script.

I’ll probably work on making this a proper add on with some interface elements, which would perform these 4 preliminary steps by itself (and allow you to easily set values for some of the parameters that affect how the end result will turn out), but for now they are required for it to work.

Cheers

Ah! Okay, thanks for explaining. If I’d used the Ivy Generator, I suppose I would have realized most of that. :slight_smile: