1
$\begingroup$

Problem

I was given some data from a simulation and am trying to animate said data. I've gone through several other posts where they accomplished this using Animation Nodes, which works for a fixed amount of objects. The problem I'm having is one data file can contain the position/rotation for an undefined amount of objects. What I need is some sort of first step that instantiates the necessary amount of objects and then a second part that animates the objects.

Solution

The solution I'm looking for needs to:

  • Instantiate a undefined (dynamic) amount of objects
  • All instantiated objects will be the same
  • Animate a undefined (dynamic) amount of position/rotation vectors

If there is some better method to accomplish this other then Animation Nodes I am open to suggestions.

What I've tried so far

So far I've been able to animate a fixed number of objects using a loop input. I've played around with using a different character to separate the objects like '$' character. But I still get stuck trying to instantiate the objects dynamically.

Setting position of object from text file

Update

Ok so I screwed around a little more and have it now so the objects get instantiated based on the length of a list taken from the first line where the elements are separated with '$' character.

I feel like I'm soo close now but I'm still running into the issue where it doesn't want to add keyframes for the 2nd line.

I've added a screenshot and the .blend so maybe someone else can see what's going wrong here?

Attempt at animating multiple objects and multiple keyframes from csv data using animation nodes

Update 2

I understand attachments are typically frowned upon in SE questions but so we can all be on the same page I've attached an example CSV file.

Some more things to note are:

  • I can format the simulation data in any manner, if changing the format of the CSV allows me to more easily create animations then so be it
  • Remember as long as I can animate an infinite/undefined amount of objects AND keyframes/data points then we're good.
  • The approach I've taken at the moment is to have every line (row) = one animation cycle. The information for each object is stored on a single line, I use a the '$' character to divide objects as a little bit of a hack.

Project Files / Example CSV

Example CSV File

$\endgroup$
7
  • $\begingroup$ According to your node, you are splitting data with "," while you claim the csv file is using "$" as a separator. Why aren't you using the right character? $\endgroup$ Commented Mar 12, 2020 at 7:16
  • $\begingroup$ Yes CSV file is traditionally separated with ',' character. Animation Nodes has a Split Text thingy so my thinking was I could exploit this by using two different separators ',' and '$' to split one line multiple times. So far that hasn't gotten me anywhere. $\endgroup$
    – Jameson
    Commented Mar 12, 2020 at 7:29
  • $\begingroup$ Also worth mentioning that I can format the input data in any manner, as long as whatever is suggested meets the criteria in my original post we're good. $\endgroup$
    – Jameson
    Commented Mar 12, 2020 at 7:29
  • $\begingroup$ Hi :) 1) First convert the CSV data into vector and rotation lists. 2) Use Get Length node to calculate the length of the (vector or rotation list) then use it as the amount in the Object Instancer node. 3) Use Object Transforms Output node for object transformation. Btw, use Loop Viewer node to view in the Loop Node. See this post blender.stackexchange.com/questions/77908/… $\endgroup$
    – 3DSinghVFX
    Commented Mar 12, 2020 at 11:41
  • $\begingroup$ @3DSinghVFX That approach makes sense if you want to move each object once. But I get confused when I want to move each object multiple times. Like if each line in the CSV is a new position/rotation to move to how do I have it so objects aren't getting instantiated for every line? - So only created once? $\endgroup$
    – Jameson
    Commented Mar 12, 2020 at 22:16

1 Answer 1

1
$\begingroup$

I finally gave up on Animation Nodes and just wrote a simple Python script instead. I changed the format of the CSV so 1 line = 1 keyframe. This is simpler but it could probably be more efficient by not forcing you to place keyframes constantly.

The objects are still separated by '$' characters to simplify parsing.

An Example CSV file can be found here

Script below:

import bpy
import csv

# File to open
csvFile = open('example-data.csv')

# Separate by lines
csvFileLines = csvFile.readlines()
csvFileLines = [line.rstrip('\n') for line in csvFileLines]
#Remove first row
csvFileLines.pop(0)

#How many objects should we instantiate?
objectCount = len(csvFileLines[0].split("$"))
print("Objects found: " + objectCount)

objs = []
objs.append(bpy.context.active_object) # First obj added is the current active object
# Get scene
scn = bpy.context.scene

# Instantiate all objects needed
for x in range(1, objectCount):
    objs.append(objs[0].copy()) # Copy first object
    objs[x].name += str(x) # Give unique name
    bpy.context.collection.objects.link(objs[x]) # Link to scene

keyInterp = bpy.context.preferences.edit.keyframe_new_interpolation_type # Remember user selected interpolation type
bpy.context.preferences.edit.keyframe_new_interpolation_type ='LINEAR' # Set interpolation type to linear

for i, line in enumerate(csvFileLines):
    # Find objects
    csvObjectPosRot = line.split("$")
    for r, values in enumerate(csvObjectPosRot):
        # Find values from object string
        csvObjectValues = values.split(",")
        # Set object position
        objs[r].location = (float(csvObjectValues[0]), float(csvObjectValues[1]), float(csvObjectValues[2]))
        # Set object rotation
        objs[r].rotation_euler = (float(csvObjectValues[3]),float(csvObjectValues[4]),float(csvObjectValues[5]))  # Note that you need to use radians rather than angles here
        # Add keyframe for object
        objs[r].keyframe_insert(data_path='location', frame=(i))
        objs[r].keyframe_insert(data_path='rotation_euler', frame=(i))

bpy.context.preferences.edit.keyframe_new_interpolation_type = keyInterp # Revert interpolation type to the users last selection
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .