Can a Render Token contain Special Characters?
-
Hi,
I want my custom render token to output a path fragment as for example
root/name
.So, when I have the render path
$MyRenderToken/myFile.png
, I want it to be resolved toroot/name/myFile.png
. All my attempts resulted in the path delimters being replaced with the underscore character, resulting in a directoryroot_name
instead of a pair of nested directoriesroot/name
.Thanks!
[edited by @ferdinand]: This is an interesting question which might be relevant for more users, so I took the liberty to make this posting more accesible.
Original posting by @Dunhou:
I want custom my render token,just like this folder structure
_[root/prj name/version/cam/prj name.png]
the function is done
but it seems token can only generate a file name?
Is there any possible to define a folder structure with a short word?
$RNDR = root/prj name/version/cam/prj name.png
but not : root_prj name_versio_cam_prj name.png
PS : I know I can save a new.c4d file to do this, but Still need a esay way to difine this ,
Thanks!
-
Hello @dunhou,
Thank you for reaching out to us. Unfortunately, the answer is no, you cannot escape this. In the backend, the render path handling has a list of special characters (
".", " ", "/", "?", "<", ">", "\\", ":", "*", "|", "(" ")"
) which will be replaced by the underscore character (_
). As you can see, this list includes the path delimiters for both Windows and macOS. Among other things, this replacement logic is applied to the output of render token callback functions. There is nothing you can do to prevent this.The only thing I could think of is to implement multiple tokens. So, let's say you want to depict a directory depth of up to 5. You would then have to implment the render tokens
$a, $b, $c, $d,
and$e
and enter a render path as shown below:$a/$b/$c/$d/$e/myFile.jpg
These tokens would have to analyze the path they are contained in and then output a desired folder structure, e.g., this:
a/b/c/d/e/myFile.jpg
You should also be able to produce shorter paths by for example let
$c
and$d
return the empty string when some condition x is met. This would formally result in this output:a/b///e/myFile.jpg
which is equivalent to
a/b/e/myFile.jpg
Cheers,
Ferdinand -
@ferdinand
Thanks for your repley. My personal solution is also use multiple custom tokens, but it is a bit painful QAQ.I have to reg multiple tokens and define a string include token symol by a command buttom script. A little annoying problem-.- but better than input by hand
Thanks for your help
-
@ferdinand
I try to return a empty string when project name don't have a delimiter like
_v
string , but in output path doesn't work anymore. This token just as a string in output:
C4D File name :token.c4d / token_v2.c4d
MyToken :$root/$rprj(real prj name with out _v[version])/$vn(version name)/$rprj
expect path A :token_v2.c4d > $root/token/v2/token.png
expect path Btoken.c4d > $root/token/token.png
but when there is no version in prj name[B], It's output like this:
token.c4d > $root/token/$vn[just the token symbol as str]/token.png
And this is the$vn
part code :import os import c4d import re delimiter = "_v" # Get version number def GetVersion(filePath): versionList = re.findall(delimiter+"\d+",filePath) if len(versionList) == 0: # If no versions found return None, None rawVersion = re.compile(delimiter).split(versionList[len(versionList)-1])[1] # [string] version = int(rawVersion) # [integer] return version, rawVersion # Thoken : Project Version Name with _v ($vn) def GetProjectVersionName(data): # _v2 prjName = data[0].GetDocumentName() ver = GetVersion(prjName)[1] # rawVersion [string] if ver == None: # if prj name have no delimiter component verStr = "" return verStr # null string else: verStr = delimiter + ver return verStr # _v2 if __name__=="__main__": for registeredToken in c4d.modules.tokensystem.GetAllTokenEntries(): if registeredToken.get("_token") in ["root", "rprj", "vn"]: exit() c4d.plugins.RegisterToken("vn", "DH Project Version Name", "v001", GetProjectVersionName)
Is there something wrong,please help me out.
Thank you -
Hey @dunhou,
Your code is fine, my suggestion simply does not work. I suggested it because I could have sworn this worked before and we show something similar with returning an empty string in the C++ Docs for the TOKENHOOK documentation.
Not sure what happened there, if this was always intended to work like this, or if this is a regression. The render token functionality is however not that old, so it likely is intended.
The culprit is this:
// #entry is here a render token String search = String("$" + entry.GetKey()); String value = CheckSpacialStrings(entry.GetValue()->GetString(const_cast<void*>(data))); if (value.IsPopulated()) { // The replacement of the token is prepared here ... }
So, when your token returns the empty string, it simply does not carry out the replacement. I am sorry that I have send you into the wrong direction. There is not really much left you can do, apart from ignoring the render token system altogether and implement this from scratch on your own.
Cheers,
Ferdinand -
@ferdinand
It's so sad , I'll try a script to define some output path token presets.
Hope it can work as expect.
Thanks for your answer -
A little update for this topic , my final solution for this problem is reg some tokens , and reg a plugin to analysis the project name and set token string depend on project name structure .
like a project name has a version sign like
_v
, than the output path set a$v
for render . All the tokens can set by the analysis plugin . It is a bit stupid way but work well for a quickly set render path just one click.Cheers