1 # SPDX-FileCopyrightText: 2010 Fabian Fricke
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # Relaxes selected vertices while retaining the shape as much as possible
9 "author": "Fabian Fricke",
11 "blender": (2, 80, 0),
12 "location": "View3D > Edit Mode Context Menu > Relax ",
13 "description": "Relax the selected verts while retaining the shape",
15 "doc_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
16 "Scripts/Modeling/Relax",
23 Launch from "W-menu" or from "Mesh -> Vertices -> Relax"
27 Author Site: http://frigi.designdevil.de
28 e-mail: frigi.f {at} gmail {dot} com
33 from bpy
.props
import IntProperty
35 def relax_mesh(context
):
37 # deselect everything that's not related
38 for obj
in context
.selected_objects
:
42 obj
= context
.active_object
44 # duplicate the object so it can be used for the shrinkwrap modifier
45 obj
.select_set(True) # make sure the object is selected!
46 bpy
.ops
.object.mode_set(mode
='OBJECT')
47 bpy
.ops
.object.duplicate()
48 target
= context
.active_object
50 # remove all other modifiers from the target
51 for m
in range(0, len(target
.modifiers
)):
52 target
.modifiers
.remove(target
.modifiers
[0])
54 context
.view_layer
.objects
.active
= obj
56 sw
= obj
.modifiers
.new(type='SHRINKWRAP', name
='relax_target')
59 # run smooth operator to relax the mesh
60 bpy
.ops
.object.mode_set(mode
='EDIT')
61 bpy
.ops
.mesh
.vertices_smooth(factor
=0.5)
62 bpy
.ops
.object.mode_set(mode
='OBJECT')
65 bpy
.ops
.object.modifier_apply(modifier
='relax_target')
67 # delete the target object
69 target
.select_set(True)
70 bpy
.ops
.object.delete()
72 # go back to initial state
74 bpy
.ops
.object.mode_set(mode
='EDIT')
76 class Relax(bpy
.types
.Operator
):
77 """Relaxes selected vertices while retaining the shape """ \
78 """as much as possible"""
79 bl_idname
= 'mesh.relax'
81 bl_options
= {'REGISTER', 'UNDO'}
83 iterations
: IntProperty(name
="Relax iterations",
84 default
=1, min=0, max=100, soft_min
=0, soft_max
=10)
87 def poll(cls
, context
):
88 obj
= context
.active_object
89 return (obj
and obj
.type == 'MESH')
91 def execute(self
, context
):
92 for i
in range(0,self
.iterations
):
97 def menu_func(self
, context
):
98 self
.layout
.operator(Relax
.bl_idname
, text
="Relax")
102 bpy
.utils
.register_class(Relax
)
104 bpy
.types
.VIEW3D_MT_edit_mesh_context_menu
.append(menu_func
)
105 bpy
.types
.VIEW3D_MT_edit_mesh_vertices
.append(menu_func
)
108 bpy
.utils
.unregister_class(Relax
)
110 bpy
.types
.VIEW3D_MT_edit_mesh_context_menu
.remove(menu_func
)
111 bpy
.types
.VIEW3D_MT_edit_mesh_vertices
.remove(menu_func
)
113 if __name__
== "__main__":