kopia lustrzana https://github.com/torrinworx/Blend_My_NFTs
Reformatting dependencies
- Deprecated Rarity.py, moved to Helpers to avoid circular import issues - Moved get_hierarchy() function from DNA_Generator.py to Helpers to avoid circular import issues - Reformatted some comments and example codepull/142/head
rodzic
5e353e42b6
commit
4a939bb9e6
|
@ -44,7 +44,6 @@ from main import \
|
||||||
Logic, \
|
Logic, \
|
||||||
Material_Generator, \
|
Material_Generator, \
|
||||||
Metadata, \
|
Metadata, \
|
||||||
Rarity, \
|
|
||||||
Refactorer
|
Refactorer
|
||||||
|
|
||||||
from UILists import \
|
from UILists import \
|
||||||
|
@ -61,7 +60,6 @@ if "bpy" in locals():
|
||||||
"Logic": Logic,
|
"Logic": Logic,
|
||||||
"Material_Generator": Material_Generator,
|
"Material_Generator": Material_Generator,
|
||||||
"Metadata": Metadata,
|
"Metadata": Metadata,
|
||||||
"Rarity": Rarity,
|
|
||||||
"Refactorer": Refactorer,
|
"Refactorer": Refactorer,
|
||||||
"Custom_Metadata_UIList": Custom_Metadata_UIList,
|
"Custom_Metadata_UIList": Custom_Metadata_UIList,
|
||||||
"Logic_UIList": Logic_UIList,
|
"Logic_UIList": Logic_UIList,
|
||||||
|
@ -547,7 +545,7 @@ class resume_failed_batch(bpy.types.Operator):
|
||||||
file_name = os.path.join(_batch_json_save_path, "Batch{}.json".format(_batchToGenerate))
|
file_name = os.path.join(_batch_json_save_path, "Batch{}.json".format(_batchToGenerate))
|
||||||
batchData = json.load(open(file_name))
|
batchData = json.load(open(file_name))
|
||||||
|
|
||||||
_fail_state, _failed_batch, _failed_dna, _failed_dna_index = Checks.check_FailedBatches(_batch_json_save_path)
|
_fail_state, _failed_batch, _failed_dna, _failed_dna_index = Helpers.check_FailedBatches(_batch_json_save_path)
|
||||||
|
|
||||||
render_settings = batchData["Generation Save"][-1]["Render_Settings"]
|
render_settings = batchData["Generation Save"][-1]["Render_Settings"]
|
||||||
|
|
||||||
|
@ -887,7 +885,7 @@ class BMNFTS_PT_GenerateNFTs(bpy.types.Panel):
|
||||||
batch_json_save_path = os.path.join(Blend_My_NFTs_Output, "Batch_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")
|
nftBatch_save_path = os.path.join(save_path, "Blend_My_NFTs Output", "Generated NFT Batches")
|
||||||
|
|
||||||
fail_state, failed_batch, failed_dna, failed_dna_index = Checks.check_FailedBatches(batch_json_save_path)
|
fail_state, failed_batch, failed_dna, failed_dna_index = Helpers.check_FailedBatches(batch_json_save_path)
|
||||||
|
|
||||||
if fail_state:
|
if fail_state:
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
|
|
@ -3,123 +3,11 @@
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import os
|
import os
|
||||||
import copy
|
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from . import Rarity, Logic, Material_Generator, Helpers
|
from . import Logic, Material_Generator, Helpers
|
||||||
from .Helpers import bcolors, Loader
|
|
||||||
|
|
||||||
|
|
||||||
def get_hierarchy():
|
|
||||||
"""
|
|
||||||
Returns the hierarchy of a given Blender scene.
|
|
||||||
"""
|
|
||||||
|
|
||||||
coll = bpy.context.scene.collection
|
|
||||||
|
|
||||||
scriptIgnoreCollection = bpy.data.collections["Script_Ignore"]
|
|
||||||
|
|
||||||
listAllCollInScene = []
|
|
||||||
listAllCollections = []
|
|
||||||
|
|
||||||
def traverse_tree(t):
|
|
||||||
yield t
|
|
||||||
for child in t.children:
|
|
||||||
yield from traverse_tree(child)
|
|
||||||
|
|
||||||
for c in traverse_tree(coll):
|
|
||||||
listAllCollInScene.append(c)
|
|
||||||
|
|
||||||
for i in listAllCollInScene:
|
|
||||||
listAllCollections.append(i.name)
|
|
||||||
|
|
||||||
listAllCollections.remove(scriptIgnoreCollection.name)
|
|
||||||
|
|
||||||
if "Scene Collection" in listAllCollections:
|
|
||||||
listAllCollections.remove("Scene Collection")
|
|
||||||
|
|
||||||
if "Master Collection" in listAllCollections:
|
|
||||||
listAllCollections.remove("Master Collection")
|
|
||||||
|
|
||||||
def allScriptIgnore(scriptIgnoreCollection):
|
|
||||||
# Removes all collections, sub collections in Script_Ignore collection from listAllCollections.
|
|
||||||
|
|
||||||
for coll in list(scriptIgnoreCollection.children):
|
|
||||||
listAllCollections.remove(coll.name)
|
|
||||||
listColl = list(coll.children)
|
|
||||||
if len(listColl) > 0:
|
|
||||||
allScriptIgnore(coll)
|
|
||||||
|
|
||||||
allScriptIgnore(scriptIgnoreCollection)
|
|
||||||
listAllCollections.sort()
|
|
||||||
|
|
||||||
exclude = ["_"] # Excluding characters that identify a Variant
|
|
||||||
attributeCollections = copy.deepcopy(listAllCollections)
|
|
||||||
|
|
||||||
def filter_num():
|
|
||||||
"""
|
|
||||||
This function removes items from 'attributeCollections' if they include values from the 'exclude' variable.
|
|
||||||
It removes child collections from the parent collections in from the "listAllCollections" list.
|
|
||||||
"""
|
|
||||||
for x in attributeCollections:
|
|
||||||
if any(a in x for a in exclude):
|
|
||||||
attributeCollections.remove(x)
|
|
||||||
|
|
||||||
for i in range(len(listAllCollections)):
|
|
||||||
filter_num()
|
|
||||||
|
|
||||||
attributeVariants = [x for x in listAllCollections if x not in attributeCollections]
|
|
||||||
attributeCollections1 = copy.deepcopy(attributeCollections)
|
|
||||||
|
|
||||||
def attributeData(attributeVariants):
|
|
||||||
"""
|
|
||||||
Creates a dictionary of each attribute
|
|
||||||
"""
|
|
||||||
allAttDataList = {}
|
|
||||||
for i in attributeVariants:
|
|
||||||
# Check if name follows naming conventions:
|
|
||||||
if int(i.count("_")) > 2 and int(i.split("_")[1]) > 0:
|
|
||||||
raise Exception(
|
|
||||||
f"\n{bcolors.ERROR}Blend_My_NFTs Error:\n"
|
|
||||||
f"There is a naming issue with the following Attribute/Variant: '{i}'\n"
|
|
||||||
f"Review the naming convention of Attribute and Variant collections here:\n{bcolors.RESET}"
|
|
||||||
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
number = i.split("_")[1]
|
|
||||||
name = i.split("_")[0]
|
|
||||||
rarity = i.split("_")[2]
|
|
||||||
except IndexError:
|
|
||||||
raise Exception(
|
|
||||||
f"\n{bcolors.ERROR}Blend_My_NFTs Error:\n"
|
|
||||||
f"There is a naming issue with the following Attribute/Variant: '{i}'\n"
|
|
||||||
f"Review the naming convention of Attribute and Variant collections here:\n{bcolors.RESET}"
|
|
||||||
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
allAttDataList[i] = {"name": name, "number": number, "rarity": rarity}
|
|
||||||
return allAttDataList
|
|
||||||
|
|
||||||
variantMetaData = attributeData(attributeVariants)
|
|
||||||
|
|
||||||
hierarchy = {}
|
|
||||||
for i in attributeCollections1:
|
|
||||||
colParLong = list(bpy.data.collections[str(i)].children)
|
|
||||||
colParShort = {}
|
|
||||||
for x in colParLong:
|
|
||||||
colParShort[x.name] = None
|
|
||||||
hierarchy[i] = colParShort
|
|
||||||
|
|
||||||
for a in hierarchy:
|
|
||||||
for b in hierarchy[a]:
|
|
||||||
for x in variantMetaData:
|
|
||||||
if str(x) == str(b):
|
|
||||||
(hierarchy[a])[b] = variantMetaData[x]
|
|
||||||
|
|
||||||
return hierarchy
|
|
||||||
|
|
||||||
|
|
||||||
def generateNFT_DNA(collectionSize, enableRarity, enableLogic, logicFile, enableMaterials, materialsFile, enable_debug):
|
def generateNFT_DNA(collectionSize, enableRarity, enableLogic, logicFile, enableMaterials, materialsFile, enable_debug):
|
||||||
|
@ -127,7 +15,7 @@ def generateNFT_DNA(collectionSize, enableRarity, enableLogic, logicFile, enable
|
||||||
Returns batchDataDictionary containing the number of NFT combinations, hierarchy, and the DNAList.
|
Returns batchDataDictionary containing the number of NFT combinations, hierarchy, and the DNAList.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
hierarchy = get_hierarchy()
|
hierarchy = Helpers.get_hierarchy()
|
||||||
|
|
||||||
# DNA random, Rarity and Logic methods:
|
# DNA random, Rarity and Logic methods:
|
||||||
DataDictionary = {}
|
DataDictionary = {}
|
||||||
|
@ -156,6 +44,48 @@ def generateNFT_DNA(collectionSize, enableRarity, enableLogic, logicFile, enable
|
||||||
|
|
||||||
return str(dna)
|
return str(dna)
|
||||||
|
|
||||||
|
def createDNArarity(hierarchy):
|
||||||
|
"""
|
||||||
|
Sorts through DataDictionary and appropriately weights each variant based on their rarity percentage set in Blender
|
||||||
|
("rarity" in DNA_Generator). Then
|
||||||
|
"""
|
||||||
|
singleDNA = ""
|
||||||
|
|
||||||
|
for i in hierarchy:
|
||||||
|
number_List_Of_i = []
|
||||||
|
rarity_List_Of_i = []
|
||||||
|
ifZeroBool = None
|
||||||
|
|
||||||
|
for k in hierarchy[i]:
|
||||||
|
number = hierarchy[i][k]["number"]
|
||||||
|
number_List_Of_i.append(number)
|
||||||
|
|
||||||
|
rarity = hierarchy[i][k]["rarity"]
|
||||||
|
rarity_List_Of_i.append(float(rarity))
|
||||||
|
|
||||||
|
for x in rarity_List_Of_i:
|
||||||
|
if x == 0:
|
||||||
|
ifZeroBool = True
|
||||||
|
elif x != 0:
|
||||||
|
ifZeroBool = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
if ifZeroBool:
|
||||||
|
variantByNum = random.choices(number_List_Of_i, k=1)
|
||||||
|
elif not ifZeroBool:
|
||||||
|
variantByNum = random.choices(number_List_Of_i, weights=rarity_List_Of_i, k=1)
|
||||||
|
except IndexError:
|
||||||
|
raise IndexError(
|
||||||
|
f"\n{Helpers.bcolors.ERROR}Blend_My_NFTs Error:\n"
|
||||||
|
f"An issue was found within the Attribute collection '{i}'. For more information on Blend_My_NFTs compatible scenes, "
|
||||||
|
f"see:\n{Helpers.bcolors.RESET}"
|
||||||
|
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
singleDNA += "-" + str(variantByNum[0])
|
||||||
|
singleDNA = ''.join(singleDNA.split('-', 1))
|
||||||
|
return singleDNA
|
||||||
|
|
||||||
def singleCompleteDNA():
|
def singleCompleteDNA():
|
||||||
"""
|
"""
|
||||||
This function applies Rarity and Logic to a single DNA created by createDNASingle() if Rarity or Logic specified
|
This function applies Rarity and Logic to a single DNA created by createDNASingle() if Rarity or Logic specified
|
||||||
|
@ -167,7 +97,7 @@ def generateNFT_DNA(collectionSize, enableRarity, enableLogic, logicFile, enable
|
||||||
# print("============")
|
# print("============")
|
||||||
# print(f"Original DNA: {singleDNA}")
|
# print(f"Original DNA: {singleDNA}")
|
||||||
if enableRarity:
|
if enableRarity:
|
||||||
singleDNA = Rarity.createDNArarity(hierarchy)
|
singleDNA = createDNArarity(hierarchy)
|
||||||
# print(f"Rarity DNA: {singleDNA}")
|
# print(f"Rarity DNA: {singleDNA}")
|
||||||
|
|
||||||
if enableLogic:
|
if enableLogic:
|
||||||
|
@ -297,13 +227,13 @@ def send_To_Record_JSON(collectionSize, nftsPerBatch, save_path, enableRarity, e
|
||||||
|
|
||||||
if not enableRarity and not enableLogic:
|
if not enableRarity and not enableLogic:
|
||||||
print(
|
print(
|
||||||
f"{bcolors.OK}NFT DNA will be determined randomly, no special properties or parameters are applied.\n{bcolors.RESET}")
|
f"{Helpers.bcolors.OK}NFT DNA will be determined randomly, no special properties or parameters are applied.\n{Helpers.bcolors.RESET}")
|
||||||
|
|
||||||
if enableRarity:
|
if enableRarity:
|
||||||
print(f"{bcolors.OK}Rarity is ON. Weights listed in .blend scene will be taken into account.\n{bcolors.RESET}")
|
print(f"{Helpers.bcolors.OK}Rarity is ON. Weights listed in .blend scene will be taken into account.\n{Helpers.bcolors.RESET}")
|
||||||
|
|
||||||
if enableLogic:
|
if enableLogic:
|
||||||
print(f"{bcolors.OK}Logic is ON. {len(list(logicFile.keys()))} rules detected and applied.\n{bcolors.RESET}")
|
print(f"{Helpers.bcolors.OK}Logic is ON. {len(list(logicFile.keys()))} rules detected and applied.\n{Helpers.bcolors.RESET}")
|
||||||
|
|
||||||
time_start = time.time()
|
time_start = time.time()
|
||||||
|
|
||||||
|
@ -325,10 +255,10 @@ def send_To_Record_JSON(collectionSize, nftsPerBatch, save_path, enableRarity, e
|
||||||
|
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
raise FileNotFoundError(
|
raise FileNotFoundError(
|
||||||
f"\n{bcolors.ERROR}Blend_My_NFTs Error:\n"
|
f"\n{Helpers.bcolors.ERROR}Blend_My_NFTs Error:\n"
|
||||||
f"Data not saved to NFTRecord.json. Please review your Blender scene and ensure it follows "
|
f"Data not saved to NFTRecord.json. Please review your Blender scene and ensure it follows "
|
||||||
f"the naming conventions and scene structure. For more information, "
|
f"the naming conventions and scene structure. For more information, "
|
||||||
f"see:\n{bcolors.RESET}"
|
f"see:\n{Helpers.bcolors.RESET}"
|
||||||
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
|
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
|
||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
|
@ -340,20 +270,20 @@ def send_To_Record_JSON(collectionSize, nftsPerBatch, save_path, enableRarity, e
|
||||||
outfile.write(ledger + '\n')
|
outfile.write(ledger + '\n')
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"\n{bcolors.OK}Blend_My_NFTs Success:\n"
|
f"\n{Helpers.bcolors.OK}Blend_My_NFTs Success:\n"
|
||||||
f"{len(DataDictionary['DNAList'])} NFT DNA saved to {NFTRecord_save_path}. NFT DNA Successfully created.\n{bcolors.RESET}")
|
f"{len(DataDictionary['DNAList'])} NFT DNA saved to {NFTRecord_save_path}. NFT DNA Successfully created.\n{Helpers.bcolors.RESET}")
|
||||||
|
|
||||||
except:
|
except:
|
||||||
raise (
|
raise (
|
||||||
f"\n{bcolors.ERROR}Blend_My_NFTs Error:\n"
|
f"\n{Helpers.bcolors.ERROR}Blend_My_NFTs Error:\n"
|
||||||
f"Data not saved to NFTRecord.json. Please review your Blender scene and ensure it follows "
|
f"Data not saved to NFTRecord.json. Please review your Blender scene and ensure it follows "
|
||||||
f"the naming conventions and scene structure. For more information, "
|
f"the naming conventions and scene structure. For more information, "
|
||||||
f"see:\n{bcolors.RESET}"
|
f"see:\n{Helpers.bcolors.RESET}"
|
||||||
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
|
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Loading Animation:
|
# Loading Animation:
|
||||||
loading = Loader(f'Creating NFT DNA...', '').start()
|
loading = Helpers.Loader(f'Creating NFT DNA...', '').start()
|
||||||
create_nft_data()
|
create_nft_data()
|
||||||
makeBatches(collectionSize, nftsPerBatch, save_path, batch_json_save_path)
|
makeBatches(collectionSize, nftsPerBatch, save_path, batch_json_save_path)
|
||||||
loading.stop()
|
loading.stop()
|
||||||
|
@ -361,5 +291,5 @@ def send_To_Record_JSON(collectionSize, nftsPerBatch, save_path, enableRarity, e
|
||||||
time_end = time.time()
|
time_end = time.time()
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"{bcolors.OK}Created and saved NFT DNA in {time_end - time_start}s.\n{bcolors.RESET}"
|
f"{Helpers.bcolors.OK}Created and saved NFT DNA in {time_end - time_start}s.\n{Helpers.bcolors.RESET}"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Purpose:
|
# Purpose:
|
||||||
# This file takes a given Batch created by DNA_Generator.py and tells blender to render the image or export a 3D model to
|
# This file takes a given Batch created by DNA_Generator.py and tells blender to render the image or export a 3D model
|
||||||
# the NFT_Output folder.
|
# to the NFT_Output folder.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import os
|
import os
|
||||||
|
|
123
main/Helpers.py
123
main/Helpers.py
|
@ -1,6 +1,7 @@
|
||||||
import bpy
|
import bpy
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
import copy
|
||||||
import platform
|
import platform
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from itertools import cycle
|
from itertools import cycle
|
||||||
|
@ -8,9 +9,6 @@ from threading import Thread
|
||||||
from shutil import get_terminal_size
|
from shutil import get_terminal_size
|
||||||
from collections import Counter, defaultdict
|
from collections import Counter, defaultdict
|
||||||
|
|
||||||
from . import DNA_Generator
|
|
||||||
|
|
||||||
|
|
||||||
# ======== ENABLE DEBUG ======== #
|
# ======== ENABLE DEBUG ======== #
|
||||||
|
|
||||||
# This section is used for debugging, coding, or general testing purposes.
|
# This section is used for debugging, coding, or general testing purposes.
|
||||||
|
@ -81,6 +79,121 @@ def save_result(result):
|
||||||
outfile.write(data + '\n')
|
outfile.write(data + '\n')
|
||||||
|
|
||||||
|
|
||||||
|
# ======== GET COMBINATIONS ======== #
|
||||||
|
|
||||||
|
# This section retrieves the Scene hierarchy from the current Blender file.
|
||||||
|
|
||||||
|
|
||||||
|
def get_hierarchy():
|
||||||
|
"""
|
||||||
|
Returns the hierarchy of a given Blender scene.
|
||||||
|
"""
|
||||||
|
|
||||||
|
coll = bpy.context.scene.collection
|
||||||
|
|
||||||
|
scriptIgnoreCollection = bpy.data.collections["Script_Ignore"]
|
||||||
|
|
||||||
|
listAllCollInScene = []
|
||||||
|
listAllCollections = []
|
||||||
|
|
||||||
|
def traverse_tree(t):
|
||||||
|
yield t
|
||||||
|
for child in t.children:
|
||||||
|
yield from traverse_tree(child)
|
||||||
|
|
||||||
|
for c in traverse_tree(coll):
|
||||||
|
listAllCollInScene.append(c)
|
||||||
|
|
||||||
|
for i in listAllCollInScene:
|
||||||
|
listAllCollections.append(i.name)
|
||||||
|
|
||||||
|
listAllCollections.remove(scriptIgnoreCollection.name)
|
||||||
|
|
||||||
|
if "Scene Collection" in listAllCollections:
|
||||||
|
listAllCollections.remove("Scene Collection")
|
||||||
|
|
||||||
|
if "Master Collection" in listAllCollections:
|
||||||
|
listAllCollections.remove("Master Collection")
|
||||||
|
|
||||||
|
def allScriptIgnore(scriptIgnoreCollection):
|
||||||
|
# Removes all collections, sub collections in Script_Ignore collection from listAllCollections.
|
||||||
|
|
||||||
|
for coll in list(scriptIgnoreCollection.children):
|
||||||
|
listAllCollections.remove(coll.name)
|
||||||
|
listColl = list(coll.children)
|
||||||
|
if len(listColl) > 0:
|
||||||
|
allScriptIgnore(coll)
|
||||||
|
|
||||||
|
allScriptIgnore(scriptIgnoreCollection)
|
||||||
|
listAllCollections.sort()
|
||||||
|
|
||||||
|
exclude = ["_"] # Excluding characters that identify a Variant
|
||||||
|
attributeCollections = copy.deepcopy(listAllCollections)
|
||||||
|
|
||||||
|
def filter_num():
|
||||||
|
"""
|
||||||
|
This function removes items from 'attributeCollections' if they include values from the 'exclude' variable.
|
||||||
|
It removes child collections from the parent collections in from the "listAllCollections" list.
|
||||||
|
"""
|
||||||
|
for x in attributeCollections:
|
||||||
|
if any(a in x for a in exclude):
|
||||||
|
attributeCollections.remove(x)
|
||||||
|
|
||||||
|
for i in range(len(listAllCollections)):
|
||||||
|
filter_num()
|
||||||
|
|
||||||
|
attributeVariants = [x for x in listAllCollections if x not in attributeCollections]
|
||||||
|
attributeCollections1 = copy.deepcopy(attributeCollections)
|
||||||
|
|
||||||
|
def attributeData(attributeVariants):
|
||||||
|
"""
|
||||||
|
Creates a dictionary of each attribute
|
||||||
|
"""
|
||||||
|
allAttDataList = {}
|
||||||
|
for i in attributeVariants:
|
||||||
|
# Check if name follows naming conventions:
|
||||||
|
if int(i.count("_")) > 2 and int(i.split("_")[1]) > 0:
|
||||||
|
raise Exception(
|
||||||
|
f"\n{bcolors.ERROR}Blend_My_NFTs Error:\n"
|
||||||
|
f"There is a naming issue with the following Attribute/Variant: '{i}'\n"
|
||||||
|
f"Review the naming convention of Attribute and Variant collections here:\n{bcolors.RESET}"
|
||||||
|
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
number = i.split("_")[1]
|
||||||
|
name = i.split("_")[0]
|
||||||
|
rarity = i.split("_")[2]
|
||||||
|
except IndexError:
|
||||||
|
raise Exception(
|
||||||
|
f"\n{bcolors.ERROR}Blend_My_NFTs Error:\n"
|
||||||
|
f"There is a naming issue with the following Attribute/Variant: '{i}'\n"
|
||||||
|
f"Review the naming convention of Attribute and Variant collections here:\n{bcolors.RESET}"
|
||||||
|
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
allAttDataList[i] = {"name": name, "number": number, "rarity": rarity}
|
||||||
|
return allAttDataList
|
||||||
|
|
||||||
|
variantMetaData = attributeData(attributeVariants)
|
||||||
|
|
||||||
|
hierarchy = {}
|
||||||
|
for i in attributeCollections1:
|
||||||
|
colParLong = list(bpy.data.collections[str(i)].children)
|
||||||
|
colParShort = {}
|
||||||
|
for x in colParLong:
|
||||||
|
colParShort[x.name] = None
|
||||||
|
hierarchy[i] = colParShort
|
||||||
|
|
||||||
|
for a in hierarchy:
|
||||||
|
for b in hierarchy[a]:
|
||||||
|
for x in variantMetaData:
|
||||||
|
if str(x) == str(b):
|
||||||
|
(hierarchy[a])[b] = variantMetaData[x]
|
||||||
|
|
||||||
|
return hierarchy
|
||||||
|
|
||||||
|
|
||||||
# ======== GET COMBINATIONS ======== #
|
# ======== GET COMBINATIONS ======== #
|
||||||
|
|
||||||
# This section is used to get the number of combinations for checks and the UI display
|
# This section is used to get the number of combinations for checks and the UI display
|
||||||
|
@ -91,7 +204,7 @@ def get_combinations():
|
||||||
combinations.
|
combinations.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
hierarchy = DNA_Generator.get_hierarchy()
|
hierarchy = get_hierarchy()
|
||||||
hierarchyByNum = []
|
hierarchyByNum = []
|
||||||
|
|
||||||
for i in hierarchy:
|
for i in hierarchy:
|
||||||
|
@ -140,7 +253,7 @@ def check_Scene(): # Not complete
|
||||||
f"\nhttps://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n{bcolors.RESET}"
|
f"\nhttps://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n{bcolors.RESET}"
|
||||||
)
|
)
|
||||||
|
|
||||||
hierarchy = DNA_Generator.get_hierarchy()
|
hierarchy = get_hierarchy()
|
||||||
collections = bpy.context.scene.collection
|
collections = bpy.context.scene.collection
|
||||||
|
|
||||||
# attribute_naming_conventions
|
# attribute_naming_conventions
|
||||||
|
|
|
@ -194,7 +194,9 @@ def get_rule_break_type(hierarchy, deconstructed_DNA, if_dict, result_dict, resu
|
||||||
|
|
||||||
|
|
||||||
def create_dicts(hierarchy, rule_list_items, result_dict_type):
|
def create_dicts(hierarchy, rule_list_items, result_dict_type):
|
||||||
# Example of output structure:
|
"""
|
||||||
|
Example of output structure:
|
||||||
|
|
||||||
structure = {
|
structure = {
|
||||||
"attribute1": {
|
"attribute1": {
|
||||||
"variant1": [
|
"variant1": [
|
||||||
|
@ -229,6 +231,7 @@ def create_dicts(hierarchy, rule_list_items, result_dict_type):
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
items_returned = collections.defaultdict(dict)
|
items_returned = collections.defaultdict(dict)
|
||||||
for a in rule_list_items:
|
for a in rule_list_items:
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
# Purpose:
|
|
||||||
# This file sorts the Variants in DNA slots based on the rarity value set in the name.
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import random
|
|
||||||
|
|
||||||
from .Helpers import bcolors, removeList, remove_file_by_extension
|
|
||||||
|
|
||||||
|
|
||||||
def createDNArarity(hierarchy):
|
|
||||||
"""
|
|
||||||
Sorts through DataDictionary and appropriately weights each variant based on their rarity percentage set in Blender
|
|
||||||
("rarity" in DNA_Generator). Then
|
|
||||||
"""
|
|
||||||
singleDNA = ""
|
|
||||||
|
|
||||||
for i in hierarchy:
|
|
||||||
number_List_Of_i = []
|
|
||||||
rarity_List_Of_i = []
|
|
||||||
ifZeroBool = None
|
|
||||||
|
|
||||||
for k in hierarchy[i]:
|
|
||||||
number = hierarchy[i][k]["number"]
|
|
||||||
number_List_Of_i.append(number)
|
|
||||||
|
|
||||||
rarity = hierarchy[i][k]["rarity"]
|
|
||||||
rarity_List_Of_i.append(float(rarity))
|
|
||||||
|
|
||||||
for x in rarity_List_Of_i:
|
|
||||||
if x == 0:
|
|
||||||
ifZeroBool = True
|
|
||||||
elif x != 0:
|
|
||||||
ifZeroBool = False
|
|
||||||
|
|
||||||
try:
|
|
||||||
if ifZeroBool:
|
|
||||||
variantByNum = random.choices(number_List_Of_i, k=1)
|
|
||||||
elif not ifZeroBool:
|
|
||||||
variantByNum = random.choices(number_List_Of_i, weights=rarity_List_Of_i, k=1)
|
|
||||||
except IndexError:
|
|
||||||
raise IndexError(
|
|
||||||
f"\n{bcolors.ERROR}Blend_My_NFTs Error:\n"
|
|
||||||
f"An issue was found within the Attribute collection '{i}'. For more information on Blend_My_NFTs compatible scenes, "
|
|
||||||
f"see:\n{bcolors.RESET}"
|
|
||||||
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
singleDNA += "-" + str(variantByNum[0])
|
|
||||||
singleDNA = ''.join(singleDNA.split('-', 1))
|
|
||||||
return singleDNA
|
|
Ładowanie…
Reference in New Issue