kopia lustrzana https://github.com/torrinworx/Blend_My_NFTs
commit
6adf409d7f
Plik binarny nie jest wyświetlany.
|
@ -2,4 +2,5 @@
|
|||
*.blend1
|
||||
*.json
|
||||
|
||||
NFTRecord.json
|
||||
NFTRecord.json
|
||||
3D_Model_Test.blend
|
|
@ -0,0 +1,4 @@
|
|||
# This directory is intentionarly ignored - this file only applies to the git repo
|
||||
*
|
||||
*/
|
||||
!.gitignore
|
|
@ -0,0 +1,4 @@
|
|||
# This directory is intentionarly ignored - this file only applies to the git repo
|
||||
*
|
||||
*/
|
||||
!.gitignore
|
BIN
Example.blend
BIN
Example.blend
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
|
@ -0,0 +1,105 @@
|
|||
import bpy
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import copy
|
||||
import time
|
||||
import json
|
||||
import itertools
|
||||
import importlib
|
||||
|
||||
dir = os.path.dirname(bpy.data.filepath)
|
||||
sys.path.append(dir)
|
||||
sys.modules.values()
|
||||
|
||||
from src.main import config
|
||||
importlib.reload(config)
|
||||
from src.main.config import *
|
||||
|
||||
class bcolors:
|
||||
'''
|
||||
The colour of console messages.
|
||||
'''
|
||||
OK = '\033[92m' # GREEN
|
||||
WARNING = '\033[93m' # YELLOW
|
||||
ERROR = '\033[91m' # RED
|
||||
RESET = '\033[0m' # RESET COLOR
|
||||
|
||||
time_start = time.time()
|
||||
|
||||
'''
|
||||
This sorter assumes that every object file variant for each attribute has a unique name. Names can include numbers, or
|
||||
any character value, but must be unique for each object.
|
||||
'''
|
||||
|
||||
def deleteAllObjects():
|
||||
'''
|
||||
Deletes all objects in the current scene open in Blender
|
||||
'''
|
||||
deleteListObjects = ['MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'HAIR', 'POINTCLOUD', 'VOLUME', 'GPENCIL',
|
||||
'ARMATURE', 'LATTICE', 'EMPTY', 'LIGHT', 'LIGHT_PROBE', 'CAMERA', 'SPEAKER']
|
||||
|
||||
for o in bpy.context.scene.objects:
|
||||
for i in deleteListObjects:
|
||||
if o.type == i:
|
||||
o.select_set(False)
|
||||
else:
|
||||
o.select_set(True)
|
||||
bpy.ops.object.delete()
|
||||
|
||||
attributeList = os.listdir(modelAssetPath)
|
||||
removeList = [".gitignore", ".DS_Store", "Script_Ignore_Folder"]
|
||||
attributeList = [x for x in attributeList if (x not in removeList)]
|
||||
hierarchy = {}
|
||||
|
||||
for i in attributeList:
|
||||
hierarchy[i] = os.listdir(modelAssetPath + slash + i)
|
||||
|
||||
def numOfCombinations(hierarchy):
|
||||
'''
|
||||
Returns "combinations" the number of all possible NFT combinations.
|
||||
'''
|
||||
hierarchyByNum = []
|
||||
for i in hierarchy:
|
||||
hierarchyByNum.append(len(hierarchy[i]))
|
||||
combinations = 1
|
||||
for i in hierarchyByNum:
|
||||
combinations = combinations*i
|
||||
|
||||
if combinations == 0:
|
||||
print(bcolors.FAIL + "ERROR:" + bcolors.RESET)
|
||||
print("The number of all possible combinations is equal to 0. Please review your collection hierarchy \n "
|
||||
"and ensure it is formatted correctly.")
|
||||
return combinations
|
||||
|
||||
combinations = numOfCombinations(hierarchy)
|
||||
allCombinationsNames = list(itertools.product(*hierarchy.values()))
|
||||
|
||||
count = 1
|
||||
for i in allCombinationsNames:
|
||||
if objectFormatImport == "gltf":
|
||||
path1 = modelAssetPath + slash + "Script_Ignore_Folder"
|
||||
Script_Ignore_Folder = os.listdir(path1)
|
||||
|
||||
for h in Script_Ignore_Folder:
|
||||
bpy.ops.import_scene.gltf(filepath=path1 + slash + h)
|
||||
|
||||
for j in i:
|
||||
def getParent(hierarchy):
|
||||
for x in hierarchy:
|
||||
for y in hierarchy[x]:
|
||||
if y == j:
|
||||
return x
|
||||
|
||||
parent = getParent(hierarchy)
|
||||
path2 = modelAssetPath + slash + parent + slash + j
|
||||
|
||||
if objectFormatImport == "gltf":
|
||||
bpy.ops.import_scene.gltf(filepath=path2)
|
||||
|
||||
bpy.ops.export_scene.gltf(filepath=model_save_path + slash + imageName + str(count),
|
||||
check_existing=True, export_format='GLB')
|
||||
deleteAllObjects()
|
||||
count += 1
|
||||
|
||||
print("Generated .glb files in %.4f seconds" % (time.time() - time_start))
|
Plik binarny nie jest wyświetlany.
|
@ -51,7 +51,7 @@ def makeBatches():
|
|||
|
||||
batchDictionaryObject = json.dumps(batchDictionary, indent=1, ensure_ascii=True)
|
||||
|
||||
with open(batch_path + slash + ("Batch{}.json".format(i+1)), "w") as outfile:
|
||||
with open(batch_save_path + slash + ("Batch{}.json".format(i + 1)), "w") as outfile:
|
||||
outfile.write(batchDictionaryObject)
|
||||
|
||||
i += 1
|
||||
|
@ -66,5 +66,5 @@ def makeBatches():
|
|||
|
||||
incompleteBatch = json.dumps(incompleteBatch, indent=1, ensure_ascii=True)
|
||||
|
||||
with open(batch_path + slash + ("Batch{}.json".format(i+1)), "w") as outfile2:
|
||||
with open(batch_save_path + slash + ("Batch{}.json".format(i + 1)), "w") as outfile2:
|
||||
outfile2.write(incompleteBatch)
|
|
@ -23,6 +23,9 @@ importlib.reload(Rarity_Sorter)
|
|||
from src.generators_and_sorters.Rarity_Sorter import *
|
||||
|
||||
class bcolors:
|
||||
'''
|
||||
The colour of console messages.
|
||||
'''
|
||||
OK = '\033[92m' # GREEN
|
||||
WARNING = '\033[93m' # YELLOW
|
||||
ERROR = '\033[91m' # RED
|
||||
|
@ -40,52 +43,74 @@ def checkCollectionChildNames():
|
|||
#AreaLigjht_1_0 != AreaLight_2_0
|
||||
#AreaLigjht vs AreaLight
|
||||
return True
|
||||
|
||||
def returnData():
|
||||
'''
|
||||
Generates important variables, dictionaries, and lists needed to be stored to catalog the NFTs.
|
||||
:return: listAllCollections, attributeCollections, attributeCollections1, hierarchy, variantMetaData, possibleCombinations
|
||||
'''
|
||||
|
||||
listAllCollections = []
|
||||
coll = bpy.context.scene.collection
|
||||
scriptIgnore = 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)
|
||||
|
||||
def listSubIgnoreCollections():
|
||||
def getParentSubCollections(collection):
|
||||
yield collection
|
||||
for child in collection.children:
|
||||
yield from getParentSubCollections(child)
|
||||
|
||||
collList = []
|
||||
for c in getParentSubCollections(scriptIgnore):
|
||||
collList.append(c.name)
|
||||
return collList
|
||||
|
||||
ignoreList = listSubIgnoreCollections()
|
||||
for i in bpy.data.collections:
|
||||
|
||||
for i in listAllCollInScene:
|
||||
if generateColors:
|
||||
if i.name in colorList:
|
||||
for j in range(len(colorList[i.name])):
|
||||
if i.name[-1].isdigit() and i.name not in ignoreList:
|
||||
listAllCollections.append(i.name + "_" + str(j+1))
|
||||
listAllCollections.append(i.name + "_" + str(j + 1))
|
||||
elif j == 0:
|
||||
listAllCollections.append(i.name)
|
||||
elif i.name[-1].isdigit() and i.name not in ignoreList:
|
||||
listAllCollections.append(i.name+"_0")
|
||||
listAllCollections.append(i.name + "_0")
|
||||
else:
|
||||
listAllCollections.append(i.name)
|
||||
listAllCollections.append(i.name)
|
||||
else:
|
||||
listAllCollections.append(i.name)
|
||||
listAllCollections.remove(scriptIgnore.name)
|
||||
listAllCollections.remove("Master Collection")
|
||||
|
||||
def allScriptIgnore(collection):
|
||||
'''
|
||||
Removes all collections, sub collections in Script_Ignore" collection from listAllCollections.
|
||||
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)
|
||||
|
@ -218,7 +243,6 @@ def returnData():
|
|||
"\nthose in Script_Ignore:")
|
||||
print(hierarchy)
|
||||
|
||||
|
||||
numBatches = combinations/nftsPerBatch
|
||||
|
||||
if numBatches < 1:
|
||||
|
@ -322,15 +346,9 @@ def turnAll(toggle):
|
|||
|
||||
# ONLY FOR TESTING, DO NOT EVER USE IF RECORD IS FULL OF REAL DATA
|
||||
# THIS WILL DELETE THE RECORD:
|
||||
# Also don't forget to add an empty list when its done to NFTRecord or else this file can't run properly.
|
||||
# Note - NFTRecrod.json will be created the next time you run main.py
|
||||
def clearNFTRecord(AREYOUSURE):
|
||||
if AREYOUSURE == True:
|
||||
file_name = os.path.join(save_path, "../../NFTRecord.json")
|
||||
print("Wiping NFTRecord.json of all data...")
|
||||
os.remove("NFTRecord.json")
|
||||
|
||||
ledger = json.load(open(file_name))
|
||||
|
||||
with open(file_name, 'w') as outfile:
|
||||
ledger.clear()
|
||||
outfile.close()
|
||||
#clearNFTRecord()
|
|
@ -25,7 +25,7 @@ def getBatchData():
|
|||
Retrieves a given batches data determined by renderBatch in config.py
|
||||
'''
|
||||
|
||||
file_name = os.path.join(batch_path, "Batch{}.json".format(renderBatch))
|
||||
file_name = os.path.join(batch_save_path, "Batch{}.json".format(renderBatch))
|
||||
batch = json.load(open(file_name))
|
||||
|
||||
NFTs_in_Batch = batch["NFTs_in_Batch"]
|
||||
|
@ -96,7 +96,7 @@ def render_and_save_NFTs():
|
|||
|
||||
imageOutputBatchSubFolder = "Batch" + str(renderBatch)
|
||||
|
||||
fullImagePath = images_path + slash + imageOutputBatchSubFolder + slash + "{}.jpeg".format(name)
|
||||
fullImagePath = images_save_path + slash + imageOutputBatchSubFolder + slash + "{}.jpeg".format(name)
|
||||
|
||||
if generateColors:
|
||||
for c in dnaDictionary:
|
||||
|
|
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
|
@ -14,9 +14,10 @@ includeRarity = False
|
|||
# True = include weighted rarity percentages in NFTRecord.json calculations,
|
||||
# False = Pure random selection of variants
|
||||
|
||||
resetViewport = True # Turns all viewport and render cameras on after Image_Generator
|
||||
resetViewport = True # If True: turns all viewport and render cameras on after Image_Generator is finished operations
|
||||
|
||||
generateColors = True # When set to true this applies the sets of colors listed below to the objects in the collections named below
|
||||
# Object colour options:
|
||||
generateColors = True # When set to true this applies the sets of colors listed below to the objects in the collections named below
|
||||
|
||||
# The collections below are RGBA Color values. You can put as many or as little color values in these lists as you would like.
|
||||
# You can create any number of rgbaColorLists and assign them to any number of collections that you would like.
|
||||
|
@ -49,5 +50,28 @@ elif platform.system() == windows:
|
|||
slash = '\\'
|
||||
|
||||
# Paths to folders
|
||||
batch_path = save_path + slash + 'Batch_Json_files'
|
||||
images_path = save_path + slash + 'NFT_Image_Output'
|
||||
batch_save_path = save_path + slash + 'Batch_Json_files' # The output path for batches genreated by Batch_Sorter.py
|
||||
images_save_path = save_path + slash + 'NFT_Image_Output' # The output path for images generated by Image_Generator.py
|
||||
|
||||
# 3D model imports and exports variables:
|
||||
useModels = False # Set to True if useing external models as attributes instead of Blender objects
|
||||
|
||||
objectFormatImport = 'gltf' # The file format of the objects you would like to import
|
||||
objectFormatExport = 'gltf' # The file format of the objects you would like to export
|
||||
|
||||
# The following are file formats Blender accepts for importing and exporting object files.
|
||||
# Please use the exact name provided below in the '' above:
|
||||
# fbx - The .FBX file format
|
||||
# gltf - The .glb file format
|
||||
# obj - The .obj file format
|
||||
# x3d - The .x3d file format
|
||||
|
||||
# Specify the XYZ location for objects imported as external files:
|
||||
locationObjectAttribute = {
|
||||
"Cone": {"x":0, "y":0, "z":0},
|
||||
"Cube": {"x":0, "y":0, "z":0}
|
||||
}
|
||||
|
||||
# Utilities - DO NOT TOUCH:
|
||||
modelAssetPath = save_path + slash + "3D_Model_Input" # The input path for 3D models
|
||||
model_save_path = save_path + slash + "3D_Model_Output" # The output path for 3D models generated by DNA_Generator_3D_Models.py
|
|
@ -19,5 +19,11 @@ from src.generators_and_sorters.DNA_Generator import *
|
|||
importlib.reload(Batch_Sorter)
|
||||
from src.generators_and_sorters.Batch_Sorter import *
|
||||
|
||||
DNA_Generator.send_To_Record_JSON()
|
||||
Batch_Sorter.makeBatches()
|
||||
if not useModels:
|
||||
DNA_Generator.send_To_Record_JSON()
|
||||
Batch_Sorter.makeBatches()
|
||||
|
||||
'''
|
||||
if useModels:
|
||||
# Some function that activates DNA_Generator_3D_Models.py
|
||||
'''
|
Ładowanie…
Reference in New Issue