Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
blender python api patterns
bl_info = {
"name": "Match Area Light",
"author": "Anthony Aragues",
"version": (1, 2),
"blender": (2, 90, 0),
"location": "n > Lights",
"description": "Rapidly create area lights to match size and orientation of selected faces",
"warning": "",
"doc_url": "",
"category": "Lighting",
}
# This example assumes we have a mesh object in edit-mode
import bpy, bmesh
from mathutils import Vector, Matrix
class LightsOp(bpy.types.Operator):
bl_idname = 'lights.go'
bl_label = 'Map Area Light to All Selected'
#this is the operator function that will be called on button press
def execute(self, context):
# Get the active mesh
obj = context.edit_object
bpy.ops.object.editmode_toggle()
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
bpy.ops.object.editmode_toggle()
objMesh = bmesh.from_edit_mesh(obj.data)
#create the lights
arrLights=[]
for objFace in objMesh.faces:
if objFace.select == True:
objLight={'location':{}, 'direction':{}, 'scale':{'x':0,'y':0,'z':0}}
objCenter= objFace.calc_center_median()
objLight['location']=objCenter.to_tuple()
objLight['direction']=objFace.normal
intMinX = None
intMinY = None
intMinZ = None
intMaxX = None
intMaxY = None
intMaxZ = None
for objVert in objFace.verts:
#coordinates per point per face of selected object
arrCo=objVert.co.to_tuple()
if intMinX == None or arrCo[0] < intMinX:
intMinX=arrCo[0]
if intMaxX == None or arrCo[0] > intMaxX:
intMaxX=arrCo[0]
if intMinY == None or arrCo[1] < intMinY:
intMinY=arrCo[1]
if intMaxY == None or arrCo[1] > intMaxY:
intMaxY=arrCo[1]
if intMinZ == None or arrCo[2] < intMinZ:
intMinZ=arrCo[2]
if intMaxZ == None or arrCo[2] > intMaxZ:
intMaxZ=arrCo[2]
objLight['scale']['x'] = intMaxX-intMinX
objLight['scale']['y'] = intMaxY-intMinY
objLight['scale']['z'] = intMaxZ-intMinZ
print(objLight)
arrLights.append(objLight)
bpy.ops.object.editmode_toggle()
for intLight,objLight in enumerate(arrLights):
objNewLight=bpy.ops.object.light_add(type='AREA', radius=1, align='WORLD', location=objLight['location'])
# set the rotation the light in the direction of the normal
bpy.context.object.rotation_mode = 'QUATERNION'
bpy.context.object.rotation_quaternion = objLight['direction'].to_track_quat('Z','Y')
#bpy.context.object.scale( objLight['scale']['x'],objLight['scale']['y'],objLight['scale']['z'] )
bpy.ops.transform.resize(value=(objLight['scale']['x']/1, objLight['scale']['y']/1, objLight['scale']['z']/1), orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)),
orient_matrix_type='GLOBAL', constraint_axis=(False, True, False), mirror=True, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False)
return {"FINISHED"}
class LightsPanel(bpy.types.Panel):
"""Creates a Panel in the Object properties window"""
bl_label = "Light"
bl_category = "Lights"
bl_idname = "Light_Panel"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
def draw(self, context):
layout = self.layout
#start with first camera found
row = layout.row()
row.label(text="Create area lights from faces")
row = layout.row()
row.label(text="1. Selected faces in edit mode")
row = layout.row()
row.label(text="2. Run the tool")
layout.operator("lights.go",text = 'Create area lights')
def register():
bpy.utils.register_class(LightsOp)
bpy.utils.register_class(LightsPanel)
def unregister():
bpy.utils.unregister_class(LightsOp)
bpy.utils.unregister_class(LightsPanel)
if __name__ == "__main__":
register()
@nurb2kea
Copy link

nurb2kea commented Jun 22, 2022

Hi,
with blender 3.2 -3.3 on latest macos the addon starts fine but when it comes to it's job, all lights point in one or random directions and not all shape sizes are ok.

Just to let you know!

Thanks in advance

SG

@SuddenDevelopment
Copy link
Author

SuddenDevelopment commented Jun 22, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment