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",
25 "blender": (2, 80, 0),
26 "location": "View3D > Tool Shelf",
35 from bpy
.types
import Operator
36 from bpy
.props
import (
45 # define the functions
46 def solidify_split(self
, list_0
):
48 loc_random
= self
.loc_random
49 random_dist
= self
.random_dist
50 distance
= self
.distance
51 thickness
= self
.thickness
52 normal_extr
= self
.normal_extr
57 bm
.faces
.ensure_lookup_table()
63 d
= random_dist
* random
.randrange(0, 10)
69 bm
.verts
.ensure_lookup_table()
70 v
= bm
.verts
[vi
.index
]
72 if normal_extr
== 'opt0':
73 p1
= (v
.co
).copy() + ((f
.normal
).copy() * d
) # out
74 p2
= (v
.co
).copy() + ((f
.normal
).copy() * (d
- thickness
)) # in
75 elif normal_extr
== 'opt1':
76 ang
= ((v
.normal
).copy()).angle((f
.normal
).copy())
77 h
= thickness
/ cos(ang
)
78 p1
= (v
.co
).copy() + ((f
.normal
).copy() * d
)
79 p2
= p1
+ (-h
* (f
.normal
).copy())
88 # add new faces, allows faces with more than 4 verts
91 k
= bm
.faces
.new(list_1
)
95 vseq
= list_1
[i
], list_2
[i
], list_2
[j
], list_1
[j
]
96 k
= bm
.faces
.new(vseq
)
100 k
= bm
.faces
.new(list_2
)
102 bpy
.ops
.mesh
.normals_make_consistent(inside
=False)
104 bmesh
.update_edit_mesh(self
.me
, True)
107 class MESH_OT_split_solidify(Operator
):
108 bl_idname
= "mesh.split_solidify"
109 bl_label
= "Split Solidify"
110 bl_description
= "Split and Solidify selected Faces"
111 bl_options
= {"REGISTER", "UNDO"}
113 distance
: FloatProperty(
115 description
="Distance of the splitted Faces to the original geometry",
117 min=-100.0, max=100.0,
121 thickness
: FloatProperty(
123 description
="Thickness of the splitted Faces",
125 min=-100.0, max=100.0,
129 random_dist
: FloatProperty(
131 description
="Randomization factor of the splitted Faces' location",
137 loc_random
: BoolProperty(
139 description
="Randomize the locations of splitted faces",
142 del_original
: BoolProperty(
143 name
="Delete original faces",
146 normal_extr
: EnumProperty(
147 items
=(('opt0', "Face", "Solidify along Face Normals"),
148 ('opt1', "Vertex", "Solidify along Vertex Normals")),
153 def draw(self
, context
):
155 layout
.label(text
="Normal:")
156 layout
.prop(self
, "normal_extr", expand
=True)
157 layout
.prop(self
, "loc_random")
159 if not self
.loc_random
:
160 layout
.label(text
="Distance:")
161 layout
.prop(self
, "distance")
162 elif self
.loc_random
:
163 layout
.label(text
="Random distance:")
164 layout
.prop(self
, "random_dist")
166 layout
.label(text
="Thickness:")
167 layout
.prop(self
, "thickness")
168 layout
.prop(self
, "del_original")
170 def execute(self
, context
):
171 obj
= bpy
.context
.active_object
173 self
.bm
= bmesh
.from_edit_mesh(self
.me
)
176 list_0
= [f
.index
for f
in self
.bm
.faces
if f
.select
]
179 self
.report({'WARNING'},
180 "No suitable selection found. Operation cancelled")
184 elif len(list_0
) != 0:
185 solidify_split(self
, list_0
)
186 context
.tool_settings
.mesh_select_mode
= (True, True, True)
187 if self
.del_original
:
188 bpy
.ops
.mesh
.delete(type='FACE')
196 bpy
.utils
.register_class(MESH_OT_split_solidify
)
200 bpy
.utils
.unregister_class(MESH_OT_split_solidify
)
203 if __name__
== "__main__":