Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement uniform scale for layer and mask UVs #196

Merged
merged 1 commit into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion Layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def add_new_layer(group_tree, layer_name, layer_type, channel_idx,
):

yp = group_tree.yp
#ypup = get_user_preferences()
ypup = get_user_preferences()
obj = bpy.context.object
mat = obj.active_material

Expand Down Expand Up @@ -149,6 +149,10 @@ def add_new_layer(group_tree, layer_name, layer_type, channel_idx,
# Tree start and end
create_essential_nodes(tree, True, False, True)

# Uniform Scale
if is_bl_newer_than(2, 81) and is_layer_using_vector(layer):
layer.enable_uniform_scale = ypup.enable_uniform_uv_scale_by_default

# Add source
if layer_type == 'VCOL':
source = new_node(tree, layer, 'source', get_vcol_bl_idname(), 'Source')
Expand Down Expand Up @@ -5971,6 +5975,15 @@ def update_layer_blur_vector_factor(self, context):
if blur_vector:
blur_vector.inputs[0].default_value = layer.blur_vector_factor

def update_layer_uniform_scale_enabled(self, context):
if not hasattr(context, 'layer'): return

update_entity_uniform_scale_enabled(self)

check_layer_tree_ios(context.layer)
reconnect_layer_nodes(context.layer)
rearrange_layer_nodes(context.layer)

class YLayer(bpy.types.PropertyGroup):
name : StringProperty(
name = 'Layer Name',
Expand Down Expand Up @@ -6185,6 +6198,15 @@ class YLayer(bpy.types.PropertyGroup):
texcoord : StringProperty(default='')
blur_vector : StringProperty(default='')

enable_uniform_scale : BoolProperty(
name = 'Enable Uniform Scale',
description = 'Use the same value for all scale components',
default = False,
update = update_layer_uniform_scale_enabled
)

uniform_scale_value : FloatProperty(default=1)

decal_process : StringProperty(default='')

#need_temp_uv_refresh : BoolProperty(default=False)
Expand Down
25 changes: 24 additions & 1 deletion Mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
def add_new_mask(layer, name, mask_type, texcoord_type, uv_name, image = None, vcol = None, segment=None, object_index=0, blend_type='MULTIPLY', hemi_space='WORLD', hemi_use_prev_normal=False, color_id=(1,0,1), source_input='RGB', edge_detect_radius=0.05, modifier_type='INVERT', interpolation='Linear'):
yp = layer.id_data.yp
yp.halt_update = True
ypup = get_user_preferences()

tree = get_tree(layer)
nodes = tree.nodes
Expand All @@ -24,6 +25,10 @@ def add_new_mask(layer, name, mask_type, texcoord_type, uv_name, image = None, v
mask.texcoord_type = texcoord_type
mask.source_input = source_input

# Uniform Scale
if is_bl_newer_than(2, 81) and is_mask_using_vector(mask):
mask.enable_uniform_scale = ypup.enable_uniform_uv_scale_by_default

if segment:
mask.segment_name = segment.name

Expand Down Expand Up @@ -403,7 +408,7 @@ def invoke(self, context, event):
elif layer.type == 'IMAGE':
source = get_layer_source(layer)
if source and source.image: self.interpolation = source.interpolation

if get_user_preferences().skip_property_popups and not event.shift:
return self.execute(context)

Expand Down Expand Up @@ -1735,6 +1740,15 @@ class YLayerMaskChannel(bpy.types.PropertyGroup):
# UI related
expand_content : BoolProperty(default=False)

def update_mask_uniform_scale_enabled(self, context):
if not hasattr(context, 'layer'): return

update_entity_uniform_scale_enabled(self)

check_layer_tree_ios(context.layer)
reconnect_layer_nodes(context.layer)
rearrange_layer_nodes(context.layer)

class YLayerMask(bpy.types.PropertyGroup):

name : StringProperty(default='', update=update_mask_name)
Expand Down Expand Up @@ -1944,6 +1958,15 @@ class YLayerMask(bpy.types.PropertyGroup):
baked_mapping : StringProperty(default='')
blur_vector : StringProperty(default='')

enable_uniform_scale : BoolProperty(
name = 'Enable Uniform Scale',
description = 'Use the same value for all scale components',
default = False,
update = update_mask_uniform_scale_enabled
)

uniform_scale_value : FloatProperty(default=1)

decal_process : StringProperty(default='')
texcoord : StringProperty(default='')
decal_alpha : StringProperty(default='')
Expand Down
11 changes: 11 additions & 0 deletions common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2167,6 +2167,17 @@ def get_entity_mapping(entity, get_baked=False):

return None

def update_entity_uniform_scale_enabled(entity):
scale_input = get_entity_mapping(entity).inputs[3]

if entity.enable_uniform_scale:
# Set the uniform scale to min axis of regular scale when uniform scale is enabled
set_entity_prop_value(entity, 'uniform_scale_value', min(map(abs, scale_input.default_value)))
else:
# Set the regular scale axes to the uniform scale when uniform scale is disabled
scale = get_entity_prop_value(entity, 'uniform_scale_value')
scale_input.default_value = (scale, scale, scale)

def get_neighbor_uv_space_input(texcoord_type):
if texcoord_type == 'UV':
return 0.0 # Tangent Space
Expand Down
8 changes: 8 additions & 0 deletions input_outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,10 @@ def check_layer_tree_ios(layer, tree=None, remove_props=False, hard_reset=False)
dirty = create_prop_input(layer, 'decal_distance_value', valid_inputs, input_index, dirty)
input_index += 1

if is_bl_newer_than(2, 81) and layer.enable_uniform_scale and is_layer_using_vector(layer):
dirty = create_prop_input(layer, 'uniform_scale_value', valid_inputs, input_index, dirty)
input_index += 1

# Channel prop inputs
for i, ch in enumerate(layer.channels):
if not get_channel_enabled(ch): continue
Expand Down Expand Up @@ -960,6 +964,10 @@ def check_layer_tree_ios(layer, tree=None, remove_props=False, hard_reset=False)
dirty = create_prop_input(mask, 'intensity_value', valid_inputs, input_index, dirty)
input_index += 1

if is_bl_newer_than(2, 81) and mask.enable_uniform_scale and is_mask_using_vector(mask):
dirty = create_prop_input(mask, 'uniform_scale_value', valid_inputs, input_index, dirty)
input_index += 1

# Mask blur vector
if mask.enable_blur_vector:
dirty = create_prop_input(mask, 'blur_vector_factor', valid_inputs, input_index, dirty)
Expand Down
18 changes: 18 additions & 0 deletions node_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -1818,6 +1818,15 @@ def reconnect_layer_nodes(layer, ch_idx=-1, merge_mask=False):

if vector and mapping and layer.texcoord_type != 'Decal':
vector = create_link(tree, vector, mapping.inputs[0])[0]

# Layer UV uniform scale value
if is_bl_newer_than(2, 81):
uniform_scale_value = get_essential_node(tree, TREE_START).get(get_entity_input_name(layer, 'uniform_scale_value'))
if uniform_scale_value:
if layer.enable_uniform_scale:
create_link(tree, uniform_scale_value, mapping.inputs[3])
else:
break_link(tree, uniform_scale_value, mapping.inputs[3])

if vector and layer.type not in {'VCOL', 'BACKGROUND', 'COLOR', 'GROUP', 'HEMI', 'OBJECT_INDEX'}:
create_link(tree, vector, source.inputs[0])
Expand Down Expand Up @@ -2082,6 +2091,15 @@ def reconnect_layer_nodes(layer, ch_idx=-1, merge_mask=False):

create_link(tree, mask_vector, mask_source.inputs[0])

# Mask UV uniform scale value
if is_bl_newer_than(2, 81):
uniform_scale_value = get_essential_node(tree, TREE_START).get(get_entity_input_name(mask, 'uniform_scale_value'))
if uniform_scale_value:
if mask.enable_uniform_scale:
create_link(tree, uniform_scale_value, mask_mapping.inputs[3])
else:
break_link(tree, uniform_scale_value, mask_mapping.inputs[3])

# Mask uv neighbor
mask_uv_neighbor = nodes.get(mask.uv_neighbor) if mask.texcoord_type != 'Layer' else uv_neighbor
if mask_uv_neighbor:
Expand Down
8 changes: 8 additions & 0 deletions preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ class YPaintPreferences(AddonPreferences):
description = "Enable baked outside by default when creating new "+get_addon_title()+" node.\n(Useful for creating game assets)",
default = False
)

enable_uniform_uv_scale_by_default : BoolProperty(
name = 'Enable Uniform UV Scale by default',
description = "Enable uniform UV scale by default in Layer and Mask UVs. This will make all scale axes have the same value",
default = False
)

# Addon updater preferences.
auto_check_update : BoolProperty(
Expand Down Expand Up @@ -139,6 +145,8 @@ def draw(self, context):
self.layout.prop(self, 'use_image_preview')
self.layout.prop(self, 'skip_property_popups')
self.layout.prop(self, 'enable_baked_outside_by_default')
if is_bl_newer_than(2, 81):
self.layout.prop(self, 'enable_uniform_uv_scale_by_default')
self.layout.prop(self, 'show_experimental')
self.layout.prop(self, 'developer_mode')
#self.layout.prop(self, 'parallax_without_baked')
Expand Down
50 changes: 39 additions & 11 deletions ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,14 +571,14 @@ def draw_inbetween_modifier_mask_props(layer, source, layout):
elif layer.modifier_type == 'RAMP':
col.template_color_ramp(source, "color_ramp", expand=True)

def draw_input_prop(layout, entity, prop_name, emboss=None):
def draw_input_prop(layout, entity, prop_name, emboss=None, text=''):
inp = get_entity_prop_input(entity, prop_name)
if emboss != None:
if inp: layout.prop(inp, 'default_value', text='', emboss=emboss)
else: layout.prop(entity, prop_name, text='', emboss=emboss)
if inp: layout.prop(inp, 'default_value', text=text, emboss=emboss)
else: layout.prop(entity, prop_name, text=text, emboss=emboss)
else:
if inp: layout.prop(inp, 'default_value', text='')
else: layout.prop(entity, prop_name, text='')
if inp: layout.prop(inp, 'default_value', text=text)
else: layout.prop(entity, prop_name, text=text)

def draw_mask_modifier_stack(layer, mask, layout, ui):
ypui = bpy.context.window_manager.ypui
Expand Down Expand Up @@ -1476,15 +1476,29 @@ def draw_layer_source(context, layout, layer, layer_tree, source, image, vcol, i
mcol.prop(mapping.inputs[1], 'default_value', text='Offset')
mcol = rrow.column()
mcol.prop(mapping.inputs[2], 'default_value', text='Rotation')
mcol = rrow.column()
mcol.prop(mapping.inputs[3], 'default_value', text='Scale')
if layer.enable_uniform_scale:
mcol = rrow.column(align=True)
mcol.label(text='Scale:')
draw_input_prop(mcol, layer, 'uniform_scale_value', None, 'X')
draw_input_prop(mcol, layer, 'uniform_scale_value', None, 'Y')
draw_input_prop(mcol, layer, 'uniform_scale_value', None, 'Z')
else:
mcol = rrow.column()
mcol.prop(mapping.inputs[3], 'default_value', text='Scale')
else:
mcol = rrow.column()
mcol.prop(mapping, 'translation')
mcol = rrow.column()
mcol.prop(mapping, 'rotation')
mcol = rrow.column()
mcol.prop(mapping, 'scale')

# Uniform scale
if is_bl_newer_than(2, 81):
rrow = boxcol.row(align=True)
splits = split_layout(rrow, 0.5)
splits.label(text='Uniform Scale:')
rrow.prop(layer, 'enable_uniform_scale', text='')

if yp.need_temp_uv_refresh:
rrow = boxcol.row(align=True)
Expand All @@ -1493,7 +1507,7 @@ def draw_layer_source(context, layout, layer, layer_tree, source, image, vcol, i

# Blur row
rrow = boxcol.row(align=True)
splits = split_layout(rrow, 0.3)
splits = split_layout(rrow, 0.5)
splits.label(text='Blur:')
if layer.enable_blur_vector:
draw_input_prop(splits, layer, 'blur_vector_factor')
Expand Down Expand Up @@ -2446,15 +2460,29 @@ def draw_layer_masks(context, layout, layer):
mcol.prop(mapping.inputs[1], 'default_value', text='Offset')
mcol = rrow.column()
mcol.prop(mapping.inputs[2], 'default_value', text='Rotation')
mcol = rrow.column()
mcol.prop(mapping.inputs[3], 'default_value', text='Scale')
if mask.enable_uniform_scale:
mcol = rrow.column(align=True)
mcol.label(text='Scale:')
draw_input_prop(mcol, mask, 'uniform_scale_value', None, 'X')
draw_input_prop(mcol, mask, 'uniform_scale_value', None, 'Y')
draw_input_prop(mcol, mask, 'uniform_scale_value', None, 'Z')
else:
mcol = rrow.column()
mcol.prop(mapping.inputs[3], 'default_value', text='Scale')
else:
mcol = rrow.column()
mcol.prop(mapping, 'translation')
mcol = rrow.column()
mcol.prop(mapping, 'rotation')
mcol = rrow.column()
mcol.prop(mapping, 'scale')

# Uniform scale
if is_bl_newer_than(2, 81):
rrow = boxcol.row(align=True)
splits = split_layout(rrow, 0.5)
splits.label(text='Uniform Scale:')
rrow.prop(mask, 'enable_uniform_scale', text='')

if mask.type == 'IMAGE' and mask.active_edit and (
yp.need_temp_uv_refresh
Expand All @@ -2466,7 +2494,7 @@ def draw_layer_masks(context, layout, layer):
# Blur row
if mask.texcoord_type != 'Layer':
rrow = boxcol.row(align=True)
splits = split_layout(rrow, 0.3)
splits = split_layout(rrow, 0.5)
splits.label(text='Blur:')
if mask.enable_blur_vector:
draw_input_prop(splits, mask, 'blur_vector_factor')
Expand Down