"A swarm of Butterflies" - Python "Short Code" Contest 2!

The old thread was getting messy. Each contest will now have a new thread here.

So now for something a little more challenging! :slight_smile:

Theme: “A Swarm of Butterflies”
Type:
Animation Contest.

Objective:

- Generate an * OPENGL* animation from the 3D viewport of fluttering butterflies animated using Python only.
- Animation to be judged on how satisfying the swarming/fluttering behaviour is from an artistic/realistic point of view.
- The example .blend shows what input the script will require from the user - more on this in a bit!

  • Code is to be judged on succinctness, quality of comments (which don’t count to length) and quality of code. Making your script as flexible and easy to use as possible is VERY IMPORTANT!

Rules:

-Script MUST be entirely your own. (No copying/pasting from existing scripts!)
-Start with .blend identical in structure to the one provided. The two object meshes can be changed or replaced - in fact this is advised!

Things to consider:

- You will want to generate many butterflies from the one(s) provided.

  • It may be a good idea to allow the user to input several butterfly models! (How?)
  • All butterflies will need to have bodies.
  • How will the script know which objects are butterflies? Think about this!
    - Have the butterflies flap their wings (this is quite essential!)
  • Boid/Swarming behaviour should be considered.
  • Randomisation of butterflies in size and other attributes.

    The example .blend key points:

- Wings mesh with object center in the middle.

Deadline:

Midnight of Tuesday the 24th (GMT). A bit longer as this one is trickier!

Prize:

Creating something useful for the Blender community. Demonstrating your scripting prowess. Coding satisfaction! Respect!

Note:

This is all leading somewhere, I promise! All the contests are going to link together to create something bigger and more interesting - so last week’s submissions have not been forgotten and are going to reappear as part of future contest(s)!

So I managed to get my proposal up earlier than expected. This one is a little more challenging than the last one I think but also a little more flexible to interesting ideas (I think!). Any suggestions should be posted in this thread.

Koba

Can we use Motion Logic Bricks to animate the butterflies?

(I know you said Python only, but using setOrientation() to rotate things is impossibly difficult.)
(Okay, it’s possible, but still difficult.)

[As requested by Koba, I am reposting my entry here in this new thread.]

Original post:

Here’s my final script, .blend file, and animation.

Since this contest relies on OpenGL rendering, if anyone wants to test this script but has a slow PC/graphics card, you might want to lower the number of butterflies to something like 20 so the screen updates are okay.

To run it, just download the .blend file and press ALT A.

A new bunch of butterflies is created each time this script is executed for the first time in a Blender session. If you reload the entire file or exit/restart Blender and reload the file, a new batch of butterflies will appear.

The script was designed to survive multiple sessions of Blender by using a simple but specially named and invisible cube to indicate if the script has been initialized since, as per the contest instructions, we were to begin with the one butterfly and go from there.

Since the butterfly structure was also a mandatory thing to follow for the contest, there arose a new problem of having to create a “flap wing” routine for two wings that were to be a single mesh.

I solved this by using a mirror modifier on the wing, so the resulting mesh is indeed two wings from one mesh, and using vertex group assignments.

The vertex group assignments help the script determine which verts need to be moved every few frames.

Randomness is the dominant factor in this script, with some slight wavering/guidance from a mathematical sin (as in sine) function.

If your GPU is fast enough to handle it, it’s interesting to rotate the display while performing an ALT A animation preview to see how the routines work out over hundreds of frames.

Each butterfly has its own direction, path, and flapping state. Each path and rotation are randomly incremented/decremented every few frames to emulate the sharp and fluttery flight of a lively group of butterflies.

A possible future use of such a script would be to commit each object’s location/rotation to corresponding IPO curves, so as to bake the motion.

The script is invoked using Blender’s internal script link service. In prior versions of Blender, I recall having to reestablish script links upon loading such a .blend file with a script.

The type of script link used here is World/frame change, and it points to the butterflies script in the text panel.

Obviously, due to render limitations of this particular challenge, there was little potential for any fanciness. At most I was able to get a pretty good OpenGL shaded look out of Blender 2.44. I suppose with the new SOC realtime OpenGl project that such renders will look substantially nicer :slight_smile:

