ui redraw on UIlist actions and code cleanup
2.0.9 - fix: prefix/suffix UIlist actions trigger UI redraw to see changes live - changed: PropertyGroups are now registered in their own file - code: cleanupgpv2
parent
c32ea207c6
commit
e0a50ea49a
|
@ -1,5 +1,11 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
2.0.9
|
||||||
|
|
||||||
|
- fix: prefix/suffix UIlist actions trigger UI redraw to see changes live
|
||||||
|
- changed: PropertyGroups are now registered in their own file
|
||||||
|
- code: cleanup
|
||||||
|
|
||||||
2.0.8
|
2.0.8
|
||||||
|
|
||||||
- changed: suffix as UIlist in prefs,
|
- changed: suffix as UIlist in prefs,
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
import re
|
||||||
|
from .utils import get_addon_prefs
|
||||||
|
from .functions import redraw_ui
|
||||||
|
|
||||||
|
class GPTB_OT_add_namespace_entry(bpy.types.Operator):
|
||||||
|
bl_idname = "gptb.add_namespace_entry"
|
||||||
|
bl_label = "Add Namespace Entry"
|
||||||
|
bl_description = "Add item in list"
|
||||||
|
bl_options = {'REGISTER', 'INTERNAL'}
|
||||||
|
|
||||||
|
idx : bpy.props.IntProperty()
|
||||||
|
new : bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'})
|
||||||
|
propname : bpy.props.StringProperty(default='prefixes', options={'SKIP_SAVE'})
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
self.pg = getattr(get_addon_prefs(), self.propname)
|
||||||
|
self.proptype = self.propname[:-2]
|
||||||
|
## Basic:
|
||||||
|
# self.pg.namespaces.add()
|
||||||
|
# return {'FINISHED'}# can just add empty entry and leave...
|
||||||
|
if self.new:
|
||||||
|
self.pg.namespaces.add()
|
||||||
|
self.idx = len(self.pg.namespaces) - 1
|
||||||
|
return context.window_manager.invoke_props_dialog(self, width=450)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
# layout.use_property_split = True
|
||||||
|
item = self.pg.namespaces[self.idx]
|
||||||
|
layout.label(text=f'Enter {self.proptype.title()}:', icon='INFO')
|
||||||
|
layout.prop(item, 'tag', text=self.proptype.title())
|
||||||
|
if item.tag and not re.match(r'^[A-Z]{2}$', item.tag):
|
||||||
|
layout.label(text=f'{self.propname.title()} are preferably two capital letter (ex: CO)', icon='ERROR')
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
layout.label(text='Provide a name (Optional):', icon='INFO')
|
||||||
|
layout.prop(item, 'name')
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
item = self.pg.namespaces[self.idx]
|
||||||
|
## Here can perform post add checks
|
||||||
|
# (check for duplicate ?)
|
||||||
|
# all_prefix = [n.tag for i, n in enumerate(self.pg.namespaces) if i != self.pg.idx]
|
||||||
|
|
||||||
|
if self.new:
|
||||||
|
# in case of new addition, remove just added if nothing specified
|
||||||
|
if not item.tag and not item.name:
|
||||||
|
self.pg.namespaces.remove(self.idx)
|
||||||
|
|
||||||
|
redraw_ui()
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
class GPTB_OT_remove_namespace_entry(bpy.types.Operator):
|
||||||
|
bl_idname = "gptb.remove_namespace_entry"
|
||||||
|
bl_label = "Remove Namespace Entry"
|
||||||
|
bl_description = "Remove item in list"
|
||||||
|
bl_options = {'REGISTER', 'INTERNAL'}
|
||||||
|
|
||||||
|
propname : bpy.props.StringProperty(default='prefixes', options={'SKIP_SAVE'})
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
self.pg = getattr(get_addon_prefs(), self.propname)
|
||||||
|
entry_count = len(self.pg.namespaces)
|
||||||
|
if not entry_count:
|
||||||
|
return {'CANCELLED'}
|
||||||
|
# check if index is out of range
|
||||||
|
if not (0 <= self.pg.idx < entry_count):
|
||||||
|
self.report({"ERROR"}, 'Must select an entry to remove it')
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
item = self.pg.namespaces[self.pg.idx]
|
||||||
|
if item.is_project:
|
||||||
|
self.report({"ERROR"}, 'Cannot remove a prefix that is defined by project, hide it instead')
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
self.pg.namespaces.remove(self.pg.idx)
|
||||||
|
self.pg.idx -= 1
|
||||||
|
redraw_ui()
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
class GPTB_OT_move_item(bpy.types.Operator):
|
||||||
|
bl_idname = "gptb.move_item"
|
||||||
|
bl_label = "Move Item"
|
||||||
|
bl_description = "Move item in list up or down"
|
||||||
|
bl_options = {'REGISTER', 'INTERNAL'}
|
||||||
|
|
||||||
|
# direction : bpy.props.IntProperty(default=1)
|
||||||
|
direction : bpy.props.EnumProperty(
|
||||||
|
items=(
|
||||||
|
('UP', 'Move Up', 'Move up'),
|
||||||
|
('DOWN', 'Move down', 'Move down'),
|
||||||
|
),
|
||||||
|
default='UP',
|
||||||
|
|
||||||
|
)
|
||||||
|
propname : bpy.props.StringProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
pg = getattr(get_addon_prefs(), self.propname)
|
||||||
|
uilist = pg.namespaces
|
||||||
|
index = pg.idx
|
||||||
|
|
||||||
|
neighbor = index + (-1 if self.direction == 'UP' else 1)
|
||||||
|
uilist.move(neighbor, index)
|
||||||
|
list_length = len(uilist) - 1 # (index starts at 0)
|
||||||
|
new_index = index + (-1 if self.direction == 'UP' else 1)
|
||||||
|
list_index = max(0, min(new_index, list_length))
|
||||||
|
|
||||||
|
setattr(pg, 'idx', list_index)
|
||||||
|
redraw_ui()
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
class GPTB_UL_namespace_list(bpy.types.UIList):
|
||||||
|
|
||||||
|
# show_desc : BoolProperty(name="Show Description", default=True,
|
||||||
|
# description="Display Description")
|
||||||
|
|
||||||
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||||
|
# self.use_filter_show = True # force open/close the search feature
|
||||||
|
# prefs = get_addon_prefs()
|
||||||
|
# split = layout.split(align=False, factor=0.3)
|
||||||
|
row = layout.row()
|
||||||
|
hide_ico = 'HIDE_ON' if item.hide else 'HIDE_OFF'
|
||||||
|
source_ico = 'NETWORK_DRIVE' if item.is_project else 'USER' # BLANK1
|
||||||
|
|
||||||
|
row.label(text='', icon=source_ico)
|
||||||
|
row.prop(item, 'hide', text='', icon=hide_ico, invert_checkbox=True)
|
||||||
|
subrow = row.row(align=True)
|
||||||
|
subrow.prop(item, 'tag', text='')
|
||||||
|
subrow.prop(item, 'name', text='')
|
||||||
|
subrow.enabled = not item.is_project
|
||||||
|
|
||||||
|
# row = layout.split(align=False)
|
||||||
|
# row.label(text=item.prefix)
|
||||||
|
# row.label(text=item.name)
|
||||||
|
|
||||||
|
# if self.show_desc:
|
||||||
|
# row.label(text=item.description)
|
||||||
|
# row.operator('sbam.open_online_repo', text='', icon='URL')
|
||||||
|
|
||||||
|
classes = (
|
||||||
|
## layer name management
|
||||||
|
GPTB_OT_add_namespace_entry,
|
||||||
|
GPTB_OT_remove_namespace_entry,
|
||||||
|
GPTB_OT_move_item,
|
||||||
|
GPTB_UL_namespace_list,
|
||||||
|
)
|
||||||
|
|
||||||
|
def register():
|
||||||
|
for cls in classes:
|
||||||
|
bpy.utils.register_class(cls)
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
for cls in reversed(classes):
|
||||||
|
bpy.utils.unregister_class(cls)
|
|
@ -1,8 +1,6 @@
|
||||||
from .utils import get_gp_objects, get_gp_datas, get_addon_prefs
|
|
||||||
import bpy
|
import bpy
|
||||||
|
from .utils import get_gp_datas, get_addon_prefs, translate_range
|
||||||
|
|
||||||
def translate_range(OldValue, OldMin, OldMax, NewMax, NewMin):
|
|
||||||
return (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
|
|
||||||
|
|
||||||
def get_hue_by_name(name, offset=0):
|
def get_hue_by_name(name, offset=0):
|
||||||
'''
|
'''
|
||||||
|
@ -127,3 +125,10 @@ class GPT_OT_auto_tint_gp_layers(bpy.types.Operator):
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
self.autotint_offset = context.scene.gptoolprops.autotint_offset
|
self.autotint_offset = context.scene.gptoolprops.autotint_offset
|
||||||
return self.execute(context)
|
return self.execute(context)
|
||||||
|
|
||||||
|
|
||||||
|
def register():
|
||||||
|
bpy.utils.register_class(GPT_OT_auto_tint_gp_layers)
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
bpy.utils.unregister_class(GPT_OT_auto_tint_gp_layers)
|
14
UI_tools.py
14
UI_tools.py
|
@ -3,13 +3,6 @@ from .utils import get_addon_prefs
|
||||||
import bpy
|
import bpy
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from bpy.types import Panel
|
from bpy.types import Panel
|
||||||
from bpy.props import (
|
|
||||||
IntProperty,
|
|
||||||
BoolProperty,
|
|
||||||
StringProperty,
|
|
||||||
FloatProperty,
|
|
||||||
EnumProperty,
|
|
||||||
)
|
|
||||||
|
|
||||||
## UI in properties
|
## UI in properties
|
||||||
|
|
||||||
|
@ -274,9 +267,10 @@ class GPTB_PT_tint_layers(Panel):
|
||||||
## pseudo color layers
|
## pseudo color layers
|
||||||
# layout.separator()
|
# layout.separator()
|
||||||
col = layout.column(align = True)
|
col = layout.column(align = True)
|
||||||
row = col.split(align=False, factor=0.63)
|
# row = col.split(align=False, factor=0.63)
|
||||||
row.prop(context.scene.gptoolprops, 'autotint_offset')
|
# row = col.row()
|
||||||
row.prop(context.scene.gptoolprops, 'autotint_namespace')
|
col.prop(context.scene.gptoolprops, 'autotint_offset', text='Hue Offset')
|
||||||
|
col.prop(context.scene.gptoolprops, 'autotint_namespace')
|
||||||
|
|
||||||
col.operator("gp.auto_tint_gp_layers", icon = "COLOR").reset = False
|
col.operator("gp.auto_tint_gp_layers", icon = "COLOR").reset = False
|
||||||
col.operator("gp.auto_tint_gp_layers", text = "Reset tint", icon = "COLOR").reset = True
|
col.operator("gp.auto_tint_gp_layers", text = "Reset tint", icon = "COLOR").reset = True
|
||||||
|
|
163
__init__.py
163
__init__.py
|
@ -4,7 +4,7 @@ bl_info = {
|
||||||
"name": "GP toolbox",
|
"name": "GP toolbox",
|
||||||
"description": "Tool set for Grease Pencil in animation production",
|
"description": "Tool set for Grease Pencil in animation production",
|
||||||
"author": "Samuel Bernou, Christophe Seux",
|
"author": "Samuel Bernou, Christophe Seux",
|
||||||
"version": (2, 0, 8),
|
"version": (2, 0, 9),
|
||||||
"blender": (3, 0, 0),
|
"blender": (3, 0, 0),
|
||||||
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
@ -43,23 +43,22 @@ from . import OP_layer_picker
|
||||||
from . import OP_layer_nav
|
from . import OP_layer_nav
|
||||||
from . import OP_material_picker
|
from . import OP_material_picker
|
||||||
from . import OP_git_update
|
from . import OP_git_update
|
||||||
|
from . import OP_layer_namespace
|
||||||
|
from . import OP_pseudo_tint
|
||||||
# from . import OP_eraser_brush
|
# from . import OP_eraser_brush
|
||||||
# from . import TOOL_eraser_brush
|
# from . import TOOL_eraser_brush
|
||||||
from . import handler_draw_cam
|
from . import handler_draw_cam
|
||||||
from . import keymaps
|
from . import keymaps
|
||||||
|
|
||||||
from .OP_pseudo_tint import GPT_OT_auto_tint_gp_layers
|
|
||||||
|
|
||||||
from . import UI_tools
|
from . import UI_tools
|
||||||
|
|
||||||
from .properties import (
|
from .properties import (
|
||||||
GP_PG_ToolsSettings,
|
GP_PG_ToolsSettings,
|
||||||
GP_PG_FixSettings,
|
GP_PG_FixSettings,
|
||||||
GP_PG_namespace_props,
|
|
||||||
GP_PG_namespaces,
|
GP_PG_namespaces,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
from bpy.props import (FloatProperty,
|
from bpy.props import (FloatProperty,
|
||||||
BoolProperty,
|
BoolProperty,
|
||||||
EnumProperty,
|
EnumProperty,
|
||||||
|
@ -109,145 +108,6 @@ def remap_on_save_update(self, context):
|
||||||
# km, kmi = TOOL_eraser_brush.addon_keymaps[0]
|
# km, kmi = TOOL_eraser_brush.addon_keymaps[0]
|
||||||
# kmi.active = self.use_precise_eraser
|
# kmi.active = self.use_precise_eraser
|
||||||
|
|
||||||
|
|
||||||
class GPTB_OT_add_namespace_entry(bpy.types.Operator):
|
|
||||||
bl_idname = "gptb.add_namespace_entry"
|
|
||||||
bl_label = "Add Namespace Entry"
|
|
||||||
bl_description = "Add item in list"
|
|
||||||
bl_options = {'REGISTER', 'INTERNAL'}
|
|
||||||
|
|
||||||
idx : bpy.props.IntProperty()
|
|
||||||
new : bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'})
|
|
||||||
propname : bpy.props.StringProperty(default='prefixes', options={'SKIP_SAVE'})
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
self.pg = getattr(get_addon_prefs(), self.propname)
|
|
||||||
self.proptype = self.propname[:-2]
|
|
||||||
## Basic:
|
|
||||||
# self.pg.namespaces.add()
|
|
||||||
# return {'FINISHED'}# can just add empty entry and leave...
|
|
||||||
if self.new:
|
|
||||||
self.pg.namespaces.add()
|
|
||||||
self.idx = len(self.pg.namespaces) - 1
|
|
||||||
return context.window_manager.invoke_props_dialog(self, width=450)
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
import re
|
|
||||||
layout = self.layout
|
|
||||||
# layout.use_property_split = True
|
|
||||||
item = self.pg.namespaces[self.idx]
|
|
||||||
layout.label(text=f'Enter {self.proptype.title()}:', icon='INFO')
|
|
||||||
layout.prop(item, 'tag', text=self.proptype.title())
|
|
||||||
if item.tag and not re.match(r'^[A-Z]{2}$', item.tag):
|
|
||||||
layout.label(text=f'{self.propname.title()} are preferably two capital letter (ex: CO)', icon='ERROR')
|
|
||||||
|
|
||||||
layout.separator()
|
|
||||||
layout.label(text='Provide a name (Optional):', icon='INFO')
|
|
||||||
layout.prop(item, 'name')
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
item = self.pg.namespaces[self.idx]
|
|
||||||
## Here can perform post add checks
|
|
||||||
# (check for duplicate ?)
|
|
||||||
# all_prefix = [n.tag for i, n in enumerate(self.pg.namespaces) if i != self.pg.idx]
|
|
||||||
|
|
||||||
if self.new:
|
|
||||||
# in case of new addition, remove just added if nothing specified
|
|
||||||
if not item.tag and not item.name:
|
|
||||||
self.pg.namespaces.remove(self.idx)
|
|
||||||
|
|
||||||
context.area.tag_redraw()
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
class GPTB_OT_remove_namespace_entry(bpy.types.Operator):
|
|
||||||
bl_idname = "gptb.remove_namespace_entry"
|
|
||||||
bl_label = "Remove Namespace Entry"
|
|
||||||
bl_description = "Remove item in list"
|
|
||||||
bl_options = {'REGISTER', 'INTERNAL'}
|
|
||||||
|
|
||||||
propname : bpy.props.StringProperty(default='prefixes', options={'SKIP_SAVE'})
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
self.pg = getattr(get_addon_prefs(), self.propname)
|
|
||||||
entry_count = len(self.pg.namespaces)
|
|
||||||
if not entry_count:
|
|
||||||
return {'CANCELLED'}
|
|
||||||
# check if index is out of range
|
|
||||||
if not (0 <= self.pg.idx < entry_count):
|
|
||||||
self.report({"ERROR"}, 'Must select an entry to remove it')
|
|
||||||
return {'CANCELLED'}
|
|
||||||
|
|
||||||
item = self.pg.namespaces[self.pg.idx]
|
|
||||||
if item.is_project:
|
|
||||||
self.report({"ERROR"}, 'Cannot remove a prefix that is defined by project, hide it instead')
|
|
||||||
return {'CANCELLED'}
|
|
||||||
|
|
||||||
self.pg.namespaces.remove(self.pg.idx)
|
|
||||||
self.pg.idx -= 1
|
|
||||||
context.area.tag_redraw()
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
class GPTB_OT_move_item(bpy.types.Operator):
|
|
||||||
bl_idname = "gptb.move_item"
|
|
||||||
bl_label = "Move Item"
|
|
||||||
bl_description = "Move item in list up or down"
|
|
||||||
bl_options = {'REGISTER', 'INTERNAL'}
|
|
||||||
|
|
||||||
# direction : bpy.props.IntProperty(default=1)
|
|
||||||
direction : bpy.props.EnumProperty(
|
|
||||||
items=(
|
|
||||||
('UP', 'Move Up', 'Move up'),
|
|
||||||
('DOWN', 'Move down', 'Move down'),
|
|
||||||
),
|
|
||||||
default='UP',
|
|
||||||
|
|
||||||
)
|
|
||||||
propname : bpy.props.StringProperty()
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
pg = getattr(get_addon_prefs(), self.propname)
|
|
||||||
uilist = pg.namespaces
|
|
||||||
index = pg.idx
|
|
||||||
|
|
||||||
neighbor = index + (-1 if self.direction == 'UP' else 1)
|
|
||||||
uilist.move(neighbor, index)
|
|
||||||
list_length = len(uilist) - 1 # (index starts at 0)
|
|
||||||
new_index = index + (-1 if self.direction == 'UP' else 1)
|
|
||||||
list_index = max(0, min(new_index, list_length))
|
|
||||||
|
|
||||||
setattr(pg, 'idx', list_index)
|
|
||||||
context.area.tag_redraw()
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
class GPTB_UL_namespace_list(bpy.types.UIList):
|
|
||||||
|
|
||||||
# show_desc : BoolProperty(name="Show Description", default=True,
|
|
||||||
# description="Display Description")
|
|
||||||
|
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
|
||||||
# self.use_filter_show = True # force open/close the search feature
|
|
||||||
# prefs = get_addon_prefs()
|
|
||||||
# split = layout.split(align=False, factor=0.3)
|
|
||||||
row = layout.row()
|
|
||||||
hide_ico = 'HIDE_ON' if item.hide else 'HIDE_OFF'
|
|
||||||
source_ico = 'NETWORK_DRIVE' if item.is_project else 'USER' # BLANK1
|
|
||||||
|
|
||||||
row.label(text='', icon=source_ico)
|
|
||||||
row.prop(item, 'hide', text='', icon=hide_ico, invert_checkbox=True)
|
|
||||||
subrow = row.row(align=True)
|
|
||||||
subrow.prop(item, 'tag', text='')
|
|
||||||
subrow.prop(item, 'name', text='')
|
|
||||||
subrow.enabled = not item.is_project
|
|
||||||
|
|
||||||
# row = layout.split(align=False)
|
|
||||||
# row.label(text=item.prefix)
|
|
||||||
# row.label(text=item.name)
|
|
||||||
|
|
||||||
# if self.show_desc:
|
|
||||||
# row.label(text=item.description)
|
|
||||||
# row.operator('sbam.open_online_repo', text='', icon='URL')
|
|
||||||
|
|
||||||
|
|
||||||
class GPTB_prefs(bpy.types.AddonPreferences):
|
class GPTB_prefs(bpy.types.AddonPreferences):
|
||||||
bl_idname = __name__
|
bl_idname = __name__
|
||||||
|
|
||||||
|
@ -883,23 +743,13 @@ class GPTB_set_env_settings(bpy.types.Operator):
|
||||||
|
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
## layer name management
|
|
||||||
GP_PG_namespace_props,
|
|
||||||
GP_PG_namespaces,
|
|
||||||
GPTB_OT_add_namespace_entry,
|
|
||||||
GPTB_OT_remove_namespace_entry,
|
|
||||||
GPTB_OT_move_item,
|
|
||||||
GPTB_UL_namespace_list,
|
|
||||||
|
|
||||||
GP_PG_FixSettings,
|
|
||||||
GP_PG_ToolsSettings,
|
|
||||||
GPTB_set_env_settings,
|
GPTB_set_env_settings,
|
||||||
GPTB_prefs,
|
GPTB_prefs,
|
||||||
GPT_OT_auto_tint_gp_layers,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
addon_modules = (
|
addon_modules = (
|
||||||
OP_helpers,
|
OP_helpers,
|
||||||
|
OP_pseudo_tint,
|
||||||
OP_keyframe_jump,
|
OP_keyframe_jump,
|
||||||
OP_file_checker,
|
OP_file_checker,
|
||||||
OP_breakdowner,
|
OP_breakdowner,
|
||||||
|
@ -916,6 +766,7 @@ addon_modules = (
|
||||||
OP_realign,
|
OP_realign,
|
||||||
OP_depth_move,
|
OP_depth_move,
|
||||||
OP_key_duplicate_send,
|
OP_key_duplicate_send,
|
||||||
|
OP_layer_namespace,
|
||||||
OP_layer_manager,
|
OP_layer_manager,
|
||||||
OP_material_picker,
|
OP_material_picker,
|
||||||
OP_git_update,
|
OP_git_update,
|
||||||
|
@ -929,6 +780,8 @@ addon_modules = (
|
||||||
)
|
)
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
# Register property group first
|
||||||
|
properties.register()
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
bpy.utils.register_class(cls)
|
bpy.utils.register_class(cls)
|
||||||
|
|
||||||
|
@ -961,6 +814,8 @@ def unregister():
|
||||||
for cls in reversed(classes):
|
for cls in reversed(classes):
|
||||||
bpy.utils.unregister_class(cls)
|
bpy.utils.unregister_class(cls)
|
||||||
|
|
||||||
|
properties.unregister()
|
||||||
|
|
||||||
del bpy.types.Scene.gptoolprops
|
del bpy.types.Scene.gptoolprops
|
||||||
|
|
||||||
|
|
||||||
|
|
45
functions.py
45
functions.py
|
@ -9,24 +9,7 @@ import bmesh
|
||||||
from .utils import get_gp_draw_plane, link_vert,gp_stroke_to_bmesh,draw_gp_stroke,remapping
|
from .utils import get_gp_draw_plane, link_vert,gp_stroke_to_bmesh,draw_gp_stroke,remapping
|
||||||
|
|
||||||
|
|
||||||
def get_view_origin_position():
|
def to_bl_image(array, img):
|
||||||
#method 1
|
|
||||||
from bpy_extras import view3d_utils
|
|
||||||
region = bpy.context.region
|
|
||||||
rv3d = bpy.context.region_data
|
|
||||||
view_loc = view3d_utils.region_2d_to_origin_3d(region, rv3d, (region.width/2.0, region.height/2.0))
|
|
||||||
print("view_loc1", view_loc)#Dbg
|
|
||||||
|
|
||||||
#method 2
|
|
||||||
r3d = bpy.context.space_data.region_3d
|
|
||||||
view_loc2 = r3d.view_matrix.inverted().translation
|
|
||||||
print("view_loc2", view_loc2)#Dbg
|
|
||||||
if view_loc != view_loc2: print('there might be an errror when finding view coordinate')
|
|
||||||
|
|
||||||
return view_loc
|
|
||||||
|
|
||||||
|
|
||||||
def to_bl_image(array,img):
|
|
||||||
# Write the result to Blender preview
|
# Write the result to Blender preview
|
||||||
width = len(array[0])
|
width = len(array[0])
|
||||||
height = len(array)
|
height = len(array)
|
||||||
|
@ -56,7 +39,7 @@ def to_bl_image(array,img):
|
||||||
image.pixels = output_pixels
|
image.pixels = output_pixels
|
||||||
|
|
||||||
|
|
||||||
def bm_angle_split(bm,angle) :
|
def bm_angle_split(bm, angle) :
|
||||||
bm.verts.ensure_lookup_table()
|
bm.verts.ensure_lookup_table()
|
||||||
loop = link_vert(bm.verts[0],[bm.verts[0]])
|
loop = link_vert(bm.verts[0],[bm.verts[0]])
|
||||||
splitted = []
|
splitted = []
|
||||||
|
@ -83,7 +66,7 @@ def bm_angle_split(bm,angle) :
|
||||||
|
|
||||||
return loops
|
return loops
|
||||||
|
|
||||||
def bm_uniform_density(bm,cam,max_spacing):
|
def bm_uniform_density(bm, cam, max_spacing):
|
||||||
from bpy_extras.object_utils import world_to_camera_view as cam_space
|
from bpy_extras.object_utils import world_to_camera_view as cam_space
|
||||||
scene = bpy.context.scene
|
scene = bpy.context.scene
|
||||||
ratio = scene.render.resolution_y/scene.render.resolution_x
|
ratio = scene.render.resolution_y/scene.render.resolution_x
|
||||||
|
@ -102,7 +85,7 @@ def bm_uniform_density(bm,cam,max_spacing):
|
||||||
return bm
|
return bm
|
||||||
|
|
||||||
|
|
||||||
def gp_stroke_angle_split (frame,strokes,angle):
|
def gp_stroke_angle_split (frame, strokes, angle):
|
||||||
strokes_info = gp_stroke_to_bmesh(strokes)
|
strokes_info = gp_stroke_to_bmesh(strokes)
|
||||||
|
|
||||||
new_strokes = []
|
new_strokes = []
|
||||||
|
@ -125,7 +108,7 @@ def gp_stroke_angle_split (frame,strokes,angle):
|
||||||
return new_strokes
|
return new_strokes
|
||||||
|
|
||||||
|
|
||||||
def gp_stroke_uniform_density(cam,frame,strokes,max_spacing):
|
def gp_stroke_uniform_density(cam, frame, strokes, max_spacing):
|
||||||
strokes_info = gp_stroke_to_bmesh(strokes)
|
strokes_info = gp_stroke_to_bmesh(strokes)
|
||||||
|
|
||||||
new_strokes = []
|
new_strokes = []
|
||||||
|
@ -152,7 +135,7 @@ def gp_stroke_uniform_density(cam,frame,strokes,max_spacing):
|
||||||
return new_strokes
|
return new_strokes
|
||||||
|
|
||||||
|
|
||||||
def along_stroke(stroke,attr,length,min,max) :
|
def along_stroke(stroke, attr, length, min, max) :
|
||||||
strokelen = len(stroke.points)
|
strokelen = len(stroke.points)
|
||||||
for index,point in enumerate(stroke.points) :
|
for index,point in enumerate(stroke.points) :
|
||||||
value = getattr(point,attr)
|
value = getattr(point,attr)
|
||||||
|
@ -164,9 +147,9 @@ def along_stroke(stroke,attr,length,min,max) :
|
||||||
remap = remapping((strokelen-index)/length,0,1,min,max)
|
remap = remapping((strokelen-index)/length,0,1,min,max)
|
||||||
setattr(point,attr,value*remap)
|
setattr(point,attr,value*remap)
|
||||||
|
|
||||||
def randomise_points(mat,points,attr,strength) :
|
def randomise_points(mat, points, attr, strength) :
|
||||||
for point in points :
|
for point in points :
|
||||||
if attr is 'co' :
|
if attr == 'co' :
|
||||||
random_x = (rand()-0.5)
|
random_x = (rand()-0.5)
|
||||||
random_y = (rand()-0.5)
|
random_y = (rand()-0.5)
|
||||||
|
|
||||||
|
@ -183,7 +166,7 @@ def randomise_points(mat,points,attr,strength) :
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def zoom_to_object(cam,resolution,box,margin=0.01) :
|
def zoom_to_object(cam, resolution, box, margin=0.01) :
|
||||||
min_x= box[0]
|
min_x= box[0]
|
||||||
max_x= box[1]
|
max_x= box[1]
|
||||||
min_y= box[2]
|
min_y= box[2]
|
||||||
|
@ -208,7 +191,7 @@ def zoom_to_object(cam,resolution,box,margin=0.01) :
|
||||||
bpy.context.scene.objects.link(zoom_cam)
|
bpy.context.scene.objects.link(zoom_cam)
|
||||||
|
|
||||||
|
|
||||||
resolution = (int(resolution[0]*factor),int(resolution[1]*factor))
|
resolution = (int(resolution[0]*factor), int(resolution[1]*factor))
|
||||||
|
|
||||||
|
|
||||||
scene = bpy.context.scene
|
scene = bpy.context.scene
|
||||||
|
@ -235,7 +218,7 @@ def zoom_to_object(cam,resolution,box,margin=0.01) :
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def set_viewport_matrix(width,height,mat):
|
def set_viewport_matrix(width, height, mat):
|
||||||
from bgl import glViewport,glMatrixMode,GL_PROJECTION,glLoadMatrixf,Buffer,GL_FLOAT,glMatrixMode,GL_MODELVIEW,glLoadIdentity
|
from bgl import glViewport,glMatrixMode,GL_PROJECTION,glLoadMatrixf,Buffer,GL_FLOAT,glMatrixMode,GL_MODELVIEW,glLoadIdentity
|
||||||
|
|
||||||
glViewport(0,0,width,height)
|
glViewport(0,0,width,height)
|
||||||
|
@ -377,3 +360,9 @@ def get_object_info(mesh_groups, order_list = []) :
|
||||||
|
|
||||||
|
|
||||||
return mesh_info, convert_table
|
return mesh_info, convert_table
|
||||||
|
|
||||||
|
def redraw_ui() -> None:
|
||||||
|
"""Forces blender to redraw the UI."""
|
||||||
|
for screen in bpy.data.screens:
|
||||||
|
for area in screen.areas:
|
||||||
|
area.tag_redraw()
|
||||||
|
|
|
@ -245,3 +245,21 @@ class GP_PG_namespaces(PropertyGroup):
|
||||||
idx : IntProperty(default=-1)
|
idx : IntProperty(default=-1)
|
||||||
|
|
||||||
namespaces : bpy.props.CollectionProperty(type=GP_PG_namespace_props)
|
namespaces : bpy.props.CollectionProperty(type=GP_PG_namespace_props)
|
||||||
|
|
||||||
|
classes = (
|
||||||
|
# Prefix/suiffix prefs prop group
|
||||||
|
GP_PG_namespace_props,
|
||||||
|
GP_PG_namespaces,
|
||||||
|
|
||||||
|
## General toolbox settings
|
||||||
|
GP_PG_FixSettings,
|
||||||
|
GP_PG_ToolsSettings,
|
||||||
|
)
|
||||||
|
|
||||||
|
def register():
|
||||||
|
for cls in classes:
|
||||||
|
bpy.utils.register_class(cls)
|
||||||
|
|
||||||
|
def unregister():
|
||||||
|
for cls in reversed(classes):
|
||||||
|
bpy.utils.unregister_class(cls)
|
4
utils.py
4
utils.py
|
@ -16,6 +16,10 @@ import subprocess
|
||||||
else :
|
else :
|
||||||
return layer.parent
|
return layer.parent
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def translate_range(OldValue, OldMin, OldMax, NewMax, NewMin):
|
||||||
|
return (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
|
||||||
|
|
||||||
def get_matrix(ob) :
|
def get_matrix(ob) :
|
||||||
'''return a copy of the world_matrix, applied object matrix if its a bone'''
|
'''return a copy of the world_matrix, applied object matrix if its a bone'''
|
||||||
if isinstance(ob, bpy.types.PoseBone) :
|
if isinstance(ob, bpy.types.PoseBone) :
|
||||||
|
|
Loading…
Reference in New Issue