From f3d58200d5e34aacf41162181e0435d65c464753 Mon Sep 17 00:00:00 2001 From: meta-androcto Date: Sun, 23 Jun 2019 20:09:39 +1000 Subject: lighting_tri_lights: Initial commit to release (standalone) T65823 713fa9b2c412 --- lighting_tri_lights.py | 271 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 lighting_tri_lights.py (limited to 'lighting_tri_lights.py') diff --git a/lighting_tri_lights.py b/lighting_tri_lights.py new file mode 100644 index 00000000..6712dd3e --- /dev/null +++ b/lighting_tri_lights.py @@ -0,0 +1,271 @@ +# gpl: author Daniel Schalla, maintained by meta-androcto + +bl_info = { + "name": "Tri-lighting", + "author": "Daniel Schalla", + "version": (0, 1, 4), + "blender": (2, 80, 0), + "location": "View3D > Add > Lights", + "description": "Add 3 Point Lighting to Selected / Active Object", + "warning": "", + "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/", + "category": "Lighting", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" + "Scripts/", +} + +import bpy +from bpy.types import Operator +from bpy.props import ( + EnumProperty, + FloatProperty, + IntProperty, + ) +from math import ( + sin, cos, + radians, + sqrt, + ) + + +class OBJECT_OT_TriLighting(Operator): + bl_idname = "object.trilighting" + bl_label = "Tri-Lighting Creator" + bl_description = ("Add 3 Point Lighting to Selected / Active Object\n" + "Needs an existing Active Object") + bl_options = {'REGISTER', 'UNDO'} + COMPAT_ENGINES = {'CYCLES', 'EEVEE'} + + height: FloatProperty( + name="Height", + default=5 + ) + distance: FloatProperty( + name="Distance", + default=5, + min=0.1, + subtype="DISTANCE" + ) + energy: IntProperty( + name="Base Energy", + default=3, + min=1 + ) + contrast: IntProperty( + name="Contrast", + default=50, + min=-100, max=100, + subtype="PERCENTAGE" + ) + leftangle: IntProperty( + name="Left Angle", + default=26, + min=1, max=90, + subtype="ANGLE" + ) + rightangle: IntProperty( + name="Right Angle", + default=45, + min=1, max=90, + subtype="ANGLE" + ) + backangle: IntProperty( + name="Back Angle", + default=235, + min=90, max=270, + subtype="ANGLE" + ) + Light_Type_List = [ + ('POINT', "Point", "Point Light"), + ('SUN', "Sun", "Sun Light"), + ('SPOT', "Spot", "Spot Light"), + ('AREA', "Area", "Area Light") + ] + primarytype: EnumProperty( + attr='tl_type', + name="Key Type", + description="Choose the types of Key Lights you would like", + items=Light_Type_List, + default='AREA' + ) + secondarytype: EnumProperty( + attr='tl_type', + name="Fill + Back Type", + description="Choose the types of secondary Lights you would like", + items=Light_Type_List, + default="AREA" + ) + + @classmethod + def poll(cls, context): + return context.active_object is not None + + def draw(self, context): + layout = self.layout + + layout.label(text="Position:") + col = layout.column(align=True) + col.prop(self, "height") + col.prop(self, "distance") + + layout.label(text="Light:") + col = layout.column(align=True) + col.prop(self, "energy") + col.prop(self, "contrast") + + layout.label(text="Orientation:") + col = layout.column(align=True) + col.prop(self, "leftangle") + col.prop(self, "rightangle") + col.prop(self, "backangle") + + col = layout.column() + col.label(text="Key Light Type:") + col.prop(self, "primarytype", text="") + col.label(text="Fill + Back Type:") + col.prop(self, "secondarytype", text="") + + + def execute(self, context): + try: + collection = context.collection + scene = context.scene + view = context.space_data + if view.type == 'VIEW_3D': + camera = view.camera + else: + camera = scene.camera + + if (camera is None): + cam_data = bpy.data.cameras.new(name='Camera') + cam_obj = bpy.data.objects.new(name='Camera', object_data=cam_data) + collection.objects.link(cam_obj) + scene.camera = cam_obj + bpy.ops.view3d.camera_to_view() + camera = cam_obj + bpy.ops.view3d.view_axis(type='TOP') + + obj = bpy.context.view_layer.objects.active + + # Calculate Energy for each Lamp + if(self.contrast > 0): + keyEnergy = self.energy + backEnergy = (self.energy / 100) * abs(self.contrast) + fillEnergy = (self.energy / 100) * abs(self.contrast) + else: + keyEnergy = (self.energy / 100) * abs(self.contrast) + backEnergy = self.energy + fillEnergy = self.energy + + # Calculate Direction for each Lamp + + # Calculate current Distance and get Delta + obj_position = obj.location + cam_position = camera.location + + delta_position = cam_position - obj_position + vector_length = sqrt( + (pow(delta_position.x, 2) + + pow(delta_position.y, 2) + + pow(delta_position.z, 2)) + ) + if not vector_length: + # division by zero most likely + self.report({'WARNING'}, + "Operation Cancelled. No viable object in the scene") + + return {'CANCELLED'} + + single_vector = (1 / vector_length) * delta_position + + # Calc back position + singleback_vector = single_vector.copy() + singleback_vector.x = cos(radians(self.backangle)) * single_vector.x + \ + (-sin(radians(self.backangle)) * single_vector.y) + + singleback_vector.y = sin(radians(self.backangle)) * single_vector.x + \ + (cos(radians(self.backangle)) * single_vector.y) + + backx = obj_position.x + self.distance * singleback_vector.x + backy = obj_position.y + self.distance * singleback_vector.y + + backData = bpy.data.lights.new(name="TriLamp-Back", type=self.secondarytype) + backData.energy = backEnergy + + backLamp = bpy.data.objects.new(name="TriLamp-Back", object_data=backData) + collection.objects.link(backLamp) + backLamp.location = (backx, backy, self.height) + + trackToBack = backLamp.constraints.new(type="TRACK_TO") + trackToBack.target = obj + trackToBack.track_axis = "TRACK_NEGATIVE_Z" + trackToBack.up_axis = "UP_Y" + + # Calc right position + singleright_vector = single_vector.copy() + singleright_vector.x = cos(radians(self.rightangle)) * single_vector.x + \ + (-sin(radians(self.rightangle)) * single_vector.y) + + singleright_vector.y = sin(radians(self.rightangle)) * single_vector.x + \ + (cos(radians(self.rightangle)) * single_vector.y) + + rightx = obj_position.x + self.distance * singleright_vector.x + righty = obj_position.y + self.distance * singleright_vector.y + + rightData = bpy.data.lights.new(name="TriLamp-Fill", type=self.secondarytype) + rightData.energy = fillEnergy + rightLamp = bpy.data.objects.new(name="TriLamp-Fill", object_data=rightData) + collection.objects.link(rightLamp) + rightLamp.location = (rightx, righty, self.height) + trackToRight = rightLamp.constraints.new(type="TRACK_TO") + trackToRight.target = obj + trackToRight.track_axis = "TRACK_NEGATIVE_Z" + trackToRight.up_axis = "UP_Y" + + # Calc left position + singleleft_vector = single_vector.copy() + singleleft_vector.x = cos(radians(-self.leftangle)) * single_vector.x + \ + (-sin(radians(-self.leftangle)) * single_vector.y) + singleleft_vector.y = sin(radians(-self.leftangle)) * single_vector.x + \ + (cos(radians(-self.leftangle)) * single_vector.y) + leftx = obj_position.x + self.distance * singleleft_vector.x + lefty = obj_position.y + self.distance * singleleft_vector.y + + leftData = bpy.data.lights.new(name="TriLamp-Key", type=self.primarytype) + leftData.energy = keyEnergy + + leftLamp = bpy.data.objects.new(name="TriLamp-Key", object_data=leftData) + collection.objects.link(leftLamp) + leftLamp.location = (leftx, lefty, self.height) + trackToLeft = leftLamp.constraints.new(type="TRACK_TO") + trackToLeft.target = obj + trackToLeft.track_axis = "TRACK_NEGATIVE_Z" + trackToLeft.up_axis = "UP_Y" + + except Exception as e: + self.report({'WARNING'}, + "Some operations could not be performed (See Console for more info)") + + print("\n[Add Advanced Objects]\nOperator: " + "object.trilighting\nError: {}".format(e)) + + return {'CANCELLED'} + + return {'FINISHED'} + +def menu_func(self, context): + self.layout.operator(OBJECT_OT_TriLighting.bl_idname, text="3 Point Lights", icon='LIGHT') + + + +# Register all operators and menu +def register(): + bpy.utils.register_class(OBJECT_OT_TriLighting) + bpy.types.VIEW3D_MT_light_add.append(menu_func) + +def unregister(): + bpy.utils.unregister_class(OBJECT_OT_TriLighting) + bpy.types.VIEW3D_MT_light_add.remove(menu_func) + +if __name__ == "__main__": + register() -- cgit v1.2.3