Hello!
First of all a disclaimer, I'm a beginner in python and coding in general, so if i'm doing things the wrong way don't hesitate to point me to the relevant documentation
For context, this script is aimed to rassemble all the used textures of the scene into a folder, either on a local disk or network storage in a studio environment. The goal is to support all shader types, and for the moment i have Standard, Octane and RS Xpresso thanks to some code from Aoktar and r_gigante.
My problem lies with the new Node Editor and material system which confuses me a lot.
I think i have read all the topics talking about textures paths, i even tried to understand the RS Api made by DunHouGo but i couldn't find anything that ressemble the workflow i'm using for the other types of materials.
I think i will also have a problem down the line with my method to compare filename if the texture is located in the asset browser, so if you have any pointers towards that would be incredible!
Here is the code :
import pipelineLib
import os
import shutil
import c4d
import filecmp
import maxon
def get_tex_path_local():
path = d:\\02_3D\\c4d_cache
return local_path
def sync_folders(src_folder, dst_folder): # FILE SYNC
if not os.path.exists(dst_folder):
os.makedirs(dst_folder)
print(f"The destination folder '{dst_folder}' was created")
src_files = set(os.listdir(src_folder))
dst_files = set(os.listdir(dst_folder))
# Find files that are in src_folder but not in dst_folder
new_files = src_files - dst_files
for filename in new_files:
src_file = os.path.join(src_folder, filename)
dst_file = os.path.join(dst_folder, filename)
with open(src_file, 'rb') as fsrc:
with open(dst_file, 'wb') as fdst:
fdst.write(fsrc.read())
# Find files that are in both src_folder and dst_folder
common_files = src_files & dst_files
for filename in common_files:
src_file = os.path.join(src_folder, filename)
dst_file = os.path.join(dst_folder, filename)
if not filecmp.cmp(src_file, dst_file):
with open(src_file, 'rb') as fsrc:
with open(dst_file, 'wb') as fdst:
fdst.write(fsrc.read())
def get_doc():
doc = c4d.documents.GetActiveDocument()
return doc
def get_materials_dict():
if not hasattr(get_materials_dict, 'textures'):
doc = get_doc()
textures = list()
c4d.documents.GetAllAssetsNew(doc, False, "", c4d.ASSETDATA_FLAG_TEXTURESONLY, textures)
get_materials_dict.textures = textures
for t in textures:
print("DICT:", t)
return get_materials_dict.textures
def set_redshift_node_path_local():
output_path = get_tex_path_local() #Get the new path
textures = get_materials_dict() # GetAllAssetsNew
textures_rs = [t for t in textures if 'texturesampler' in str(t['nodePath'])] # Clean the dictionary
for t in textures_rs:
textureOwner = t["owner"]
filename = t["filename"]
head, tail = os.path.split(filename) # Filename extract
new_filename = os.path.join(output_path, tail) # Filename merge
if not os.path.exists(new_filename) and "\\images\\" not in filename: # Verify if the file exist in the folder
shutil.copy2(filename, new_filename)
if filename == new_filename:
print("File already exist in local cache") # Identical file check
...
elif "d:\\02_3D\\c4d_cache" in filename:
print("File already exist in local cache") # Folder path check
...
elif "\\images\\" in filename: # Skip Roto/Plate images on the server
print("File skipped")
...
else:
try: # Set the new path, this is where it's not working
print("try")
textureOwner[maxon.Id("com.redshift3d.redshift4c4d.nodes.core.texturesampler.tex0")] = new_filename
except:
print("Not supported, use other scripts")
# notify Cinema about the changes
c4d.EventAdd()
This is what the console outputs :
# Verify if the project is connected to the pipe
tpl : \\my\network\folder
# Local cache output path resolved if the pipe exist, otherwise print error and return
tpl : d:\02_3D\c4d_cache\motion_dev\tex
DICT: {'filename': 'C:\\Users\\myname\\Downloads\\camellia-4881662.jpg', 'assetname': 'C:\\Users\\myname\\Downloads\\camellia-4881662.jpg', 'channelId': 3, 'netRequestOnDemand': True, 'owner': <c4d.Material object called Mat/Mat with ID 5703 at 3191915188736>, 'exists': True, 'paramId': -1, 'nodePath': '[email protected]$nLrnAxFRmq2S7wjxLCrZ', 'nodeSpace': 'com.redshift3d.redshift4c4d.class.nodespace'}
DICT: {'filename': 'C:\\Users\\myname\\Pictures\\images.jpg', 'assetname': 'C:\\Users\\myname\\Pictures\\images.jpg', 'channelId': 3, 'netRequestOnDemand': True, 'owner': <c4d.Material object called Mat.1/Mat with ID 5703 at 3191915354112>, 'exists': True, 'paramId': -1, 'nodePath': '[email protected]', 'nodeSpace': 'com.redshift3d.redshift4c4d.class.nodespace'}
try
try
But unfortunatly the path doesn't change, i know it's wrong but i cannot wrap my head around this logic for the moment
Thank you in advance for any help you can provide!