2021-11-27 01:25:07 +00:00
|
|
|
# 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
|
2021-12-01 21:50:40 +00:00
|
|
|
# the NFT_Output folder.
|
2021-11-21 17:39:43 +00:00
|
|
|
|
2021-10-19 19:10:54 +00:00
|
|
|
import bpy
|
|
|
|
import os
|
2021-11-15 00:23:31 +00:00
|
|
|
import time
|
|
|
|
import json
|
2021-10-19 19:10:54 +00:00
|
|
|
|
2021-11-01 04:11:48 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
enableGeneration = False
|
|
|
|
colorList = []
|
|
|
|
generationType = None
|
2021-11-27 00:43:13 +00:00
|
|
|
|
2021-12-20 02:01:08 +00:00
|
|
|
class bcolors:
|
|
|
|
'''
|
|
|
|
The colour of console messages.
|
|
|
|
'''
|
|
|
|
OK = '\033[92m' # GREEN
|
|
|
|
WARNING = '\033[93m' # YELLOW
|
|
|
|
ERROR = '\033[91m' # RED
|
|
|
|
RESET = '\033[0m' # RESET COLOR
|
2021-11-27 01:25:07 +00:00
|
|
|
|
2022-01-23 23:36:57 +00:00
|
|
|
|
2021-11-02 05:28:00 +00:00
|
|
|
def stripColorFromName(name):
|
|
|
|
return "_".join(name.split("_")[:-1])
|
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
def getBatchData(batchToGenerate, batch_json_save_path):
|
2022-01-28 21:56:59 +00:00
|
|
|
"""
|
2021-10-30 03:39:41 +00:00
|
|
|
Retrieves a given batches data determined by renderBatch in config.py
|
2022-01-28 21:56:59 +00:00
|
|
|
"""
|
2021-10-30 03:39:41 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
file_name = os.path.join(batch_json_save_path, "Batch{}.json".format(batchToGenerate))
|
2021-10-20 01:29:20 +00:00
|
|
|
batch = json.load(open(file_name))
|
2021-10-24 16:05:51 +00:00
|
|
|
|
2021-10-20 01:29:20 +00:00
|
|
|
NFTs_in_Batch = batch["NFTs_in_Batch"]
|
2021-10-24 16:05:51 +00:00
|
|
|
hierarchy = batch["hierarchy"]
|
2021-10-20 01:29:20 +00:00
|
|
|
BatchDNAList = batch["BatchDNAList"]
|
2021-10-19 19:10:54 +00:00
|
|
|
|
2021-10-24 16:05:51 +00:00
|
|
|
return NFTs_in_Batch, hierarchy, BatchDNAList
|
2021-10-19 19:10:54 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
def render_and_save_NFTs(nftName, maxNFTs, batchToGenerate, batch_json_save_path, nftBatch_save_path, enableImages,
|
|
|
|
imageFileFormat, enableAnimations, animationFileFormat, enableModelsBlender,
|
|
|
|
modelFileFormat
|
|
|
|
):
|
2022-01-28 21:56:59 +00:00
|
|
|
"""
|
2021-10-30 03:39:41 +00:00
|
|
|
Renders the NFT DNA in a Batch#.json, where # is renderBatch in config.py. Turns off the viewport camera and
|
|
|
|
the render camera for all items in hierarchy.
|
2022-01-28 21:56:59 +00:00
|
|
|
"""
|
2021-10-19 19:10:54 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
NFTs_in_Batch, hierarchy, BatchDNAList = getBatchData(batchToGenerate, batch_json_save_path)
|
2021-11-15 00:23:31 +00:00
|
|
|
|
2021-11-02 03:09:38 +00:00
|
|
|
time_start_1 = time.time()
|
|
|
|
|
2021-10-24 16:05:51 +00:00
|
|
|
x = 1
|
|
|
|
for a in BatchDNAList:
|
|
|
|
for i in hierarchy:
|
|
|
|
for j in hierarchy[i]:
|
2022-02-02 15:37:42 +00:00
|
|
|
if enableGeneration:
|
2022-01-28 21:56:59 +00:00
|
|
|
"""
|
2021-11-02 05:28:00 +00:00
|
|
|
Remove Color code so blender recognises the collection
|
2022-01-28 21:56:59 +00:00
|
|
|
"""
|
2021-11-02 05:28:00 +00:00
|
|
|
j = stripColorFromName(j)
|
2021-10-24 16:05:51 +00:00
|
|
|
bpy.data.collections[j].hide_render = True
|
|
|
|
bpy.data.collections[j].hide_viewport = True
|
2021-10-20 01:29:20 +00:00
|
|
|
|
2021-10-24 16:05:51 +00:00
|
|
|
def match_DNA_to_Variant(a):
|
2022-01-23 23:36:57 +00:00
|
|
|
"""
|
|
|
|
Matches each DNA number separated by "-" to its attribute, then its variant.
|
|
|
|
"""
|
2021-10-30 03:39:41 +00:00
|
|
|
|
2021-10-24 16:05:51 +00:00
|
|
|
listAttributes = list(hierarchy.keys())
|
2021-11-21 17:39:43 +00:00
|
|
|
listDnaDecunstructed = a.split('-')
|
2021-10-24 16:05:51 +00:00
|
|
|
dnaDictionary = {}
|
2021-10-20 01:29:20 +00:00
|
|
|
|
2021-11-21 17:39:43 +00:00
|
|
|
for i, j in zip(listAttributes, listDnaDecunstructed):
|
2021-10-24 16:05:51 +00:00
|
|
|
dnaDictionary[i] = j
|
2021-10-20 01:29:20 +00:00
|
|
|
|
2021-10-24 16:05:51 +00:00
|
|
|
for x in dnaDictionary:
|
|
|
|
for k in hierarchy[x]:
|
|
|
|
kNum = hierarchy[x][k]["number"]
|
|
|
|
if kNum == dnaDictionary[x]:
|
2021-11-21 17:39:43 +00:00
|
|
|
dnaDictionary.update({x: k})
|
2021-10-24 16:05:51 +00:00
|
|
|
return dnaDictionary
|
2021-10-20 01:29:20 +00:00
|
|
|
|
2021-10-30 03:39:41 +00:00
|
|
|
dnaDictionary = match_DNA_to_Variant(a)
|
2022-02-02 15:37:42 +00:00
|
|
|
name = nftName + "_" + str(x)
|
2021-10-20 01:29:20 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
print(f"\n{bcolors.OK}|---Generating NFT {x}/{NFTs_in_Batch} ---|{bcolors.RESET}")
|
2022-01-28 21:56:59 +00:00
|
|
|
print(f"DNA attribute list:\n{dnaDictionary}\nDNA Code:{a}")
|
2021-10-19 19:10:54 +00:00
|
|
|
|
2021-10-24 16:05:51 +00:00
|
|
|
for c in dnaDictionary:
|
|
|
|
collection = dnaDictionary[c]
|
2022-02-02 15:37:42 +00:00
|
|
|
if not enableGeneration:
|
2021-11-02 05:28:00 +00:00
|
|
|
bpy.data.collections[collection].hide_render = False
|
|
|
|
bpy.data.collections[collection].hide_viewport = False
|
2021-10-19 19:10:54 +00:00
|
|
|
|
2021-10-30 03:39:41 +00:00
|
|
|
time_start_2 = time.time()
|
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
batchFolder = os.path.join(nftBatch_save_path, "Batch" + str(batchToGenerate))
|
2021-12-03 22:05:55 +00:00
|
|
|
|
2021-12-09 16:28:28 +00:00
|
|
|
imagePath = os.path.join(batchFolder, "Images", name)
|
|
|
|
animationPath = os.path.join(batchFolder, "Animations", name)
|
|
|
|
modelPath = os.path.join(batchFolder, "Models", name)
|
2021-12-03 22:05:55 +00:00
|
|
|
|
|
|
|
imageFolder = os.path.join(batchFolder, "Images")
|
|
|
|
animationFolder = os.path.join(batchFolder, "Animations")
|
|
|
|
modelFolder = os.path.join(batchFolder, "Models")
|
2021-12-10 02:58:11 +00:00
|
|
|
metaDataFolder = os.path.join(batchFolder, "BMNFT_metaData")
|
2021-11-02 03:09:38 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
# Material handling:
|
|
|
|
if enableGeneration:
|
2021-11-02 05:28:00 +00:00
|
|
|
for c in dnaDictionary:
|
|
|
|
collection = dnaDictionary[c]
|
2022-02-02 15:37:42 +00:00
|
|
|
if stripColorFromName(collection) in colorList:
|
2021-11-21 17:39:43 +00:00
|
|
|
colorVal = int(collection.rsplit("_", 1)[1])-1
|
2021-11-02 05:28:00 +00:00
|
|
|
collection = stripColorFromName(collection)
|
|
|
|
bpy.data.collections[collection].hide_render = False
|
|
|
|
bpy.data.collections[collection].hide_viewport = False
|
2022-02-02 15:37:42 +00:00
|
|
|
if generationType == 'color':
|
2021-11-16 04:58:20 +00:00
|
|
|
for activeObject in bpy.data.collections[collection].all_objects:
|
|
|
|
mat = bpy.data.materials.new("PKHG")
|
2022-02-02 15:37:42 +00:00
|
|
|
mat.diffuse_color = colorList[collection][colorVal]
|
2021-11-16 04:58:20 +00:00
|
|
|
activeObject.active_material = mat
|
2022-02-02 15:37:42 +00:00
|
|
|
if generationType == 'material':
|
2021-11-16 04:58:20 +00:00
|
|
|
for activeObject in bpy.data.collections[collection].all_objects:
|
2022-02-02 15:37:42 +00:00
|
|
|
activeObject.material_slots[0].material = bpy.data.materials[colorList[collection][colorVal]]
|
2021-11-02 05:28:00 +00:00
|
|
|
else:
|
|
|
|
collection = stripColorFromName(collection)
|
|
|
|
bpy.data.collections[collection].hide_render = False
|
|
|
|
bpy.data.collections[collection].hide_viewport = False
|
2021-11-27 00:43:13 +00:00
|
|
|
|
2021-11-27 23:40:42 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
if enableImages:
|
|
|
|
print(f"{bcolors.OK}Rendering Image{bcolors.RESET}")
|
|
|
|
|
2021-12-03 22:05:55 +00:00
|
|
|
if not os.path.exists(imageFolder):
|
|
|
|
os.makedirs(imageFolder)
|
|
|
|
|
2021-11-27 23:40:42 +00:00
|
|
|
bpy.context.scene.render.filepath = imagePath
|
2022-02-02 15:37:42 +00:00
|
|
|
bpy.context.scene.render.image_settings.file_format = imageFileFormat
|
2021-11-27 23:40:42 +00:00
|
|
|
bpy.ops.render.render(write_still=True)
|
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
if enableAnimations:
|
|
|
|
print(f"{bcolors.OK}Rendering Animation{bcolors.RESET}")
|
2021-12-03 22:05:55 +00:00
|
|
|
if not os.path.exists(animationFolder):
|
|
|
|
os.makedirs(animationFolder)
|
2021-11-27 23:40:42 +00:00
|
|
|
|
2021-12-03 22:05:55 +00:00
|
|
|
bpy.context.scene.render.filepath = animationPath
|
2022-02-03 00:40:05 +00:00
|
|
|
|
|
|
|
if animationFileFormat == 'MP4':
|
|
|
|
bpy.context.scene.render.image_settings.file_format = "FFMPEG"
|
|
|
|
|
|
|
|
bpy.context.scene.render.ffmpeg.format = 'MPEG4'
|
|
|
|
bpy.context.scene.render.ffmpeg.codec = 'H264'
|
|
|
|
bpy.ops.render.render(animation=True)
|
|
|
|
|
|
|
|
else:
|
|
|
|
bpy.context.scene.render.image_settings.file_format = animationFileFormat
|
|
|
|
bpy.ops.render.render(animation=True)
|
2021-12-03 22:05:55 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
if enableModelsBlender:
|
|
|
|
print(f"{bcolors.OK}Generating 3D Model{bcolors.RESET}")
|
2021-12-03 22:05:55 +00:00
|
|
|
if not os.path.exists(modelFolder):
|
|
|
|
os.makedirs(modelFolder)
|
2021-11-27 23:40:42 +00:00
|
|
|
|
|
|
|
for i in dnaDictionary:
|
|
|
|
coll = dnaDictionary[i]
|
|
|
|
|
|
|
|
for obj in bpy.data.collections[coll].all_objects:
|
|
|
|
obj.select_set(True)
|
|
|
|
|
|
|
|
for obj in bpy.data.collections['Script_Ignore'].all_objects:
|
|
|
|
obj.select_set(True)
|
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
if modelFileFormat == 'GLB':
|
|
|
|
bpy.ops.export_scene.gltf(filepath=f"{modelPath}.glb",
|
2021-11-27 23:40:42 +00:00
|
|
|
check_existing=True,
|
|
|
|
export_format='GLB',
|
|
|
|
use_selection=True)
|
2022-02-02 15:37:42 +00:00
|
|
|
if modelFileFormat == 'GLTF_SEPARATE':
|
|
|
|
bpy.ops.export_scene.gltf(filepath=f"{modelPath}",
|
|
|
|
check_existing=True,
|
|
|
|
export_format='GLTF_SEPARATE',
|
|
|
|
use_selection=True)
|
|
|
|
if modelFileFormat == 'GLTF_EMBEDDED':
|
|
|
|
bpy.ops.export_scene.gltf(filepath=f"{modelPath}.gltf",
|
|
|
|
check_existing=True,
|
|
|
|
export_format='GLTF_EMBEDDED',
|
|
|
|
use_selection=True)
|
|
|
|
elif modelFileFormat == 'FBX':
|
|
|
|
bpy.ops.export_scene.fbx(filepath=f"{modelPath}.fbx",
|
2021-11-27 23:40:42 +00:00
|
|
|
check_existing=True,
|
|
|
|
use_selection=True)
|
2022-02-02 15:37:42 +00:00
|
|
|
elif modelFileFormat == 'OBJ':
|
|
|
|
bpy.ops.export_scene.obj(filepath=f"{modelPath}.obj",
|
2021-11-27 23:40:42 +00:00
|
|
|
check_existing=True,
|
|
|
|
use_selection=True)
|
2022-02-02 15:37:42 +00:00
|
|
|
elif modelFileFormat == 'X3D':
|
|
|
|
bpy.ops.export_scene.x3d(filepath=f"{modelPath}.x3d",
|
2021-11-27 23:40:42 +00:00
|
|
|
check_existing=True,
|
|
|
|
use_selection=True)
|
2022-02-03 00:40:05 +00:00
|
|
|
elif modelFileFormat == 'STL':
|
|
|
|
bpy.ops.export_mesh.stl(filepath=f"{modelPath}.stl",
|
|
|
|
check_existing=True,
|
|
|
|
use_selection=True)
|
2022-02-02 15:37:42 +00:00
|
|
|
elif modelFileFormat == 'VOX':
|
2022-02-03 00:40:05 +00:00
|
|
|
bpy.ops.export_vox.some_data(filepath=f"{modelPath}.vox")
|
2021-11-02 05:28:00 +00:00
|
|
|
|
2021-12-10 02:58:11 +00:00
|
|
|
if not os.path.exists(metaDataFolder):
|
|
|
|
os.makedirs(metaDataFolder)
|
2021-11-21 17:39:43 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
metaDataDict = {"name": name, "NFT_DNA": a, "NFT_Variants": dnaDictionary}
|
2021-12-09 17:13:41 +00:00
|
|
|
|
2021-12-10 02:58:11 +00:00
|
|
|
jsonMetaData = json.dumps(metaDataDict, indent=1, ensure_ascii=True)
|
2021-12-03 22:05:55 +00:00
|
|
|
|
2021-12-10 02:58:11 +00:00
|
|
|
with open(os.path.join(metaDataFolder, "Data_" + name + ".json"), 'w') as outfile:
|
|
|
|
outfile.write(jsonMetaData + '\n')
|
2021-11-21 17:39:43 +00:00
|
|
|
|
2021-11-02 22:56:45 +00:00
|
|
|
print("Completed {} render in ".format(name) + "%.4f seconds" % (time.time() - time_start_2))
|
2021-10-24 16:05:51 +00:00
|
|
|
x += 1
|
2021-11-10 04:13:53 +00:00
|
|
|
|
2022-02-02 15:37:42 +00:00
|
|
|
for a in BatchDNAList:
|
|
|
|
for i in hierarchy:
|
|
|
|
for j in hierarchy[i]:
|
|
|
|
if enableGeneration:
|
|
|
|
j = stripColorFromName(j)
|
|
|
|
bpy.data.collections[j].hide_render = False
|
|
|
|
bpy.data.collections[j].hide_viewport = False
|
|
|
|
|
|
|
|
print(f"\nAll NFTs successfully generated and sent to {nftBatch_save_path}")
|
|
|
|
print("Completed all renders in Batch{}.json in ".format(batchToGenerate) + "%.4f seconds" % (time.time() - time_start_1) + "\n")
|
2021-10-30 03:39:41 +00:00
|
|
|
|
2022-01-23 23:36:57 +00:00
|
|
|
|
2021-11-15 00:23:31 +00:00
|
|
|
if __name__ == '__main__':
|
2021-11-16 02:27:28 +00:00
|
|
|
render_and_save_NFTs()
|