From d2236c1e43f165f191b39326bfe353f05c901b49 Mon Sep 17 00:00:00 2001 From: Henri Hebeisen Date: Fri, 21 Jul 2023 19:23:10 +0200 Subject: [PATCH 1/8] Adding keystone parameters and exposing them to UI --- projector.py | 17 +++++++++++++++++ ui.py | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/projector.py b/projector.py index 26e2632..fc60ad6 100644 --- a/projector.py +++ b/projector.py @@ -287,6 +287,13 @@ def update_throw_ratio(proj_settings, context): throw_ratio * inverted_aspect_ratio +def update_keystone(proj_settings, context): + """ + Apply the keystone parameters to the camera and texture + """ + projector = get_projector(context) + print('On update le keystone calice') + def update_lens_shift(proj_settings, context): """ Apply the shift to the camera and texture. @@ -603,6 +610,16 @@ class ProjectorSettings(bpy.types.PropertyGroup): soft_min=-20, soft_max=20, update=update_lens_shift, subtype='PERCENTAGE') + h_keystone: bpy.props.FloatProperty( + name="Horizontal KeyStone", + description="Amount of Horizontal Keystone Distortion", + soft_min=-1, soft_max=1, + update=update_keystone) + v_keystone: bpy.props.FloatProperty( + name="Vertical KeyStone", + description="Amount of Vertical Keystone Distortion", + soft_min=-1, soft_max=1, + update=update_keystone) projected_color: bpy.props.FloatVectorProperty( subtype='COLOR', update=update_checker_color) diff --git a/ui.py b/ui.py index 2f292d1..4f3f12a 100644 --- a/ui.py +++ b/ui.py @@ -55,6 +55,13 @@ def draw(self, context): col.prop(proj_settings, 'v_shift', text='Vertical Shift') layout.prop(proj_settings, 'projected_texture', text='Project') + + #Keystone + col = box.column(align=True) + col.prop(proj_settings, + 'h_keystone', text="Horizontal Keystone") + col.prop(proj_settings, + 'v_keystone', text="Vertical Keystone") # Pixel Grid box.prop(proj_settings, 'show_pixel_grid') From 36d3b0b327609403738b7028f9d4be1c17a2d6ff Mon Sep 17 00:00:00 2001 From: Henri Hebeisen Date: Tue, 29 Aug 2023 21:22:33 +0200 Subject: [PATCH 2/8] changed the projection node setup to allow for keystone correction --- projector.py | 63 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/projector.py b/projector.py index fc60ad6..38b9c3f 100644 --- a/projector.py +++ b/projector.py @@ -128,21 +128,36 @@ def add_projector_node_tree_to_spot(spot): map_1.location = auto_pos(200) sep = nodes.new('ShaderNodeSeparateXYZ') - sep.location = auto_pos(350) - - div_1 = nodes.new('ShaderNodeMath') - div_1.operation = 'DIVIDE' - div_1.name = ADDON_ID + 'div_01' - div_1.location = auto_pos(200) - - div_2 = nodes.new('ShaderNodeMath') - div_2.operation = 'DIVIDE' - div_2.name = ADDON_ID + 'div_02' - div_2.location = auto_pos(y=-200) - - com = nodes.new('ShaderNodeCombineXYZ') - com.inputs['Z'].default_value = 1.0 - com.location = auto_pos(200) + sep.location = auto_pos(200, y=-150) + + keystone_horizontal = nodes.new('ShaderNodeMath') + keystone_horizontal.operation = "MULTIPLY" + keystone_horizontal.name = ADDON_ID + 'keystone_horizontal' + keystone_horizontal.label = 'Horizontal Keystone' + keystone_horizontal.inputs[0].default_value = 0.0 + keystone_horizontal.location = auto_pos(200, y=-100) + + keystone_vertical = nodes.new('ShaderNodeMath') + keystone_vertical.operation = "MULTIPLY" + keystone_vertical.name = ADDON_ID + 'keystone_vertical' + keystone_vertical.label = 'Vertical Keystone' + keystone_vertical.inputs[1].default_value = 0.0 + keystone_vertical.location = auto_pos(y= -300) + + add_1 = nodes.new('ShaderNodeMath') + add_1.operation = "ADD" + add_1.name = ADDON_ID + 'add_01' + add_1.location = auto_pos(200, y=-100) + + add_2 = nodes.new('ShaderNodeMath') + add_2.operation = "ADD" + add_2.name = ADDON_ID + 'add_02' + add_2.location = auto_pos(200,y=-150) + + vec_div = nodes.new('ShaderNodeVectorMath') + vec_div.operation = "DIVIDE" + vec_div.name = ADDON_ID + 'vec_div' + vec_div.location = auto_pos(200, y=50) map_2 = nodes.new('ShaderNodeMapping') map_2.location = auto_pos(200) @@ -197,15 +212,19 @@ def add_projector_node_tree_to_spot(spot): tree.links.new(tex.outputs['Normal'], map_1.inputs['Vector']) tree.links.new(map_1.outputs['Vector'], sep.inputs['Vector']) - tree.links.new(sep.outputs[0], div_1.inputs[0]) # X -> value0 - tree.links.new(sep.outputs[2], div_1.inputs[1]) # Z -> value1 - tree.links.new(sep.outputs[1], div_2.inputs[0]) # Y -> value0 - tree.links.new(sep.outputs[2], div_2.inputs[1]) # Z -> value1 + tree.links.new(sep.outputs[0], keystone_horizontal.inputs[1]) + tree.links.new(sep.outputs[1], keystone_vertical.inputs[0]) + tree.links.new(sep.outputs[2], add_1.inputs[1]) + + tree.links.new(keystone_horizontal.outputs[0], add_1.inputs[0]) + tree.links.new(keystone_vertical.outputs[0], add_2.inputs[1]) + + tree.links.new(add_1.outputs[0], add_2.inputs[0]) - tree.links.new(div_1.outputs[0], com.inputs[0]) - tree.links.new(div_2.outputs[0], com.inputs[1]) + tree.links.new(map_1.outputs['Vector'], vec_div.inputs[0]) + tree.links.new(add_2.outputs[0], vec_div.inputs[1]) - tree.links.new(com.outputs['Vector'], map_2.inputs['Vector']) + tree.links.new(vec_div.outputs['Vector'], map_2.inputs['Vector']) # Textures # a) generated texture From 9ff65692ec37ce418b5b0a1cbdff80c85034fe4a Mon Sep 17 00:00:00 2001 From: Henri Hebeisen Date: Tue, 29 Aug 2023 21:58:13 +0200 Subject: [PATCH 3/8] keystone update works ! --- projector.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/projector.py b/projector.py index 38b9c3f..ada238d 100644 --- a/projector.py +++ b/projector.py @@ -132,14 +132,14 @@ def add_projector_node_tree_to_spot(spot): keystone_horizontal = nodes.new('ShaderNodeMath') keystone_horizontal.operation = "MULTIPLY" - keystone_horizontal.name = ADDON_ID + 'keystone_horizontal' + keystone_horizontal.name = 'keystone_horizontal' keystone_horizontal.label = 'Horizontal Keystone' keystone_horizontal.inputs[0].default_value = 0.0 keystone_horizontal.location = auto_pos(200, y=-100) keystone_vertical = nodes.new('ShaderNodeMath') keystone_vertical.operation = "MULTIPLY" - keystone_vertical.name = ADDON_ID + 'keystone_vertical' + keystone_vertical.name = 'keystone_vertical' keystone_vertical.label = 'Vertical Keystone' keystone_vertical.inputs[1].default_value = 0.0 keystone_vertical.location = auto_pos(y= -300) @@ -311,7 +311,18 @@ def update_keystone(proj_settings, context): Apply the keystone parameters to the camera and texture """ projector = get_projector(context) - print('On update le keystone calice') + + h_shift = proj_settings.get('h_keystone', 0.0) + v_shift = proj_settings.get('v_keystone', 0.0) + + spot = projector.children[0] + nodes = spot.data.node_tree.nodes['Group'].node_tree.nodes + if bpy.app.version < (2, 81): + nodes['keystone_horizontal'].translation[0] = h_shift + nodes['keystone_vertical'].translation[1] = v_shift + else: + nodes['keystone_horizontal'].inputs[0].default_value = h_shift + nodes['keystone_vertical'].inputs[1].default_value = v_shift def update_lens_shift(proj_settings, context): """ From 63012f5dded2ef542b158f3b6b5f724e3f028925 Mon Sep 17 00:00:00 2001 From: Henri Hebeisen Date: Wed, 30 Aug 2023 22:28:49 +0200 Subject: [PATCH 4/8] Ui for post scale --- projector.py | 22 ++++++++++++++++------ ui.py | 5 +++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/projector.py b/projector.py index ada238d..174695e 100644 --- a/projector.py +++ b/projector.py @@ -312,17 +312,20 @@ def update_keystone(proj_settings, context): """ projector = get_projector(context) - h_shift = proj_settings.get('h_keystone', 0.0) - v_shift = proj_settings.get('v_keystone', 0.0) + h_keystone = proj_settings.get('h_keystone', 0.0) + v_keystone = proj_settings.get('v_keystone', 0.0) spot = projector.children[0] nodes = spot.data.node_tree.nodes['Group'].node_tree.nodes if bpy.app.version < (2, 81): - nodes['keystone_horizontal'].translation[0] = h_shift - nodes['keystone_vertical'].translation[1] = v_shift + nodes['keystone_horizontal'].translation[0] = h_keystone + nodes['keystone_vertical'].translation[1] = v_keystone else: - nodes['keystone_horizontal'].inputs[0].default_value = h_shift - nodes['keystone_vertical'].inputs[1].default_value = v_shift + nodes['keystone_horizontal'].inputs[0].default_value = h_keystone + nodes['keystone_vertical'].inputs[1].default_value = v_keystone + +def update_post_scale(proj_settings, context): + print('on update le post scale') def update_lens_shift(proj_settings, context): """ @@ -650,6 +653,13 @@ class ProjectorSettings(bpy.types.PropertyGroup): description="Amount of Vertical Keystone Distortion", soft_min=-1, soft_max=1, update=update_keystone) + post_scale: bpy.props.FloatProperty( + name="Scale Factor", + description="Global scale factor of the projected image", + min=0.0, + default=1.0, + update=update_post_scale + ) projected_color: bpy.props.FloatVectorProperty( subtype='COLOR', update=update_checker_color) diff --git a/ui.py b/ui.py index 4f3f12a..4bf650b 100644 --- a/ui.py +++ b/ui.py @@ -62,6 +62,11 @@ def draw(self, context): 'h_keystone', text="Horizontal Keystone") col.prop(proj_settings, 'v_keystone', text="Vertical Keystone") + + #Post Projection Scale + col = box.column(align=True) + col.prop(proj_settings, + "post_scale", text="Scale Adjustment Factor") # Pixel Grid box.prop(proj_settings, 'show_pixel_grid') From 02fb733bbce305f73bb032af6714fb685d22c977 Mon Sep 17 00:00:00 2001 From: Henri Hebeisen Date: Wed, 30 Aug 2023 22:36:23 +0200 Subject: [PATCH 5/8] adding correct post scale at projector creation --- projector.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/projector.py b/projector.py index 174695e..180a5f9 100644 --- a/projector.py +++ b/projector.py @@ -163,6 +163,11 @@ def add_projector_node_tree_to_spot(spot): map_2.location = auto_pos(200) map_2.vector_type = 'TEXTURE' + scale = nodes.new('ShaderNodeVectorMath') + scale.operation = "SCALE" + scale.name ='post_scale' + scale.location = auto_pos(200) + add = nodes.new('ShaderNodeMixRGB') add.blend_type = 'ADD' add.inputs[0].default_value = 1 @@ -225,10 +230,11 @@ def add_projector_node_tree_to_spot(spot): tree.links.new(add_2.outputs[0], vec_div.inputs[1]) tree.links.new(vec_div.outputs['Vector'], map_2.inputs['Vector']) + tree.links.new(map_2.outputs['Vector'], scale.inputs[0]) # Textures # a) generated texture - tree.links.new(map_2.outputs['Vector'], add.inputs['Color1']) + tree.links.new(scale.outputs['Vector'], add.inputs['Color1']) tree.links.new(add.outputs['Color'], img.inputs['Vector']) tree.links.new(add.outputs['Color'], group_output_node.inputs[0]) # b) checker texture From 60b8b5b3ca6c22a74e6313b07766aac3a728690d Mon Sep 17 00:00:00 2001 From: Henri Hebeisen Date: Wed, 30 Aug 2023 22:45:16 +0200 Subject: [PATCH 6/8] update post scale works ! --- projector.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/projector.py b/projector.py index 180a5f9..30ea960 100644 --- a/projector.py +++ b/projector.py @@ -314,7 +314,7 @@ def update_throw_ratio(proj_settings, context): def update_keystone(proj_settings, context): """ - Apply the keystone parameters to the camera and texture + Apply the keystone parameters to the texture """ projector = get_projector(context) @@ -331,7 +331,20 @@ def update_keystone(proj_settings, context): nodes['keystone_vertical'].inputs[1].default_value = v_keystone def update_post_scale(proj_settings, context): - print('on update le post scale') + """ + Apply the post scale parameters to the texture + """ + + projector = get_projector(context) + post_scale = 1 / proj_settings.get('post_scale', 0.0) + + spot = projector.children[0] + nodes = spot.data.node_tree.nodes['Group'].node_tree.nodes + if bpy.app.version < (2, 81): + nodes['post_scale'].translation[3] = post_scale + else: + nodes['post_scale'].inputs[3].default_value = post_scale + def update_lens_shift(proj_settings, context): """ From 12f9fa79076810e1272c957984534c3b83b7ba5f Mon Sep 17 00:00:00 2001 From: Henri Hebeisen Date: Wed, 30 Aug 2023 22:46:20 +0200 Subject: [PATCH 7/8] New minimum for post scale to avoid Nan. --- projector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projector.py b/projector.py index 30ea960..26343b4 100644 --- a/projector.py +++ b/projector.py @@ -675,7 +675,7 @@ class ProjectorSettings(bpy.types.PropertyGroup): post_scale: bpy.props.FloatProperty( name="Scale Factor", description="Global scale factor of the projected image", - min=0.0, + min=0.001, default=1.0, update=update_post_scale ) From 821e03426afd40d82bf5072fd170fef8bcf2fbb4 Mon Sep 17 00:00:00 2001 From: Henri Hebeisen Date: Sat, 9 Sep 2023 22:17:43 +0200 Subject: [PATCH 8/8] Changed Text To be easier to read --- ui.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ui.py b/ui.py index 4bf650b..c18c9b2 100644 --- a/ui.py +++ b/ui.py @@ -50,18 +50,17 @@ def draw(self, context): res_row.enabled = True # Lens Shift col = box.column(align=True) - col.prop(proj_settings, - 'h_shift', text='Horizontal Shift') - col.prop(proj_settings, 'v_shift', text='Vertical Shift') + col.prop(proj_settings, 'h_shift', text='H Shift') + col.prop(proj_settings, 'v_shift', text='V Shift') layout.prop(proj_settings, 'projected_texture', text='Project') #Keystone col = box.column(align=True) col.prop(proj_settings, - 'h_keystone', text="Horizontal Keystone") + 'h_keystone', text="H Keystone") col.prop(proj_settings, - 'v_keystone', text="Vertical Keystone") + 'v_keystone', text="V Keystone") #Post Projection Scale col = box.column(align=True)