pull/135/head
Torrin Leonard 2022-06-03 22:47:09 -04:00
rodzic 7bb741a185
commit 6495b12654
4 zmienionych plików z 94 dodań i 116 usunięć

Wyświetl plik

@ -199,7 +199,7 @@ def generateNFT_DNA(collectionSize, enableRarity, enableLogic, logicFile, enable
# print(f"Rarity DNA: {singleDNA}")
if enableLogic:
singleDNA = Logic.logicafyDNAsingle(hierarchy, singleDNA, logicFile)
singleDNA = Logic.logicafyDNAsingle(hierarchy, singleDNA, logicFile, enableRarity)
# print(f"Original DNA: {singleDNA}")
# print("============\n")
@ -328,7 +328,7 @@ def send_To_Record_JSON(collectionSize, nftsPerBatch, save_path, enableRarity, e
print(f"{bcolors.OK}Rarity is ON. Weights listed in .blend scene will be taken into account.\n{bcolors.RESET}")
if enableLogic:
print(f"{bcolors.OK}Logic is ON. Rules listed in {logicFile} will be taken into account.\n{bcolors.RESET}")
print(f"{bcolors.OK}Logic is ON. {len(list(logicFile.keys()))} rules from your Logic.json file will be applied.\n{bcolors.RESET}")
time_start = time.time()

Wyświetl plik

@ -413,13 +413,13 @@ def render_and_save_NFTs(input):
if not os.path.exists(solanaMetadataPath):
os.makedirs(solanaMetadataPath)
createSolanaMetaData(name, Order_Num, full_single_dna, dnaDictionary, metadataMaterialDict, input.custom_Fields,
input.enableCustomFields, input.cardano_description, solanaMetadataPath)
input.enableCustomFields, input.solana_description, solanaMetadataPath)
if input.erc721MetaData:
if not os.path.exists(erc721MetadataPath):
os.makedirs(erc721MetadataPath)
createErc721MetaData(name, Order_Num, full_single_dna, dnaDictionary, metadataMaterialDict, input.custom_Fields,
input.enableCustomFields, input.cardano_description, erc721MetadataPath)
input.enableCustomFields, input.erc721_description, erc721MetadataPath)
if not os.path.exists(BMNFT_metaData_Folder):
os.makedirs(BMNFT_metaData_Folder)

Wyświetl plik

