Browse Source

Merge pull request #123 from Hoikas/mod-copypasta

Modifier CopyPasta
pull/125/head
Adam Johnson 6 years ago committed by GitHub
parent
commit
c876e41ba7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 113
      korman/operators/op_modifier.py
  2. 6
      korman/properties/prop_scene.py
  3. 15
      korman/ui/ui_modifiers.py

113
korman/operators/op_modifier.py

@ -32,6 +32,15 @@ def _fetch_modifiers():
return items
class ModifierOperator:
def _get_modifier(self, context):
if self.active_modifier == -1:
return None
pl_mods = context.object.plasma_modifiers.modifiers
pl_mod = next((i for i in pl_mods if self.active_modifier == i.display_order), None)
if pl_mod is None:
raise IndexError(self.active_modifier)
return pl_mod
@classmethod
def poll(cls, context):
return context.scene.render.engine == "PLASMA_GAME"
@ -63,6 +72,95 @@ class ModifierAddOperator(ModifierOperator, bpy.types.Operator):
return {"FINISHED"}
class ModifierCopyOperator(ModifierOperator, bpy.types.Operator):
bl_idname = "object.plasma_modifier_copy"
bl_label = "Copy Modifiers"
bl_description = "Copy Modifiers from an Object"
active_modifier = IntProperty(name="Modifier Display Order",
default=-1,
options={"HIDDEN"})
def execute(self, context):
pl_scene = context.scene.plasma_scene
pl_scene.modifier_copy_object = context.object
pl_mod = self._get_modifier(context)
if pl_mod is None:
pl_scene.property_unset("modifier_copy_id")
else:
pl_scene.modifier_copy_id = pl_mod.pl_id
return {"FINISHED"}
class ModifierPasteOperator(ModifierOperator, bpy.types.Operator):
bl_idname = "object.plasma_modifier_paste"
bl_label = "Paste Modifier"
bl_description = "Paste Modifier(s) to another Object"
def execute(self, context):
pl_scene = context.scene.plasma_scene
if not pl_scene.is_property_set("modifier_copy_object"):
raise RuntimeError()
dst_object, src_object = context.object, pl_scene.modifier_copy_object
pl_mod_id = pl_scene.modifier_copy_id
if pl_mod_id:
self._paste_modifier(src_object, dst_object, pl_mod_id)
else:
for mod_cls in modifiers.PlasmaModifierProperties.__subclasses__():
self._paste_modifier(src_object, dst_object, mod_cls.pl_id)
return {"FINISHED"}
def _paste_modifier(self, src_object, dst_object, pl_mod_id):
src_mod = getattr(src_object.plasma_modifiers, pl_mod_id)
dst_mod = getattr(dst_object.plasma_modifiers, pl_mod_id)
if not src_mod.enabled:
return
# The modifier index needs to be refigured, otherwise, bad things will happen
# when the user tries to use the modifier operators again.
mod_id = dst_object.plasma_modifiers.determine_next_id()
# NOTE: Usage of keys vs items is intentional because the value returned by items may
# not be accepted as a valid type for assignment. Sounds like a blender bug IMO.
for i in src_mod.rna_type.properties:
self._paste_property(src_mod, dst_mod, i)
# See above, ensure no id collisions
dst_mod.display_order = mod_id
def _paste_property(self, src, dst, prop):
prop_name = prop.identifier
# Old properties? Discard their asses.
if not hasattr(dst, prop_name):
return
# Collection properties must be manually copied...
if prop.type == "COLLECTION":
dst_prop, src_prop = getattr(dst, prop_name), getattr(src, prop_name)
dst_prop.clear()
for src_item in src_prop:
dst_item = dst_prop.add()
for item_prop in src_item.rna_type.properties:
self._paste_property(src_item, dst_item, item_prop)
else:
try:
if src.is_property_set(prop_name):
setattr(dst, prop_name, getattr(src, prop_name))
else:
dst.property_unset(prop_name)
except AttributeError:
pass
@classmethod
def poll(cls, context):
pl_scene = context.scene.plasma_scene
return super().poll(context) and pl_scene.is_property_set("modifier_copy_object")
class ModifierRemoveOperator(ModifierOperator, bpy.types.Operator):
bl_idname = "object.plasma_modifier_remove"
bl_label = "Remove Modifier"
@ -104,12 +202,7 @@ class ModifierRemoveOperator(ModifierOperator, bpy.types.Operator):
self.mods2delete.clear()
want2delete = OrderedSet()
for i in mods.modifiers:
if i.display_order == self.active_modifier:
want2delete.add(i.pl_id)
break
else:
raise IndexError()
want2delete.add(self._get_modifier(context).pl_id)
# Here's the rub
# When we start, we should have just one modifier in want2delete
@ -145,13 +238,7 @@ class ModifierResetOperator(ModifierOperator, bpy.types.Operator):
def execute(self, context):
assert self.active_modifier >= 0
for i in context.object.plasma_modifiers.modifiers:
if i.display_order == self.active_modifier:
mod = i
break
else:
raise IndexError(self.active_modifier)
mod = self._get_modifier(context)
props = set(mod.keys()) - {"display_order", "display_name"}
for i in props:
mod.property_unset(i)

