OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
read_beacon_info_into_blender.py
1 import bpy
2 
3 #============================================================================
4 # Edit below here
5 
6 # Edit the two file names here to change them to match the files you want to
7 # open.
8 
9 locationFile = open('HDK_LED_locations_3rmt.csv')
10 patternFile = open('HDK_LED_patterns.txt')
11 
12 # Edit the Y offset to by applied to move the group of beacons
13 # associated with different sensors to avoid overlap. This is
14 # in cm.
15 
16 sensorYOffset = 8.5
17 
18 # Edit the number of repetitions of flashings done here.
19 # This will not change the camera behavior, which is set to
20 # move to the right over one set of flashes and then to the
21 # left over a second set.
22 
23 numRepeats = 2
24 
25 # Probably don't edit below here.
26 #============================================================================
27 
28 locations = locationFile.readlines()
29 patterns = patternFile.readlines()
30 
31 def setMaterial(ob, mat):
32  me = ob.data
33  me.materials.append(mat)
34 
35 def makeMaterial(name, diffuse, specular, alpha):
36  mat = bpy.data.materials.new(name)
37  mat.diffuse_color = diffuse
38  mat.diffuse_shader = 'LAMBERT'
39  mat.diffuse_intensity = 1.0
40  mat.specular_color = specular
41  mat.specular_shader = 'COOKTORR'
42  mat.specular_intensity = 0.0
43  mat.alpha = alpha
44  mat.ambient = 1
45  return mat
46 
47 # Replaces select_name() function that was removed in
48 # version 2.62. The select_pattern() function does not quite
49 # do the same thing.
50 def selectNamed(name):
51  bpy.ops.object.select_all(action='DESELECT')
52  myobject = bpy.data.objects[name]
53  myobject.select = True
54  bpy.context.scene.objects.active = myobject
55 
56 # Faster version of the above that pulls the entry from the
57 # specified entry in a list
58 def selectObject(myObject):
59  bpy.ops.object.select_all(action='DESELECT')
60  myObject.select = True
61  bpy.context.scene.objects.active = myObject
62 
63 
64 # Create some materials
65 bright = makeMaterial('Bright', (1,1,1), (1,1,1), 1)
66 
67 # Make a single sphere that will be duplicated to make the beacons.
68 # Units are in centimeters throughout the model. Put this one very
69 # far away so it will be clipped and we'll never see it.
70 bpy.ops.mesh.primitive_uv_sphere_add(size = 0.25, location=(1000.0,1000.0,1000.0))
71 
72 # Make a sphere for each beacon with the bright material.
73 sphereNum = 0
74 listIndex = 0
75 sphereList = list()
76 for location in locations:
77 
78  # Skip the first line of the locations file because it is a header.
79  # If this beacon is from a sensor number larger than 0, shift it up
80  # in Y by the offset amount so that it will not overlap other sensors.
81  if sphereNum > 0:
82  # Pull the X, Y, Z coordinates out as the last three entries
83  # in the line, skipping
84  currentLocation = location.split(",")
85 
86  # Construct a new sphere
87  selectNamed("Sphere")
88  bpy.ops.object.duplicate(linked=False)
89  setMaterial(bpy.context.object, bright)
90  bpy.ops.object.shade_smooth()
91  sphereList.append(bpy.context.scene.objects.active)
92 
93  # Move the sphere to its correct location
94  # Remember to convert from mm to cm
95  # Name it after the 0-indexed beacon number (0-39 for 40 beacons)
96  selectObject(sphereList[listIndex])
97  myname = 'OSVR_beacon'+str(sphereNum-1).zfill(3)
98  bpy.context.active_object.name = myname
99  bpy.context.active_object.location = (float(currentLocation[2])/10, float(currentLocation[3])/10 + sensorYOffset * float(currentLocation[5]), float(currentLocation[4])/10)
100  listIndex += 1
101 
102  # Always increment the sphere number even if we're skipping this sphere
103  sphereNum += 1
104 
105 # Keep track of which frame we're in. There will be one for every
106 # character in a single line of the patterns file. Each line in that
107 # file should have the same number of frames.
108 
109 frameNum = 1
110 rep = 0
111 while rep < numRepeats:
112 
113  count = 0;
114  while count < len(patterns[0])-1:
115 
116  bpy.context.scene.frame_set(frameNum)
117  print("Handling time = ", frameNum)
118 
119  # Set each beacon's size based on the frame we're in
120  # and its entry in the string. It gets smaller for a
121  # dim beacon and larger for a bright one.
122  # TODO: we'd like to maybe adjust its diffuse color as
123  # well, to make it dimmer, but we're probably going to
124  # be overblowing the sensor so size is the main effect.
125  beaconId = 0;
126  for sphere in sphereList:
127  selectObject(sphereList[beaconId])
128  if patterns[beaconId][count] == '*':
129  bpy.context.object.scale = [1.00, 1.00, 1.00]
130  else:
131  bpy.context.object.scale = [0.75, 0.75, 0.75]
132  bpy.ops.anim.keyframe_insert_menu(type='Scaling')
133  beaconId += 1
134 
135  count += 1
136 
137  # Next frame we will set.
138  bpy.data.scenes["Scene"].frame_end = frameNum
139  frameNum += 1
140 
141  rep += 1
142