The script (works and is included with enclosed .blend file below):


###########################################################
# Blender Artists Python Challenge # 2
# ("A Swarm of Butterflies" animation)
# Script by RobertT
# Status: Final Submission
# Designed and tested in Blender 2.44
#
#
# Please note: This script uses Blender's script links
# function.  To run this script, do NOT press ALT P.
# Instead, press ALT A in the 3D VIEW to watch the
# animate come to life.  Press ESC when done.
# You can also render out the animation using the
# ANIM button or perform a 3D View render by
# holding the CTRL KEY when clicking the render
# button in the 3D View.



# Import the things we will need to make this script work

import Blender
from Blender import Scene, Object, Mesh, Mathutils
from Blender.Mathutils import Rand
from math import sin



###########################################################
# This user-definable variable controls how many
# butterflies are created for the animation.
# This can only be changed upon first loading
# this unmodified blend file and running the script.


howManyButterflies = 111



currentScene = Scene.GetCurrent()
currentContext = currentScene.getRenderingContext()
currentFrame = currentContext.cFrame


###########################################################
# Place the Butterflies at random locations, rotations,
# and resize them slightly randomly as well

def randomizeButterflyLocation(butterflyNumber, rX, rY, rZ, rR):
    emptyObject = "butterflyEmpty.%03d" % butterflyNumber
    #print emptyObject, rX, rY, rZ
    butterflyEmpty = Blender.Object.Get(emptyObject)
    butterflyEmpty.LocX += rX
    butterflyEmpty.LocY += rY
    butterflyEmpty.LocZ += rZ
    butterflyEmpty.RotX += rR
    butterflyEmpty.RotY += rR
    butterflyEmpty.RotZ += rR
    butterflyEmpty.SizeX += rR / 50
    butterflyEmpty.SizeY += rR / 50
    butterflyEmpty.SizeZ += rR / 50


###########################################################
# Create butterflies to be placed in the animation
# based on the initially defined butterfly
# consisting of two mesh objects and one empty object.
# This function makes use of Blender's Duplicate function,
# which duplicates those objects that are currently selected.
# This function all enables us to retain the parenting
# relationship of the 2 meshes to the Empty object as
# defined in the original setup (as per the challenge rules).

def createButterflies():
    scene = Blender.Scene.GetCurrent()
    empty = Blender.Object.Get("butterflyEmpty")
    butterflyBody = Blender.Object.Get("butterflyBody")
    butterflyWings = Blender.Object.Get("butterflyWings")
    empty.sel = butterflyBody.sel = butterflyWings.sel = True

    for a in range(howManyButterflies):
        b = a + 1
        Blender.Object.Duplicate()
        rX = Rand(-.75, .75)
        rY = Rand(-.75, .75)
        rZ = Rand(-.75, .75)
        rR = Rand(-5.0, 5.0)
        randomizeButterflyLocation(b, rX, rY, rZ, rR)

    # This mysterious cube is explained in the following
    # setupEverything() function.
    cubeMesh = Mesh.Primitives.Cube(.5)
    cubeNew = scene.objects.new(cubeMesh, "DoneCube")
    cubeNew.setLocation(0, 0, 0)
    cubeNew.setSize(0, 0, 0)



###########################################################
# This is the initialization function.  If the scene
# has already been set up, then it does nothing.
# This is important, since, when script links are
# activated and this entire script is invoked at
# each new frame, we do not want to have more
# butterflies added per frame.  The script tests
# for the initialization in a way that can survive
# multiple Blender sessions by placing a "DoneCube"
# in the center of the scene.  This cube is hidden
# and will not render, but its presence helps the
# script avoiding unintended reinitializations.
    
def setupEverything():
    try:
        test = Blender.Object.Get("DoneCube")
    except:
        createButterflies()
        print "Initializing scene."
        Blender.Redraw()



###########################################################
# Here we randomly animate each butterfly's wings
# and move/rotate each Empty, which moves/rotates
# each butterfly.
    
