-
Notifications
You must be signed in to change notification settings - Fork 0
/
autolow_op.py
197 lines (169 loc) · 6.46 KB
/
autolow_op.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
import bpy
from bpy.types import Operator
from bpy_extras.io_utils import ImportHelper
from .autolow_main import remesh_process, uv_unwrap_process, bake_process
from .autolow_utils import get_props, save, copy_obj
import pathlib
class AUTOLOW_OT_start(Operator):
bl_idname = "autolow.start"
bl_label = "Start Process"
bl_description = "Start process"
def execute(self, context):
props = get_props()
if not save():
self.report({"WARNING"}, "Save file before activating autosave")
return {"CANCELLED"}
if props.is_image_saved:
path = props.image_path
default = ".\\Autolow\\"
if path != default:
# check if image path exists
if not pathlib.Path(path).is_dir():
self.report(
{"ERROR"},
(
"The set path doesn't exist."
" Path has been reset to the default"
),
)
props.image_path = default
return {"CANCELLED"}
elif bpy.data.filepath == "":
# check if file has been saved
self.report(
{"ERROR"},
(
"Image path unknown."
" Either save the blender file or set the path in settings"
),
)
return {"CANCELLED"}
autolow_queue = context.scene.queue
objects = []
if len(autolow_queue) > 0:
for object in autolow_queue:
current = bpy.data.objects[object.name]
current.select_set(False)
objects.append(current)
else:
active_object = bpy.context.active_object
if not active_object:
self.report({"ERROR"}, "No object selected")
return {"CANCELLED"}
if active_object.type != "MESH":
self.report({"ERROR"}, "Object must be a mesh")
return {"CANCELLED"}
if len(active_object.data.polygons) == 0:
self.report({"ERROR"}, "The mesh must have more than 0 polygons")
return {"CANCELLED"}
objects.append(active_object)
for highpoly in objects:
highpoly.hide_set(False)
lowpoly = copy_obj(highpoly)
lowpoly.name = highpoly.name + "_LP"
# shade smooth and turn off autosmooth
bpy.ops.object.shade_smooth()
highpoly.data.use_auto_smooth = False
lowpoly.data.use_auto_smooth = False
remesh_process(highpoly, lowpoly)
if (props.unwrap_method != "NONE" or props.bake_method != "NONE") and len(
lowpoly.data.polygons
) == 0:
self.report({"ERROR"}, "The mesh has 0 polygons after remeshing")
return {"CANCELLED"}
uv_unwrap_process()
bake_process(highpoly, lowpoly)
highpoly.hide_set(True)
lowpoly.modifiers.clear()
if props.autosave_after:
save()
# remove all items from queue
context.scene.queue.clear()
return {"FINISHED"}
class AUTOLOW_OT_set_workflow(Operator):
bl_idname = "autolow.set_workflow"
bl_label = "Set Workflow"
bl_description = (
"Change addon settings to the workflow selected. "
"This is not necessary when using the addon and is only a shortcut. "
"If you would like to customize the settings, this panel can be ignored"
)
def execute(self, context):
props = get_props()
workflow = props.workflow
remesher = props.remesher
if workflow == "FULL":
if remesher == "NONE":
props.remesher = "VOXEL"
props.unwrap_method = "SMART"
props.bake_method = "TRANSFER"
elif workflow == "TRANSFER_BAKE":
props.remesher = "NONE"
props.unwrap_method = "SMART"
props.bake_method = "TRANSFER"
elif workflow == "ACTIVE_BAKE":
props.remesher = "NONE"
props.unwrap_method = "SMART"
props.bake_method = "ACTIVE"
else:
props.remesher = "NONE"
props.unwrap_method = "NONE"
props.bake_method = "NONE"
return {"FINISHED"}
class AUTOLOW_OT_open_filebrowser(Operator, ImportHelper):
bl_idname = "autolow.open_filebrowser"
bl_label = "Set Path"
bl_description = (
"Set path of saved images."
" If path is not set, images will be saved in a folder called 'AutoLow'"
)
def execute(self, context):
new_path = self.filepath
if pathlib.Path(new_path).is_dir():
get_props().image_path = new_path
self.report({"INFO"}, "Path: " + new_path)
else:
self.report({"ERROR"}, "The path must end with a folder")
return {"CANCELLED"}
return {"FINISHED"}
class AUTOLOW_OT_queue_actions(Operator):
bl_idname = "queue.actions"
bl_label = "Actions"
bl_description = "Add, remove, move up, move down"
bl_options = {"REGISTER"}
action: bpy.props.EnumProperty(
items=(
("UP", "Up", ""),
("DOWN", "Down", ""),
("REMOVE", "Remove", ""),
("ADD", "Add", ""),
)
)
def invoke(self, context, event):
scn = context.scene
idx = scn.queue_index
try:
item = scn.queue[idx]
except IndexError:
pass
else:
if self.action == "DOWN" and idx < len(scn.queue) - 1:
scn.queue.move(idx, idx + 1)
scn.queue_index += 1
elif self.action == "UP" and idx >= 1:
scn.queue.move(idx, idx - 1)
scn.queue_index -= 1
elif self.action == "REMOVE":
scn.queue_index -= 1
scn.queue.remove(idx)
if self.action == "ADD":
if context.object.type != "MESH":
self.report({"ERROR"}, "Object must be a mesh")
elif context.object:
item = scn.queue.add()
item.name = context.object.name
item.obj_id = len(scn.queue)
scn.queue_index = len(scn.queue) - 1
else:
self.report({"INFO"}, "Nothing selected in the Viewport")
return {"FINISHED"}