Sun Position: fix error in HDRI mode when no env tex is selected
[blender-addons.git] / mesh_tools / split_solidify.py
blob116c7acff7fd77d1122e5602c231f455541e2041
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 bl_info = {
4 "name": "Split Solidify",
5 "author": "zmj100, updated by zeffii to BMesh",
6 "version": (0, 1, 2),
7 "blender": (2, 80, 0),
8 "location": "View3D > Tool Shelf",
9 "description": "",
10 "warning": "",
11 "doc_url": "",
12 "category": "Mesh",
15 import bpy
16 import bmesh
17 from bpy.types import Operator
18 from bpy.props import (
19 EnumProperty,
20 FloatProperty,
21 BoolProperty,
23 import random
24 from math import cos
27 # define the functions
28 def solidify_split(self, list_0):
30 loc_random = self.loc_random
31 random_dist = self.random_dist
32 distance = self.distance
33 thickness = self.thickness
34 normal_extr = self.normal_extr
36 bm = self.bm
38 for fi in list_0:
39 bm.faces.ensure_lookup_table()
40 f = bm.faces[fi]
41 list_1 = []
42 list_2 = []
44 if loc_random:
45 d = random_dist * random.randrange(0, 10)
46 elif not loc_random:
47 d = distance
49 # add new vertices
50 for vi in f.verts:
51 bm.verts.ensure_lookup_table()
52 v = bm.verts[vi.index]
54 if normal_extr == 'opt0':
55 p1 = (v.co).copy() + ((f.normal).copy() * d) # out
56 p2 = (v.co).copy() + ((f.normal).copy() * (d - thickness)) # in
57 elif normal_extr == 'opt1':
58 ang = ((v.normal).copy()).angle((f.normal).copy())
59 h = thickness / cos(ang)
60 p1 = (v.co).copy() + ((f.normal).copy() * d)
61 p2 = p1 + (-h * (f.normal).copy())
63 v1 = bm.verts.new(p1)
64 v2 = bm.verts.new(p2)
65 v1.select = False
66 v2.select = False
67 list_1.append(v1)
68 list_2.append(v2)
70 # add new faces, allows faces with more than 4 verts
71 n = len(list_1)
73 k = bm.faces.new(list_1)
74 k.select = False
75 for i in range(n):
76 j = (i + 1) % n
77 vseq = list_1[i], list_2[i], list_2[j], list_1[j]
78 k = bm.faces.new(vseq)
79 k.select = False
81 list_2.reverse()
82 k = bm.faces.new(list_2)
83 k.select = False
84 bpy.ops.mesh.normals_make_consistent(inside=False)
86 bmesh.update_edit_mesh(self.me, loop_triangles=True)
89 class MESH_OT_split_solidify(Operator):
90 bl_idname = "mesh.split_solidify"
91 bl_label = "Split Solidify"
92 bl_description = "Split and Solidify selected Faces"
93 bl_options = {"REGISTER", "UNDO"}
95 distance: FloatProperty(
96 name="",
97 description="Distance of the splitted Faces to the original geometry",
98 default=0.4,
99 min=-100.0, max=100.0,
100 step=1,
101 precision=3
103 thickness: FloatProperty(
104 name="",
105 description="Thickness of the splitted Faces",
106 default=0.04,
107 min=-100.0, max=100.0,
108 step=1,
109 precision=3
111 random_dist: FloatProperty(
112 name="",
113 description="Randomization factor of the splitted Faces' location",
114 default=0.06,
115 min=-10.0, max=10.0,
116 step=1,
117 precision=3
119 loc_random: BoolProperty(
120 name="Random",
121 description="Randomize the locations of splitted faces",
122 default=False
124 del_original: BoolProperty(
125 name="Delete original faces",
126 default=True
128 normal_extr: EnumProperty(
129 items=(('opt0', "Face", "Solidify along Face Normals"),
130 ('opt1', "Vertex", "Solidify along Vertex Normals")),
131 name="Normal",
132 default='opt0'
135 def draw(self, context):
136 layout = self.layout
137 layout.label(text="Normal:")
138 layout.prop(self, "normal_extr", expand=True)
139 layout.prop(self, "loc_random")
141 if not self.loc_random:
142 layout.label(text="Distance:")
143 layout.prop(self, "distance")
144 elif self.loc_random:
145 layout.label(text="Random distance:")
146 layout.prop(self, "random_dist")
148 layout.label(text="Thickness:")
149 layout.prop(self, "thickness")
150 layout.prop(self, "del_original")
152 def execute(self, context):
153 obj = bpy.context.active_object
154 self.me = obj.data
155 self.bm = bmesh.from_edit_mesh(self.me)
156 self.me.update()
158 list_0 = [f.index for f in self.bm.faces if f.select]
160 if len(list_0) == 0:
161 self.report({'WARNING'},
162 "No suitable selection found. Operation cancelled")
164 return {'CANCELLED'}
166 elif len(list_0) != 0:
167 solidify_split(self, list_0)
168 context.tool_settings.mesh_select_mode = (True, True, True)
169 if self.del_original:
170 bpy.ops.mesh.delete(type='FACE')
171 else:
172 pass
174 return {'FINISHED'}
177 def register():
178 bpy.utils.register_class(MESH_OT_split_solidify)
181 def unregister():
182 bpy.utils.unregister_class(MESH_OT_split_solidify)
185 if __name__ == "__main__":
186 register()