Blend_3D_collections/main/material_generator.py

139 wiersze
5.4 KiB
Python

# Purpose:
# The purpose of this file is to apply the materials a user sets in a given .json file to the Variant collection objects
# also specified in the .json file. The Materialized DNA is then returned in the following format: 1-1-1:1-1-1
# Where the numbers right of the ":" are the material numbers applied to the respective Variants to the left of the ":"
import json
import random
from .helpers import TextColors
def select_material(material_list, variant, enable_rarity):
"""Selects a material from a passed material list. """
material_list_of_i = [] # List of Material names instead of order numbers
rarity_list_of_i = []
if_zero_bool = None
for material in material_list:
# Material Order Number comes from index in the Material List in materials.json for a given Variant.
# material_order_num = list(material_list.keys()).index(material)
material_list_of_i.append(material)
material_rarity_percent = material_list[material]
rarity_list_of_i.append(float(material_rarity_percent))
# print(f"MATERIAL_LIST_OF_I:{material_list_of_i}")
# print(f"RARITY_LIST_OF_I:{rarity_list_of_i}")
for b in rarity_list_of_i:
if b == 0:
if_zero_bool = True
elif b != 0:
if_zero_bool = False
if enable_rarity:
try:
if if_zero_bool:
selected_material = random.choices(material_list_of_i, k=1)
elif not if_zero_bool:
selected_material = random.choices(material_list_of_i, weights=rarity_list_of_i, k=1)
except IndexError:
raise IndexError(
f"\n{TextColors.ERROR}Blend_My_NFTs Error:\n"
f"An issue was found within the Material List of the Variant collection '{variant}'. For more "
f"information on Blend_My_NFTs compatible scenes, see:\n{TextColors.RESET}"
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
)
else:
try:
selected_material = random.choices(material_list_of_i, k=1)
except IndexError:
raise IndexError(
f"\n{TextColors.ERROR}Blend_My_NFTs Error:\n"
f"An issue was found within the Material List of the Variant collection '{variant}'. For more "
f"information on Blend_My_NFTs compatible scenes, see:\n{TextColors.RESET}"
f"https://github.com/torrinworx/Blend_My_NFTs#blender-file-organization-and-structure\n"
)
return selected_material[0], material_list
def get_variant_att_index(variant, hierarchy):
variant_attribute = None
for attribute in hierarchy:
for variant_h in hierarchy[attribute]:
if variant_h == variant:
variant_attribute = attribute
attribute_index = list(hierarchy.keys()).index(variant_attribute)
variant_order_num = variant.split("_")[1]
return attribute_index, variant_order_num
def match_dna_to_variant(hierarchy, single_dna):
"""
Matches each DNA number separated by "-" to its attribute, then its variant.
"""
list_attributes = list(hierarchy.keys())
list_dna_decunstructed = single_dna.split('-')
dna_dictionary = {}
for i, j in zip(list_attributes, list_dna_decunstructed):
dna_dictionary[i] = j
for x in dna_dictionary:
for k in hierarchy[x]:
k_num = hierarchy[x][k]["number"]
if k_num == dna_dictionary[x]:
dna_dictionary.update({x: k})
return dna_dictionary
def apply_materials(hierarchy, single_dna, materials_file, enable_rarity):
"""
DNA with applied material example: "1-1:1-1" <Normal DNA>:<Selected Material for each Variant>
The Material DNA will select the material for the Variant order number in the NFT DNA based on the Variant Material
list in the Variant_Material.json file.
"""
single_dna_dict = match_dna_to_variant(hierarchy, single_dna)
materials_file = json.load(open(materials_file))
deconstructed_material_dna = {}
for a in single_dna_dict:
complete = False
for b in materials_file:
if single_dna_dict[a] == b:
material_name, material_list, = select_material(materials_file[b]['Material List'], b, enable_rarity)
# Gets the Order Number of the Material
material_order_num = list(material_list.keys()).index(material_name)
deconstructed_material_dna[a] = str(material_order_num + 1)
complete = True
if not complete:
deconstructed_material_dna[a] = "0"
# This section is now incorrect and needs updating:
# Make Attributes have the same materials:
# Order your Attributes alphabetically, then assign each Attribute a number, starting with 0. So Attribute 'A' = 0,
# Attribute 'B' = 1, 'C' = 2, 'D' = 3, etc. For each pair you want to equal another, add its number it to this list:
# synced_material_attributes = [1, 2]
#
# first_mat = deconstructed_material_dna[synced_material_attributes[0]]
# for i in synced_material_attributes:
# deconstructed_material_dna[i] = first_mat
material_dna = ""
for a in deconstructed_material_dna:
num = "-" + str(deconstructed_material_dna[a])
material_dna += num
material_dna = ''.join(material_dna.split('-', 1))
return f"{single_dna}:{material_dna}"