Browse Source

Fix #119

This adds the ability to copy and paste all modifiers (or a single
modifier) to another object.
pull/123/head
Adam Johnson 6 years ago
parent
commit
e307c36a7d
Signed by: Hoikas
GPG Key ID: 0B6515D6FF6F271E
  1. 98
      korman/operators/op_modifier.py
  2. 6
      korman/properties/prop_scene.py
  3. 15
      korman/ui/ui_modifiers.py

98
korman/operators/op_modifier.py

@ -32,6 +32,15 @@ def _fetch_modifiers():
return items return items
class ModifierOperator: 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 @classmethod
def poll(cls, context): def poll(cls, context):
return context.scene.render.engine == "PLASMA_GAME" return context.scene.render.engine == "PLASMA_GAME"
@ -63,6 +72,95 @@ class ModifierAddOperator(ModifierOperator, bpy.types.Operator):
return {"FINISHED"} 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): class ModifierRemoveOperator(ModifierOperator, bpy.types.Operator):
bl_idname = "object.plasma_modifier_remove" bl_idname = "object.plasma_modifier_remove"
bl_label = "Remove Modifier" bl_label = "Remove Modifier"

6
korman/properties/prop_scene.py

@ -44,3 +44,9 @@ class PlasmaBakePass(bpy.types.PropertyGroup):
class PlasmaScene(bpy.types.PropertyGroup): class PlasmaScene(bpy.types.PropertyGroup):
bake_passes = CollectionProperty(type=PlasmaBakePass) bake_passes = CollectionProperty(type=PlasmaBakePass)
active_pass_index = IntProperty(options={"HIDDEN"}) 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... # 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 # ... I hope that my rambling has helped somebody understand more about the undocumented mess
# that is Blender Python. # 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 # 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. # 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_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_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_reset", text="", icon="FILE_REFRESH").active_modifier = modifier.display_order
row.operator("object.plasma_modifier_remove", text="", icon="X").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... # by whatever insanity is in the modifier module. modifier modifier modifier...
# MODDDDDDDDIFIIIIEEEERRRRRRRR!!! # MODDDDDDDDIFIIIIEEEERRRRRRRR!!!
return layout 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