2022-02-03 00:40:05 +00:00
|
|
|
import bpy
|
|
|
|
import re
|
|
|
|
import copy
|
|
|
|
|
|
|
|
class bcolors:
|
2022-02-04 14:44:36 +00:00
|
|
|
"""
|
2022-02-03 00:40:05 +00:00
|
|
|
The colour of console messages.
|
2022-02-04 14:44:36 +00:00
|
|
|
"""
|
2022-02-03 00:40:05 +00:00
|
|
|
OK = '\033[92m' # GREEN
|
|
|
|
WARNING = '\033[93m' # YELLOW
|
|
|
|
ERROR = '\033[91m' # RED
|
|
|
|
RESET = '\033[0m' # RESET COLOR
|
|
|
|
|
|
|
|
def stripColorFromName(name):
|
|
|
|
return "_".join(name.split("_")[:-1])
|
|
|
|
|
|
|
|
def get_combinations_from_scene():
|
2022-02-04 14:44:36 +00:00
|
|
|
"""
|
2022-02-03 00:40:05 +00:00
|
|
|
Generates important variables, dictionaries, and lists needed to be stored to catalog the NFTs.
|
|
|
|
:return: listAllCollections, attributeCollections, attributeCollections1, hierarchy, variantMetaData, possibleCombinations
|
2022-02-04 14:44:36 +00:00
|
|
|
"""
|
2022-02-03 00:40:05 +00:00
|
|
|
|
|
|
|
coll = bpy.context.scene.collection
|
|
|
|
|
|
|
|
try:
|
|
|
|
scriptIgnore = bpy.data.collections["Script_Ignore"]
|
|
|
|
except:
|
|
|
|
print(f"{bcolors.ERROR} ERROR:\nScript_Ignore collection is not in .blend file scene. Please add the Script_Ignore collection to your "
|
|
|
|
f".blend file scene. For more information, read the README.md file.\n {bcolors.RESET}")
|
|
|
|
|
|
|
|
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:
|
2022-03-25 12:22:28 +00:00
|
|
|
listAllCollections.append(i.name)
|
2022-02-03 00:40:05 +00:00
|
|
|
|
|
|
|
listAllCollections.remove(scriptIgnore.name)
|
|
|
|
|
|
|
|
if "Scene Collection" in listAllCollections:
|
|
|
|
listAllCollections.remove("Scene Collection")
|
|
|
|
|
|
|
|
if "Master Collection" in listAllCollections:
|
|
|
|
listAllCollections.remove("Master Collection")
|
|
|
|
|
|
|
|
def allScriptIgnore(collection):
|
|
|
|
'''
|
|
|
|
Removes all collections, sub collections in Script_Ignore collection from listAllCollections.
|
|
|
|
'''
|
|
|
|
for coll in list(collection.children):
|
|
|
|
listAllCollections.remove(coll.name)
|
|
|
|
listColl = list(coll.children)
|
|
|
|
if len(listColl) > 0:
|
|
|
|
allScriptIgnore(coll)
|
|
|
|
|
|
|
|
allScriptIgnore(scriptIgnore)
|
|
|
|
listAllCollections.sort()
|
|
|
|
|
|
|
|
exclude = ["_", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
|
|
|
|
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 = {}
|
|
|
|
count = 0
|
|
|
|
previousAttribute = ""
|
|
|
|
for i in attributeVariants:
|
|
|
|
|
|
|
|
def getName(i):
|
|
|
|
"""
|
|
|
|
Returns the name of "i" attribute variant
|
|
|
|
"""
|
|
|
|
name = i.split("_")[0]
|
|
|
|
return name
|
|
|
|
|
|
|
|
def getOrder_rarity(i):
|
|
|
|
"""
|
|
|
|
Returns the "order", "rarity" and "color" (if enabled) of i attribute variant in a list
|
|
|
|
"""
|
|
|
|
x = re.sub(r'[a-zA-Z]', "", i)
|
|
|
|
a = x.split("_")
|
|
|
|
del a[0]
|
|
|
|
return list(a)
|
|
|
|
|
|
|
|
name = getName(i)
|
|
|
|
orderRarity = getOrder_rarity(i)
|
|
|
|
|
|
|
|
if len(orderRarity) == 0:
|
|
|
|
print(f"{bcolors.ERROR} \nERROR: {bcolors.RESET}")
|
|
|
|
print(f"The collection {i} doesn't follow the naming conventions of attributes. Please move this \n"
|
|
|
|
"colleciton to Script_Ignore or review proper collection format in README.md")
|
|
|
|
return
|
|
|
|
|
|
|
|
elif len(orderRarity) > 0:
|
|
|
|
number = orderRarity[0]
|
|
|
|
rarity = orderRarity[1]
|
2022-03-25 12:22:28 +00:00
|
|
|
|
|
|
|
eachObject = {"name": name, "number": number, "rarity": rarity}
|
2022-02-03 00:40:05 +00:00
|
|
|
allAttDataList[i] = eachObject
|
|
|
|
return allAttDataList
|
|
|
|
|
|
|
|
variantMetaData = attributeData(attributeVariants)
|
|
|
|
|
|
|
|
def getHierarchy():
|
|
|
|
"""
|
|
|
|
Constructs the hierarchy dictionary from attributeCollections1 and variantMetaData.
|
|
|
|
"""
|
|
|
|
hierarchy = {}
|
|
|
|
for i in attributeCollections1:
|
|
|
|
colParLong = list(bpy.data.collections[str(i)].children)
|
|
|
|
colParShort = {}
|
|
|
|
for x in colParLong:
|
2022-03-25 12:22:28 +00:00
|
|
|
colParShort[x.name] = None
|
2022-02-03 00:40:05 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
hierarchy = getHierarchy()
|
|
|
|
|
|
|
|
def numOfCombinations(hierarchy):
|
|
|
|
"""
|
|
|
|
Returns "combinations" the number of all possible NFT combinations.
|
|
|
|
"""
|
|
|
|
|
|
|
|
hierarchyByNum = []
|
|
|
|
|
|
|
|
for i in hierarchy:
|
|
|
|
# Ignore Collections with nothing in them
|
|
|
|
if len(hierarchy[i]) != 0:
|
|
|
|
hierarchyByNum.append(len(hierarchy[i]))
|
|
|
|
else:
|
|
|
|
print(f"The following collection has been identified as empty: {i}")
|
|
|
|
|
|
|
|
combinations = 1
|
|
|
|
for i in hierarchyByNum:
|
|
|
|
combinations = combinations*i
|
|
|
|
|
|
|
|
if combinations == 0:
|
|
|
|
print(bcolors.ERROR + "\nERROR:" + bcolors.RESET)
|
|
|
|
print("The number of all possible combinations is equal to 0. Please review your collection hierarchy"
|
|
|
|
"and ensure it is formatted correctly. Please review README.md for more information. \nHere is the "
|
|
|
|
"hierarchy of all collections the DNA_Generator gathered from your .blend file, excluding those in "
|
|
|
|
f"Script_Ignore: {hierarchy}")
|
|
|
|
|
|
|
|
return combinations
|
|
|
|
|
|
|
|
possibleCombinations = numOfCombinations(hierarchy)
|
|
|
|
|
|
|
|
return possibleCombinations
|