import bpy
import mathutils
from ... utility import addon
from ... utils.context import ExecutionContext
from ... utility import modifier as modsort
# Do the Basic Union, Difference and Intersection operations
def operation(context, _operation, x, y, z, zx, zy, zz, direction, used_axis):
object = bpy.context.active_object
object.select_set(True)
if(len(bpy.context.selected_objects)) == 1: # one is selected , add mirror mod immediately to that object#
if object.type in {"MESH", "CURVE"}:
if object.type in {"CURVE"}:
if addon.preference().property.Hops_mirror_modes != "MODIFIER":
bpy.ops.object.convert(target='MESH')
if addon.preference().property.Hops_mirror_modes == "MODIFIER":
with ExecutionContext(mode="OBJECT", active_object=object):
mirror_mod = None
for modifier in object.modifiers:
if modifier.name == "hops_mirror":
mirror_mod = modifier
if mirror_mod is None:
mirror_mod = object.modifiers.new("hops_mirror", "MIRROR")
mirror_mod.use_clip = True
mirror_mod.use_axis[0] = False
mirror_mod.use_axis[1] = False
mirror_mod.use_axis[2] = False
mirror_mod.use_mirror_u = addon.preference().property.Hops_gizmo_mirror_u
mirror_mod.use_mirror_v = addon.preference().property.Hops_gizmo_mirror_v
elif addon.preference().property.Hops_mirror_modes == "BISECT":
with ExecutionContext(mode="OBJECT", active_object=object):
if addon.preference().property.Hops_mirror_direction == "+":
clear_inner = True
clear_outer = False
elif addon.preference().property.Hops_mirror_direction == "-":
clear_inner = False
clear_outer = True
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bisect(plane_co=(x, y, z), plane_no=(zx, zy, zz), clear_inner=clear_inner, clear_outer=clear_outer)
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT')
object = bpy.context.active_object
mirror_mod = None
if addon.preference().property.Hops_mirror_modal_mod_on_bisect:
for modifier in object.modifiers:
if modifier.name == "hops_mirror":
mirror_mod = modifier
if mirror_mod is None:
mirror_mod = object.modifiers.new("hops_mirror", "MIRROR")
mirror_mod.use_clip = True
mirror_mod.use_axis[0] = False
mirror_mod.use_axis[1] = False
mirror_mod.use_axis[2] = False
mirror_mod.use_mirror_u = addon.preference().property.Hops_gizmo_mirror_u
mirror_mod.use_mirror_v = addon.preference().property.Hops_gizmo_mirror_v
elif addon.preference().property.Hops_mirror_modes == "SYMMETRY":
with ExecutionContext(mode="EDIT", active_object=object):
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.symmetrize(direction=direction)
bpy.ops.mesh.select_all(action='DESELECT')
if addon.preference().property.Hops_mirror_modal_mod_on_bisect:
mods = {"BISECT", "MODIFIER"}
else:
mods = {"MODIFIER"}
if addon.preference().property.Hops_mirror_modes in mods:
if _operation == "MIRROR_X":
mirror_mod.use_axis[0] = True
if addon.preference().property.Hops_mirror_modes == "MODIFIER":
mirror_mod.use_bisect_axis[0] = True
if addon.preference().property.Hops_mirror_direction == "-":
mirror_mod.use_bisect_flip_axis[0] = True
else:
mirror_mod.use_bisect_flip_axis[0] = False
mirror_mod.show_on_cage = True
elif _operation == "MIRROR_Y":
mirror_mod.use_axis[1] = True
if addon.preference().property.Hops_mirror_modes == "MODIFIER":
mirror_mod.use_bisect_axis[1] = True
if addon.preference().property.Hops_mirror_direction == "-":
mirror_mod.use_bisect_flip_axis[1] = True
else:
mirror_mod.use_bisect_flip_axis[1] = False
mirror_mod.show_on_cage = True
elif _operation == "MIRROR_Z":
mirror_mod.use_axis[2] = True
if addon.preference().property.Hops_mirror_modes == "MODIFIER":
mirror_mod.use_bisect_axis[2] = True
if addon.preference().property.Hops_mirror_direction == "-":
mirror_mod.use_bisect_flip_axis[2] = True
else:
mirror_mod.use_bisect_flip_axis[2] = False
mirror_mod.show_on_cage = True
elif object.type in {"GPENCIL", "GREASEPENCIL"}:
if object.type == 'GPENCIL':
mtype = "GP_MIRROR"
mods_s = 'grease_pencil_modifiers'
else:
"GREASE_PENCIL_MIRROR"
mtype = "GREASE_PENCIL_MIRROR"
mods_s = 'modifiers'
mirror_mod = None
for modifier in getattr(object, mods_s):
if modifier.name == "hops_mirror":
mirror_mod = modifier
if mirror_mod is None:
mirror_mod = getattr(object, mods_s).new("hops_mirror", mtype)
mirror_mod.x_axis = False
if _operation == "MIRROR_X":
mirror_mod.x_axis = not mirror_mod.x_axis
elif _operation == "MIRROR_Y":
mirror_mod.y_axis = not mirror_mod.y_axis
elif _operation == "MIRROR_Z":
mirror_mod.z_axis = not mirror_mod.z_axis
else:
if addon.preference().property.Hops_mirror_modes_multi == "VIA_ACTIVE":
with ExecutionContext(mode="OBJECT", active_object=object):
mirror_ob = bpy.context.active_object # last ob selected
for obj in bpy.context.selected_objects:
if obj != mirror_ob:
if obj.type in {"MESH", "CURVE"}:
mirror_ob.select_set(False) # pop object from sel_stack
object = obj
mirror_mod_multi = None
for modifier in object.modifiers:
if modifier.name == "hops_mirror_via_active":
mirror_mod_multi = modifier
if mirror_mod_multi is None:
mirror_mod_multi = object.modifiers.new("hops_mirror_via_active", "MIRROR")
mirror_mod_multi.use_axis[0] = False
mirror_mod_multi.use_axis[1] = False
mirror_mod_multi.use_axis[2] = False
mirror_mod_multi.use_clip = True
mirror_mod_multi.mirror_object = mirror_ob
mirror_mod_multi.use_mirror_u = addon.preference().property.Hops_gizmo_mirror_u
mirror_mod_multi.use_mirror_v = addon.preference().property.Hops_gizmo_mirror_v
if _operation == "MIRROR_X":
mirror_mod_multi.use_axis[0] = True
if addon.preference().property.Hops_mirror_direction == "-":
mirror_mod_multi.use_bisect_axis[0] = True
mirror_mod_multi.use_bisect_flip_axis[0] = True
else:
mirror_mod_multi.use_bisect_axis[0] = True
mirror_mod_multi.use_bisect_flip_axis[0] = False
elif _operation == "MIRROR_Y":
mirror_mod_multi.use_axis[1] = True
if addon.preference().property.Hops_mirror_direction == "-":
mirror_mod_multi.use_bisect_axis[1] = True
mirror_mod_multi.use_bisect_flip_axis[1] = True
else:
mirror_mod_multi.use_bisect_axis[1] = True
mirror_mod_multi.use_bisect_flip_axis[1] = False
elif _operation == "MIRROR_Z":
mirror_mod_multi.use_axis[2] = True
if addon.preference().property.Hops_mirror_direction == "-":
mirror_mod_multi.use_bisect_axis[2] = True
mirror_mod_multi.use_bisect_flip_axis[2] = True
else:
mirror_mod_multi.use_bisect_axis[2] = True
mirror_mod_multi.use_bisect_flip_axis[2] = False
elif addon.preference().property.Hops_mirror_modes_multi == "SYMMETRY":
selected = bpy.context.selected_objects
for obj in selected:
bpy.context.view_layer.objects.active = obj
with ExecutionContext(mode="EDIT", active_object=obj):
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.symmetrize(direction=direction)
bpy.ops.mesh.select_all(action='DESELECT')
# mirror_ob.select = 1
# object.select = 1
bpy.context.view_layer.objects.active = object
modsort.sort(object, types=['WEIGHTED_NORMAL'], last=True)
# ------------------- OPERATOR CLASSES ------------------------------
# Mirror Tool
# legacy
class HOPS_OT_MirrorX(bpy.types.Operator):
bl_idname = "hops.mirror_mirror_x"
bl_label = "Mirror X"
bl_description = "Mirror On the X Axis"
bl_options = {"REGISTER", "UNDO", 'INTERNAL'}
def draw(self, context):
layout = self.layout
layout.prop(addon.preference(), "Hops_mirror_direction")
layout.prop(addon.preference(), "Hops_mirror_modes")
@classmethod
def poll(cls, context):
# selected = context.selected_objects
object = context.active_object
if object is None: return False
if object.mode in {"OBJECT", "EDIT"}:
return True
def execute(self, context):
x, y, z = bpy.context.object.location
zx, zy, zz = bpy.context.object.rotation_euler
if addon.preference().property.Hops_mirror_direction == "+":
direction = "POSITIVE_X"
elif addon.preference().property.Hops_mirror_direction == "-":
direction = "NEGATIVE_X"
used_axis = "X"
vec = mathutils.Vector((1, 0, 0))
mat = mathutils.Matrix.Rotation(zx, 4, "X")
vec.rotate(mat)
mat = mathutils.Matrix.Rotation(zy, 4, "Y")
vec.rotate(mat)
mat = mathutils.Matrix.Rotation(zz, 4, "Z")
vec.rotate(mat)
nx = vec[0]
ny = vec[1]
nz = vec[2]
operation(context, "MIRROR_X", x, y, z, nx, ny, nz, direction, used_axis)
return {'FINISHED'}
class HOPS_OT_MirrorY(bpy.types.Operator):
bl_idname = "hops.mirror_mirror_y"
bl_label = "Mirror Y"
bl_description = "Mirror On the Y Axis"
bl_options = {"REGISTER", "UNDO", 'INTERNAL'}
def draw(self, context):
layout = self.layout
layout.prop(addon.preference(), "Hops_mirror_direction")
layout.prop(addon.preference(), "Hops_mirror_modes")
@classmethod
def poll(cls, context):
# selected = context.selected_objects
object = context.active_object
if object is None: return False
if object.mode in {"OBJECT", "EDIT"}:
return True
def execute(self, context):
x, y, z = bpy.context.object.location
zx, zy, zz = bpy.context.object.rotation_euler
if addon.preference().property.Hops_mirror_direction == "+":
direction = "POSITIVE_Y"
elif addon.preference().property.Hops_mirror_direction == "-":
direction = "NEGATIVE_Y"
used_axis = "Y"
vec = mathutils.Vector((0, 1, 0))
mat = mathutils.Matrix.Rotation(zx, 4, "X")
vec.rotate(mat)
mat = mathutils.Matrix.Rotation(zy, 4, "Y")
vec.rotate(mat)
mat = mathutils.Matrix.Rotation(zz, 4, "Z")
vec.rotate(mat)
nx = vec[0]
ny = vec[1]
nz = vec[2]
operation(context, "MIRROR_Y", x, y, z, nx, ny, nz, direction, used_axis)
return {'FINISHED'}
class HOPS_OT_MirrorZ(bpy.types.Operator):
bl_idname = "hops.mirror_mirror_z"
bl_label = "Mirror Z"
bl_description = "Mirror On the Z Axis"
bl_options = {"REGISTER", "UNDO", 'INTERNAL'}
def draw(self, context):
layout = self.layout
layout.prop(addon.preference(), "Hops_mirror_direction")
layout.prop(addon.preference(), "Hops_mirror_modes")
@classmethod
def poll(cls, context):
object = context.active_object
if object is None: return False
if object.mode in {"OBJECT", "EDIT"}:
return True
def execute(self, context):
x, y, z = bpy.context.object.location
zx, zy, zz = bpy.context.object.rotation_euler
if addon.preference().property.Hops_mirror_direction == "+":
direction = "POSITIVE_Z"
elif addon.preference().property.Hops_mirror_direction == "-":
direction = "NEGATIVE_Z"
used_axis = "Z"
vec = mathutils.Vector((0, 0, 1))
mat = mathutils.Matrix.Rotation(zx, 4, "X")
vec.rotate(mat)
mat = mathutils.Matrix.Rotation(zy, 4, "Y")
vec.rotate(mat)
mat = mathutils.Matrix.Rotation(zz, 4, "Z")
vec.rotate(mat)
nx = vec[0]
ny = vec[1]
nz = vec[2]
operation(context, "MIRROR_Z", x, y, z, nx, ny, nz, direction, used_axis)
return {'FINISHED'}