1 # mesh_relax.py Copyright (C) 2010, Fabian Fricke
3 # Relaxes selected vertices while retaining the shape as much as possible
5 # ***** BEGIN GPL LICENSE BLOCK *****
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License
10 # as published by the Free Software Foundation; either version 2
11 # of the License, or (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software Foundation,
20 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 # ***** END GPL LICENCE BLOCK *****
26 "author": "Fabian Fricke",
28 "blender": (2, 80, 0),
29 "location": "View3D > Specials > Relax ",
30 "description": "Relax the selected verts while retaining the shape",
32 "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
33 "Scripts/Modeling/Relax",
40 Launch from "W-menu" or from "Mesh -> Vertices -> Relax"
44 Author Site: http://frigi.designdevil.de
45 e-mail: frigi.f {at} gmail {dot} com
50 from bpy
.props
import IntProperty
52 def relax_mesh(context
):
54 # deselect everything that's not related
55 for obj
in context
.selected_objects
:
59 obj
= context
.active_object
61 # duplicate the object so it can be used for the shrinkwrap modifier
62 obj
.select_set(True) # make sure the object is selected!
63 bpy
.ops
.object.mode_set(mode
='OBJECT')
64 bpy
.ops
.object.duplicate()
65 target
= context
.active_object
67 # remove all other modifiers from the target
68 for m
in range(0, len(target
.modifiers
)):
69 target
.modifiers
.remove(target
.modifiers
[0])
71 context
.view_layer
.objects
.active
= obj
73 sw
= obj
.modifiers
.new(type='SHRINKWRAP', name
='relax_target')
76 # run smooth operator to relax the mesh
77 bpy
.ops
.object.mode_set(mode
='EDIT')
78 bpy
.ops
.mesh
.vertices_smooth()
79 bpy
.ops
.object.mode_set(mode
='OBJECT')
82 bpy
.ops
.object.modifier_apply(modifier
='relax_target')
84 # delete the target object
86 target
.select_set(True)
87 bpy
.ops
.object.delete()
89 # go back to initial state
91 bpy
.ops
.object.mode_set(mode
='EDIT')
93 class Relax(bpy
.types
.Operator
):
94 """Relaxes selected vertices while retaining the shape """ \
95 """as much as possible"""
96 bl_idname
= 'mesh.relax'
98 bl_options
= {'REGISTER', 'UNDO'}
100 iterations
: IntProperty(name
="Relax iterations",
101 default
=1, min=0, max=100, soft_min
=0, soft_max
=10)
104 def poll(cls
, context
):
105 obj
= context
.active_object
106 return (obj
and obj
.type == 'MESH')
108 def execute(self
, context
):
109 for i
in range(0,self
.iterations
):
114 def menu_func(self
, context
):
115 self
.layout
.operator(Relax
.bl_idname
, text
="Relax")
119 bpy
.utils
.register_class(Relax
)
121 bpy
.types
.VIEW3D_MT_edit_mesh_specials
.append(menu_func
)
122 bpy
.types
.VIEW3D_MT_edit_mesh_vertices
.append(menu_func
)
125 bpy
.utils
.unregister_class(Relax
)
127 bpy
.types
.VIEW3D_MT_edit_mesh_specials
.remove(menu_func
)
128 bpy
.types
.VIEW3D_MT_edit_mesh_vertices
.remove(menu_func
)
130 if __name__
== "__main__":