Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormeta-androcto <meta.androcto1@gmail.com>2017-04-01 04:19:55 +0300
committermeta-androcto <meta.androcto1@gmail.com>2017-04-01 04:19:55 +0300
commita72be7c9becf47ddc22778d55b41b95e1f9825e2 (patch)
tree4e8fc0fa98561d304d14e408ccd16e32e4962d23 /mesh_auto_mirror.py
parente0c236644bc9d3fff711ee69555fa9a7ffa61706 (diff)
mesh auto mirror, promote addons release: T50941
Diffstat (limited to 'mesh_auto_mirror.py')
-rw-r--r--mesh_auto_mirror.py221
1 files changed, 221 insertions, 0 deletions
diff --git a/mesh_auto_mirror.py b/mesh_auto_mirror.py
new file mode 100644
index 00000000..4be783a2
--- /dev/null
+++ b/mesh_auto_mirror.py
@@ -0,0 +1,221 @@
+######################################################################################################
+# An simple add-on to auto cut in two and mirror an object #
+# Actualy partialy uncommented (see further version) #
+# Author: Lapineige #
+# License: GPL v3 #
+######################################################################################################
+
+
+############# Add-on description (used by Blender)
+
+bl_info = {
+ "name": "Auto Mirror",
+ "description": "Super fast cutting and mirroring for mesh",
+ "author": "Lapineige",
+ "version": (2, 4, 1),
+ "blender": (2, 7, 1),
+ "location": "View 3D > Toolbar > Tools tab > AutoMirror (panel)",
+ "warning": "",
+ "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Modeling/AutoMirror",
+ "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
+ "category": "Mesh"}
+
+
+import bpy
+from mathutils import Vector
+
+bpy.types.Scene.AutoMirror_axis = bpy.props.EnumProperty(items = [("x", "X", "", 1),
+ ("y", "Y", "", 2),
+ ("z", "Z", "", 3)],
+ description="Axis used by the mirror modifier")
+bpy.types.Scene.AutoMirror_orientation = bpy.props.EnumProperty(items = [("positive","Positive", "", 1),
+ ("negative", "Negative", "", 2)],
+ description="Choose the side along the axis of the editable part (+/- coordinates)")
+bpy.types.Scene.AutoMirror_threshold = bpy.props.FloatProperty(default= 0.001,
+ min= 0.001,
+ description="Vertices closer than this distance are merged on the loopcut")
+bpy.types.Scene.AutoMirror_toggle_edit = bpy.props.BoolProperty(default= True,
+ description="If not in edit mode, change mode to edit")
+bpy.types.Scene.AutoMirror_cut = bpy.props.BoolProperty(default= True,
+ description="If enabeled, cut the mesh in two parts and mirror it. If not, just make a loopcut")
+bpy.types.Scene.AutoMirror_clipping = bpy.props.BoolProperty(default=True)
+bpy.types.Scene.AutoMirror_use_clip = bpy.props.BoolProperty(default=True,
+ description="Use clipping for the mirror modifier")
+bpy.types.Scene.AutoMirror_show_on_cage = bpy.props.BoolProperty(default=True,
+ description="Enable to edit the cage (it's the classical modifier's option)")
+bpy.types.Scene.AutoMirror_apply_mirror = bpy.props.BoolProperty(description="Apply the mirror modifier (useful to symmetrise the mesh)")
+
+############### Operator
+
+class AlignVertices(bpy.types.Operator):
+ """ """
+ bl_idname = "object.align_vertices"
+ bl_label = "Align Vertices on 1 Axis"
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def execute(self, context):
+ bpy.ops.object.mode_set(mode = 'OBJECT')
+
+ x1,y1,z1 = bpy.context.scene.cursor_location
+ bpy.ops.view3d.snap_cursor_to_selected()
+
+ x2,y2,z2 = bpy.context.scene.cursor_location
+
+ bpy.context.scene.cursor_location[0],bpy.context.scene.cursor_location[1],bpy.context.scene.cursor_location[2] = 0,0,0
+
+ #Vertices coordinate to 0 (local coordinate, so on the origin)
+ for vert in bpy.context.object.data.vertices:
+ if vert.select:
+ if bpy.context.scene.AutoMirror_axis == 'x':
+ axis = 0
+ elif bpy.context.scene.AutoMirror_axis == 'y':
+ axis = 1
+ elif bpy.context.scene.AutoMirror_axis == 'z':
+ axis = 2
+ vert.co[axis] = 0
+ #
+ bpy.context.scene.cursor_location = x2,y2,z2
+
+ bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
+
+ bpy.context.scene.cursor_location = x1,y1,z1
+
+ bpy.ops.object.mode_set(mode = 'EDIT')
+ return {'FINISHED'}
+
+class AutoMirror(bpy.types.Operator):
+ """ Automatically cut an object along an axis """
+ bl_idname = "object.automirror"
+ bl_label = "AutoMirror"
+ bl_options = {'REGISTER'} # 'UNDO' ?
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def draw(self, context):
+ layout = self.layout
+ if bpy.context.object and bpy.context.object.type == 'MESH':
+ layout.prop(context.scene, "AutoMirror_axis", text="Mirror axis")
+ layout.prop(context.scene, "AutoMirror_orientation", text="Orientation")
+ layout.prop(context.scene, "AutoMirror_threshold", text="Threshold")
+ layout.prop(context.scene, "AutoMirror_toggle_edit", text="Toggle edit")
+ layout.prop(context.scene, "AutoMirror_cut", text="Cut and mirror")
+ if bpy.context.scene.AutoMirror_cut:
+ layout.prop(context.scene, "AutoMirror_clipping", text="Clipping")
+ layout.prop(context.scene, "AutoMirror_apply_mirror", text="Apply mirror")
+ else:
+ layout.label(icon="ERROR", text="No mesh selected")
+
+ def get_local_axis_vector(self, context, X, Y, Z, orientation):
+ loc = context.object.location
+ bpy.ops.object.mode_set(mode="OBJECT") # Needed to avoid to translate vertices
+
+ v1 = Vector((loc[0],loc[1],loc[2]))
+ bpy.ops.transform.translate(value=(X*orientation, Y*orientation, Z*orientation),
+ constraint_axis=((X==1), (Y==1), (Z==1)),
+ constraint_orientation='LOCAL')
+ v2 = Vector((loc[0],loc[1],loc[2]))
+ bpy.ops.transform.translate(value=(-X*orientation, -Y*orientation, -Z*orientation),
+ constraint_axis=((X==1), (Y==1), (Z==1)),
+ constraint_orientation='LOCAL')
+
+ bpy.ops.object.mode_set(mode="EDIT")
+ return v2-v1
+
+ def execute(self, context):
+ X,Y,Z = 0,0,0
+ if bpy.context.scene.AutoMirror_axis == 'x':
+ X = 1
+ elif bpy.context.scene.AutoMirror_axis == 'y':
+ Y = 1
+ elif bpy.context.scene.AutoMirror_axis == 'z':
+ Z = 1
+
+ current_mode = bpy.context.object.mode # Save the current mode
+
+ if bpy.context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT") # Go to edit mode
+ bpy.ops.mesh.select_all(action='SELECT') # Select all the vertices
+ if bpy.context.scene.AutoMirror_orientation == 'positive':
+ orientation = 1
+ else:
+ orientation = -1
+ cut_normal = self.get_local_axis_vector(context, X, Y, Z, orientation)
+
+ bpy.ops.mesh.bisect(plane_co=(bpy.context.object.location[0],
+ bpy.context.object.location[1],
+ bpy.context.object.location[2]),
+ plane_no=cut_normal,
+ use_fill= False,
+ clear_inner= bpy.context.scene.AutoMirror_cut,
+ clear_outer= 0,
+ threshold= bpy.context.scene.AutoMirror_threshold) # Cut the mesh
+
+ bpy.ops.object.align_vertices() # Use to align the vertices on the origin, needed by the "threshold"
+
+ if not bpy.context.scene.AutoMirror_toggle_edit:
+ bpy.ops.object.mode_set(mode=current_mode) # Reload previous mode
+
+ if bpy.context.scene.AutoMirror_cut:
+ bpy.ops.object.modifier_add(type='MIRROR') # Add a mirror modifier
+ bpy.context.object.modifiers[-1].use_x = X # Choose the axis to use, based on the cut's axis
+ bpy.context.object.modifiers[-1].use_y = Y
+ bpy.context.object.modifiers[-1].use_z = Z
+ bpy.context.object.modifiers[-1].use_clip = context.scene.AutoMirror_use_clip
+ bpy.context.object.modifiers[-1].show_on_cage = context.scene.AutoMirror_show_on_cage
+ if bpy.context.scene.AutoMirror_apply_mirror:
+ bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.modifier_apply(apply_as= 'DATA', modifier= bpy.context.object.modifiers[-1].name)
+ if bpy.context.scene.AutoMirror_toggle_edit:
+ bpy.ops.object.mode_set(mode='EDIT')
+ else:
+ bpy.ops.object.mode_set(mode=current_mode)
+
+ return {'FINISHED'}
+
+#################### Panel
+
+class BisectMirror(bpy.types.Panel):
+ """ The AutoMirror panel on the toolbar tab 'Tools' """
+ bl_label = "Auto Mirror"
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_category = "Tools"
+
+ def draw(self, context):
+ layout = self.layout
+ if bpy.context.object and bpy.context.object.type == 'MESH':
+ layout.operator("object.automirror")
+ layout.prop(context.scene, "AutoMirror_axis", text="Mirror Axis", expand=True)
+ layout.prop(context.scene, "AutoMirror_orientation", text="Orientation")
+ layout.prop(context.scene, "AutoMirror_threshold", text="Threshold")
+ layout.prop(context.scene, "AutoMirror_toggle_edit", text="Toggle Edit")
+ layout.prop(context.scene, "AutoMirror_cut", text="Cut and Mirror")
+ if bpy.context.scene.AutoMirror_cut:
+ row = layout.row()
+ row.prop(context.scene, "AutoMirror_use_clip", text="Use Clip")
+ row.prop(context.scene, "AutoMirror_show_on_cage", text="Editable")
+ layout.prop(context.scene, "AutoMirror_apply_mirror", text="Apply Mirror")
+
+ else:
+ layout.label(icon="ERROR", text="No mesh selected")
+
+
+def register():
+ bpy.utils.register_class(BisectMirror)
+ bpy.utils.register_class(AutoMirror)
+ bpy.utils.register_class(AlignVertices)
+
+
+def unregister():
+ bpy.utils.unregister_class(BisectMirror)
+ bpy.utils.unregister_class(AutoMirror)
+ bpy.utils.unregister_class(AlignVertices)
+
+
+if __name__ == "__main__":
+ register()