6
korman/properties/prop_scene.py

@ -44,3 +44,9 @@ class PlasmaBakePass(bpy.types.PropertyGroup):
class PlasmaScene(bpy.types.PropertyGroup):
bake_passes = CollectionProperty(type=PlasmaBakePass)
active_pass_index = IntProperty(options={"HIDDEN"})
modifier_copy_object = PointerProperty(name="INTERNAL: Object to copy modifiers from",
options={"HIDDEN", "SKIP_SAVE"},
type=bpy.types.Object)
modifier_copy_id = StringProperty(name="INTERNAL: Modifier to copy from",
options={"HIDDEN", "SKIP_SAVE"})

15
korman/ui/ui_modifiers.py

@ -48,7 +48,9 @@ class PlasmaModifiersPanel(ModifierButtonsPanel, bpy.types.Panel):
# Any items following that are members of that category, of course...
# ... I hope that my rambling has helped somebody understand more about the undocumented mess
# that is Blender Python.
layout.operator_menu_enum("object.plasma_modifier_add", "types")
row = layout.row(align=True)
row.operator_menu_enum("object.plasma_modifier_add", "types")
row.menu("PlasmaModifiersSpecialMenu", icon="DOWNARROW_HLT", text="")
# First, let's sort the list of modifiers based on their display order
# We don't do this sort in the property itself because this is really just a UI hint.
@ -77,6 +79,7 @@ class PlasmaModifiersPanel(ModifierButtonsPanel, bpy.types.Panel):
row.operator("object.plasma_modifier_move_up", text="", icon="TRIA_UP").active_modifier = modifier.display_order
row.operator("object.plasma_modifier_move_down", text="", icon="TRIA_DOWN").active_modifier = modifier.display_order
row.operator("object.plasma_modifier_copy", text="", icon="COPYDOWN").active_modifier = modifier.display_order
row.operator("object.plasma_modifier_reset", text="", icon="FILE_REFRESH").active_modifier = modifier.display_order
row.operator("object.plasma_modifier_remove", text="", icon="X").active_modifier = modifier.display_order
@ -84,3 +87,13 @@ class PlasmaModifiersPanel(ModifierButtonsPanel, bpy.types.Panel):
# by whatever insanity is in the modifier module. modifier modifier modifier...
# MODDDDDDDDIFIIIIEEEERRRRRRRR!!!
return layout
class PlasmaModifiersSpecialMenu(ModifierButtonsPanel, bpy.types.Menu):
bl_label = "Plasma Modifier Specials"
def draw(self, context):
layout = self.layout
layout.operator("object.plasma_modifier_copy", icon="COPYDOWN", text="Copy Modifiers").active_modifier = -1
layout.operator("object.plasma_modifier_paste", icon="PASTEDOWN", text="Paste Modifier(s)")

Loading…
Cancel
Save