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-03 13:52:14 +0300
committermeta-androcto <meta.androcto1@gmail.com>2017-04-03 13:52:14 +0300
commit89f92968a76d4138f4d79e4b6c140a90879bcb93 (patch)
tree0ff8d6db4dcae62fe9c8884f285c70315e5e2b7d /mesh_extra_tools
parent16df27d62e6a0aa3d1450bc56f5d90fdd05cf4a4 (diff)
mesh edit tools, update multi extrude, add vertex align
Diffstat (limited to 'mesh_extra_tools')
-rw-r--r--mesh_extra_tools/__init__.py28
-rw-r--r--mesh_extra_tools/mesh_mextrude_plus.py57
-rw-r--r--mesh_extra_tools/vertex_align.py334
3 files changed, 390 insertions, 29 deletions
diff --git a/mesh_extra_tools/__init__.py b/mesh_extra_tools/__init__.py
index 89b9a453..d8e8792a 100644
--- a/mesh_extra_tools/__init__.py
+++ b/mesh_extra_tools/__init__.py
@@ -64,6 +64,7 @@ if "bpy" in locals():
importlib.reload(mesh_info_select)
importlib.reload(mesh_extrude_and_reshape)
importlib.reload(mesh_check)
+ importlib.reload(vertex_align)
else:
from . import face_inset_fillet
@@ -85,6 +86,7 @@ else:
from . import mesh_help
from . import mesh_extrude_and_reshape
from . import mesh_check
+ from . import vertex_align
from .mesh_select_tools import mesh_select_by_direction
from .mesh_select_tools import mesh_select_by_edge_length
@@ -238,6 +240,30 @@ class EditToolsPanel(Panel):
row.operator("mesh.random_vertices", text="Random Vertices")
row.operator("mesh.extra_tools_help",
icon="LAYER_USED").help_ids = "random_vertices"
+ cen0 = context.scene.va_custom_props.en0
+ layout = self.layout
+ layout.label(text="Vertex Align:", icon="VERTEXSEL")
+ layout.prop(context.scene.va_custom_props, 'en0', expand = False)
+
+ if cen0 == 'opt0':
+ row = layout.split(0.60)
+ row.label('Store data:')
+ row.operator('va.op0_id', text = 'Vertex')
+ row1 = layout.split(0.8, align=True)
+ row1.operator('va.op2_id', text = 'Align')
+ row1.operator('va.op7_id', text = '', icon = "LAYER_USED")
+ elif cen0 == 'opt1':
+ layout.operator('va.op3_id', text = 'Align')
+ elif cen0 == 'opt2':
+ row = layout.split(0.40)
+ row.label('Store data:')
+ row.operator('va.op0_id', text = 'Two vertices')
+ layout.operator('va.op5_id', text = 'Align')
+ elif cen0 == 'opt3':
+ row = layout.split(0.60)
+ row.label('Store data:')
+ row.operator('va.op1_id', text = 'Face')
+ layout.operator('va.op6_id', text = 'Align')
# Edge options
box1 = self.layout.box()
@@ -784,6 +810,7 @@ def register():
vfe_specials.register()
mesh_extrude_and_reshape.register()
mesh_check.register()
+ vertex_align.register()
bpy.utils.register_module(__name__)
# Register Scene Properties
@@ -808,6 +835,7 @@ def unregister():
vfe_specials.unregister()
mesh_extrude_and_reshape.unregister()
mesh_check.unregister()
+ vertex_align.unregister()
del bpy.types.Scene.mesh_extra_tools
del bpy.types.Object.tkkey
diff --git a/mesh_extra_tools/mesh_mextrude_plus.py b/mesh_extra_tools/mesh_mextrude_plus.py
index cb7c8b69..0ae161b7 100644
--- a/mesh_extra_tools/mesh_mextrude_plus.py
+++ b/mesh_extra_tools/mesh_mextrude_plus.py
@@ -19,7 +19,7 @@
# Repeats extrusion + rotation + scale for one or more faces
# Original code by liero
# Update by Jimmy Hazevoet 03/2017 for Blender 2.79
-# normal rotation, probability, scaled offset, object origin, initial scale noise
+# normal rotation, probability, scaled offset, object coörds, initial and per step noise
bl_info = {
@@ -81,29 +81,29 @@ class MExtrude(Operator):
off = FloatProperty(
name="Offset",
- soft_min=0.001, soft_max=2,
- min=-2, max=5,
+ soft_min=0.001, soft_max=10,
+ min=-100, max=100,
default=1.0,
description="Translation"
)
offx = FloatProperty(
name="Loc X",
- soft_min=-2.0, soft_max=2.0,
- min=-5.0, max=5.0,
+ soft_min=-10.0, soft_max=10.0,
+ min=-100.0, max=100.0,
default=0.0,
description="Global translation X"
)
offy = FloatProperty(
name="Loc Y",
- soft_min=-2.0, soft_max=2.0,
- min=-5.0, max=5.0,
+ soft_min=-10.0, soft_max=10.0,
+ min=-100.0, max=100.0,
default=0.0,
description="Global translation Y"
)
offz = FloatProperty(
name="Loc Z",
- soft_min=-2.0, soft_max=2.0,
- min=-5.0, max=5.0,
+ soft_min=-10.0, soft_max=10.0,
+ min=-100.0, max=100.0,
default=0.0,
description="Global translation Z"
)
@@ -152,27 +152,27 @@ class MExtrude(Operator):
)
sca = FloatProperty(
name="Scale",
- min=0.1, max=2,
- soft_min=0.5, soft_max=1.2,
+ min=0.01, max=10,
+ soft_min=0.5, soft_max=1.5,
default=1.0,
description="Scaling of the selected faces after extrusion"
)
var1 = FloatProperty(
- name="Offset Var", min=-5, max=5,
+ name="Offset Var", min=-10, max=10,
soft_min=-1, soft_max=1,
default=0,
description="Offset variation"
)
var2 = FloatProperty(
name="Rotation Var",
- min=-5, max=5,
+ min=-10, max=10,
soft_min=-1, soft_max=1,
default=0,
description="Rotation variation"
)
var3 = FloatProperty(
name="Scale Noise",
- min=-5, max=5,
+ min=-10, max=10,
soft_min=-1, soft_max=1,
default=0,
description="Scaling noise"
@@ -185,7 +185,7 @@ class MExtrude(Operator):
)
num = IntProperty(
name="Repeat",
- min=1, max=250,
+ min=1, max=500,
soft_max=100,
default=5,
description="Repetitions"
@@ -207,17 +207,16 @@ class MExtrude(Operator):
description="Scale * Offset"
)
opt3 = BoolProperty(
- name="Per step scale noise",
+ name="Per step rotation noise",
default=False,
- description="Per step scale noise, Initial scale noise"
+ description="Per step rotation noise, Initial rotation noise"
)
opt4 = BoolProperty(
- name="Per step rotation noise",
+ name="Per step scale noise",
default=False,
- description="Per step rotation noise, Initial rotation noise"
+ description="Per step scale noise, Initial scale noise"
)
-
@classmethod
def poll(cls, context):
obj = context.object
@@ -253,7 +252,7 @@ class MExtrude(Operator):
col.prop(self, 'num')
col = layout.column(align=True)
- col.label(text="Extra settings:")
+ col.label(text="Options:")
col.prop(self, "opt1")
col.prop(self, "opt2")
col.prop(self, "opt3")
@@ -280,12 +279,12 @@ class MExtrude(Operator):
loc = gloc(self, i)
of.normal_update()
- # initial scale noise
- if self.opt3 is False:
- s = vsca(self, i)
# initial rotation noise
- if self.opt4 is False:
+ if self.opt3 is False:
rot = vrot(self, i)
+ # initial scale noise
+ if self.opt4 is False:
+ s = vsca(self, i)
# extrusion loop
for r in range(self.num):
@@ -303,12 +302,12 @@ class MExtrude(Operator):
else:
ce = origin
- # per step scale noise
- if self.opt3 is True:
- s = vsca(self, i + r)
# per step rotation noise
- if self.opt4 is True:
+ if self.opt3 is True:
rot = vrot(self, i + r)
+ # per step scale noise
+ if self.opt4 is True:
+ s = vsca(self, i + r)
# proportional, scale * offset
if self.opt2 is True:
diff --git a/mesh_extra_tools/vertex_align.py b/mesh_extra_tools/vertex_align.py
new file mode 100644
index 00000000..04401aef
--- /dev/null
+++ b/mesh_extra_tools/vertex_align.py
@@ -0,0 +1,334 @@
+# -*- coding: utf-8 -*-
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+
+# ------ ------
+bl_info = {
+ 'name': 'vertex align',
+ 'author': '',
+ 'version': (0, 1, 6),
+ 'blender': (2, 6, 1),
+ 'location': 'View3D > Tool Shelf',
+ 'description': '',
+ 'warning': '',
+ 'wiki_url': '',
+ 'tracker_url': '',
+ 'category': 'Mesh' }
+
+# ------ ------
+import bpy
+from bpy.props import PointerProperty, EnumProperty, FloatProperty, BoolProperty
+from mathutils import Vector
+from mathutils.geometry import intersect_point_line, intersect_line_plane
+
+# ------ Edit Mode Toggle------
+def edit_mode_out():
+ bpy.ops.object.mode_set(mode = 'OBJECT')
+
+def edit_mode_in():
+ bpy.ops.object.mode_set(mode = 'EDIT')
+
+# ------ ------
+def get_mesh_data_():
+ edit_mode_out()
+ ob_act = bpy.context.active_object
+ me = ob_act.data
+ edit_mode_in()
+ return me
+
+def list_clear_(l):
+ l[:] = []
+ return l
+
+# -- -- Prpoerty Group-- --
+class va_p_group0(bpy.types.PropertyGroup):
+
+ en0 = EnumProperty( items =( ('opt0', 'Original vertex', ''),
+ ('opt1', 'Custom coordinates', '')),
+ ## REMOVED BROKEN ('opt2', 'Line', ''), ('opt3', 'Plane', '')),
+ name = 'Align to',
+ default = 'opt0' )
+
+ en1 = EnumProperty( items =( ('en1_opt0', 'x', ''),
+ ('en1_opt1', 'y', ''),
+ ('en1_opt2', 'z', '')),
+ name = 'Axis',
+ default = 'en1_opt0' )
+
+# ------ ------
+class va_buf():
+ list_v = []
+ list_f = []
+ list_0 = []
+
+# ------ operator 0 ------
+class va_op0(bpy.types.Operator):
+ bl_idname = 'va.op0_id'
+ bl_label = ''
+ bl_description = "Store single vert as align point"
+
+ def execute(self, context):
+ me = get_mesh_data_()
+ list_clear_(va_buf.list_v)
+ for v in me.vertices:
+ if v.select:
+ va_buf.list_v.append(v.index)
+ bpy.ops.mesh.select_all(action = 'DESELECT')
+ return {'FINISHED'}
+
+# ------ operator 1 ------
+class va_op1(bpy.types.Operator):
+ bl_idname = 'va.op1_id'
+ bl_label = ''
+ bl_description = "test2"
+
+ def execute(self, context):
+ me = get_mesh_data_()
+ list_clear_(va_buf.list_f)
+ for f in me.faces:
+ if f.select:
+ va_buf.list_f.append(f.index)
+ bpy.ops.mesh.select_all(action = 'DESELECT')
+ return {'FINISHED'}
+
+# ------ operator 2 ------ align to original
+class va_op2(bpy.types.Operator):
+ bl_idname = 'va.op2_id'
+ bl_label = 'Align to original'
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Align selection to stored single vert"
+
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('Axis:')
+ layout.prop(context.scene.va_custom_props, 'en1', expand = True)
+
+ def execute(self, context):
+
+ edit_mode_out()
+ ob_act = context.active_object
+ me = ob_act.data
+ cen1 = context.scene.va_custom_props.en1
+ list_0 = [v.index for v in me.vertices if v.select]
+
+ if len(va_buf.list_v) == 0:
+ self.report({'INFO'}, 'Original vertex not stored in memory')
+ edit_mode_in()
+ return {'CANCELLED'}
+ elif len(va_buf.list_v) != 0:
+ if len(list_0) == 0:
+ self.report({'INFO'}, 'No vertices selected')
+ edit_mode_in()
+ return {'CANCELLED'}
+ elif len(list_0) != 0:
+ vo = (me.vertices[va_buf.list_v[0]].co).copy()
+ if cen1 == 'en1_opt0':
+ for i in list_0:
+ v = (me.vertices[i].co).copy()
+ me.vertices[i].co = Vector(( vo[0], v[1], v[2] ))
+ elif cen1 == 'en1_opt1':
+ for i in list_0:
+ v = (me.vertices[i].co).copy()
+ me.vertices[i].co = Vector(( v[0], vo[1], v[2] ))
+ elif cen1 == 'en1_opt2':
+ for i in list_0:
+ v = (me.vertices[i].co).copy()
+ me.vertices[i].co = Vector(( v[0], v[1], vo[2] ))
+ edit_mode_in()
+ return {'FINISHED'}
+
+# ------ operator 3 ------ align to custom coordinates
+class va_op3(bpy.types.Operator):
+ bl_idname = 'va.op3_id'
+ bl_label = ''
+ bl_description = "Align to custom coordinates"
+
+ def execute(self, context):
+ edit_mode_out()
+ ob_act = context.active_object
+ me = ob_act.data
+ list_clear_(va_buf.list_0)
+ va_buf.list_0 = [v.index for v in me.vertices if v.select][:]
+ if len(va_buf.list_0) == 0:
+ self.report({'INFO'}, 'No vertices selected')
+ edit_mode_in()
+ return {'CANCELLED'}
+ elif len(va_buf.list_0) != 0:
+ bpy.ops.va.op4_id('INVOKE_DEFAULT')
+ edit_mode_in()
+ return {'FINISHED'}
+
+# ------ operator 4 ------ align to custom coordinates
+class va_op4(bpy.types.Operator):
+ bl_idname = 'va.op4_id'
+ bl_label = 'Align to custom coordinates'
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Align to custom coordinates2"
+
+ x = y = z = FloatProperty( name = '', default = 0.0, min = -100.0, max = 100.0, step = 1, precision = 3 )
+ b_x = b_y = b_z = BoolProperty()
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.split(0.25)
+ row.prop(self, 'b_x', text = 'x')
+ row.prop(self, 'x')
+ row = layout.split(0.25)
+ row.prop(self, 'b_y', text = 'y')
+ row.prop(self, 'y')
+ row = layout.split(0.25)
+ row.prop(self, 'b_z', text = 'z')
+ row.prop(self, 'z')
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_props_dialog(self, width = 200)
+
+ def execute(self, context):
+ edit_mode_out()
+ ob_act = context.active_object
+ me = ob_act.data
+
+ for i in va_buf.list_0:
+ v = (me.vertices[i].co).copy()
+ tmp = Vector((v[0], v[1], v[2]))
+ if self.b_x == True:
+ tmp[0] = self.x
+ if self.b_y == True:
+ tmp[1] = self.y
+ if self.b_z == True:
+ tmp[2] = self.z
+ me.vertices[i].co = tmp
+ edit_mode_in()
+ return {'FINISHED'}
+
+# ------ operator 5 ------ align to line
+class va_op5(bpy.types.Operator):
+ bl_idname = 'va.op5_id'
+ bl_label = 'Align to line'
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Align to line"
+
+ def execute(self, context):
+ edit_mode_out()
+ ob_act = context.active_object
+ me = ob_act.data
+ list_0 = [v.index for v in me.vertices if v.select]
+
+ if len(va_buf.list_v) != 2:
+ self.report({'INFO'}, 'Two guide vertices must be stored in memory.')
+ edit_mode_in()
+ return {'CANCELLED'}
+ elif len(va_buf.list_v) > 1:
+ if len(list_0) == 0:
+ self.report({'INFO'}, 'No vertices selected')
+ edit_mode_in()
+ return {'CANCELLED'}
+ elif len(list_0) != 0:
+ p1 = (me.vertices[va_buf.list_v[0]].co).copy()
+ p2 = (me.vertices[va_buf.list_v[1]].co).copy()
+ for i in list_0:
+ v = (me.vertices[i].co).copy()
+ me.vertices[i].co = intersect_point_line( v, p1, p2)[0]
+ edit_mode_in()
+ return {'FINISHED'}
+
+# ------ operator 6 ------ align to plane
+class va_op6(bpy.types.Operator):
+ bl_idname = 'va.op6_id'
+ bl_label = 'Align to plane'
+ bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Align to Plane"
+
+ def execute(self, context):
+ edit_mode_out()
+ ob_act = context.active_object
+ me = ob_act.data
+ list_0 = [v.index for v in me.vertices if v.select]
+
+ if len(va_buf.list_f) == 0:
+ self.report({'INFO'}, 'No face stored in memory')
+ edit_mode_in()
+ return {'CANCELLED'}
+ elif len(va_buf.list_f) != 0:
+ if len(list_0) == 0:
+ self.report({'INFO'}, 'No vertices selected')
+ edit_mode_in()
+ return {'CANCELLED'}
+ elif len(list_0) != 0:
+ f = me.faces[va_buf.list_f[0]]
+ for i in list_0:
+ v = (me.vertices[i].co).copy()
+ p = v + ((f.normal).copy() * 0.1)
+ pp = (me.vertices[f.vertices[0]].co).copy()
+ pn = (f.normal).copy()
+ me.vertices[i].co = intersect_line_plane(v, p, pp, pn)
+ edit_mode_in()
+ return {'FINISHED'}
+
+# ------ operator 7 Help------
+class va_op7(bpy.types.Operator):
+
+ bl_idname = 'va.op7_id'
+ bl_label = ''
+ bl_description = "Info"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('Help:')
+ layout.label('To use select whatever you want vertices to be aligned to ')
+ layout.label('and click button next to store data label. ')
+ layout.label('Select vertices that you want to align and click Align button. ')
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 400)
+
+# ------ operator 8 ------
+class va_op8(bpy.types.Operator):
+ bl_idname = 'va.op8_id'
+ bl_label = ''
+ bl_description = "Executs"
+ def execute(self, context):
+ bpy.ops.va.op7_id('INVOKE_DEFAULT')
+ return {'FINISHED'}
+
+# ------ ------
+class_list = [ va_op0, va_op1, va_op2, va_op3, va_op4, va_op5, va_op6, va_op7, va_op8, va_p_group0 ]
+
+# ------ ------
+def register():
+ for c in class_list:
+ bpy.utils.register_class(c)
+
+ bpy.types.Scene.va_custom_props = PointerProperty(type = va_p_group0)
+
+# ------ ------
+def unregister():
+ for c in class_list:
+ bpy.utils.unregister_class(c)
+
+ del bpy.context.scene['va_custom_props']
+
+# ------ ------
+if __name__ == "__main__":
+ register()