@ -2,10 +2,11 @@
# The purpose of this file is to add logic and rules to the DNA that are sent to the NFTRecord.json file in DNA_Generator.py
import bpy
import json
import random
import collections
from .Constants import bcolors, removeList, remove_file_by_extension
# Helper Functions
def isAttorVar(hierarchy, items_List):
@ -26,11 +27,13 @@ def isAttorVar(hierarchy, items_List):
return dict(items_returned)
def getAttIndex(hierarchy, attribute):
attList = list(hierarchy.keys())
index = attList.index(attribute)
return index
def getVarNum(variant):
if variant == "Empty":
num = '0'
@ -38,6 +41,7 @@ def getVarNum(variant):
num = variant.split("_")[1]
return num
def items_to_num(items_List):
num_List = {}
for i in items_List:
@ -49,47 +53,70 @@ def items_to_num(items_List):
num_List[i] = variant_num_list
return num_List
def rar_selectVar(hierarchy, items_List, deconstructed_DNA):
for attribute in items_List:
a_attribute_index = getAttIndex(hierarchy, attribute)
def select_from_then_list(hierarchy, deconstructed_DNA, then_num_list, enableRarity):
for a in then_num_list:
selected_variants = items_List[attribute]
hierarchy_selected_variants = list(hierarchy[attribute])
a_attribute_index = getAttIndex(hierarchy, a)
selected_variants = then_num_list[a]
hierarchy_selected_variants = list(hierarchy[a])
# Left over variants are removed for when the user only specifies individual variants instead of whole attributes
left_over_variants = [x for x in hierarchy_selected_variants if x not in selected_variants]
# If 'a' is a full attribute:
if not left_over_variants:
deconstructed_DNA[int(a_attribute_index)] = "0"
# If 'a' is only part of an attribute (the user specified variant(s) from the attribute that don't add to the full
# attribute):
else:
number_List_Of_i = []
rarity_List_Of_i = []
ifZeroBool = None
variantNum = None
for a in left_over_variants:
number = a.split("_")[1]
rarity = a.split("_")[2]
for b in left_over_variants:
number = b.split("_")[1]
rarity = b.split("_")[2]
number_List_Of_i.append(int(number))
rarity_List_Of_i.append(float(rarity))
for x in rarity_List_Of_i:
if x == 0:
for b in rarity_List_Of_i:
if b == 0:
ifZeroBool = True
elif x != 0:
elif b != 0:
ifZeroBool = False
if ifZeroBool:
variantNum = random.choices(number_List_Of_i, k=1)
if not ifZeroBool:
variantNum = random.choices(number_List_Of_i, weights=rarity_List_Of_i, k=1)
if enableRarity:
try:
if ifZeroBool:
variantNum = random.choices(number_List_Of_i, k=1)
elif not ifZeroBool:
variantNum = 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 '{a}'. 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"
)
else:
try:
variantNum = random.choices(number_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 '{a}'. 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"
)
deconstructed_DNA[int(a_attribute_index)] = str(variantNum[0])
return deconstructed_DNA
def reconstructDNA(deconstructedDNA):
reconstructed_DNA = ""
for a in deconstructedDNA:
@ -97,117 +124,57 @@ def reconstructDNA(deconstructedDNA):
reconstructed_DNA += num
return (''.join(reconstructed_DNA.split('-', 1)))
def strip_empty_variant(num_list):
"""Strips empty variants if full attribute collection. Used for processing below."""
for i in num_list:
var_list = num_list[i]
def check_if_dna_violates_rules(hierarchy, deconstructed_DNA, if_num_list, then_num_list):
"""Returns True if singleDNA violates Rules stated in a Logic.json file."""
violates_rule = None
# Strips empty variants if full attribute collection
for i in if_num_list:
var_list = if_num_list[i]
if "0" in var_list:
var_list.remove("0")
num_list[i] = var_list
return num_list
if_num_list[i] = var_list
# Rule Checks:
def never_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
"""Returns True if singleDNA violates Never with Rule stated in Logic.json."""
violates_rule = None
for a in if_num_list:
for b in then_num_list:
# The attributes slot value from the DNA given 'a' from if_num_list and 'b' from then_num_list:
attribute_slot_value_IF = str(deconstructed_DNA[getAttIndex(hierarchy, a)])
attribute_slot_value_THEN = str(deconstructed_DNA[getAttIndex(hierarchy, b)])
num_List1 = strip_empty_variant(num_List1)
num_List2 = strip_empty_variant(num_List2)
for a in num_List1:
for b in num_List2:
if str(deconstructed_DNA[getAttIndex(hierarchy, a)]) in num_List1[a] and \
str(deconstructed_DNA[getAttIndex(hierarchy, b)]) in num_List2[b]:
if attribute_slot_value_IF in if_num_list[a] and attribute_slot_value_THEN in then_num_list[b]:
violates_rule = True
return violates_rule
else:
violates_rule = False
return violates_rule
def only_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
"""Returns True if singleDNA violates Only with Rule stated in Logic.json."""
violates_rule = None
for a in num_List1:
for b in num_List2:
if str(deconstructed_DNA[getAttIndex(hierarchy, a)]) in num_List1[a] and \
str(deconstructed_DNA[getAttIndex(hierarchy, b)]) not in num_List2[b]:
violates_rule = True
return violates_rule
else:
violates_rule = False
return violates_rule
def always_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
"""Returns True if singleDNA violates Always with Rule stated in Logic.json."""
violates_rule = None
for a in num_List2:
if str(deconstructed_DNA[getAttIndex(hierarchy, a)]) not in num_List2[a]:
violates_rule = True
return violates_rule
else:
violates_rule = False
return violates_rule
# Main Function
def logicafyDNAsingle(hierarchy, singleDNA, logicFile):
def logicafyDNAsingle(hierarchy, singleDNA, logicFile, enableRarity):
deconstructed_DNA = singleDNA.split("-")
didReconstruct = True
originalDNA = str(singleDNA)
while didReconstruct:
didReconstruct = False
for rule in logicFile:
items_List1 = isAttorVar(hierarchy, logicFile[rule]["Items-1"])
items_List2 = isAttorVar(hierarchy, logicFile[rule]["Items-2"])
num_List1 = items_to_num(items_List1)
num_List2 = items_to_num(items_List2)
# Items from 'IF' key for a given rule
if_list = isAttorVar(hierarchy, logicFile[rule]["IF"])
if_num_list = items_to_num(if_list)
if logicFile[rule]["Rule-Type"] == "Never With":
if never_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
# Items from 'THEN' key for a given rule
then_list = isAttorVar(hierarchy, logicFile[rule]["THEN"])
then_num_list = items_to_num(then_list)
rand_bool = bool(random.getrandbits(1))
if check_if_dna_violates_rules(hierarchy, deconstructed_DNA, if_num_list, then_num_list):
deconstructed_DNA = select_from_then_list(hierarchy, deconstructed_DNA, then_num_list, enableRarity)
if rand_bool:
deconstructed_DNA = rar_selectVar(hierarchy, items_List2, deconstructed_DNA)
if not rand_bool:
deconstructed_DNA = rar_selectVar(hierarchy, items_List1, deconstructed_DNA)
newDNA = reconstructDNA(deconstructed_DNA)
if newDNA != originalDNA:
originalDNA = str(newDNA)
didReconstruct = True
break
if logicFile[rule]["Rule-Type"] == "Only With":
if only_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
for b in num_List1:
if "0" in num_List1[b]: # If complete attribute
deconstructed_DNA[getAttIndex(hierarchy, b)] = "0"
if "0" not in num_List1[b]: # Not complete attribute, select from other variants with rarity:
deconstructed_DNA = rar_selectVar(hierarchy, items_List1, deconstructed_DNA)
newDNA = reconstructDNA(deconstructed_DNA)
if newDNA != originalDNA:
originalDNA = str(newDNA)
didReconstruct = True
break
if logicFile[rule]["Rule-Type"] == "Always With":
if always_with_Rule_Check(hierarchy, deconstructed_DNA, num_List1, num_List2):
deconstructed_DNA = rar_selectVar(hierarchy, items_List1, deconstructed_DNA)
newDNA = reconstructDNA(deconstructed_DNA)
if newDNA != originalDNA:
originalDNA = str(newDNA)
didReconstruct = True
break
newDNA = reconstructDNA(deconstructed_DNA)
if newDNA != originalDNA:
originalDNA = str(newDNA)
didReconstruct = True
break
return str(reconstructDNA(deconstructed_DNA))

Wyświetl plik

@ -4,6 +4,9 @@
import bpy
import random
from .Constants 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
@ -32,10 +35,18 @@ def createDNArarity(hierarchy):
elif x != 0:
ifZeroBool = False
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)
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))