2022-02-02 15:37:42 +00:00
|
|
|
bl_info = {
|
2022-05-31 12:19:24 +00:00
|
|
|
"name": "Blend_My_NFTs",
|
2022-08-24 17:04:20 +00:00
|
|
|
"author": "Torrin Leonard, This Cozy Studio Inc.",
|
|
|
|
"version": (4, 5, 1),
|
2022-08-11 13:48:01 +00:00
|
|
|
"blender": (3, 2, 2),
|
2022-02-02 15:37:42 +00:00
|
|
|
"location": "View3D",
|
2022-08-24 17:04:20 +00:00
|
|
|
"description": "A free and opensource Blender add-on that enables you to create thousands of unique images, "
|
|
|
|
"animations, and 3D models.",
|
2022-08-11 13:48:01 +00:00
|
|
|
"support": "COMMUNITY",
|
|
|
|
"doc_url": "https://github.com/torrinworx/Blend_My_NFTs",
|
|
|
|
"tracker_url": "https://github.com/torrinworx/Blend_My_NFTs/issues/new",
|
2022-02-02 15:37:42 +00:00
|
|
|
"category": "Development",
|
|
|
|
}
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
BMNFTS_VERSION = "v4.5.1"
|
2022-08-28 02:03:16 +00:00
|
|
|
LAST_UPDATED = "10:03PM, Aug 27th, 2022"
|
2022-05-25 23:58:33 +00:00
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
# ======== Import handling ======== #
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
# Blender modules:
|
2022-02-02 15:37:42 +00:00
|
|
|
import bpy
|
2022-02-03 00:40:05 +00:00
|
|
|
from bpy.app.handlers import persistent
|
2022-08-27 23:41:41 +00:00
|
|
|
from bpy.props import (IntProperty, BoolProperty, CollectionProperty)
|
|
|
|
|
2022-08-11 13:48:01 +00:00
|
|
|
# Python modules:
|
2022-02-02 15:37:42 +00:00
|
|
|
import os
|
2022-04-11 17:20:00 +00:00
|
|
|
import sys
|
2022-03-26 03:47:54 +00:00
|
|
|
import json
|
2022-02-02 15:37:42 +00:00
|
|
|
import importlib
|
2022-08-11 13:48:01 +00:00
|
|
|
import traceback
|
2022-08-11 02:18:35 +00:00
|
|
|
from typing import Any
|
2022-08-11 13:48:01 +00:00
|
|
|
from dataclasses import dataclass
|
|
|
|
from datetime import datetime, timezone
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-06-28 06:44:07 +00:00
|
|
|
# "a little hacky bs" - matt159 ;)
|
2022-04-11 17:20:00 +00:00
|
|
|
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
# Local modules:
|
2022-04-17 20:42:47 +00:00
|
|
|
from main import \
|
2022-08-24 15:49:09 +00:00
|
|
|
helpers, \
|
|
|
|
dna_generator, \
|
|
|
|
exporter, \
|
|
|
|
headless_util, \
|
|
|
|
intermediate, \
|
|
|
|
logic, \
|
|
|
|
material_generator, \
|
|
|
|
metadata_templates, \
|
|
|
|
refactorer
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-04-20 01:04:17 +00:00
|
|
|
from UILists import \
|
2022-08-24 15:49:09 +00:00
|
|
|
custom_metadata_ui_list, \
|
|
|
|
logic_ui_list
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
# Refresh Locals for development:
|
2022-04-18 15:06:04 +00:00
|
|
|
if "bpy" in locals():
|
2022-04-17 20:42:47 +00:00
|
|
|
modules = {
|
2022-08-24 15:49:09 +00:00
|
|
|
"helpers": helpers,
|
|
|
|
"dna_generator": dna_generator,
|
|
|
|
"exporter": exporter,
|
|
|
|
"headless_util": headless_util,
|
|
|
|
"intermediate": intermediate,
|
|
|
|
"logic": logic,
|
|
|
|
"material_generator": material_generator,
|
|
|
|
"metadata_templates": metadata_templates,
|
|
|
|
"refactorer": refactorer,
|
|
|
|
"custom_metadata_ui_list": custom_metadata_ui_list,
|
|
|
|
"logic_ui_list": logic_ui_list,
|
2022-04-17 20:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for i in modules:
|
|
|
|
if i in locals():
|
|
|
|
importlib.reload(modules[i])
|
2022-04-14 02:18:09 +00:00
|
|
|
|
2022-08-24 12:56:10 +00:00
|
|
|
# ======== Persistent UI Refresh ======== #
|
2022-04-14 02:18:09 +00:00
|
|
|
# Used for updating text and buttons in UI panels
|
2022-08-24 12:56:10 +00:00
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
combinations: int = 0
|
|
|
|
recommended_limit: int = 0
|
2022-08-11 13:48:01 +00:00
|
|
|
dt = datetime.now(timezone.utc).astimezone() # Date Time in UTC local
|
2022-04-14 02:18:09 +00:00
|
|
|
|
2022-08-11 13:48:01 +00:00
|
|
|
|
|
|
|
@persistent
|
2022-08-27 23:41:41 +00:00
|
|
|
def refresh_ui(dummy1, dummy2):
|
2022-08-11 13:48:01 +00:00
|
|
|
"""
|
|
|
|
Refreshes the UI upon user interacting with Blender (using depsgraph_update_post handler). Might be a better handler
|
|
|
|
to use.
|
|
|
|
"""
|
|
|
|
global combinations
|
|
|
|
global recommended_limit
|
|
|
|
|
2022-08-24 15:49:09 +00:00
|
|
|
combinations = (helpers.get_combinations())
|
2022-08-11 13:48:01 +00:00
|
|
|
recommended_limit = int(round(combinations / 2))
|
|
|
|
|
|
|
|
# Add panel classes that require refresh to this refresh_panels tuple:
|
|
|
|
refresh_panel_classes = (
|
|
|
|
BMNFTS_PT_CreateData,
|
|
|
|
)
|
|
|
|
|
|
|
|
def redraw_panel(panels):
|
|
|
|
for i in panels:
|
|
|
|
try:
|
|
|
|
bpy.utils.unregister_class(i)
|
|
|
|
except Exception:
|
|
|
|
print(traceback.format_exc())
|
|
|
|
bpy.utils.register_class(i)
|
|
|
|
|
|
|
|
redraw_panel(refresh_panel_classes)
|
|
|
|
|
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
bpy.app.handlers.depsgraph_update_post.append(refresh_ui)
|
2022-08-11 13:48:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
# ======== Defining BMNFTs Data ======== #
|
2022-06-28 19:36:47 +00:00
|
|
|
@dataclass
|
2022-07-01 03:32:14 +00:00
|
|
|
class BMNFTData:
|
2022-08-24 17:04:20 +00:00
|
|
|
nft_name: str
|
2022-06-28 19:36:47 +00:00
|
|
|
save_path: str
|
2022-08-24 17:04:20 +00:00
|
|
|
nfts_per_batch: int
|
|
|
|
batch_to_generate: int
|
|
|
|
collection_size: int
|
2022-06-28 19:36:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
blend_my_nfts_output: str
|
2022-06-28 19:36:47 +00:00
|
|
|
batch_json_save_path: str
|
2022-08-24 17:04:20 +00:00
|
|
|
nft_batch_save_path: str
|
2022-06-28 19:36:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_images: bool
|
|
|
|
image_file_format: str
|
2022-06-28 19:36:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_animations: bool
|
|
|
|
animation_file_format: str
|
2022-06-28 19:36:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_models: bool
|
|
|
|
model_file_format: str
|
2022-06-28 19:36:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_custom_fields: bool
|
2022-06-28 19:36:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
cardano_metadata_bool: bool
|
|
|
|
solana_metadata_bool: bool
|
|
|
|
erc721_metadata: bool
|
2022-06-28 19:36:47 +00:00
|
|
|
|
|
|
|
cardano_description: str
|
|
|
|
solana_description: str
|
|
|
|
erc721_description: str
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_materials: bool
|
|
|
|
materials_file: str
|
2022-06-28 19:36:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_logic: bool
|
|
|
|
enable_logic_json: bool
|
|
|
|
logic_file: str
|
2022-07-14 12:35:48 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_rarity: bool
|
2022-07-01 00:09:20 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_auto_shutdown: bool
|
2022-08-11 13:48:01 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
specify_time_bool: bool
|
2022-08-11 13:48:01 +00:00
|
|
|
hours: int
|
|
|
|
minutes: int
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
email_notification_bool: bool
|
2022-08-11 13:48:01 +00:00
|
|
|
sender_from: str
|
|
|
|
email_password: str
|
|
|
|
receiver_to: str
|
2022-08-25 13:41:22 +00:00
|
|
|
|
2022-08-24 12:56:10 +00:00
|
|
|
enable_debug: bool
|
2022-08-25 13:41:22 +00:00
|
|
|
log_path: str
|
2022-08-11 13:48:01 +00:00
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
enable_dry_run: str
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
custom_fields: dict = None
|
2022-06-28 19:36:47 +00:00
|
|
|
fail_state: Any = False
|
|
|
|
failed_batch: Any = None
|
|
|
|
failed_dna: Any = None
|
|
|
|
failed_dna_index: Any = None
|
|
|
|
|
|
|
|
def __post_init__(self):
|
2022-08-24 17:04:20 +00:00
|
|
|
self.custom_fields = {}
|
2022-06-28 19:36:47 +00:00
|
|
|
|
2022-08-11 13:48:01 +00:00
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
def get_bmnft_data():
|
2022-07-14 14:02:05 +00:00
|
|
|
_save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
|
|
|
_Blend_My_NFTs_Output, _batch_json_save_path, _nftBatch_save_path = make_directories(_save_path)
|
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
# IMPORTANT: if a new directory variable is ever added, use 'bpy.path.abspath' instead of 'os.path.abspath'.
|
2022-08-11 13:48:01 +00:00
|
|
|
data = BMNFTData(
|
2022-08-24 17:04:20 +00:00
|
|
|
nft_name=bpy.context.scene.input_tool.nft_name,
|
2022-08-27 23:41:41 +00:00
|
|
|
save_path=bpy.path.abspath(_save_path), # Converting from Blender's relative path system to absolute.
|
2022-08-24 17:04:20 +00:00
|
|
|
nfts_per_batch=bpy.context.scene.input_tool.nfts_per_batch,
|
|
|
|
batch_to_generate=bpy.context.scene.input_tool.batch_to_generate,
|
|
|
|
collection_size=bpy.context.scene.input_tool.collection_size,
|
2022-07-14 14:02:05 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_rarity=bpy.context.scene.input_tool.enable_rarity,
|
2022-07-14 14:02:05 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
blend_my_nfts_output=_Blend_My_NFTs_Output,
|
2022-08-11 13:48:01 +00:00
|
|
|
batch_json_save_path=_batch_json_save_path,
|
2022-08-24 17:04:20 +00:00
|
|
|
nft_batch_save_path=_nftBatch_save_path,
|
2022-07-14 14:02:05 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_logic=bpy.context.scene.input_tool.enable_logic,
|
|
|
|
enable_logic_json=bpy.context.scene.input_tool.enable_logic_json,
|
2022-08-27 23:41:41 +00:00
|
|
|
logic_file=bpy.path.abspath(bpy.context.scene.input_tool.logic_file),
|
2022-07-14 14:02:05 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_images=bpy.context.scene.input_tool.image_bool,
|
|
|
|
image_file_format=bpy.context.scene.input_tool.image_enum,
|
2022-07-14 14:02:05 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_animations=bpy.context.scene.input_tool.animation_bool,
|
|
|
|
animation_file_format=bpy.context.scene.input_tool.animation_enum,
|
2022-07-14 14:02:05 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_models=bpy.context.scene.input_tool.model_bool,
|
|
|
|
model_file_format=bpy.context.scene.input_tool.model_enum,
|
2022-07-14 14:02:05 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_custom_fields=bpy.context.scene.input_tool.enable_custom_fields,
|
2022-07-14 14:02:05 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
cardano_metadata_bool=bpy.context.scene.input_tool.cardano_metadata_bool,
|
|
|
|
solana_metadata_bool=bpy.context.scene.input_tool.solana_metadata_bool,
|
|
|
|
erc721_metadata=bpy.context.scene.input_tool.erc721_metadata,
|
2022-07-14 14:02:05 +00:00
|
|
|
|
2022-08-11 13:48:01 +00:00
|
|
|
cardano_description=bpy.context.scene.input_tool.cardano_description,
|
|
|
|
solana_description=bpy.context.scene.input_tool.solana_description,
|
|
|
|
erc721_description=bpy.context.scene.input_tool.erc721_description,
|
2022-07-14 14:02:05 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_materials=bpy.context.scene.input_tool.enable_materials,
|
|
|
|
materials_file=bpy.path.abspath(bpy.context.scene.input_tool.materials_file),
|
2022-06-28 19:36:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_auto_shutdown=bpy.context.scene.input_tool.enable_auto_shutdown,
|
2022-04-14 02:18:09 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
specify_time_bool=bpy.context.scene.input_tool.specify_time_bool,
|
2022-08-11 13:48:01 +00:00
|
|
|
hours=bpy.context.scene.input_tool.hours,
|
|
|
|
minutes=bpy.context.scene.input_tool.minutes,
|
2022-04-14 02:18:09 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
email_notification_bool=bpy.context.scene.input_tool.email_notification_bool,
|
2022-08-11 13:48:01 +00:00
|
|
|
sender_from=bpy.context.scene.input_tool.sender_from,
|
|
|
|
email_password=bpy.context.scene.input_tool.email_password,
|
|
|
|
receiver_to=bpy.context.scene.input_tool.receiver_to,
|
2022-08-25 13:41:22 +00:00
|
|
|
|
|
|
|
enable_debug=bpy.context.scene.input_tool.enable_debug,
|
2022-08-27 23:41:41 +00:00
|
|
|
log_path=bpy.path.abspath(bpy.context.scene.input_tool.log_path),
|
|
|
|
|
|
|
|
enable_dry_run=bpy.context.scene.input_tool.enable_dry_run
|
2022-04-14 02:18:09 +00:00
|
|
|
)
|
|
|
|
|
2022-08-11 13:48:01 +00:00
|
|
|
return data
|
2022-04-14 02:18:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
# ======== Helper functions ======== #
|
|
|
|
def make_directories(save_path):
|
|
|
|
"""Makes all Blend_My_NFTs Output folder directories from save_path input."""
|
|
|
|
Blend_My_NFTs_Output = os.path.join(save_path, "Blend_My_NFTs Output", "NFT_Data")
|
|
|
|
batch_json_save_path = os.path.join(Blend_My_NFTs_Output, "Batch_Data")
|
|
|
|
|
|
|
|
nftBatch_save_path = os.path.join(save_path, "Blend_My_NFTs Output", "Generated NFT Batches")
|
|
|
|
|
|
|
|
if not os.path.exists(Blend_My_NFTs_Output):
|
|
|
|
os.makedirs(Blend_My_NFTs_Output)
|
|
|
|
if not os.path.exists(batch_json_save_path):
|
|
|
|
os.makedirs(batch_json_save_path)
|
|
|
|
if not os.path.exists(nftBatch_save_path):
|
|
|
|
os.makedirs(nftBatch_save_path)
|
|
|
|
return Blend_My_NFTs_Output, batch_json_save_path, nftBatch_save_path
|
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
def run_as_headless():
|
2022-04-14 02:18:09 +00:00
|
|
|
"""
|
|
|
|
For use when running from the command line.
|
|
|
|
"""
|
2022-08-11 13:48:01 +00:00
|
|
|
|
2022-06-29 21:59:31 +00:00
|
|
|
# force CUDA device usage with cycles renderer
|
|
|
|
cprefs = bpy.context.preferences.addons['cycles'].preferences
|
|
|
|
cprefs.compute_device_type = 'CUDA'
|
|
|
|
cprefs.get_devices()
|
|
|
|
print(cprefs.devices.keys())
|
|
|
|
|
|
|
|
for key in cprefs.devices.keys():
|
2022-08-11 13:48:01 +00:00
|
|
|
cprefs.devices[key].use = True
|
2022-06-29 21:59:31 +00:00
|
|
|
|
|
|
|
print('Using {} devices for rendering!'.format(cprefs.get_num_gpu_devices()))
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
# def dumpSettings(settings):
|
|
|
|
# output = (
|
|
|
|
# f"nft_name={settings.nft_name}\n"
|
|
|
|
# f"collection_size={str(settings.collection_size)}\n"
|
|
|
|
# f"nfts_per_batch={str(settings.nfts_per_batch)}\n"
|
|
|
|
# f"save_path={settings.save_path}\n"
|
|
|
|
# f"enable_rarity={(settings.enable_rarity)}\n"
|
|
|
|
# f"enable_logic={str(settings.enable_logic)}\n"
|
|
|
|
# f"image_bool={str(settings.image_bool)}\n"
|
|
|
|
# f"image_enum={settings.image_enum}\n"
|
|
|
|
# f"animation_bool={str(settings.animation_bool)}\n"
|
|
|
|
# f"animation_enum={settings.animation_enum}\n"
|
|
|
|
# f"model_bool={str(settings.model_bool)}\n"
|
|
|
|
# f"model_enum={settings.model_enum}\n"
|
|
|
|
# f"batch_to_generate={str(settings.batch_to_generate)}\n"
|
|
|
|
# f"cardano_metadata_bool={str(settings.cardano_metadata_bool)}\n"
|
|
|
|
# f"cardano_description={settings.cardano_description}\n"
|
|
|
|
# f"erc721_metadata={str(settings.erc721_metadata)}\n"
|
|
|
|
# f"erc721_description={settings.erc721_description}\n"
|
|
|
|
# f"solana_metadata_bool={str(settings.solana_metadata_bool)}\n"
|
|
|
|
# f"solana_description={settings.solana_description}\n"
|
|
|
|
# f"enable_custom_fields={str(settings.enable_custom_fields)}\n"
|
|
|
|
# f"custom_fields_file={settings.custom_fields_file}\n"
|
|
|
|
# f"enable_materials={str(settings.custom_fields_file)}\n"
|
|
|
|
# f"materials_file={settings.materials_file}\n"
|
|
|
|
# )
|
|
|
|
# print(output)
|
|
|
|
|
|
|
|
args, parser = headless_util.get_python_args()
|
2022-04-14 02:18:09 +00:00
|
|
|
|
|
|
|
settings = bpy.context.scene.input_tool
|
|
|
|
|
|
|
|
# dumpSettings(settings)
|
|
|
|
|
|
|
|
with open(args.config_path, 'r') as f:
|
|
|
|
configs = [line.strip() for line in f.readlines() if not (line[0] == '#' or len(line.strip()) < 1)]
|
|
|
|
|
|
|
|
pairs = [config.strip().split('=') for config in configs]
|
|
|
|
|
|
|
|
# print(pairs)
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
settings.nft_name = pairs[0][1]
|
|
|
|
settings.collection_size = int(pairs[1][1])
|
|
|
|
settings.nfts_per_batch = int(pairs[2][1])
|
2022-08-11 13:48:01 +00:00
|
|
|
settings.save_path = pairs[3][1]
|
2022-08-27 23:41:41 +00:00
|
|
|
settings.enable_rarity = pairs[4][1] == 'True'
|
|
|
|
settings.enable_logic = pairs[5][1] == 'True'
|
2022-08-11 13:48:01 +00:00
|
|
|
settings.enableLogicJson = pairs[6][1] == 'True'
|
2022-08-24 17:04:20 +00:00
|
|
|
settings.logic_file = pairs[7][1]
|
2022-08-27 23:41:41 +00:00
|
|
|
settings.image_bool = pairs[8][1] == 'True'
|
2022-08-24 17:04:20 +00:00
|
|
|
settings.image_enum = pairs[9][1]
|
2022-08-27 23:41:41 +00:00
|
|
|
settings.animation_bool = pairs[10][1] == 'True'
|
2022-08-24 17:04:20 +00:00
|
|
|
settings.animation_enum = pairs[11][1]
|
2022-08-27 23:41:41 +00:00
|
|
|
settings.model_bool = pairs[12][1] == 'True'
|
2022-08-24 17:04:20 +00:00
|
|
|
settings.model_enum = pairs[13][1]
|
|
|
|
settings.batch_to_generate = int(pairs[14][1])
|
2022-08-27 23:41:41 +00:00
|
|
|
settings.cardano_metadata_bool = pairs[15][1] == 'True'
|
2022-08-11 13:48:01 +00:00
|
|
|
settings.cardano_description = pairs[16][1]
|
2022-08-27 23:41:41 +00:00
|
|
|
settings.erc721_metadata = pairs[17][1] == 'True'
|
2022-08-11 13:48:01 +00:00
|
|
|
settings.erc721_description = pairs[18][1]
|
2022-08-27 23:41:41 +00:00
|
|
|
settings.solana_metadata_bool = pairs[19][1] == 'True'
|
2022-08-11 13:48:01 +00:00
|
|
|
settings.solanaDescription = pairs[20][1]
|
2022-08-27 23:41:41 +00:00
|
|
|
settings.enable_custom_fields = pairs[21][1] == 'True'
|
2022-08-24 17:04:20 +00:00
|
|
|
settings.custom_fields_file = pairs[22][1]
|
2022-08-27 23:41:41 +00:00
|
|
|
settings.enable_materials = pairs[23][1] == 'True'
|
2022-08-24 17:04:20 +00:00
|
|
|
settings.materials_file = pairs[24][1]
|
2022-04-14 02:18:09 +00:00
|
|
|
|
|
|
|
if args.save_path:
|
|
|
|
settings.save_path = args.save_path
|
|
|
|
|
|
|
|
if args.batch_number:
|
2022-08-24 17:04:20 +00:00
|
|
|
settings.batch_to_generate = args.batch_number
|
2022-04-14 02:18:09 +00:00
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
input = get_bmnft_data()
|
2022-04-14 02:18:09 +00:00
|
|
|
|
2022-07-14 14:02:05 +00:00
|
|
|
if args.batch_data_path:
|
|
|
|
input.batch_json_save_path = args.batch_data_path
|
2022-07-14 12:35:48 +00:00
|
|
|
|
2022-09-21 20:25:29 +00:00
|
|
|
if args.resume_failed_batch:
|
2022-09-21 21:12:00 +00:00
|
|
|
_fail_state, _failed_batch, _failed_dna, _failed_dna_index = helpers.check_failed_batches(input.batch_json_save_path)
|
2022-09-21 20:25:29 +00:00
|
|
|
|
2022-09-21 23:41:37 +00:00
|
|
|
input.fail_state = _fail_state
|
|
|
|
input.failed_batch = _failed_batch
|
|
|
|
input.failed_dna= _failed_dna
|
|
|
|
input.failed_dna_index = _failed_dna_index
|
2022-09-21 20:25:29 +00:00
|
|
|
|
2022-07-01 04:44:15 +00:00
|
|
|
if args.operation == 'create-dna':
|
2022-08-24 17:04:20 +00:00
|
|
|
intermediate.send_to_record(input)
|
2022-04-14 02:18:09 +00:00
|
|
|
|
2022-07-01 04:44:15 +00:00
|
|
|
elif args.operation == 'generate-nfts':
|
2022-08-24 17:04:20 +00:00
|
|
|
intermediate.render_and_save_nfts(input)
|
2022-04-14 02:18:09 +00:00
|
|
|
|
2022-07-01 04:44:15 +00:00
|
|
|
elif args.operation == 'refactor-batches':
|
2022-08-24 17:04:20 +00:00
|
|
|
refactorer.reformat_nft_collection(input)
|
2022-04-14 02:18:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
# ======== User input Property Group ======== #
|
|
|
|
class BMNFTS_PGT_Input_Properties(bpy.types.PropertyGroup):
|
|
|
|
# Create NFT Data Panel:
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
nft_name: bpy.props.StringProperty(name="NFT Name")
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
collection_size: bpy.props.IntProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="NFT Collection Size",
|
|
|
|
default=1,
|
|
|
|
min=1
|
|
|
|
) # max=(combinations - offset)
|
2022-08-24 17:04:20 +00:00
|
|
|
nfts_per_batch: bpy.props.IntProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="NFTs Per Batch",
|
|
|
|
default=1,
|
|
|
|
min=1
|
|
|
|
) # max=(combinations - offset)
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-02-04 14:44:36 +00:00
|
|
|
save_path: bpy.props.StringProperty(
|
2022-04-17 20:42:47 +00:00
|
|
|
name="Save Path",
|
|
|
|
description="Save path for NFT files",
|
|
|
|
default="",
|
|
|
|
maxlen=1024,
|
|
|
|
subtype="DIR_PATH"
|
2022-02-04 14:44:36 +00:00
|
|
|
)
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_rarity: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Enable Rarity"
|
|
|
|
)
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_logic: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Enable Logic"
|
|
|
|
)
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_logic_json: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Use Logic.json instead"
|
|
|
|
)
|
2022-08-24 17:04:20 +00:00
|
|
|
logic_file: bpy.props.StringProperty(
|
2022-04-20 18:50:53 +00:00
|
|
|
name="Logic File Path",
|
2022-04-17 20:42:47 +00:00
|
|
|
description="Path where Logic.json is located.",
|
|
|
|
default="",
|
|
|
|
maxlen=1024,
|
|
|
|
subtype="FILE_PATH"
|
|
|
|
)
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_materials: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Enable Materials"
|
|
|
|
)
|
2022-08-24 17:04:20 +00:00
|
|
|
materials_file: bpy.props.StringProperty(
|
2022-04-17 20:42:47 +00:00
|
|
|
name="Materials File",
|
|
|
|
description="Path where Materials.json is located.",
|
|
|
|
default="",
|
|
|
|
maxlen=1024,
|
|
|
|
subtype="FILE_PATH"
|
2022-04-14 02:18:09 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
# Generate NFTs Panel:
|
2022-08-24 17:04:20 +00:00
|
|
|
image_bool: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Image"
|
|
|
|
)
|
2022-08-24 17:04:20 +00:00
|
|
|
image_enum: bpy.props.EnumProperty(
|
2022-04-17 20:42:47 +00:00
|
|
|
name="Image File Format",
|
|
|
|
description="Select Image file format",
|
2022-02-02 15:37:42 +00:00
|
|
|
items=[
|
|
|
|
('PNG', ".PNG", "Export NFT as PNG"),
|
|
|
|
('JPEG', ".JPEG", "Export NFT as JPEG")
|
|
|
|
]
|
|
|
|
)
|
2022-04-14 02:18:09 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
animation_bool: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Animation"
|
|
|
|
)
|
2022-08-24 17:04:20 +00:00
|
|
|
animation_enum: bpy.props.EnumProperty(
|
2022-04-17 20:42:47 +00:00
|
|
|
name="Animation File Format",
|
|
|
|
description="Select Animation file format",
|
2022-02-02 15:37:42 +00:00
|
|
|
items=[
|
2022-02-03 00:40:05 +00:00
|
|
|
('AVI_JPEG', '.avi (AVI_JPEG)', 'Export NFT as AVI_JPEG'),
|
|
|
|
('AVI_RAW', '.avi (AVI_RAW)', 'Export NFT as AVI_RAW'),
|
|
|
|
('FFMPEG', '.mkv (FFMPEG)', 'Export NFT as FFMPEG'),
|
2022-05-31 05:28:01 +00:00
|
|
|
('MP4', '.mp4', 'Export NFT as .mp4'),
|
2022-05-31 12:03:52 +00:00
|
|
|
('PNG', '.png', 'Export NFT as PNG'),
|
|
|
|
('TIFF', '.tiff', 'Export NFT as TIFF')
|
2022-02-02 15:37:42 +00:00
|
|
|
]
|
|
|
|
)
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
model_bool: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="3D Model"
|
|
|
|
)
|
2022-08-24 17:04:20 +00:00
|
|
|
model_enum: bpy.props.EnumProperty(
|
2022-04-17 20:42:47 +00:00
|
|
|
name="3D Model File Format",
|
|
|
|
description="Select 3D Model file format",
|
2022-02-02 15:37:42 +00:00
|
|
|
items=[
|
|
|
|
('GLB', '.glb', 'Export NFT as .glb'),
|
2022-04-17 20:42:47 +00:00
|
|
|
('GLTF_SEPARATE', '.gltf + .bin + textures',
|
|
|
|
'Export NFT as .gltf with separated textures in .bin + textures.'),
|
2022-02-02 15:37:42 +00:00
|
|
|
('GLTF_EMBEDDED', '.gltf', 'Export NFT as embedded .gltf file that contains textures.'),
|
|
|
|
('FBX', '.fbx', 'Export NFT as .fbx'),
|
|
|
|
('OBJ', '.obj', 'Export NFT as .obj'),
|
|
|
|
('X3D', '.x3d', 'Export NFT as .x3d'),
|
2022-02-03 00:40:05 +00:00
|
|
|
('STL', '.stl', 'Export NFT as .stl'),
|
2022-04-17 20:42:47 +00:00
|
|
|
('VOX', '.vox (Experimental)',
|
|
|
|
'Export NFT as .vox, requires the voxwriter add on: https://github.com/Spyduck/voxwriter')
|
2022-02-02 15:37:42 +00:00
|
|
|
]
|
|
|
|
)
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
batch_to_generate: bpy.props.IntProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Batch To Generate",
|
|
|
|
default=1,
|
|
|
|
min=1
|
|
|
|
)
|
2022-04-14 02:18:09 +00:00
|
|
|
|
|
|
|
# Refactor Batches & Create Metadata Panel:
|
2022-08-24 17:04:20 +00:00
|
|
|
cardano_metadata_bool: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Cardano Cip"
|
|
|
|
)
|
|
|
|
cardano_description: bpy.props.StringProperty(
|
|
|
|
name="Cardano description"
|
|
|
|
)
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
solana_metadata_bool: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Solana Metaplex"
|
|
|
|
)
|
|
|
|
solana_description: bpy.props.StringProperty(
|
|
|
|
name="Solana description"
|
|
|
|
)
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
erc721_metadata: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="ERC721"
|
|
|
|
)
|
|
|
|
erc721_description: bpy.props.StringProperty(
|
|
|
|
name="ERC721 description"
|
|
|
|
)
|
2022-03-11 01:03:20 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_custom_fields: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Enable Custom Metadata Fields"
|
|
|
|
)
|
2022-08-24 17:04:20 +00:00
|
|
|
custom_fields_file: bpy.props.StringProperty(
|
2022-04-17 20:42:47 +00:00
|
|
|
name="Custom Fields File",
|
|
|
|
description="Path where Custom_Fields.json is located.",
|
|
|
|
default="",
|
|
|
|
maxlen=1024,
|
|
|
|
subtype="FILE_PATH"
|
2022-03-08 03:21:25 +00:00
|
|
|
)
|
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
# Other Panel:
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_auto_save: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Auto Save Before Generation",
|
|
|
|
description="Automatically saves your Blender file when 'Generate NFTs & Create Metadata' button is clicked"
|
|
|
|
)
|
2022-08-11 13:48:01 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_auto_shutdown: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Auto Shutdown",
|
|
|
|
description="Automatically shuts down your computer after a Batch is finished Generating"
|
|
|
|
)
|
2022-08-11 13:48:01 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
specify_time_bool: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Shutdown in a Given Amount of Time",
|
|
|
|
description="Wait a given amount of time after a Batch is generated before Automatic Shutdown"
|
|
|
|
)
|
|
|
|
hours: bpy.props.IntProperty(
|
|
|
|
default=0, min=0
|
|
|
|
)
|
|
|
|
minutes: bpy.props.IntProperty(
|
|
|
|
default=0, min=0
|
|
|
|
)
|
2022-08-11 13:48:01 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
email_notification_bool: bpy.props.BoolProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="Email Notifications",
|
|
|
|
description="Receive Email Notifications from Blender once a batch is finished generating"
|
|
|
|
)
|
|
|
|
sender_from: bpy.props.StringProperty(
|
|
|
|
name="From",
|
|
|
|
default="from@example.com"
|
|
|
|
)
|
|
|
|
email_password: bpy.props.StringProperty(
|
|
|
|
name="Password",
|
|
|
|
subtype='PASSWORD'
|
|
|
|
)
|
|
|
|
receiver_to: bpy.props.StringProperty(
|
|
|
|
name="To",
|
|
|
|
default="to@example.com"
|
|
|
|
)
|
2022-03-11 01:03:20 +00:00
|
|
|
|
2022-08-24 15:49:09 +00:00
|
|
|
enable_debug: bpy.props.BoolProperty(
|
|
|
|
name="Enable Debug Mode",
|
2022-08-28 01:48:44 +00:00
|
|
|
description="Allows you to run Blend_My_NFTs without generating any content files and enables debugging "
|
|
|
|
"console messages saved to a BMNFTs_Log.txt file."
|
2022-08-24 15:49:09 +00:00
|
|
|
)
|
2022-08-25 13:41:22 +00:00
|
|
|
log_path: bpy.props.StringProperty(
|
|
|
|
name="Debug Log Path",
|
|
|
|
description="Path where BMNFT_Log.txt is located.",
|
|
|
|
default="",
|
|
|
|
maxlen=1024,
|
|
|
|
subtype="FILE_PATH"
|
|
|
|
)
|
2022-08-24 12:56:10 +00:00
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
enable_dry_run: bpy.props.BoolProperty(
|
|
|
|
name="Enable Dry Run",
|
|
|
|
description="Allows you to run Blend_My_NFTs without generating any content files."
|
|
|
|
)
|
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
# API Panel properties:
|
2022-08-24 17:04:20 +00:00
|
|
|
api_key: bpy.props.StringProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
name="API Key",
|
|
|
|
subtype='PASSWORD'
|
|
|
|
) # Test code for future features
|
2022-02-03 00:40:05 +00:00
|
|
|
|
2022-03-26 03:47:54 +00:00
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
# ======== Main Operators ======== #
|
2022-08-27 23:41:41 +00:00
|
|
|
class CreateData(bpy.types.Operator):
|
2022-02-02 15:37:42 +00:00
|
|
|
bl_idname = 'create.data'
|
|
|
|
bl_label = 'Create Data'
|
2022-08-24 17:04:20 +00:00
|
|
|
bl_description = 'Creates NFT Data. Run after any changes were made to scene. All previous data will be ' \
|
|
|
|
'overwritten and cannot be recovered.'
|
2022-02-02 15:37:42 +00:00
|
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
|
|
|
2022-04-20 01:04:17 +00:00
|
|
|
reverse_order: BoolProperty(
|
|
|
|
default=False,
|
|
|
|
name="Reverse Order")
|
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
def execute(self, context):
|
2022-08-28 01:48:44 +00:00
|
|
|
helpers.activate_logging()
|
2022-08-27 23:41:41 +00:00
|
|
|
|
2022-04-20 01:04:17 +00:00
|
|
|
# Handling Custom Fields UIList input:
|
2022-08-27 23:41:41 +00:00
|
|
|
input = get_bmnft_data()
|
2022-04-20 01:04:17 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
if input.enable_logic:
|
|
|
|
if input.enable_logic_json and not input.logic_file:
|
2022-08-11 13:48:01 +00:00
|
|
|
self.report({'ERROR'},
|
|
|
|
f"No Logic.json file path set. Please set the file path to your Logic.json file.")
|
2022-04-20 01:04:17 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
intermediate.send_to_record(input)
|
2022-08-11 13:48:01 +00:00
|
|
|
|
2022-03-12 17:18:41 +00:00
|
|
|
self.report({'INFO'}, f"NFT Data created!")
|
2022-02-02 15:37:42 +00:00
|
|
|
return {"FINISHED"}
|
|
|
|
|
2022-05-10 12:14:53 +00:00
|
|
|
def invoke(self, context, event):
|
|
|
|
return context.window_manager.invoke_confirm(self, event)
|
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
class ExportNFTs(bpy.types.Operator):
|
2022-02-02 15:37:42 +00:00
|
|
|
bl_idname = 'exporter.nfts'
|
|
|
|
bl_label = 'Export NFTs'
|
|
|
|
bl_description = 'Generate and export a given batch of NFTs.'
|
|
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
|
|
|
2022-05-10 12:14:53 +00:00
|
|
|
reverse_order: BoolProperty(
|
|
|
|
default=False,
|
|
|
|
name="Reverse Order")
|
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
def execute(self, context):
|
2022-08-28 01:48:44 +00:00
|
|
|
helpers.activate_logging()
|
2022-08-27 23:41:41 +00:00
|
|
|
|
|
|
|
input = get_bmnft_data()
|
2022-08-11 13:48:01 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
intermediate.render_and_save_nfts(input)
|
2022-03-12 17:18:41 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
self.report({'INFO'}, f"All NFTs generated for batch {input.batch_to_generate}!")
|
2022-03-12 17:18:41 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
return {"FINISHED"}
|
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
class ResumeFailedBatch(bpy.types.Operator):
|
2022-03-26 03:47:54 +00:00
|
|
|
bl_idname = 'exporter.resume_nfts'
|
|
|
|
bl_label = 'Resume Failed Batch'
|
|
|
|
bl_description = 'Failed Batch detected. Generate NFTs where the previous batch failed?'
|
|
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
|
|
|
|
|
|
def execute(self, context):
|
2022-08-28 01:48:44 +00:00
|
|
|
helpers.activate_logging()
|
2022-08-27 23:41:41 +00:00
|
|
|
|
2022-06-28 19:39:57 +00:00
|
|
|
_save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
|
|
|
_Blend_My_NFTs_Output, _batch_json_save_path, _nftBatch_save_path = make_directories(_save_path)
|
2022-03-26 03:47:54 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
_batchToGenerate = bpy.context.scene.input_tool.batch_to_generate
|
2022-06-28 19:39:57 +00:00
|
|
|
|
|
|
|
file_name = os.path.join(_batch_json_save_path, "Batch{}.json".format(_batchToGenerate))
|
2022-08-27 23:41:41 +00:00
|
|
|
batch_data = json.load(open(file_name))
|
2022-06-28 19:39:57 +00:00
|
|
|
|
2022-08-24 15:49:09 +00:00
|
|
|
_fail_state, _failed_batch, _failed_dna, _failed_dna_index = helpers.check_failed_batches(_batch_json_save_path)
|
2022-03-26 03:47:54 +00:00
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
render_settings = batch_data["Generation Save"][-1]["Render_Settings"]
|
2022-08-11 14:26:16 +00:00
|
|
|
|
2022-08-11 13:48:01 +00:00
|
|
|
input = BMNFTData(
|
2022-08-24 17:04:20 +00:00
|
|
|
nft_name=render_settings["nft_name"],
|
2022-08-11 13:48:01 +00:00
|
|
|
save_path=_save_path,
|
2022-08-24 17:04:20 +00:00
|
|
|
nfts_per_batch=render_settings["nfts_per_batch"],
|
|
|
|
batch_to_generate=render_settings["batch_to_generate"],
|
|
|
|
collection_size=render_settings["collection_size"],
|
2022-03-26 03:47:54 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
blend_my_nfts_output=_Blend_My_NFTs_Output,
|
2022-08-11 13:48:01 +00:00
|
|
|
batch_json_save_path=_batch_json_save_path,
|
2022-08-24 17:04:20 +00:00
|
|
|
nft_batch_save_path=render_settings["nft_batch_save_path"],
|
2022-08-11 14:26:16 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_images=render_settings["enable_images"],
|
|
|
|
image_file_format=render_settings["image_file_format"],
|
2022-08-11 14:26:16 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_animations=render_settings["enable_animations"],
|
|
|
|
animation_file_format=render_settings["animation_file_format"],
|
2022-08-11 14:26:16 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_models=render_settings["enable_models"],
|
|
|
|
model_file_format=render_settings["model_file_format"],
|
2022-03-26 03:47:54 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_custom_fields=render_settings["enable_custom_fields"],
|
2022-05-10 12:14:53 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
cardano_metadata_bool=render_settings["cardano_metadata_bool"],
|
|
|
|
solana_metadata_bool=render_settings["solana_metadata_bool"],
|
|
|
|
erc721_metadata=render_settings["erc721_metadata"],
|
2022-05-10 12:14:53 +00:00
|
|
|
|
2022-08-11 14:26:16 +00:00
|
|
|
cardano_description=render_settings["cardano_description"],
|
|
|
|
solana_description=render_settings["solana_description"],
|
|
|
|
erc721_description=render_settings["erc721_description"],
|
2022-05-10 12:14:53 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_materials=render_settings["enable_materials"],
|
|
|
|
materials_file=render_settings["materials_file"],
|
2022-05-10 12:14:53 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_logic=render_settings["enable_logic"],
|
|
|
|
enable_logic_json=render_settings["enable_logic_json"],
|
|
|
|
logic_file=render_settings["logic_file"],
|
2022-05-10 12:14:53 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_rarity=render_settings["enable_rarity"],
|
2022-05-10 12:14:53 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
enable_auto_shutdown=render_settings["enable_auto_shutdown"],
|
2022-08-11 14:26:16 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
specify_time_bool=render_settings["specify_time_bool"],
|
2022-08-11 14:26:16 +00:00
|
|
|
hours=render_settings["hours"],
|
|
|
|
minutes=render_settings["minutes"],
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
email_notification_bool=render_settings["email_notification_bool"],
|
2022-08-11 14:26:16 +00:00
|
|
|
sender_from=render_settings["sender_from"],
|
|
|
|
email_password=render_settings["email_password"],
|
|
|
|
receiver_to=render_settings["receiver_to"],
|
2022-08-24 17:29:47 +00:00
|
|
|
|
2022-08-24 12:56:10 +00:00
|
|
|
enable_debug=render_settings["enable_debug"],
|
2022-08-25 13:41:22 +00:00
|
|
|
log_path=render_settings["log_path"],
|
2022-06-28 19:39:57 +00:00
|
|
|
|
2022-08-27 23:41:41 +00:00
|
|
|
enable_dry_run=render_settings["enable_dry_run"],
|
|
|
|
|
2022-08-11 13:48:01 +00:00
|
|
|
fail_state=_fail_state,
|
|
|
|
failed_batch=_failed_batch,
|
|
|
|
failed_dna=_failed_dna,
|
2022-08-11 14:26:16 +00:00
|
|
|
failed_dna_index=_failed_dna_index,
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
custom_fields=render_settings["custom_fields"],
|
2022-06-28 19:39:57 +00:00
|
|
|
)
|
2022-05-10 12:14:53 +00:00
|
|
|
|
2022-08-24 15:49:09 +00:00
|
|
|
exporter.render_and_save_nfts(input)
|
2022-03-26 03:47:54 +00:00
|
|
|
|
|
|
|
self.report({'INFO'}, f"Resuming Failed Batch Generation!")
|
|
|
|
|
|
|
|
return {"FINISHED"}
|
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
class RefactorBatches(bpy.types.Operator):
|
2022-03-12 17:18:41 +00:00
|
|
|
"""Refactor your collection? This action cannot be undone."""
|
2022-02-02 15:37:42 +00:00
|
|
|
bl_idname = 'refactor.batches'
|
2022-02-03 23:57:23 +00:00
|
|
|
bl_label = 'Refactor your Batches?'
|
|
|
|
bl_description = 'This action cannot be undone.'
|
|
|
|
bl_options = {'REGISTER', 'INTERNAL'}
|
|
|
|
|
2022-04-18 15:06:04 +00:00
|
|
|
reverse_order: BoolProperty(
|
|
|
|
default=False,
|
|
|
|
name="Reverse Order")
|
2022-02-02 15:37:42 +00:00
|
|
|
|
|
|
|
def execute(self, context):
|
2022-08-28 01:48:44 +00:00
|
|
|
helpers.activate_logging()
|
2022-08-27 23:41:41 +00:00
|
|
|
|
|
|
|
refactorer.reformat_nft_collection(get_bmnft_data())
|
2022-02-03 23:48:52 +00:00
|
|
|
return {"FINISHED"}
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-02-03 23:57:23 +00:00
|
|
|
def invoke(self, context, event):
|
|
|
|
return context.window_manager.invoke_confirm(self, event)
|
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
class ExportSettings(bpy.types.Operator):
|
2022-04-14 02:18:09 +00:00
|
|
|
"""Export your settings into a configuration file."""
|
|
|
|
bl_idname = 'export.settings'
|
|
|
|
bl_label = 'Export Settings'
|
|
|
|
bl_description = 'Save your settings to a configuration file'
|
|
|
|
bl_options = {"REGISTER", "UNDO"}
|
|
|
|
|
|
|
|
def execute(self, context):
|
2022-08-28 01:48:44 +00:00
|
|
|
helpers.activate_logging()
|
2022-08-27 23:41:41 +00:00
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
|
|
|
filename = "config.cfg"
|
|
|
|
|
|
|
|
settings = bpy.context.scene.input_tool
|
|
|
|
|
|
|
|
with open(save_path + filename, 'w') as config:
|
|
|
|
output = (
|
|
|
|
"#This file was auto-generated from the Blend_My_NFTs addon and is used\n"
|
|
|
|
"#when running Blend_My_NFTs in a headless environment.\n"
|
|
|
|
"\n"
|
|
|
|
"#The name of your nft project\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"nft_name={settings.nft_name}\n"
|
2022-04-14 02:18:09 +00:00
|
|
|
"\n"
|
|
|
|
"#NFT Collection Size\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"collection_size={settings.collection_size}\n"
|
2022-04-14 02:18:09 +00:00
|
|
|
"\n"
|
|
|
|
"#The number of NFTs to generate per batch\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"nfts_per_batch={str(settings.nfts_per_batch)}\n"
|
2022-04-14 02:18:09 +00:00
|
|
|
"\n"
|
|
|
|
"#Save path for your NFT files\n"
|
2022-08-11 13:48:01 +00:00
|
|
|
f"save_path={settings.save_path}\n"
|
2022-04-14 02:18:09 +00:00
|
|
|
"\n"
|
|
|
|
"#Enable Rarity\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"enable_rarity={settings.enable_rarity}\n"
|
2022-04-14 02:18:09 +00:00
|
|
|
"\n"
|
|
|
|
"#Enable Logic\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"enable_logic={str(settings.enable_logic)}\n"
|
|
|
|
f"enableLogicJson={str(settings.enable_logic_json)}\n"
|
|
|
|
f"logicFilePath={settings.logic_file}\n"
|
2022-04-14 02:18:09 +00:00
|
|
|
"\n"
|
|
|
|
"#NFT Media output type(s):\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"image_bool={str(settings.image_bool)}\n"
|
|
|
|
f"image_enum={settings.image_enum}\n"
|
|
|
|
f"animation_bool={str(settings.animation_bool)}\n"
|
|
|
|
f"animation_enum={settings.animation_enum}\n"
|
|
|
|
f"model_bool={str(settings.model_bool)}\n"
|
|
|
|
f"model_enum={settings.model_enum}\n"
|
2022-04-14 02:18:09 +00:00
|
|
|
"\n"
|
|
|
|
"#Batch to generate\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"batch_to_generate={str(settings.batch_to_generate)}\n"
|
2022-04-14 02:18:09 +00:00
|
|
|
"\n"
|
|
|
|
"#Metadata Format\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"cardano_metadata_bool={str(settings.cardano_metadata_bool)}\n"
|
2022-08-11 13:48:01 +00:00
|
|
|
f"cardano_description={settings.cardano_description}\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"erc721_metadata={str(settings.erc721_metadata)}\n"
|
2022-08-11 13:48:01 +00:00
|
|
|
f"erc721_description={settings.erc721_description}\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"solana_metadata_bool={str(settings.solana_metadata_bool)}\n"
|
2022-08-11 13:48:01 +00:00
|
|
|
f"solana_description={settings.solana_description}\n"
|
2022-04-14 02:18:09 +00:00
|
|
|
"\n"
|
|
|
|
"#Enable Custom Fields\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"enable_custom_fields={str(settings.enable_custom_fields)}\n"
|
|
|
|
f"custom_fields_file={settings.custom_fields_file}\n"
|
2022-04-17 20:42:47 +00:00
|
|
|
"\n"
|
|
|
|
"#Enable Materials\n"
|
2022-08-24 17:04:20 +00:00
|
|
|
f"enable_materials={str(settings.enable_materials)}\n"
|
|
|
|
f"materials_file={settings.materials_file}\n"
|
2022-04-14 02:18:09 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
print(output, file=config)
|
|
|
|
|
|
|
|
self.report({'INFO'}, f"Saved settings to: {save_path + filename}!")
|
|
|
|
|
|
|
|
return {"FINISHED"}
|
|
|
|
|
|
|
|
|
|
|
|
# ======== UI Panels ======== #
|
2022-02-04 14:44:36 +00:00
|
|
|
class BMNFTS_PT_CreateData(bpy.types.Panel):
|
|
|
|
bl_label = "Create NFT Data"
|
|
|
|
bl_idname = "BMNFTS_PT_CreateData"
|
2022-02-02 15:37:42 +00:00
|
|
|
bl_space_type = 'VIEW_3D'
|
|
|
|
bl_region_type = 'UI'
|
|
|
|
bl_category = 'Blend_My_NFTs'
|
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
scene = context.scene
|
2022-04-14 02:18:09 +00:00
|
|
|
input_tool_scene = scene.input_tool
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-02-04 14:44:36 +00:00
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "nft_name")
|
2022-02-04 14:44:36 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
row = layout.row()
|
2022-03-08 03:21:25 +00:00
|
|
|
layout.label(text=f"Maximum Number Of NFTs: {combinations}")
|
|
|
|
layout.label(text=f"Recommended limit: {recommended_limit}")
|
2022-02-02 15:37:42 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "collection_size")
|
2022-02-02 15:37:42 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "nfts_per_batch")
|
2022-02-02 15:37:42 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
2022-04-14 02:18:09 +00:00
|
|
|
row.prop(input_tool_scene, "save_path")
|
2022-02-02 15:37:42 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "enable_rarity")
|
2022-02-04 14:44:36 +00:00
|
|
|
|
2022-03-08 03:21:25 +00:00
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "enable_logic")
|
2022-03-08 03:21:25 +00:00
|
|
|
|
2022-04-20 01:04:17 +00:00
|
|
|
# Logic_UIList implementation:
|
2022-08-24 17:04:20 +00:00
|
|
|
if bpy.context.scene.input_tool.enable_logic:
|
2022-04-20 01:04:17 +00:00
|
|
|
layout = self.layout
|
|
|
|
scn = bpy.context.scene
|
|
|
|
|
|
|
|
rows = 2
|
2022-03-08 03:21:25 +00:00
|
|
|
row = layout.row()
|
2022-04-20 01:04:17 +00:00
|
|
|
row.template_list("CUSTOM_UL_logic_items", "", scn, "logic_fields", scn,
|
|
|
|
"logic_fields_index", rows=rows)
|
|
|
|
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.operator("logic_uilist.logic_list_action", icon='ZOOM_IN', text="").action = 'ADD'
|
|
|
|
col.operator("logic_uilist.logic_list_action", icon='ZOOM_OUT', text="").action = 'REMOVE'
|
|
|
|
col.separator()
|
|
|
|
col.operator("logic_uilist.logic_list_action", icon='TRIA_UP', text="").action = 'UP'
|
|
|
|
col.operator("logic_uilist.logic_list_action", icon='TRIA_DOWN', text="").action = 'DOWN'
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
col = row.column(align=True)
|
|
|
|
row = col.row(align=True)
|
|
|
|
row.operator("logic_uilist.logic_clear_list", icon="X")
|
|
|
|
row = col.row(align=True)
|
|
|
|
row.label(text=f"*Field Names must be unique.")
|
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "enable_logic_json")
|
2022-04-20 01:04:17 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
if bpy.context.scene.input_tool.enable_logic_json:
|
2022-04-20 01:04:17 +00:00
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "logic_file")
|
2022-03-08 03:21:25 +00:00
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "enable_materials")
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
if bpy.context.scene.input_tool.enable_materials:
|
2022-04-17 20:42:47 +00:00
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "materials_file")
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-02-04 14:44:36 +00:00
|
|
|
row = layout.row()
|
|
|
|
self.layout.operator("create.data", icon='DISCLOSURE_TRI_RIGHT', text="Create Data")
|
2022-05-25 23:58:33 +00:00
|
|
|
row = layout.row()
|
|
|
|
layout.label(text=f"{BMNFTS_VERSION}")
|
2022-02-04 14:44:36 +00:00
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-02-04 14:44:36 +00:00
|
|
|
class BMNFTS_PT_GenerateNFTs(bpy.types.Panel):
|
2022-05-31 02:45:39 +00:00
|
|
|
bl_label = "Generate NFTs & Create Metadata"
|
2022-02-04 14:44:36 +00:00
|
|
|
bl_idname = "BMNFTS_PT_GenerateNFTs"
|
|
|
|
bl_space_type = 'VIEW_3D'
|
|
|
|
bl_region_type = 'UI'
|
|
|
|
bl_category = 'Blend_My_NFTs'
|
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
scene = context.scene
|
2022-04-14 02:18:09 +00:00
|
|
|
input_tool_scene = scene.input_tool
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-03-08 03:21:25 +00:00
|
|
|
row = layout.row()
|
|
|
|
layout.label(text="NFT Media files:")
|
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "image_bool")
|
|
|
|
if bpy.context.scene.input_tool.image_bool:
|
|
|
|
row.prop(input_tool_scene, "image_enum")
|
2022-02-02 15:37:42 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "animation_bool")
|
|
|
|
if bpy.context.scene.input_tool.animation_bool:
|
|
|
|
row.prop(input_tool_scene, "animation_enum")
|
2022-02-02 15:37:42 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "model_bool")
|
|
|
|
if bpy.context.scene.input_tool.model_bool:
|
|
|
|
row.prop(input_tool_scene, "model_enum")
|
2022-02-02 15:37:42 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
layout.label(text="Meta Data format:")
|
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "cardano_metadata_bool")
|
|
|
|
if bpy.context.scene.input_tool.cardano_metadata_bool:
|
2022-03-11 01:03:20 +00:00
|
|
|
row = layout.row()
|
2022-04-14 02:18:09 +00:00
|
|
|
row.prop(input_tool_scene, "cardano_description")
|
2022-03-11 01:03:20 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.operator("wm.url_open", text="Cardano Metadata Documentation",
|
|
|
|
icon='URL').url = "https://cips.cardano.org/cips/cip25/"
|
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "solana_metadata_bool")
|
|
|
|
if bpy.context.scene.input_tool.solana_metadata_bool:
|
2022-03-11 01:03:20 +00:00
|
|
|
row = layout.row()
|
2022-04-14 02:18:09 +00:00
|
|
|
row.prop(input_tool_scene, "solana_description")
|
2022-03-11 01:03:20 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.operator("wm.url_open", text="Solana Metadata Documentation",
|
|
|
|
icon='URL').url = "https://docs.metaplex.com/token-metadata/specification"
|
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "erc721_metadata")
|
|
|
|
if bpy.context.scene.input_tool.erc721_metadata:
|
2022-03-11 01:03:20 +00:00
|
|
|
row = layout.row()
|
2022-04-14 02:18:09 +00:00
|
|
|
row.prop(input_tool_scene, "erc721_description")
|
2022-03-11 01:03:20 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.operator("wm.url_open", text="ERC721 Metadata Documentation",
|
|
|
|
icon='URL').url = "https://docs.opensea.io/docs/metadata-standards"
|
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "enable_custom_fields")
|
2022-04-18 15:06:04 +00:00
|
|
|
|
2022-04-20 01:04:17 +00:00
|
|
|
# Custom Metadata Fields UIList:
|
2022-08-24 17:04:20 +00:00
|
|
|
if bpy.context.scene.input_tool.enable_custom_fields:
|
2022-04-18 15:06:04 +00:00
|
|
|
layout = self.layout
|
|
|
|
scn = bpy.context.scene
|
|
|
|
|
|
|
|
rows = 2
|
2022-03-11 01:03:20 +00:00
|
|
|
row = layout.row()
|
2022-08-11 13:48:01 +00:00
|
|
|
row.template_list("CUSTOM_UL_custom_metadata_fields_items", "", scn, "custom_metadata_fields", scn,
|
|
|
|
"custom_metadata_fields_index", rows=rows)
|
2022-04-18 15:06:04 +00:00
|
|
|
|
|
|
|
col = row.column(align=True)
|
2022-04-20 01:04:17 +00:00
|
|
|
col.operator("custom_metadata_fields_uilist.list_action", icon='ZOOM_IN', text="").action = 'ADD'
|
|
|
|
col.operator("custom_metadata_fields_uilist.list_action", icon='ZOOM_OUT', text="").action = 'REMOVE'
|
2022-04-18 15:06:04 +00:00
|
|
|
col.separator()
|
2022-04-20 01:04:17 +00:00
|
|
|
col.operator("custom_metadata_fields_uilist.list_action", icon='TRIA_UP', text="").action = 'UP'
|
|
|
|
col.operator("custom_metadata_fields_uilist.list_action", icon='TRIA_DOWN', text="").action = 'DOWN'
|
2022-04-18 15:06:04 +00:00
|
|
|
|
2022-03-11 01:03:20 +00:00
|
|
|
row = layout.row()
|
2022-04-18 15:06:04 +00:00
|
|
|
col = row.column(align=True)
|
|
|
|
row = col.row(align=True)
|
|
|
|
row.label(text=f"*Field Names must be unique.")
|
|
|
|
row = col.row(align=True)
|
2022-04-20 01:04:17 +00:00
|
|
|
row.operator("custom_metadata_fields_uilist.clear_list", icon="X")
|
2022-03-11 01:03:20 +00:00
|
|
|
|
2022-05-10 12:14:53 +00:00
|
|
|
row = layout.row()
|
2022-08-24 15:49:09 +00:00
|
|
|
row.prop(input_tool_scene, "batch_to_generate")
|
2022-05-10 12:14:53 +00:00
|
|
|
|
|
|
|
save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
|
|
|
Blend_My_NFTs_Output = os.path.join(save_path, "Blend_My_NFTs Output", "NFT_Data")
|
|
|
|
batch_json_save_path = os.path.join(Blend_My_NFTs_Output, "Batch_Data")
|
|
|
|
nftBatch_save_path = os.path.join(save_path, "Blend_My_NFTs Output", "Generated NFT Batches")
|
|
|
|
|
2022-08-24 15:49:09 +00:00
|
|
|
fail_state, failed_batch, failed_dna, failed_dna_index = helpers.check_failed_batches(batch_json_save_path)
|
2022-05-10 12:14:53 +00:00
|
|
|
|
|
|
|
if fail_state:
|
|
|
|
row = layout.row()
|
2022-05-31 02:45:39 +00:00
|
|
|
self.layout.operator("exporter.nfts", icon='RENDER_RESULT', text="Generate NFTs & Create Metadata")
|
2022-05-10 12:14:53 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.alert = True
|
|
|
|
row.operator("exporter.resume_nfts", icon='ERROR', text="Resume Failed Batch")
|
|
|
|
|
|
|
|
if not fail_state:
|
|
|
|
row = layout.row()
|
2022-05-31 02:45:39 +00:00
|
|
|
self.layout.operator("exporter.nfts", icon='RENDER_RESULT', text="Generate NFTs & Create Metadata")
|
2022-05-10 12:14:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
class BMNFTS_PT_Refactor(bpy.types.Panel):
|
2022-05-31 02:45:39 +00:00
|
|
|
bl_label = "Refactor Batches"
|
2022-05-10 12:14:53 +00:00
|
|
|
bl_idname = "BMNFTS_PT_Refactor"
|
|
|
|
bl_space_type = 'VIEW_3D'
|
|
|
|
bl_region_type = 'UI'
|
|
|
|
bl_category = 'Blend_My_NFTs'
|
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
scene = context.scene
|
|
|
|
input_tool_scene = scene.input_tool
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
layout.label(text="Ensure all batches have been created before refactoring.")
|
|
|
|
layout.label(text="Refactoring combines all batches into one easy to manage folder.")
|
|
|
|
|
2022-03-11 01:03:20 +00:00
|
|
|
row = layout.row()
|
2022-05-31 02:45:39 +00:00
|
|
|
self.layout.operator("refactor.batches", icon='FOLDER_REDIRECT', text="Refactor Batches")
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
class BMNFTS_PT_Other(bpy.types.Panel):
|
|
|
|
bl_label = "Other"
|
|
|
|
bl_idname = "BMNFTS_PT_Other"
|
2022-02-04 14:44:36 +00:00
|
|
|
bl_space_type = 'VIEW_3D'
|
|
|
|
bl_region_type = 'UI'
|
|
|
|
bl_category = 'Blend_My_NFTs'
|
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
scene = context.scene
|
2022-04-14 02:18:09 +00:00
|
|
|
input_tool_scene = scene.input_tool
|
2022-04-11 00:00:19 +00:00
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
"""
|
2022-08-11 13:48:01 +00:00
|
|
|
Other:
|
|
|
|
A place to store miscellaneous settings, features, and external links that the user may find useful but doesn't
|
|
|
|
want to get in the way of their work flow.
|
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
Export Settings:
|
|
|
|
This panel gives the user the option to export all settings from the Blend_My_NFTs addon into a config file. Settings
|
|
|
|
will be read from the config file when running heedlessly.
|
|
|
|
"""
|
2022-08-11 13:48:01 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "enable_auto_save")
|
2022-08-11 13:48:01 +00:00
|
|
|
|
|
|
|
# Auto Shutdown:
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "enable_auto_shutdown")
|
2022-08-11 13:48:01 +00:00
|
|
|
row.label(text="*Must Run Blender as Admin")
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
if bpy.context.scene.input_tool.enable_auto_shutdown:
|
2022-08-11 13:48:01 +00:00
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "specify_time_bool")
|
2022-08-11 13:48:01 +00:00
|
|
|
|
|
|
|
time_row1 = layout.row()
|
|
|
|
time_row1.label(text=f"Hours")
|
|
|
|
time_row1.prop(input_tool_scene, "hours", text="")
|
|
|
|
|
|
|
|
time_row2 = layout.row()
|
|
|
|
time_row2.label(text=f"Minutes")
|
|
|
|
time_row2.prop(input_tool_scene, "minutes", text="")
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
if not bpy.context.scene.input_tool.specify_time_bool:
|
2022-08-11 13:48:01 +00:00
|
|
|
time_row1.enabled = False
|
|
|
|
time_row2.enabled = False
|
|
|
|
else:
|
|
|
|
time_row1.enabled = True
|
|
|
|
time_row2.enabled = True
|
|
|
|
layout.separator()
|
|
|
|
|
|
|
|
row = layout.row()
|
2022-08-24 17:04:20 +00:00
|
|
|
row.prop(input_tool_scene, "email_notification_bool")
|
2022-08-11 13:48:01 +00:00
|
|
|
row.label(text="*Windows 10+ only")
|
|
|
|
|
2022-08-24 17:04:20 +00:00
|
|
|
if bpy.context.scene.input_tool.email_notification_bool:
|
2022-08-11 13:48:01 +00:00
|
|
|
row = layout.row()
|
|
|
|
row.prop(input_tool_scene, "sender_from")
|
|
|
|
row = layout.row()
|
|
|
|
row.prop(input_tool_scene, "email_password")
|
|
|
|
|
|
|
|
layout.separator()
|
|
|
|
row = layout.row()
|
|
|
|
row.prop(input_tool_scene, "receiver_to")
|
|
|
|
|
|
|
|
layout.separator()
|
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
layout.label(text=f"Running Blend_My_NFTs Headless:")
|
2022-04-11 02:41:12 +00:00
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
2022-04-12 08:37:28 +00:00
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
if save_path and os.path.isdir(save_path):
|
|
|
|
row = layout.row()
|
|
|
|
self.layout.operator("export.settings", icon='FOLDER_REDIRECT', text="Export BMNFTs Settings to a File")
|
|
|
|
else:
|
|
|
|
row = layout.row()
|
|
|
|
layout.label(text=f"**Set a Save Path in Create NFT Data to Export Settings")
|
2022-04-11 02:41:12 +00:00
|
|
|
|
2022-08-24 12:56:10 +00:00
|
|
|
row = layout.row()
|
|
|
|
row.prop(input_tool_scene, "enable_debug")
|
2022-08-25 13:41:22 +00:00
|
|
|
if bpy.context.scene.input_tool.enable_debug:
|
2022-08-27 23:41:41 +00:00
|
|
|
row = layout.row()
|
2022-08-25 13:41:22 +00:00
|
|
|
row.prop(input_tool_scene, "log_path")
|
2022-04-17 20:42:47 +00:00
|
|
|
row = layout.row()
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
layout.label(text=f"Looking for help?")
|
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
row = layout.row()
|
|
|
|
row.operator("wm.url_open", text="Blend_My_NFTs Documentation",
|
|
|
|
icon='URL').url = "https://github.com/torrinworx/Blend_My_NFTs"
|
2022-04-11 17:20:00 +00:00
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
row = layout.row()
|
2022-08-25 13:41:22 +00:00
|
|
|
row.operator(
|
|
|
|
"wm.url_open",
|
|
|
|
text="YouTube Tutorials",
|
|
|
|
icon='URL'
|
|
|
|
).url = "https://www.youtube.com/watch?v=ygKJYz4BjRs&list=PLuVvzaanutXcYtWmPVKu2bx83EYNxLRsX"
|
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
row = layout.row()
|
|
|
|
row.operator("wm.url_open", text="Join Our Discord Community!",
|
|
|
|
icon='URL').url = "https://discord.gg/UpZt5Un57t"
|
|
|
|
|
2022-05-25 23:58:33 +00:00
|
|
|
row = layout.row()
|
|
|
|
layout.label(text=f"{BMNFTS_VERSION}, {LAST_UPDATED}")
|
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
# ======== Blender add-on register/unregister handling ======== #
|
2022-02-03 00:40:05 +00:00
|
|
|
classes = (
|
2022-08-24 17:04:20 +00:00
|
|
|
# Property Group Classes:
|
2022-08-27 23:41:41 +00:00
|
|
|
BMNFTS_PGT_Input_Properties,
|
|
|
|
|
|
|
|
# Operator Classes:
|
|
|
|
CreateData,
|
|
|
|
ExportNFTs,
|
|
|
|
ResumeFailedBatch,
|
|
|
|
RefactorBatches,
|
|
|
|
ExportSettings,
|
|
|
|
|
|
|
|
# Panel Classes:
|
|
|
|
BMNFTS_PT_CreateData,
|
|
|
|
BMNFTS_PT_GenerateNFTs,
|
|
|
|
BMNFTS_PT_Refactor,
|
|
|
|
BMNFTS_PT_Other,
|
2022-08-24 17:04:20 +00:00
|
|
|
) + custom_metadata_ui_list.classes_Custom_Metadata_UIList + logic_ui_list.classes_Logic_UIList
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
def register():
|
|
|
|
for cls in classes:
|
|
|
|
bpy.utils.register_class(cls)
|
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
bpy.types.Scene.input_tool = bpy.props.PointerProperty(type=BMNFTS_PGT_Input_Properties)
|
2022-02-02 15:37:42 +00:00
|
|
|
|
2022-08-11 13:48:01 +00:00
|
|
|
bpy.types.Scene.custom_metadata_fields = CollectionProperty(
|
2022-08-24 15:49:09 +00:00
|
|
|
type=custom_metadata_ui_list.CUSTOM_custom_metadata_fields_objectCollection)
|
2022-04-20 01:04:17 +00:00
|
|
|
bpy.types.Scene.custom_metadata_fields_index = IntProperty()
|
|
|
|
|
2022-08-24 15:49:09 +00:00
|
|
|
bpy.types.Scene.logic_fields = CollectionProperty(type=logic_ui_list.CUSTOM_logic_objectCollection)
|
2022-04-20 01:04:17 +00:00
|
|
|
bpy.types.Scene.logic_fields_index = IntProperty()
|
2022-04-17 20:42:47 +00:00
|
|
|
|
2022-08-11 13:48:01 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
def unregister():
|
2022-04-18 15:06:04 +00:00
|
|
|
for cls in reversed(classes):
|
2022-02-02 15:37:42 +00:00
|
|
|
bpy.utils.unregister_class(cls)
|
|
|
|
|
2022-04-14 02:18:09 +00:00
|
|
|
del bpy.types.Scene.input_tool
|
2022-04-12 08:37:28 +00:00
|
|
|
|
2022-04-20 01:04:17 +00:00
|
|
|
del bpy.types.Scene.custom_metadata_fields
|
|
|
|
del bpy.types.Scene.custom_metadata_fields_index
|
|
|
|
|
|
|
|
del bpy.types.Scene.logic_fields
|
|
|
|
del bpy.types.Scene.logic_fields_index
|
2022-04-12 08:37:28 +00:00
|
|
|
|
2022-04-12 05:39:58 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
register()
|
2022-08-27 23:41:41 +00:00
|
|
|
run_as_headless()
|