adds apply and revert color feature to editor
This commit is contained in:
parent
7b86199ee5
commit
816b5e51cb
7 changed files with 208 additions and 9 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
## Planned features
|
## Planned features
|
||||||
|
|
||||||
### ID Mask - Editor
|
### ID Mask - Editor
|
||||||
- [ ] A way to automatically get already used colors, f.E. you already did it by hand
|
- [X] A way to automatically get already used colors, f.E. you already did it by hand
|
||||||
- [X] Select by color
|
- [X] Select by color
|
||||||
- [ ] Update after color change
|
- [ ] Update after color change
|
||||||
|
|
@ -3,10 +3,12 @@ import bpy
|
||||||
from src.menu import id_mask_select_menu
|
from src.menu import id_mask_select_menu
|
||||||
from src.menu.id_mask_editor_options import IDEDITOR_IDMaskEditorOptionsMenu
|
from src.menu.id_mask_editor_options import IDEDITOR_IDMaskEditorOptionsMenu
|
||||||
from src.operators.create_id_mask import CreateIDMaskOperator
|
from src.operators.create_id_mask import CreateIDMaskOperator
|
||||||
|
from src.operators.id_editor_apply_color import IDEDITOR_ColorApplyOperator
|
||||||
from src.operators.id_editor_create_id import IDEDITOR_CreateIDOperator
|
from src.operators.id_editor_create_id import IDEDITOR_CreateIDOperator
|
||||||
from src.operators.id_editor_find_used_ids import IDEDITOR_FindUsedIDsOperator
|
from src.operators.id_editor_find_used_ids import IDEDITOR_FindUsedIDsOperator
|
||||||
from src.operators.id_editor_paint import IDEDITOR_PaintIDMaskOperator
|
from src.operators.id_editor_paint import IDEDITOR_PaintIDMaskOperator
|
||||||
from src.operators.id_editor_remove_id import IDEDITOR_RemoveIDOperator
|
from src.operators.id_editor_remove_id import IDEDITOR_RemoveIDOperator
|
||||||
|
from src.operators.id_editor_revert_color import IDEDITOR_ColorResetOperator
|
||||||
from src.operators.id_mask_select import IDEDITOR_SelectIDMaskOperator
|
from src.operators.id_mask_select import IDEDITOR_SelectIDMaskOperator
|
||||||
from src.panels.id_mask_editor_id_list import IDMaskEditorIDList
|
from src.panels.id_mask_editor_id_list import IDMaskEditorIDList
|
||||||
from src.properties.id_mask_editor_value_properties import IDMaskEditorValueProperties
|
from src.properties.id_mask_editor_value_properties import IDMaskEditorValueProperties
|
||||||
|
|
@ -45,7 +47,9 @@ classes = (
|
||||||
IDEDITOR_PaintIDMaskOperator,
|
IDEDITOR_PaintIDMaskOperator,
|
||||||
IDEDITOR_SelectIDMaskOperator,
|
IDEDITOR_SelectIDMaskOperator,
|
||||||
IDEDITOR_FindUsedIDsOperator,
|
IDEDITOR_FindUsedIDsOperator,
|
||||||
IDEDITOR_IDMaskEditorOptionsMenu
|
IDEDITOR_IDMaskEditorOptionsMenu,
|
||||||
|
IDEDITOR_ColorResetOperator,
|
||||||
|
IDEDITOR_ColorApplyOperator,
|
||||||
)
|
)
|
||||||
|
|
||||||
menu_additions = [
|
menu_additions = [
|
||||||
|
|
|
||||||
84
src/operators/id_editor_apply_color.py
Normal file
84
src/operators/id_editor_apply_color.py
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
class IDEDITOR_ColorApplyOperator(bpy.types.Operator):
|
||||||
|
bl_idname = "id_mask_editor.apply_colors"
|
||||||
|
bl_label = "Apply changed ID-Mask colors"
|
||||||
|
bl_description = "Searches the current ID-mask for colors and adds them to the id-list"
|
||||||
|
bl_options = {'INTERNAL'}
|
||||||
|
|
||||||
|
triggeredByList: bpy.props.BoolProperty(default=False)
|
||||||
|
listId: bpy.props.IntProperty(default=0)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
obj = context.active_object
|
||||||
|
if obj.type != 'MESH':
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not obj.data:
|
||||||
|
return False
|
||||||
|
|
||||||
|
mesh = obj.data
|
||||||
|
properties = mesh.id_mask_editor_properties
|
||||||
|
|
||||||
|
if not properties.target_attribute:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
obj = context.active_object
|
||||||
|
|
||||||
|
old_mode = bpy.context.object.mode
|
||||||
|
if old_mode != "OBJECT":
|
||||||
|
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||||
|
mesh = obj.data
|
||||||
|
properties = mesh.id_mask_editor_properties
|
||||||
|
color_attribute = mesh.color_attributes.get(properties.target_attribute)
|
||||||
|
|
||||||
|
colors = []
|
||||||
|
|
||||||
|
if self.triggeredByList:
|
||||||
|
list_item = properties.possible_ids[self.listId]
|
||||||
|
if list_item.color_changed:
|
||||||
|
colors.append((list_item.original_color, list_item.color))
|
||||||
|
else:
|
||||||
|
for id in properties.possible_ids:
|
||||||
|
if not id.color_changed:
|
||||||
|
continue
|
||||||
|
|
||||||
|
colors.append((id.original_color, id.color))
|
||||||
|
|
||||||
|
for polygon in mesh.polygons:
|
||||||
|
polygon_color = self.get_color_from_polygon(color_attribute, polygon)
|
||||||
|
|
||||||
|
for (original_color, color) in colors:
|
||||||
|
if original_color[0] != polygon_color[0] or original_color[1] != polygon_color[1] or original_color[2] != polygon_color[2]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for idx in polygon.loop_indices:
|
||||||
|
color_attribute.data[idx].color = (color.r, color.g, color.b, 1.0)
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
if self.triggeredByList:
|
||||||
|
list_item = properties.possible_ids[self.listId]
|
||||||
|
list_item.color_changed = False
|
||||||
|
else:
|
||||||
|
for id in properties.possible_ids:
|
||||||
|
id.color_changed = False
|
||||||
|
|
||||||
|
if old_mode != "OBJECT":
|
||||||
|
bpy.ops.object.mode_set(mode=old_mode, toggle=False)
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def reset_color(self, value):
|
||||||
|
if not value.color_changed:
|
||||||
|
return
|
||||||
|
|
||||||
|
value.color = value.original_color
|
||||||
|
value.color_changed = False
|
||||||
|
|
||||||
|
def get_color_from_polygon(self, attribute, polygon):
|
||||||
|
color = attribute.data[polygon.loop_indices[0]].color
|
||||||
|
return (color[0], color[1], color[2], 1.0)
|
||||||
49
src/operators/id_editor_revert_color.py
Normal file
49
src/operators/id_editor_revert_color.py
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
class IDEDITOR_ColorResetOperator(bpy.types.Operator):
|
||||||
|
bl_idname = "id_mask_editor.reset_colors"
|
||||||
|
bl_label = "Resets ID-Mask colors"
|
||||||
|
bl_description = "Resets the colors to the previous values"
|
||||||
|
bl_options = {'INTERNAL'}
|
||||||
|
|
||||||
|
triggeredByList: bpy.props.BoolProperty(default=False)
|
||||||
|
listId: bpy.props.IntProperty(default=0)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
obj = context.active_object
|
||||||
|
if obj.type != 'MESH':
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not obj.data:
|
||||||
|
return False
|
||||||
|
|
||||||
|
mesh = obj.data
|
||||||
|
properties = mesh.id_mask_editor_properties
|
||||||
|
|
||||||
|
if not properties.target_attribute:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
obj = context.active_object
|
||||||
|
|
||||||
|
mesh = obj.data
|
||||||
|
properties = mesh.id_mask_editor_properties
|
||||||
|
|
||||||
|
if self.triggeredByList:
|
||||||
|
self.reset_color(properties.possible_ids[self.listId])
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
for prop in properties.possible_ids:
|
||||||
|
self.reset_color(prop)
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def reset_color(self, value):
|
||||||
|
if not value.color_changed:
|
||||||
|
return
|
||||||
|
|
||||||
|
value.color = value.original_color
|
||||||
|
value.color_changed = False
|
||||||
|
|
@ -2,9 +2,11 @@ import bpy
|
||||||
|
|
||||||
from src.menu.id_mask_editor_options import IDEDITOR_IDMaskEditorOptionsMenu
|
from src.menu.id_mask_editor_options import IDEDITOR_IDMaskEditorOptionsMenu
|
||||||
from src.operators.create_id_mask import CreateIDMaskOperator
|
from src.operators.create_id_mask import CreateIDMaskOperator
|
||||||
|
from src.operators.id_editor_apply_color import IDEDITOR_ColorApplyOperator
|
||||||
from src.operators.id_editor_create_id import IDEDITOR_CreateIDOperator
|
from src.operators.id_editor_create_id import IDEDITOR_CreateIDOperator
|
||||||
from src.operators.id_editor_paint import IDEDITOR_PaintIDMaskOperator
|
from src.operators.id_editor_paint import IDEDITOR_PaintIDMaskOperator
|
||||||
from src.operators.id_editor_remove_id import IDEDITOR_RemoveIDOperator
|
from src.operators.id_editor_remove_id import IDEDITOR_RemoveIDOperator
|
||||||
|
from src.operators.id_editor_revert_color import IDEDITOR_ColorResetOperator
|
||||||
from src.operators.id_mask_select import IDEDITOR_SelectIDMaskOperator
|
from src.operators.id_mask_select import IDEDITOR_SelectIDMaskOperator
|
||||||
from src.types.colors import get_color
|
from src.types.colors import get_color
|
||||||
|
|
||||||
|
|
@ -61,7 +63,6 @@ class IDMaskEditorPanel(bpy.types.Panel):
|
||||||
button_row.operator(IDEDITOR_PaintIDMaskOperator.bl_idname, text='Paint', icon='VPAINT_HLT')
|
button_row.operator(IDEDITOR_PaintIDMaskOperator.bl_idname, text='Paint', icon='VPAINT_HLT')
|
||||||
button_row.operator(IDEDITOR_SelectIDMaskOperator.bl_idname, text='Select', icon='SELECT_SET').isCalledFromEditor = True
|
button_row.operator(IDEDITOR_SelectIDMaskOperator.bl_idname, text='Select', icon='SELECT_SET').isCalledFromEditor = True
|
||||||
|
|
||||||
|
|
||||||
col.template_list(
|
col.template_list(
|
||||||
'IDMaskEditorIDList',
|
'IDMaskEditorIDList',
|
||||||
'IDMaskEditorIDList',
|
'IDMaskEditorIDList',
|
||||||
|
|
@ -72,6 +73,23 @@ class IDMaskEditorPanel(bpy.types.Panel):
|
||||||
rows=3
|
rows=3
|
||||||
)
|
)
|
||||||
|
|
||||||
|
color_button_row = col.row(align=True)
|
||||||
|
has_color_changed = False
|
||||||
|
for id in properties.possible_ids:
|
||||||
|
if not id.color_changed:
|
||||||
|
continue
|
||||||
|
has_color_changed = True
|
||||||
|
break
|
||||||
|
|
||||||
|
color_button_row.enabled = has_color_changed
|
||||||
|
|
||||||
|
reset_op = color_button_row.operator(IDEDITOR_ColorResetOperator.bl_idname, icon='LOOP_BACK', text='Reset Colors')
|
||||||
|
reset_op.triggeredByList = False
|
||||||
|
|
||||||
|
apply_op = color_button_row.operator(IDEDITOR_ColorApplyOperator.bl_idname, icon='CHECKMARK', text='Apply Colors')
|
||||||
|
apply_op.triggeredByList = False
|
||||||
|
|
||||||
|
|
||||||
col = row.column(align=True)
|
col = row.column(align=True)
|
||||||
col.operator(IDEDITOR_CreateIDOperator.bl_idname, icon='ADD', text="")
|
col.operator(IDEDITOR_CreateIDOperator.bl_idname, icon='ADD', text="")
|
||||||
col.operator(IDEDITOR_RemoveIDOperator.bl_idname, icon='REMOVE', text="")
|
col.operator(IDEDITOR_RemoveIDOperator.bl_idname, icon='REMOVE', text="")
|
||||||
|
|
@ -80,7 +98,6 @@ class IDMaskEditorPanel(bpy.types.Panel):
|
||||||
col.menu(IDEDITOR_IDMaskEditorOptionsMenu.bl_idname, icon='DOWNARROW_HLT', text="")
|
col.menu(IDEDITOR_IDMaskEditorOptionsMenu.bl_idname, icon='DOWNARROW_HLT', text="")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def draw_options(self, context, layout, props, element):
|
def draw_options(self, context, layout, props, element):
|
||||||
|
|
||||||
has_render_ui = 'render_ui' in dir(element)
|
has_render_ui = 'render_ui' in dir(element)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
|
from src.operators.id_editor_apply_color import IDEDITOR_ColorApplyOperator
|
||||||
|
from src.operators.id_editor_find_used_ids import IDEDITOR_FindUsedIDsOperator
|
||||||
from src.operators.id_editor_paint import IDEDITOR_PaintIDMaskOperator
|
from src.operators.id_editor_paint import IDEDITOR_PaintIDMaskOperator
|
||||||
|
from src.operators.id_editor_revert_color import IDEDITOR_ColorResetOperator
|
||||||
|
|
||||||
|
|
||||||
class IDMaskEditorIDList(bpy.types.UIList):
|
class IDMaskEditorIDList(bpy.types.UIList):
|
||||||
|
|
@ -11,7 +14,19 @@ class IDMaskEditorIDList(bpy.types.UIList):
|
||||||
split.alignment = 'LEFT'
|
split.alignment = 'LEFT'
|
||||||
split.prop(attribute, 'color', text='')
|
split.prop(attribute, 'color', text='')
|
||||||
|
|
||||||
split.emboss = 'NONE'
|
row = split.row()
|
||||||
split2 = split.split(factor=0.75)
|
col = row.column()
|
||||||
split2.prop(attribute, "name", text="")
|
col.alignment = 'RIGHT'
|
||||||
split2.emboss = 'NORMAL'
|
col.emboss = 'NONE'
|
||||||
|
col.prop(attribute, "name", text="")
|
||||||
|
col.emboss = 'NORMAL'
|
||||||
|
|
||||||
|
row1 = row.row(align=True)
|
||||||
|
row1.enabled = attribute.color_changed
|
||||||
|
reset_op = row1.operator(IDEDITOR_ColorResetOperator.bl_idname, icon='LOOP_BACK', text='')
|
||||||
|
reset_op.triggeredByList = True
|
||||||
|
reset_op.listId = _index
|
||||||
|
|
||||||
|
apply_op = row1.operator(IDEDITOR_ColorApplyOperator.bl_idname, icon='CHECKMARK', text='')
|
||||||
|
apply_op.triggeredByList = True
|
||||||
|
apply_op.listId = _index
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,21 @@
|
||||||
from bpy.types import (PropertyGroup)
|
from bpy.types import (PropertyGroup)
|
||||||
from bpy.props import (StringProperty, FloatVectorProperty)
|
from bpy.props import (StringProperty,BoolProperty, FloatVectorProperty)
|
||||||
|
|
||||||
|
def get_color(self):
|
||||||
|
return self['color']
|
||||||
|
|
||||||
|
def set_color(self, value):
|
||||||
|
if 'color' not in self:
|
||||||
|
self['color'] = value
|
||||||
|
return
|
||||||
|
|
||||||
|
prev_color = self['color']
|
||||||
|
|
||||||
|
if not self.color_changed:
|
||||||
|
self.color_changed = True
|
||||||
|
self.original_color = prev_color
|
||||||
|
|
||||||
|
self['color'] = value
|
||||||
|
|
||||||
class IDMaskEditorValueProperties(PropertyGroup):
|
class IDMaskEditorValueProperties(PropertyGroup):
|
||||||
name: StringProperty(
|
name: StringProperty(
|
||||||
|
|
@ -8,10 +24,24 @@ class IDMaskEditorValueProperties(PropertyGroup):
|
||||||
default='ID'
|
default='ID'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
color_changed: BoolProperty(
|
||||||
|
default=False
|
||||||
|
)
|
||||||
|
|
||||||
color: FloatVectorProperty(
|
color: FloatVectorProperty(
|
||||||
name="Color",
|
name="Color",
|
||||||
subtype='COLOR',
|
subtype='COLOR',
|
||||||
default=[1.0, 1.0, 1.0],
|
default=[1.0, 1.0, 1.0],
|
||||||
min=0,
|
min=0,
|
||||||
|
max=1,
|
||||||
|
get=get_color,
|
||||||
|
set=set_color
|
||||||
|
)
|
||||||
|
|
||||||
|
original_color: FloatVectorProperty(
|
||||||
|
name="Original Color",
|
||||||
|
subtype='COLOR',
|
||||||
|
default=[1.0, 1.0, 1.0],
|
||||||
|
min=0,
|
||||||
max=1
|
max=1
|
||||||
)
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue