From 6d5d8e187d913bbe4a477b063678c36eb50f1ce7 Mon Sep 17 00:00:00 2001 From: meta-androcto Date: Mon, 2 Dec 2019 12:43:30 +1100 Subject: mesh tools: merge mesh relax: T71560 --- mesh_tools/__init__.py | 6 +++ mesh_tools/mesh_relax.py | 131 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 mesh_tools/mesh_relax.py (limited to 'mesh_tools') diff --git a/mesh_tools/__init__.py b/mesh_tools/__init__.py index 13238e50..9a1147b6 100644 --- a/mesh_tools/__init__.py +++ b/mesh_tools/__init__.py @@ -49,6 +49,7 @@ if "bpy" in locals(): importlib.reload(mesh_edges_length) importlib.reload(pkhg_faces) importlib.reload(mesh_cut_faces) + importlib.reload(mesh_relax) else: from . import mesh_offset_edges @@ -63,6 +64,7 @@ else: from . import mesh_edges_length from . import pkhg_faces from . import mesh_cut_faces + from . import mesh_relax import bmesh @@ -1013,6 +1015,8 @@ class VIEW3D_PT_edit_mesh_tools(Panel): props.quad_method = props.ngon_method = 'BEAUTY' row = col_top.row(align=True) row.operator("mesh.tris_convert_to_quads") + row = col_top.row(align=True) + row.operator("mesh.relax") # property group containing all properties for the gui in the panel class EditToolsProps(PropertyGroup): @@ -1134,6 +1138,7 @@ def register(): mesh_edges_length.register() pkhg_faces.register() mesh_cut_faces.register() + mesh_relax.register() # unregistering and removing menus @@ -1159,6 +1164,7 @@ def unregister(): mesh_edges_length.unregister() pkhg_faces.unregister() mesh_cut_faces.unregister() + mesh_relax.unregister() if __name__ == "__main__": diff --git a/mesh_tools/mesh_relax.py b/mesh_tools/mesh_relax.py new file mode 100644 index 00000000..a1dabf3d --- /dev/null +++ b/mesh_tools/mesh_relax.py @@ -0,0 +1,131 @@ +# mesh_relax.py Copyright (C) 2010, Fabian Fricke +# +# Relaxes selected vertices while retaining the shape as much as possible +# +# ***** 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": "Relax", + "author": "Fabian Fricke", + "version": (1, 2, 0), + "blender": (2, 80, 0), + "location": "View3D > Edit Mode Context Menu > Relax ", + "description": "Relax the selected verts while retaining the shape", + "warning": "", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" + "Scripts/Modeling/Relax", + "category": "Mesh", +} + +""" +Usage: + +Launch from "W-menu" or from "Mesh -> Vertices -> Relax" + + +Additional links: + Author Site: http://frigi.designdevil.de + e-mail: frigi.f {at} gmail {dot} com +""" + + +import bpy +from bpy.props import IntProperty + +def relax_mesh(context): + + # deselect everything that's not related + for obj in context.selected_objects: + obj.select_set(False) + + # get active object + obj = context.active_object + + # duplicate the object so it can be used for the shrinkwrap modifier + obj.select_set(True) # make sure the object is selected! + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.duplicate() + target = context.active_object + + # remove all other modifiers from the target + for m in range(0, len(target.modifiers)): + target.modifiers.remove(target.modifiers[0]) + + context.view_layer.objects.active = obj + + sw = obj.modifiers.new(type='SHRINKWRAP', name='relax_target') + sw.target = target + + # run smooth operator to relax the mesh + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.vertices_smooth() + bpy.ops.object.mode_set(mode='OBJECT') + + # apply the modifier + bpy.ops.object.modifier_apply(modifier='relax_target') + + # delete the target object + obj.select_set(False) + target.select_set(True) + bpy.ops.object.delete() + + # go back to initial state + obj.select_set(True) + bpy.ops.object.mode_set(mode='EDIT') + +class Relax(bpy.types.Operator): + """Relaxes selected vertices while retaining the shape """ \ + """as much as possible""" + bl_idname = 'mesh.relax' + bl_label = 'Relax' + bl_options = {'REGISTER', 'UNDO'} + + iterations: IntProperty(name="Relax iterations", + default=1, min=0, max=100, soft_min=0, soft_max=10) + + @classmethod + def poll(cls, context): + obj = context.active_object + return (obj and obj.type == 'MESH') + + def execute(self, context): + for i in range(0,self.iterations): + relax_mesh(context) + return {'FINISHED'} + + +def menu_func(self, context): + self.layout.operator(Relax.bl_idname, text="Relax") + + +def register(): + bpy.utils.register_class(Relax) + + bpy.types.VIEW3D_MT_edit_mesh_context_menu.append(menu_func) + bpy.types.VIEW3D_MT_edit_mesh_vertices.append(menu_func) + +def unregister(): + bpy.utils.unregister_class(Relax) + + bpy.types.VIEW3D_MT_edit_mesh_context_menu.remove(menu_func) + bpy.types.VIEW3D_MT_edit_mesh_vertices.remove(menu_func) + +if __name__ == "__main__": + register() -- cgit v1.2.3