5
$\begingroup$

I am a highschool student working at a college's engineering department for the summer. I just began working in blender and have intermediate knowledge of python. Could anyone share a script that:

  1. Read a .csv file of xyz coordinates and a .csv file of quaternion coordinates into python.

  2. Turn these points into some type of curve or path that an object can then follow to model the path the coordinates map out


My .csv files (around 250 lines) have three and four points on each line. All the coordinates would need to be floats on account that they are decimals.

Here you can find both example .csv files: https://gist.github.com/anonymous/a1a4cbe6e959ac14e5af to play with. My code looks like:

import os
import bpy
import csv
from mathutils import Vector

def set_keyframes(obj, loc_txt, quat_txt):
    obj.rotation_mode = 'QUATERNION'

    with open(loc_txt, 'r') as loc_fh:
        with open(quat_txt, 'r') as quat_fh:
            r_loc = csv.reader(loc_fh, delimiter=',')
            r_quat = csv.reader(quat_fh, delimiter=',')

            i = 0

            for row_loc in r_loc:
                row_quat = r_quat.__next__()
                row_loc = [ float(x.strip()) for x in row_loc[:3]]
                row_quat = [ float(x.strip()) for x in row_quat[:4]]

                fr = 10+2*i

                obj.location = Vector(row_loc) * 10
                obj.rotation_quaternion = row_quat
                obj.keyframe_insert(data_path="location", frame=fr)
                obj.keyframe_insert(data_path="rotation_quaternion", frame=fr)

                i += 1


base_folder =  '/Users/sharonshorak/Desktop/ARYA_PYTHON'

#  os.path.join  takes care of joining folder with filename.        
positions = os.path.join(base_folder, 'xyzposition.csv')
quaternions = os.path.join(base_folder, 'quaternions.csv')

set_keyframes(bpy.context.active_object, positions, quaternions)
$\endgroup$
  • 2
    $\begingroup$ related: blender.stackexchange.com/questions/34018 $\endgroup$ – zeffii Aug 18 '15 at 17:31
  • $\begingroup$ @zeffii ok thanks, i added the two files. the quaternion is actually longer than the xyz file i hope thats ok. $\endgroup$ – Alyssa Shorak Aug 18 '15 at 19:53
  • $\begingroup$ @zeffii are you going to submit an answer? it would be much appreciated $\endgroup$ – Alyssa Shorak Aug 19 '15 at 2:39
  • $\begingroup$ @zeffii sorry i accidentally changed it back before realizing you did this. an error came up if i just used positions or quaternions so i needed to add the path or directory of both $\endgroup$ – Alyssa Shorak Aug 20 '15 at 14:50
  • $\begingroup$ @zeffii I actually remade the files, Ill change the link so that you have the new updated files. They are now the same lengths $\endgroup$ – Alyssa Shorak Aug 20 '15 at 15:14
3
$\begingroup$

Your data was rather ugly, but I was able to write code that copes with the extra commas and spaces:

From http://www.purplefrog.com/~thoth/blender/python-cookbook/csv-to-fcurve-loc-rot.html :

Here's an updated version that handles the situation where the location and quaternion .CSV files do not have the same number of lines. This opens up more questions about why they differ. Are they different sample rates or different time spans or both?

import bpy
import csv

def keyframe_location(obj, fname):
    with open(fname, 'r') as loc_fh:
        r_loc = csv.reader(loc_fh, delimiter=',')
        i = 0
        for row_loc in r_loc:
            row_loc = [ float(x.strip()) for x in row_loc[:3]]
            fr = 10+2*i
            obj.location = row_loc
            obj.keyframe_insert(data_path="location", frame=fr)

            i = i+1


def keyframe_rotation(obj, fname):
    with open(fname, 'r') as quat_fh:
        r_quat = csv.reader(quat_fh, delimiter=',')
        i = 0
        obj.rotation_mode = 'QUATERNION'
        for row_quat in r_quat:
            row_quat = [ float(x.strip()) for x in row_quat[:4]]
            fr = 10+2*i
            obj.rotation_quaternion = row_quat
            obj.keyframe_insert(data_path="rotation_quaternion", frame=fr)

            i = i+1


def mission2(obj, loc_csv, quat_csv):
    """
     Use this version if the loc and quat .CSV files do not have the same number of lines.
     This opens up the question: why do they have differing numbers of lines?
     Are they covering the same time span at different frame rates, or do they cover different time spans?
    """
    keyframe_location(obj, loc_csv)
    keyframe_rotation(obj, quat_csv)


#
#

mission2(bpy.context.active_object, '/var/tmp/loc.txt', "/var/tmp/quat.txt")
$\endgroup$
  • $\begingroup$ I'm sorry if this is a stupid question but where would I put in the files specific to my files ie. xyzpositions.csv and quaternions.csv $\endgroup$ – Alyssa Shorak Aug 18 '15 at 21:12
  • 1
    $\begingroup$ I used /tmp/loc.txt and /tmp/quat.txt. Change those to refer to your file. $\endgroup$ – Mutant Bob Aug 18 '15 at 21:27
  • 1
    $\begingroup$ Also, you could use i += 1 instead of i = i + 1 $\endgroup$ – BlendingJake Aug 19 '15 at 15:04
  • 1
    $\begingroup$ You must add a cube or something, and select it, then run the script. it will make keyframes for the object. Then use the timeline to 'scrub time' or hit play $\endgroup$ – zeffii Aug 20 '15 at 13:37
  • $\begingroup$ @zeffii The code worked fine besides the scale of movement! similarily to the last code yoy helped me with these points are very small... where and what could i put into the code to scale it up say 100 times? I know in the last code you put in scale = 100. $\endgroup$ – Alyssa Shorak Aug 20 '15 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.