Renaming addon to fit convention of other addons
[blender-addons-contrib.git] / mesh_vertex_chamfer.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20
21 bl_info = {
22     "name": "Vertex Chamfer",
23     "author": "Andrew Hale (TrumanBlending)",
24     "version": (0, 1),
25     "blender": (2, 6, 3),
26     "location": "Spacebar Menu",
27     "description": "Chamfer vertex",
28     "wiki_url": "",
29     "tracker_url": "",
30     "category": "Mesh"}
31
32
33 import bpy
34 import bmesh
35
36
37 class VertexChamfer(bpy.types.Operator):
38     bl_idname = "mesh.vertex_chamfer"
39     bl_label = "Chamfer Vertex"
40     bl_options = {'REGISTER', 'UNDO'}
41
42     factor = bpy.props.FloatProperty(name="Factor",
43                                      default=0.1,
44                                      min=0.0,
45                                      soft_max=1.0)
46     relative = bpy.props.BoolProperty(name="Relative", default=True)
47     dissolve = bpy.props.BoolProperty(name="Remove", default=True)
48     displace = bpy.props.FloatProperty(name="Displace",
49                                        soft_min=-5.0,
50                                        soft_max=5.0)
51
52     @classmethod
53     def poll(self, context):
54         return (context.active_object.type == 'MESH' and
55                 context.mode == 'EDIT_MESH')
56
57     def draw(self, context):
58         layout = self.layout
59         layout.prop(self, "factor", text="Fac" if self.relative else "Dist")
60         sub = layout.row()
61         sub.prop(self, "relative")
62         sub.prop(self, "dissolve")
63         if not self.dissolve:
64             layout.prop(self, "displace")
65
66     def execute(self, context):
67         ob = context.active_object
68         me = ob.data
69         bm = bmesh.from_edit_mesh(me)
70
71         bm.select_flush(True)
72
73         fac = self.factor
74         rel = self.relative
75         dissolve = self.dissolve
76         displace = self.displace
77
78         for v in bm.verts:
79             v.tag = False
80
81         # Loop over edges to find those with both verts selected
82         for e in bm.edges[:]:
83             e.tag = e.select
84             if not e.select:
85                 continue
86             elen = e.calc_length()
87             val = fac if rel else fac / elen
88             val = min(val, 0.5)
89             # Loop over the verts of the edge to split
90             for v in e.verts:
91                 #if val == 0.5 and e.other_vert(v).tag:
92                 #    continue
93                 en, vn = bmesh.utils.edge_split(e, v, val)
94                 en.tag = vn.tag = True
95                 val = 1.0 if val == 1.0 else val / (1.0 - val)
96
97         # Get all verts which are selected but not created previously
98         verts = [v for v in bm.verts if v.select and not v.tag]
99
100         # Loop over all verts to split their linked edges
101         for v in verts:
102             for e in v.link_edges[:]:
103                 if e.tag:
104                     continue
105                 elen = e.calc_length()
106                 val = fac if rel else fac / elen
107                 bmesh.utils.edge_split(e, v, val)
108
109             # Loop over all the loops of the vert
110             for l in v.link_loops:
111                 # Split the face
112                 bmesh.utils.face_split(l.face,
113                                        l.link_loop_next.vert,
114                                        l.link_loop_prev.vert)
115
116             # Remove the vert or displace otherwise
117             if dissolve:
118                 bmesh.utils.vert_dissolve(v)
119             else:
120                 v.co += displace * v.normal
121
122         me.calc_tessface()
123
124         return {'FINISHED'}
125
126
127 def register():
128     bpy.utils.register_module(__name__)
129
130
131 def unregister():
132     bpy.utils.unregister_module(__name__)
133
134
135 if __name__ == "__main__":
136     register()