-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathproperties.py
365 lines (313 loc) · 12.4 KB
/
properties.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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
import os
import bpy
from bpy.props import (
StringProperty,
FloatProperty,
IntProperty,
CollectionProperty,
EnumProperty,
)
from .utils import update_uv_maps, get_mesh_objects
class LoRAModel(bpy.types.PropertyGroup):
path: StringProperty(
name="LoRA Path", description="Path to the LoRA model file", subtype="FILE_PATH"
)
strength: FloatProperty(
name="Strength LoRA",
description="Strength of the LoRA model",
default=1.0,
min=0.0,
max=2.0,
)
def update_paths(self, context):
if context.scene.sd_version == "sd15":
context.scene.checkpoint_path = "runwayml/stable-diffusion-v1-5"
context.scene.canny_controlnet_path = "lllyasviel/sd-controlnet-canny"
context.scene.normal_controlnet_path = "lllyasviel/sd-controlnet-normal"
context.scene.depth_controlnet_path = "lllyasviel/sd-controlnet-depth"
elif context.scene.sd_version == "sdxl":
context.scene.checkpoint_path = "stabilityai/stable-diffusion-xl-base-1.0"
context.scene.canny_controlnet_path = "diffusers/controlnet-canny-sdxl-1.0"
context.scene.normal_controlnet_path = "xinsir/controlnet-union-sdxl-1.0"
context.scene.depth_controlnet_path = "diffusers/controlnet-depth-sdxl-1.0"
def update_loras(self, context):
scene = context.scene
num_loras = scene.num_loras
lora_models = scene.lora_models
while len(lora_models) < num_loras:
lora_models.add()
while len(lora_models) > num_loras:
lora_models.remove(len(lora_models) - 1)
def update_ipadapter_image(self, context):
"""Ensure the selected image from the preview window is set in scene.ipadapter_image."""
image = context.scene.ipadapter_image
if image:
image_data = bpy.data.images.get(image.name)
# Only set the image if it's not already correctly set to prevent recursion
if image_data != context.scene.ipadapter_image:
context.scene.ipadapter_image = image_data
def update_input_image(self, context):
"""Ensure the selected image from the preview window is set in scene.input_image."""
image = context.scene.input_texture_path
if image:
image_data = bpy.data.images.get(image.name)
# Only set the image if it's not already correctly set to prevent recursion
if image_data != context.scene.input_texture_path:
context.scene.input_texture_path = image_data
def update_output_path(self, context):
if self.output_path.startswith("//"):
self.output_path = bpy.path.abspath(self.output_path)
def register_properties():
try:
bpy.utils.register_class(LoRAModel)
except Exception as e:
print(
f"Warning: {LoRAModel.__name__} was not registered or failed to register. {e}"
)
bpy.types.Scene.my_mesh_object = EnumProperty(
name="Mesh Object",
items=get_mesh_objects,
description="Select the mesh object you want to use texturize.",
)
bpy.types.Scene.my_uv_map = EnumProperty(
name="UV Map",
items=update_uv_maps,
description="Select the UV map you want to use for the final texture.",
)
bpy.types.Scene.my_prompt = StringProperty(
name="Prompt", description="Define what the object should be"
)
bpy.types.Scene.my_negative_prompt = StringProperty(
name="Negative Prompt", description="Define what the object should NOT be"
)
bpy.types.Scene.guidance_scale = FloatProperty(
name="Guidance Scale",
description="A higher guidance scale value encourages the model to generate images closely linked to the text `prompt` at the expense of lower image quality. Guidance scale is enabled when `guidance_scale > 1`.",
default=10.0,
min=0.0,
max=30.0, # Ensure this is a float value for finer control
)
bpy.types.Scene.operation_mode = EnumProperty(
name="Operation Mode",
description="The complexity, polycount and detail of the selected mesh.",
items=[
(
"PARALLEL_IMG",
"Parallel Processing on Images",
"Generate textures by merging images in parallel.",
),
(
"SEQUENTIAL_IMG",
"Sequential Processing on Images",
"Generate textures by merging images sequentially.",
),
# (
# "PARALLEL_LATENT",
# "Parallel Processing on Latents",
# "Generate textures by merging latents in parallel.",
# ),
# (
# "SEQUENTIAL_LATENT",
# "Sequential Processing on Latents",
# "Generate textures by repeatedly merging latents sequentially.",
# )
# # (
# # "TEXTURE2TEXTURE_ENHANCEMENT",
# # "Texture2Texture Enhancement",
# # "Enhance textures using input textures.",
# # ),
],
# update=update_operation_mode, # Add the update function
)
bpy.types.Scene.num_inference_steps = IntProperty(
name="Number of Inference Steps",
description="Number of inference steps to run the model for",
default=50,
min=1,
)
bpy.types.Scene.denoise_strength = FloatProperty(
name="Denoise Strength",
description="Strength of denoise for Stable Diffusion",
default=1.0,
min=0.0,
max=1.0, # Ensure this is a float value for finer control
)
bpy.types.Scene.texture_resolution = EnumProperty(
name="Texture Resolution",
description="The final texture resolution of the selected mesh object.",
items=[
("512", "512x512", ""),
("1024", "1024x1024", ""),
("2048", "2048x2048", ""),
("4096", "4096x4096", ""),
],
default="1024",
)
bpy.types.Scene.render_resolution = EnumProperty(
name="Render Resolution",
description="The Render resolution used in Stable Diffusion.",
items=[
("1024", "1024x1024", ""),
("2048", "2048x2048", ""),
("4096", "4096x4096", ""),
("8192", "8192x8192", ""),
],
default="2048",
)
bpy.types.Scene.output_path = StringProperty(
name="Output Path",
description="Directory to store the resulting texture and temporary files",
subtype="DIR_PATH",
default="",
update=update_output_path,
)
bpy.types.Scene.input_texture_path = bpy.props.PointerProperty(
type=bpy.types.Image,
name="Input Texture",
description="Select an image to use as input texture",
update=update_input_image, # Attach the update callback
)
bpy.types.Scene.mesh_complexity = EnumProperty(
name="Mesh Complexity",
description="How complex is the mesh.",
items=[("LOW", "Low", ""), ("MEDIUM", "Medium", ""), ("HIGH", "High", "")],
)
bpy.types.Scene.num_cameras = EnumProperty(
name="Cameras",
description="Number of camera viewpoints. 4 Cameras for a quick process, 16 for more details.",
items=[
("4", "4 Camera Viewpoints", ""),
("9", "9 Camera Viewpoints", ""),
("16", "16 Camera Viewpoints", ""),
],
)
bpy.types.Scene.texture_seed = IntProperty(
name="Seed",
description="Seed for randomization to ensure repeatable results",
default=0,
min=0,
)
# bpy.types.Scene.checkpoint_path = StringProperty(
# name="Checkpoint Path",
# description="Optional path to the Stable Diffusion base model checkpoint",
# subtype="FILE_PATH",
# )
bpy.types.Scene.num_loras = IntProperty(
name="Number of LoRAs",
description="Number of additional LoRA models to use",
default=0,
min=0,
update=update_loras,
)
bpy.types.Scene.lora_models = CollectionProperty(type=LoRAModel)
# IPAdapter-specific properties
bpy.types.Scene.use_ipadapter = bpy.props.BoolProperty(
name="Use IPAdapter",
description="Activate IPAdapter for texture generation",
default=False,
)
bpy.types.Scene.ipadapter_image = bpy.props.PointerProperty(
type=bpy.types.Image,
name="IPAdapter Image",
description="Select an image to use for IPAdapter",
update=update_ipadapter_image, # Attach the update callback
)
bpy.types.Scene.ipadapter_strength = bpy.props.FloatProperty(
name="IPAdapter Strength",
description="This method controls the amount of text or image conditioning to apply to the model. A value of 1.0 means the model is only conditioned on the image prompt. Lowering this value encourages the model to produce more diverse images, but they may not be as aligned with the image prompt. Typically, a value of 0.5 achieves a good balance between the two prompt types and produces good results.",
default=0.5,
min=0.0,
soft_max=1.0,
)
# Advanced settings
bpy.types.Scene.sd_version = EnumProperty(
name="Stable Diffusion Version",
description="Select the version of Stable Diffusion to use",
items=[
("sd15", "Stable Diffusion 1.5", "Use Stable Diffusion 1.5 models"),
("sdxl", "Stable Diffusion XL", "Use Stable Diffusion XL models"),
],
default="sd15",
update=update_paths,
)
bpy.types.Scene.checkpoint_path = StringProperty(
name="Checkpoint Path",
description="Optional path to the Stable Diffusion base model checkpoint",
subtype="FILE_PATH",
default="runwayml/stable-diffusion-v1-5",
)
bpy.types.Scene.custom_sd_resolution = IntProperty(
name="Custom SD Resolution",
description="Custom resolution for Stable Diffusion",
default=0,
min=0,
)
bpy.types.Scene.canny_controlnet_path = StringProperty(
name="Canny ControlNet Path",
description="Optional path to the Canny ControlNet checkpoint",
subtype="FILE_PATH",
default="lllyasviel/sd-controlnet-canny",
)
bpy.types.Scene.normal_controlnet_path = StringProperty(
name="Normal ControlNet Path",
description="Optional path to the Normal ControlNet checkpoint",
subtype="FILE_PATH",
default="lllyasviel/sd-controlnet-normal",
)
bpy.types.Scene.depth_controlnet_path = StringProperty(
name="Depth ControlNet Path",
description="Optional path to the Depth ControlNet checkpoint",
subtype="FILE_PATH",
default="lllyasviel/sd-controlnet-depth",
)
bpy.types.Scene.canny_controlnet_strength = FloatProperty(
name="Canny ControlNet Strength",
description="Strength of the Canny ControlNet",
default=0.9,
min=0.0,
max=1.0,
)
bpy.types.Scene.normal_controlnet_strength = FloatProperty(
name="Normal ControlNet Strength",
description="Strength of the Normal ControlNet",
default=0.9,
min=0.0,
max=1.0,
)
bpy.types.Scene.depth_controlnet_strength = FloatProperty(
name="Depth ControlNet Strength",
description="Strength of the Depth ControlNet",
default=1.0,
min=0.0,
max=1.0,
)
def unregister_properties():
bpy.utils.unregister_class(LoRAModel)
del bpy.types.Scene.num_loras
del bpy.types.Scene.lora_models
del bpy.types.Scene.use_ipadapter
del bpy.types.Scene.ipadapter_image
del bpy.types.Scene.ipadapter_strength
del bpy.types.Scene.my_mesh_object
del bpy.types.Scene.my_uv_map
del bpy.types.Scene.my_prompt
del bpy.types.Scene.my_negative_prompt
del bpy.types.Scene.guidance_scale
del bpy.types.Scene.mesh_complexity
del bpy.types.Scene.texture_resolution
del bpy.types.Scene.render_resolution
del bpy.types.Scene.operation_mode
del bpy.types.Scene.denoise_strength
del bpy.types.Scene.output_path
del bpy.types.Scene.texture_seed
del bpy.types.Scene.num_inference_steps
del bpy.types.Scene.num_cameras
del bpy.types.Scene.input_texture_path
del bpy.types.Scene.sd_version
del bpy.types.Scene.checkpoint_path
del bpy.types.Scene.canny_controlnet_path
del bpy.types.Scene.normal_controlnet_path
del bpy.types.Scene.depth_controlnet_path
del bpy.types.Scene.canny_controlnet_strength
del bpy.types.Scene.normal_controlnet_strength
del bpy.types.Scene.depth_controlnet_strength