-
Notifications
You must be signed in to change notification settings - Fork 7
/
__init__.py
230 lines (175 loc) · 6.36 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# SuperPoke created by Midge "Mantissa" Sinnaeve (mantissa.xyz)
# Downloaded form https://github.com/mantissa-/RandoMesh
# Licensed under GPLv3
bl_info = {
"name": "SuperPoke",
"author": "Midge \"Mantissa\" Sinnaeve",
"version": (0, 0, 6),
"blender": (2, 80, 0),
"location": "View3D > Tool Shelf > SuperPoke Tab",
"description": "Create superpoked geometry",
"wiki_url": "https://github.com/mantissa-/SuperPoke",
"category": "3D View",
"warning": "You might have fun"
}
import bpy, bmesh
from bpy.props import (IntProperty, FloatProperty, BoolProperty, PointerProperty)
from bpy.types import (Panel, Operator, PropertyGroup)
#------------#
# PROPERTIES #
#------------#
class SuperPokeProps(PropertyGroup):
bool_keep_original : BoolProperty(
name = "Keep Original",
description = "Keep a copy of the original mesh",
default = True
)
bool_apply_modifiers : BoolProperty(
name = "Apply Modifiers",
description = "Apply the current modifers to object before processing",
default = True
)
int_iterations : IntProperty(
name = "Iterations",
description = "SuperPoke Iterations",
default = 6,
min = 1,
max = 15,
soft_max = 8
)
fl_poke_offset : FloatProperty(
name = "Poke Offset:",
description = "Set base poke offset, multiplier applied per iteration",
default = -0.5,
soft_min = -1,
soft_max = 1,
min = -2.0,
max = 2.0,
precision = 2
)
fl_poke_multiplier : FloatProperty(
name = "Offset Multiplier:",
description = "Set base poke offset, halved per iteration",
default = 0.5,
soft_max = 1.0,
min = 0,
max = 2.0,
precision = 2
)
bool_poke_alternate : BoolProperty(
name = "Alternate Offset",
description = "Alternate the poke offset for a recursive look",
default = True
)
bool_shape_keys : BoolProperty(
name = "Create Shape Keys (SLOW)",
description = "Create a shape key to animate each iteration",
default = False
)
#----#
# UI #
#----#
class SuperPokePanel(bpy.types.Panel):
# Creates a Panel in the sidebar
bl_label = "SuperPoke"
bl_idname = "OBJECT_PT_SuperPoke"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_context = "objectmode"
bl_category = "SuperPoke"
def draw(self, context):
layout = self.layout
scene = context.scene
col = layout.column(align=False)
row = col.row(align=True)
col.prop(scene.sp_props, "bool_keep_original")
col.prop(scene.sp_props, "bool_apply_modifiers")
col.prop(scene.sp_props, "int_iterations")
col.prop(scene.sp_props, "fl_poke_offset")
col.prop(scene.sp_props, "fl_poke_multiplier")
col.prop(scene.sp_props, "bool_poke_alternate")
col.prop(scene.sp_props, "bool_shape_keys")
obj = bpy.context.object
if obj != None and obj.type in ['MESH']:
spp = bpy.context.scene.sp_props
iter = spp.int_iterations
me = bpy.context.object.data
fpc = ((len(me.polygons))*4)*(3**(iter-1))
col.separator()
col.separator()
col.label(text=" Final Polycount: " + "{:,}".format(fpc))
col.separator()
col.separator()
sub = col.row()
sub.scale_y = 2.0
sub.operator("wm.superpoke")
#----------#
# OPERATOR #
#----------#
class SuperPoke(bpy.types.Operator):
# SuperPoke Operator
bl_idname = "wm.superpoke"
bl_label = "POKE THAT SHIT"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
spp = bpy.context.scene.sp_props
off = spp.fl_poke_offset
iter = spp.int_iterations
keep = spp.bool_keep_original
apply = spp.bool_apply_modifiers
mult = spp.fl_poke_multiplier
alt = spp.bool_poke_alternate
keys = spp.bool_shape_keys
if keep:
ori = bpy.context.active_object
bpy.ops.object.duplicate(linked=False)
ori.hide_viewport = True
ori.hide_render = True
if apply:
bpy.ops.object.convert(target='MESH')
me = bpy.context.object.data
if keys:
bpy.ops.object.shape_key_add(from_mix=True)
for i in range(iter):
bpy.ops.object.shape_key_add(from_mix=True)
bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(me)
for f in bm.faces:
f.select = True
bmesh.ops.poke(bm, faces=bm.faces, offset=off, use_relative_offset=True)
bmesh.update_edit_mesh(me)
if(alt):
off *= -mult
else:
off *= mult
bpy.ops.object.mode_set(mode='OBJECT')
else:
bm = bmesh.new() # create an empty BMesh
bm.from_mesh(me) # fill it in from a Mesh
for i in range(iter):
bmesh.ops.poke(bm, faces=bm.faces, offset=off, use_relative_offset=True)
if(alt):
off *= -mult
else:
off *= mult
bm.to_mesh(me) # write the bmesh back to mesh
bm.free()
me.update() # update obj in viewport
return {'FINISHED'}
#----------#
# REGISTER #
#----------#
def register():
bpy.utils.register_class(SuperPokePanel)
bpy.utils.register_class(SuperPoke)
bpy.utils.register_class(SuperPokeProps)
bpy.types.Scene.sp_props = PointerProperty(type=SuperPokeProps)
def unregister():
bpy.utils.unregister_class(SuperPokePanel)
bpy.utils.unregister_class(SuperPoke)
bpy.utils.unregister_class(SuperPokeProps)
del bpy.types.Scene.sp_props
if __name__ == "__main__":
register()