def animateButterflies():
    objects = Blender.Object.Get()
    for o in objects:
        objName = str(o)
        updateEveryXFrames = 8
        updateFrame = currentFrame / updateEveryXFrames

        if objName.find("butterflyWings") != -1:
            butterflyMesh = o.getData(mesh = True)
            if (updateFrame) == int(updateFrame):
                rFlap = Rand(-2.5, 2.5)
                wingVerts = butterflyMesh.getVertsFromGroup('OuterWing')
                for v in wingVerts:
                    butterflyMesh.verts[v].co[2] = rFlap
                butterflyMesh.update()

        
        if objName.find("butterflyEmpty") != -1:
            updateEveryXFrames =  3
            updateFrame = currentFrame / updateEveryXFrames
            if (updateFrame) == int(updateFrame):
                rMove = Rand(-.3, .3)
                o.LocX += (sin(currentFrame)*.01) + rMove
                o.LocY += (sin(currentFrame)*.01) + rMove
            rMove = Rand(-.3, .3)
            o.LocZ += sin(currentFrame) * (rMove*2)
            o.RotX += sin(currentFrame * rMove)
            o.RotY += sin(currentFrame + rMove) 
            o.RotZ += sin(currentFrame / (rMove+1))


###########################################################
# The Main Program Begins Here!

setupEverything()
animateButterflies()


Here is the animation. (OpenGL/3D View animation; 1.5MB; Xvid encoded)

Animation was tested in Windows Media Player, VirtualDub, and VLC.

Here is a regular render, just for fun:

http://www.artofinterpretation.com/blenderfiles/butterflies-byrjt2007.jpg

Here is the .blend file.

Well, this was another great challenge. Thanks to Koba for providing this great opportunity to learn and have some fun doing something completely different with Blender. I hope to see more participants and many future challenges.

Enjoy the weekend, everyone! :slight_smile:

RobertT

Here’s my entry (just for fun)

Here’s the link to download the original competition blend with my script in it.
http://www.alienhelpdesk.com/misc/index.php?file=Butterfly_Entry_macouno.blend

It is written to work in blender 2.44 and may not work in any other versions!

It is exactly the original file, I just replaced the buttons window at the bottom with a text window and loaded my script in it.

Hover your mouse over the script and click ALT + P

There are some settings at the top of the script as well.

The script will only run once in the file!!! You’ll have to reload the file to run it again.

The speed of the butterflies is completely limited by what your computer can do… if they seem too quick… add more butterflies!!! if they’re slow… use less butterflies :wink: Or just change their speed.

Unfortunately I do not believe I will be able to get a script posted.

If I get time or a boost of energy later tonight or tomorrow (I’ve had very little sleep in the past 48 hours–maybe 2 hours of sleep comprised of short, light dozing over the whole couple of days) and if I can accomplish something I will edit this post with my results, otherwise I’ll probably have to sit this one out. I may continue to work on my script during the week, though, for practice. :RocknRoll:

Good luck to the entrants though!

@macuono - Didn’t you write a “swarm” script about a year or so ago?

forTe: Yes I did… but that’s still a work in progress. I figured I just had to do something since I’ve been doing swarms for a while. I want to make clear that this entry isn’t my previous swarm script. I’ve used a few functions I had lying around but this thing is new and only for the competition. I’m actually working on making my swarm stuff GE.

Not sure if I can get mine done. I’ve got a control model roughed out, but I’m having a tough time with the basics of turning what the butterfly wants to do and what actually happens on screen.

Unfortunately, the total time I have to code this is about 3 hours. Hehe :slight_smile:

I’ll try and get it done tomorrow, just to get it done really, also in case anyone else wants to play with the idea.

The idea was to build the butterflies as individuals, and let them learn. I’ve got a sketch of a reinforcement learning method I was going to use, before that the idea was to use a model of cliques of neurons in the hippocampus to give the butterflies memories, and let them build up from there.

Sorry Koba & everyone.

IanC, do it anyway… even if not for this thing… I’d like to see it :wink:

I think I might have a bit of it sorted now. The rotation +movement code works (ish, they corkscrew I think…)

Where has the time gone? The deadline is over and I hardly noticed!

Ok this week’s contest is over. I’ll create the voting threads later tonight. Oh and thanks for your entries RobertT and macouno!

Koba

Ok…I’ve been shamefully lazy. Sorry guys! :frowning:

Here is the image voting thread: here

Here is the code voting thread: here

Koba