3
$\begingroup$

I have a C++ program which creates an array and stores the z-coordinates of the objects blender. How do make use of these values in the python script of blender? I surfed the net and found boost Python but not sure if it would work in blender.

Please suggest ways of doing this.

$\endgroup$
7
  • 1
    $\begingroup$ Save the array to a file and open, with Python, from within blender $\endgroup$ Feb 3, 2015 at 16:54
  • $\begingroup$ How the array looks like [1,2,3]? $\endgroup$
    – p2or
    Feb 3, 2015 at 17:03
  • $\begingroup$ @poor yeah its a one dimeensional array $\endgroup$
    – Ross
    Feb 3, 2015 at 17:05
  • $\begingroup$ @someonewithpc how to open text file in blender? $\endgroup$
    – Ross
    Feb 3, 2015 at 19:57
  • 3
    $\begingroup$ @Ross Like you would with normal Python; check stackoverflow.com/questions/3277503/… $\endgroup$ Feb 3, 2015 at 20:24

1 Answer 1

9
$\begingroup$

You can print your cpp values to the console and execute the app with python's subprocess module. Here is a simple cpp program that outputs random x,y,z values:

#include <iostream>     // std::cout
#include <vector>       // std::vector
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand

int main () {

  std::vector<float> z(10);
  float x = 0.171; 
  float y = 0.324;

  // iteration to store random numbers
  std::srand (static_cast <unsigned> (std::time(0)));
  for (std::vector<float>::iterator i = z.begin(); i != z.end(); i++){
    *i = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
  }

  // iteration to print x y z values
  for (std::vector<float>::iterator i = z.begin(); i != z.end(); i++){
    std::cout << (*i * x) << " " << (*i * y) << " " << *i << "\n";
  }

  return 0;
}

The output should be something like this:

0.170636 0.32331 0.997869
0.0806884 0.152883 0.471862
0.0141332 0.0267788 0.0826505
...

Get the values

Use Popen.communicate() to read the output and split the lines as you like:

import subprocess

# path to the app
app = '/home/user/Desktop/app'

# communicate can read the data:
out, err = subprocess.Popen(app, stdout=subprocess.PIPE).communicate() 

#  split the string by line
out = out.splitlines()
print (out)

# create lists
xValues, yValues, zValues = [],[],[]

# append the values to to the lists  
for line in out:
    line = line.strip()
    columns = line.split()
    xValues.append(float(columns[0]))
    yValues.append(float(columns[1]))
    zValues.append(float(columns[2]))

# print the values
print (zValues)

Creating keyframes

Iterate through the z values, set the start frame, offset value (optional) and use keyframe_insert in order to create keyframes for the selected object(s):

# get selected object
obj = bpy.context.active_object

# animation start frame
start_frame = 1

# frame value
frame_number = start_frame

# keyframe offset
offset = 3

# iterate through z values and apply them
for i in zvalues:
    # set the frame
    bpy.context.scene.frame_set(frame_number)
    # set new location
    obj.location = (0,0,i)
    # insert keyframe
    obj.keyframe_insert(data_path="location", index=-1)
    # add offset value
    frame_number += offset

Adjusting the timeline

To adjust the timeline use bpy.data.actions to get a list of actions in the scene and assign the last key value to bpy.context.scene.frame_end:

# get all actions
action_list = [action.frame_range for action in bpy.data.actions]

# sort, remove doubles and create a set
keys = (sorted(set([item for sublist in action_list for item in sublist])))

# assign new start frame
bpy.context.scene.frame_start = start_frame

# assign new end frame
bpy.context.scene.frame_end = keys[-1]

For more details see this answer: How to find number of animated frames in a scene via python?

Result

enter image description here

$\endgroup$

You must log in to answer this question.

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