1 # -*- coding: utf-8 -*-
3 # ##### BEGIN GPL LICENSE BLOCK #####
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software Foundation,
17 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 # ##### END GPL LICENSE BLOCK #####
22 "name": "Split Solidify",
23 "author": "zmj100, updated by zeffii to BMesh",
26 "location": "View3D > Tool Shelf",
34 from bpy
.types
import Operator
35 from bpy
.props
import (
44 # define the functions
45 def solidify_split(self
, list_0
):
47 loc_random
= self
.loc_random
48 random_dist
= self
.random_dist
49 distance
= self
.distance
50 thickness
= self
.thickness
51 normal_extr
= self
.normal_extr
56 bm
.faces
.ensure_lookup_table()
62 d
= random_dist
* random
.randrange(0, 10)
68 bm
.verts
.ensure_lookup_table()
69 v
= bm
.verts
[vi
.index
]
71 if normal_extr
== 'opt0':
72 p1
= (v
.co
).copy() + ((f
.normal
).copy() * d
) # out
73 p2
= (v
.co
).copy() + ((f
.normal
).copy() * (d
- thickness
)) # in
74 elif normal_extr
== 'opt1':
75 ang
= ((v
.normal
).copy()).angle((f
.normal
).copy())
76 h
= thickness
/ cos(ang
)
77 p1
= (v
.co
).copy() + ((f
.normal
).copy() * d
)
78 p2
= p1
+ (-h
* (v
.normal
).copy())
87 # add new faces, allows faces with more than 4 verts
90 k
= bm
.faces
.new(list_1
)
94 vseq
= list_1
[i
], list_2
[i
], list_2
[j
], list_1
[j
]
95 k
= bm
.faces
.new(vseq
)
99 k
= bm
.faces
.new(list_2
)
101 bpy
.ops
.mesh
.normals_make_consistent(inside
=False)
103 bmesh
.update_edit_mesh(self
.me
, True)
106 class MESH_OT_split_solidify(Operator
):
107 bl_idname
= "mesh.split_solidify"
108 bl_label
= "Split Solidify"
109 bl_description
= "Split and Solidify selected Faces"
110 bl_options
= {"REGISTER", "UNDO"}
112 distance
= FloatProperty(
114 description
="Distance of the splitted Faces to the original geometry",
116 min=-100.0, max=100.0,
120 thickness
= FloatProperty(
122 description
="Thickness of the splitted Faces",
124 min=-100.0, max=100.0,
128 random_dist
= FloatProperty(
130 description
="Randomization factor of the splitted Faces' location",
136 loc_random
= BoolProperty(
138 description
="Randomize the locations of splitted faces",
141 del_original
= BoolProperty(
142 name
="Delete original faces",
145 normal_extr
= EnumProperty(
146 items
=(('opt0', "Face", "Solidify along Face Normals"),
147 ('opt1', "Vertex", "Solidify along Vertex Normals")),
152 def draw(self
, context
):
154 layout
.label("Normal:")
155 layout
.prop(self
, "normal_extr", expand
=True)
156 layout
.prop(self
, "loc_random")
158 if not self
.loc_random
:
159 layout
.label("Distance:")
160 layout
.prop(self
, "distance")
161 elif self
.loc_random
:
162 layout
.label("Random distance:")
163 layout
.prop(self
, "random_dist")
165 layout
.label("Thickness:")
166 layout
.prop(self
, "thickness")
167 layout
.prop(self
, "del_original")
169 def execute(self
, context
):
170 obj
= bpy
.context
.active_object
172 self
.bm
= bmesh
.from_edit_mesh(self
.me
)
175 list_0
= [f
.index
for f
in self
.bm
.faces
if f
.select
]
178 self
.report({'WARNING'},
179 "No suitable selection found. Operation cancelled")
183 elif len(list_0
) != 0:
184 solidify_split(self
, list_0
)
185 context
.tool_settings
.mesh_select_mode
= (True, True, True)
186 if self
.del_original
:
187 bpy
.ops
.mesh
.delete(type='FACE')
195 bpy
.utils
.register_class(MESH_OT_split_solidify
)
199 bpy
.utils
.unregister_class(MESH_OT_split_solidify
)
202 if __name__
== "__main__":