This commit implements described in the #104573. The goal is to fix the confusion of the submodule hashes change, which are not ideal for any of the supported git-module configuration (they are either always visible causing confusion, or silently staged and committed, also causing confusion). This commit replaces submodules with a checkout of addons and addons_contrib, covered by the .gitignore, and locale and developer tools are moved to the main repository. This also changes the paths: - /release/scripts are moved to the /scripts - /source/tools are moved to the /tools - /release/datafiles/locale is moved to /locale This is done to avoid conflicts when using bisect, and also allow buildbot to automatically "recover" wgen building older or newer branches/patches. Running `make update` will initialize the local checkout to the changed repository configuration. Another aspect of the change is that the make update will support Github style of remote organization (origin remote pointing to thy fork, upstream remote pointing to the upstream blender/blender.git). Pull Request #104755
434 lines
13 KiB
Python
434 lines
13 KiB
Python
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
# panels get subclassed (not registered directly)
|
|
# menus are referenced `as is`
|
|
|
|
from bpy.types import Menu, UIList
|
|
from bpy.app.translations import contexts as i18n_contexts
|
|
|
|
|
|
# Use by both image & clip context menus.
|
|
def draw_mask_context_menu(layout, _context):
|
|
layout.operator_menu_enum("mask.handle_type_set", "type")
|
|
layout.operator("mask.switch_direction")
|
|
layout.operator("mask.cyclic_toggle")
|
|
|
|
layout.separator()
|
|
layout.operator("mask.copy_splines", icon='COPYDOWN')
|
|
layout.operator("mask.paste_splines", icon='PASTEDOWN')
|
|
|
|
layout.separator()
|
|
|
|
layout.operator("mask.shape_key_rekey", text="Re-Key Shape Points")
|
|
layout.operator("mask.feather_weight_clear")
|
|
layout.operator("mask.shape_key_feather_reset", text="Reset Feather Animation")
|
|
|
|
layout.separator()
|
|
|
|
layout.operator("mask.parent_set")
|
|
layout.operator("mask.parent_clear")
|
|
|
|
layout.separator()
|
|
|
|
layout.operator("mask.delete")
|
|
|
|
|
|
class MASK_UL_layers(UIList):
|
|
def draw_item(self, _context, layout, _data, item, icon,
|
|
_active_data, _active_propname, _index):
|
|
# assert(isinstance(item, bpy.types.MaskLayer)
|
|
mask = item
|
|
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
|
layout.prop(mask, "name", text="", emboss=False, icon_value=icon)
|
|
row = layout.row(align=True)
|
|
row.prop(mask, "hide", text="", emboss=False)
|
|
row.prop(mask, "hide_select", text="", emboss=False)
|
|
row.prop(mask, "hide_render", text="", emboss=False)
|
|
elif self.layout_type == 'GRID':
|
|
layout.alignment = 'CENTER'
|
|
layout.label(text="", icon_value=icon)
|
|
|
|
|
|
class MASK_PT_mask:
|
|
# subclasses must define...
|
|
# ~ bl_space_type = 'CLIP_EDITOR'
|
|
# ~ bl_region_type = 'UI'
|
|
bl_label = "Mask Settings"
|
|
bl_options = {'DEFAULT_CLOSED'}
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
space_data = context.space_data
|
|
return space_data.mask and space_data.mode == 'MASK'
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
layout.use_property_split = True
|
|
layout.use_property_decorate = False
|
|
|
|
sc = context.space_data
|
|
mask = sc.mask
|
|
|
|
col = layout.column(align=True)
|
|
col.prop(mask, "frame_start")
|
|
col.prop(mask, "frame_end")
|
|
|
|
|
|
class MASK_PT_layers:
|
|
# subclasses must define...
|
|
# ~ bl_space_type = 'CLIP_EDITOR'
|
|
# ~ bl_region_type = 'UI'
|
|
bl_label = "Mask Layers"
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
space_data = context.space_data
|
|
return space_data.mask and space_data.mode == 'MASK'
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
layout.use_property_split = True
|
|
layout.use_property_decorate = False
|
|
|
|
sc = context.space_data
|
|
mask = sc.mask
|
|
active_layer = mask.layers.active
|
|
|
|
rows = 4 if active_layer else 1
|
|
|
|
row = layout.row()
|
|
row.template_list("MASK_UL_layers", "", mask, "layers",
|
|
mask, "active_layer_index", rows=rows)
|
|
|
|
sub = row.column(align=True)
|
|
|
|
sub.operator("mask.layer_new", icon='ADD', text="")
|
|
sub.operator("mask.layer_remove", icon='REMOVE', text="")
|
|
|
|
if active_layer:
|
|
sub.separator()
|
|
|
|
sub.operator("mask.layer_move", icon='TRIA_UP', text="").direction = 'UP'
|
|
sub.operator("mask.layer_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
|
|
|
|
# blending
|
|
row = layout.row(align=True)
|
|
row.prop(active_layer, "alpha")
|
|
row.prop(active_layer, "invert", text="", icon='IMAGE_ALPHA')
|
|
|
|
layout.prop(active_layer, "blend")
|
|
layout.prop(active_layer, "falloff")
|
|
|
|
col = layout.column()
|
|
col.prop(active_layer, "use_fill_overlap", text="Overlap")
|
|
col.prop(active_layer, "use_fill_holes", text="Holes")
|
|
|
|
|
|
class MASK_PT_spline:
|
|
# subclasses must define...
|
|
# ~ bl_space_type = 'CLIP_EDITOR'
|
|
# ~ bl_region_type = 'UI'
|
|
bl_label = "Active Spline"
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
sc = context.space_data
|
|
mask = sc.mask
|
|
|
|
if mask and sc.mode == 'MASK':
|
|
return mask.layers.active and mask.layers.active.splines.active
|
|
|
|
return False
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
layout.use_property_split = True
|
|
layout.use_property_decorate = False
|
|
|
|
sc = context.space_data
|
|
mask = sc.mask
|
|
spline = mask.layers.active.splines.active
|
|
|
|
col = layout.column()
|
|
col.prop(spline, "offset_mode")
|
|
col.prop(spline, "weight_interpolation", text="Interpolation")
|
|
|
|
col.prop(spline, "use_cyclic")
|
|
col.prop(spline, "use_fill")
|
|
|
|
col.prop(spline, "use_self_intersection_check")
|
|
|
|
|
|
class MASK_PT_point:
|
|
# subclasses must define...
|
|
# ~ bl_space_type = 'CLIP_EDITOR'
|
|
# ~ bl_region_type = 'UI'
|
|
bl_label = "Active Point"
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
sc = context.space_data
|
|
mask = sc.mask
|
|
|
|
if mask and sc.mode == 'MASK':
|
|
mask_layer_active = mask.layers.active
|
|
return (mask_layer_active and
|
|
mask_layer_active.splines.active_point)
|
|
|
|
return False
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
layout.use_property_split = True
|
|
layout.use_property_decorate = False
|
|
|
|
sc = context.space_data
|
|
mask = sc.mask
|
|
point = mask.layers.active.splines.active_point
|
|
parent = point.parent
|
|
|
|
col = layout.column()
|
|
# Currently only parenting the movie-clip is allowed,
|
|
# so do not over-complicate things for now by using single template_ID
|
|
#col.template_any_ID(parent, "id", "id_type", text="")
|
|
|
|
col.label(text="Parent:")
|
|
col.prop(parent, "id", text="")
|
|
|
|
if parent.id_type == 'MOVIECLIP' and parent.id:
|
|
clip = parent.id
|
|
tracking = clip.tracking
|
|
|
|
row = col.row()
|
|
row.prop(parent, "type", expand=True)
|
|
|
|
col.prop_search(parent, "parent", tracking,
|
|
"objects", icon='OBJECT_DATA', text="Object")
|
|
|
|
tracks_list = "tracks" if parent.type == 'POINT_TRACK' else "plane_tracks"
|
|
|
|
if parent.parent in tracking.objects:
|
|
ob = tracking.objects[parent.parent]
|
|
col.prop_search(parent, "sub_parent", ob,
|
|
tracks_list, icon='ANIM_DATA', text="Track")
|
|
else:
|
|
col.prop_search(parent, "sub_parent", tracking,
|
|
tracks_list, icon='ANIM_DATA', text="Track")
|
|
|
|
|
|
class MASK_PT_display:
|
|
# subclasses must define...
|
|
# ~ bl_space_type = 'CLIP_EDITOR'
|
|
# ~ bl_region_type = 'HEADER'
|
|
bl_label = "Mask Display"
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
space_data = context.space_data
|
|
return space_data.mask and space_data.mode == 'MASK'
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
space_data = context.space_data
|
|
|
|
row = layout.row(align=True)
|
|
row.prop(space_data, "show_mask_spline", text="Spline")
|
|
sub = row.row()
|
|
sub.active = space_data.show_mask_spline
|
|
sub.prop(space_data, "mask_display_type", text="")
|
|
row = layout.row(align=True)
|
|
row.prop(space_data, "show_mask_overlay", text="Overlay")
|
|
sub = row.row()
|
|
sub.active = space_data.show_mask_overlay
|
|
sub.prop(space_data, "mask_overlay_mode", text="")
|
|
row = layout.row()
|
|
row.active = (space_data.mask_overlay_mode in ['COMBINED'] and space_data.show_mask_overlay)
|
|
row.prop(space_data, "blend_factor", text="Blending Factor")
|
|
|
|
|
|
class MASK_PT_transforms:
|
|
# subclasses must define...
|
|
# ~ bl_space_type = 'CLIP_EDITOR'
|
|
# ~ bl_region_type = 'TOOLS'
|
|
bl_label = "Transforms"
|
|
bl_category = "Mask"
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
space_data = context.space_data
|
|
return space_data.mask and space_data.mode == 'MASK'
|
|
|
|
def draw(self, _context):
|
|
layout = self.layout
|
|
|
|
col = layout.column(align=True)
|
|
col.label(text="Transform:")
|
|
col.operator("transform.translate")
|
|
col.operator("transform.rotate")
|
|
col.operator("transform.resize", text="Scale")
|
|
col.operator("transform.transform", text="Scale Feather").mode = 'MASK_SHRINKFATTEN'
|
|
|
|
|
|
class MASK_PT_tools:
|
|
bl_label = "Mask Tools"
|
|
bl_category = "Mask"
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
space_data = context.space_data
|
|
return space_data.mask and space_data.mode == 'MASK'
|
|
|
|
def draw(self, _context):
|
|
layout = self.layout
|
|
|
|
col = layout.column(align=True)
|
|
col.label(text="Spline:")
|
|
col.operator("mask.delete")
|
|
col.operator("mask.cyclic_toggle")
|
|
col.operator("mask.switch_direction")
|
|
col.operator("mask.handle_type_set").type = 'VECTOR'
|
|
col.operator("mask.feather_weight_clear")
|
|
|
|
col = layout.column(align=True)
|
|
col.label(text="Parenting:")
|
|
row = col.row(align=True)
|
|
row.operator("mask.parent_set", text="Parent")
|
|
row.operator("mask.parent_clear", text="Clear")
|
|
|
|
col = layout.column(align=True)
|
|
col.label(text="Animation:")
|
|
row = col.row(align=True)
|
|
row.operator("mask.shape_key_insert", text="Insert Key")
|
|
row.operator("mask.shape_key_clear", text="Clear Key")
|
|
col.operator("mask.shape_key_feather_reset", text="Reset Feather Animation")
|
|
col.operator("mask.shape_key_rekey", text="Re-Key Shape Points")
|
|
|
|
|
|
class MASK_MT_mask(Menu):
|
|
bl_label = "Mask"
|
|
|
|
def draw(self, _context):
|
|
layout = self.layout
|
|
|
|
layout.menu("MASK_MT_transform")
|
|
layout.operator("mask.feather_weight_clear")
|
|
|
|
layout.separator()
|
|
layout.operator("mask.cyclic_toggle")
|
|
layout.operator("mask.handle_type_set")
|
|
layout.operator("mask.normals_make_consistent")
|
|
layout.operator("mask.switch_direction")
|
|
|
|
layout.separator()
|
|
layout.operator("mask.copy_splines")
|
|
layout.operator("mask.paste_splines")
|
|
|
|
layout.separator()
|
|
layout.operator("mask.parent_clear")
|
|
layout.operator("mask.parent_set")
|
|
|
|
layout.separator()
|
|
layout.menu("MASK_MT_animation")
|
|
|
|
layout.separator()
|
|
layout.menu("MASK_MT_visibility")
|
|
layout.operator("mask.delete")
|
|
|
|
|
|
class MASK_MT_add(Menu):
|
|
bl_idname = "MASK_MT_add"
|
|
bl_label = "Add"
|
|
bl_translation_context = i18n_contexts.operator_default
|
|
|
|
def draw(self, _context):
|
|
layout = self.layout
|
|
|
|
layout.operator_context = 'INVOKE_REGION_WIN'
|
|
layout.operator("mask.primitive_circle_add", text="Circle", icon='MESH_CIRCLE')
|
|
layout.operator("mask.primitive_square_add", text="Square", icon='MESH_PLANE')
|
|
|
|
|
|
class MASK_MT_visibility(Menu):
|
|
bl_label = "Show/Hide"
|
|
|
|
def draw(self, _context):
|
|
layout = self.layout
|
|
|
|
layout.operator("mask.hide_view_clear")
|
|
layout.operator("mask.hide_view_set", text="Hide Selected").unselected = False
|
|
layout.operator("mask.hide_view_set", text="Hide Unselected").unselected = True
|
|
|
|
|
|
class MASK_MT_transform(Menu):
|
|
bl_label = "Transform"
|
|
|
|
def draw(self, _context):
|
|
layout = self.layout
|
|
|
|
layout.operator("transform.translate")
|
|
layout.operator("transform.rotate")
|
|
layout.operator("transform.resize")
|
|
|
|
layout.separator()
|
|
layout.operator("transform.tosphere")
|
|
layout.operator("transform.shear")
|
|
layout.operator("transform.push_pull")
|
|
|
|
layout.separator()
|
|
layout.operator("transform.transform", text="Scale Feather").mode = 'MASK_SHRINKFATTEN'
|
|
|
|
|
|
class MASK_MT_animation(Menu):
|
|
bl_label = "Animation"
|
|
|
|
def draw(self, _context):
|
|
layout = self.layout
|
|
|
|
layout.operator("mask.shape_key_clear")
|
|
layout.operator("mask.shape_key_insert")
|
|
layout.operator("mask.shape_key_feather_reset")
|
|
layout.operator("mask.shape_key_rekey")
|
|
|
|
|
|
class MASK_MT_select(Menu):
|
|
bl_label = "Select"
|
|
|
|
def draw(self, _context):
|
|
layout = self.layout
|
|
|
|
layout.operator("mask.select_all", text="All").action = 'SELECT'
|
|
layout.operator("mask.select_all", text="None").action = 'DESELECT'
|
|
layout.operator("mask.select_all", text="Invert").action = 'INVERT'
|
|
|
|
layout.separator()
|
|
|
|
layout.operator("mask.select_box")
|
|
layout.operator("mask.select_circle")
|
|
layout.operator_menu_enum("mask.select_lasso", "mode")
|
|
|
|
layout.separator()
|
|
|
|
layout.operator("mask.select_more")
|
|
layout.operator("mask.select_less")
|
|
|
|
layout.separator()
|
|
|
|
layout.operator("mask.select_linked", text="Select Linked")
|
|
|
|
|
|
classes = (
|
|
MASK_UL_layers,
|
|
MASK_MT_mask,
|
|
MASK_MT_add,
|
|
MASK_MT_visibility,
|
|
MASK_MT_transform,
|
|
MASK_MT_animation,
|
|
MASK_MT_select,
|
|
)
|
|
|
|
if __name__ == "__main__": # only for live edit.
|
|
from bpy.utils import register_class
|
|
for cls in classes:
|
|
register_class(cls)
|