-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathGenerateLightArray.py
More file actions
executable file
·114 lines (89 loc) · 5.25 KB
/
Copy pathGenerateLightArray.py
File metadata and controls
executable file
·114 lines (89 loc) · 5.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
"""===================== GenerateLightArray.py ======================
This function is used to initialize an array of lamp objects in the scene.
By default, all lamps are splotlights pointed at the world origin and are
initially turned off.
@author: aidanmurphy (murphyap@mail.nih.gov)
"""
import bpy
import numpy as np
import mathutils as mu
import math
def appendSpherical_np(xyz):
ptsnew = np.hstack((xyz, np.zeros(xyz.shape)))
xy = xyz[:,0]**2 + xyz[:,1]**2
ptsnew[:,3] = np.sqrt(xy + xyz[:,2]**2)
ptsnew[:,4] = np.arctan2(np.sqrt(xy), xyz[:,2]) # for elevation angle defined from Z-axis down
#ptsnew[:,4] = np.arctan2(xyz[:,2], np.sqrt(xy)) # for elevation angle defined from XY-plane up
ptsnew[:,5] = np.arctan2(xyz[:,1], xyz[:,0])
return ptsnew
def GenerateLightArray(LampType='SPOT', LampArrangement='hemi', TargetLocation=0):
# LampType = 'POINT'; 'SUN'; 'SPOT'; 'HEMI';
# LampArrangement = 'circle'; 'hemi'; 'sphere'
#============== Add empty object as lamp target
if not TargetLocation:
TrackedObject = []
else:
TrackedObject = bpy.data.objects.new( "empty", None)
bpy.context.scene.objects.link(TrackedObject)
TrackedObject.name = 'Lamp_target'
TrackedObject.location = TargetLocation
#=============== Set lamp array parameters
FlipArray = 1 # 0 = pole is Y-axis; 1 = pole is Z-axis
LampNoAzAngles = 8 # Default number of azimuth angles
LampNoElAngles = 3 # Default number of elevation angles
LampArrayRadius = 1.5 # Radius of array of lamps
LampCircleHeight = 1 # Lamp height (meters) for circular lamp arrangement
#=============== Generate spherical coordinates for each lamp
if LampArrangement == 'circle':
LampAzAngles = np.linspace(0,2*math.pi, LampNoAzAngles+1)
LampElAngles = np.tile(math.atan(LampCircleHeight/LampArrayRadius), 3)
elif LampArrangement == 'sphere':
LampAzAngles = np.linspace(0,2*math.pi, LampNoAzAngles+1)
LampElAngles = np.linspace(0,math.pi, LampNoElAngles+2)
elif LampArrangement == 'hemi':
LampAzAngles = np.linspace(0,2*math.pi, LampNoAzAngles+1)
LampElAngles = np.linspace(0,math.pi, LampNoElAngles+2)
LampElAngles = LampElAngles[:-np.floor(LampNoElAngles/2)]
LampAzAngles = LampAzAngles[:-1] # Remove last angle from list (2*pi == 0)
LampElAngles = LampElAngles[1:-1] # Remove first and last angle from list
#============== Loop through array locations
LampLocs = np.zeros((LampNoAzAngles*LampNoElAngles,3))
LampRot = np.zeros((LampNoAzAngles*LampNoElAngles,3))
LampObjects = {}
li = 0
for el in LampElAngles:
for az in LampAzAngles:
LampLocs[li][0] = LampArrayRadius*math.sin(el)*math.sin(az)
LampLocs[li][1] = LampArrayRadius*math.sin(el)*math.cos(az)
LampLocs[li][2] = LampArrayRadius*math.cos(el)
LampRot[li][0] = -el
LampRot[li][1] = 0
LampRot[li][2] = -az
if FlipArray == 1:
LampLocs[li] = [LampLocs[li][i] for i in [0,2,1]]
LampRot[li] = [LampRot[li][i] for i in [0,2,1]]
LampLocs[li][1] = -LampLocs[li][1]
LampRot[li][1] = -LampRot[li][1]
LampRot[li][0] = -LampRot[li][0]
#============== Add lamp
lamp_data = bpy.data.lamps.new(name='Lamp_%d' % (li), type=LampType) # Create new lamp data block
lamp_object = bpy.data.objects.new(name='Lamp_%d' % (li), object_data=lamp_data) # Create new lamp
bpy.data.scenes[0].objects.link(lamp_object) # Link new lamp to scene
lamp_object.location = mu.Vector((LampLocs[li])) # Position lamp
lamp_object.hide_render = True # Turn lamp off by default
lamp_data.shadow_method = 'RAY_SHADOW'
if not TargetLocation: #============= Apply target tracking constraint
lamp_object.rotation_euler = mu.Vector((LampRot[li])) # Rotate lamp
else:
ttc = lamp_object.constraints.new(type='TRACK_TO')
ttc.target = TrackedObject
ttc.track_axis = 'TRACK_NEGATIVE_Z'
ttc.up_axis = 'UP_X'
bpy.ops.object.select_all(action='DESELECT')
lamp_object.select = True
bpy.ops.object.visual_transform_apply()
lamp_object.constraints.remove(ttc) # Remove constraint once lamp is pointed at target
print('Lamp %d of %d added to scene...' % (li+1, LampNoAzAngles*LampNoElAngles))
LampObjects[li] = lamp_object
li = li+1;
return LampObjects