On 24/07/2017 at 01:30, xxxxxxxx wrote:
Hello,
Is it possible to set layers from .psd files?
I did find layersets in the SDK, but i cant find a way to set them.
On 24/07/2017 at 01:30, xxxxxxxx wrote:
Hello,
Is it possible to set layers from .psd files?
I did find layersets in the SDK, but i cant find a way to set them.
On 24/07/2017 at 08:13, xxxxxxxx wrote:
Here a code I did 6 months ago. So it's not the cleanest but it's working and since this subject is not very well documented I guess It gonna help you ;)
def setAlpha(self,path,shader) :
if path.endswith( ('.psd' , '.PSD') ) : #PSD
bc = c4d.BaseContainer()
bc.SetFilename(c4d.LOADTEXTURE_FILENAME, path.encode('utf-8'))
tex = c4d.modules.bodypaint.SendPainterCommand(c4d.PAINTER_LOADTEXTURE, doc=self.doc, tex=None, bc=bc)
if tex is False:
print path
return
layer = tex.GetFirstLayer()
layerName = layer.GetName()
layermode = c4d.LAYERSETMODE_LAYERALPHA
c4d.modules.bodypaint.SendPainterCommand(c4d.PAINTER_FORCECLOSETEXTURE, doc=self.doc, tex=tex, bc=c4d.BaseContainer())
else:#tiff, But if you already know the name simply use this
layerName = 'Alpha'
layermode = c4d.LAYERSETMODE_ALPHAS
layerSet = c4d.LayerSet()
layerSet.SetMode(layermode)
layerSet.AddLayer(layerName)
shader[c4d.BITMAPSHADER_LAYERSET] = layerSet
If it's an psd it load it and have a c4d.modules.bodypaint.PaintTexture object.
Then now you are able to list all the layer. I my case I always used the first layer, but you can loop using GetNext/GetDown, in other way if you already know the name of the layer simply use the exemple for the tiff ;)
Then after you just have to create a LayerSet and set thoses data.
Hope it's helped
On 27/07/2017 at 03:12, xxxxxxxx wrote:
Little extra question:
I have a test code that can find a psd layer by name and then sets it. but it returns only the name. I need it to return the path in the psd. like somefolder/somefolder/lmb_tp
right now it only returns the name of layer that i'm seeking.
import c4d
from c4d import gui
#Welcome to the world of Python
path = 'C:/Program Files/MAXON/CINEMA 4D R18/library/scripts/rig_menu/test.psd'
def main() :
bc = c4d.BaseContainer()
bc.SetFilename(c4d.LOADTEXTURE_FILENAME, path.encode('utf-8'))
tex = c4d.modules.bodypaint.SendPainterCommand(c4d.PAINTER_LOADTEXTURE, doc=doc, tex=None, bc=bc)
mat = doc.SearchMaterial("Mat.1")
layerName = ''
layers = tex.GetFirstLayer()
#search for name and store in layername
layerName = FindLayerPSD(layers, 'lmb_tp')
c4d.modules.bodypaint.SendPainterCommand(c4d.PAINTER_FORCECLOSETEXTURE, doc=doc, tex=tex, bc=c4d.BaseContainer())
layerSet = c4d.LayerSet()
#set color
layermode = c4d.LAYERSETMODE_LAYERS
layerSet.AddLayer(layerName)
layerSet.SetMode(layermode)
sha = mat[c4d.MATERIAL_COLOR_SHADER]
sha[c4d.BITMAPSHADER_LAYERSET] = layerSet
mat[c4d.MATERIAL_COLOR_SHADER] = sha
#set alpha
layermode = c4d.LAYERSETMODE_LAYERALPHA
layerSet.AddLayer(layerName)
layerSet.SetMode(layermode)
sha = mat[c4d.MATERIAL_ALPHA_SHADER]
sha[c4d.BITMAPSHADER_LAYERSET] = layerSet
mat[c4d.MATERIAL_ALPHA_SHADER] = sha
#force redraw
c4d.CallCommand(12147)
c4d.EventAdd()
def GetNextObject(op) :
if op==None:
return None
if op.GetDown() :
return op.GetDown()
while not op.GetNext() and op.GetUp() :
op = op.GetUp()
return op.GetNext()
def FindLayerPSD(op, gname) :
if op is None:
return
count = 0
while op:
count += 1
if gname in op.GetName() :
layername = op.GetName()
op = GetNextObject(op)
return layername
if __name__=='__main__':
main()
On 27/07/2017 at 03:42, xxxxxxxx wrote:
I did it for object but since BaseObject and c4d.modules.bodypaint.PaintTexture are both BaseList2D that change nothing.
I comment it(maybe too much? :p) but if you still don't understand a part feel free to ask ;)
import c4d
def get_full_path(op) :
full_path = list()
while op:
full_path.append(op.GetName())
op = op.GetUp()
#Since we build from bottom to parent we need to reverse the list to keep it consistent
full_path.reverse()
#Then we join for build our string line
str_full_path = "/".join(full_path)
return str_full_path
def find_by_name(op, name_to_find) :
#We loop throught all op
while op:
#If the name is the same then our name to find we lunch our function to get the full path then we return
if op.GetName() == name_to_find:
return get_full_path(op)
#We lunch recusrive search like that we get also child object
#Since it's recursive function that mean a child function can have fund the object
#Then if a child function make a return we also need to return in the parent function
return_value = find_by_name(op.GetDown(), name_to_find)
if return_value is not None:
return return_value
#then finally we go the next object
op = op.GetNext()
#If we return here that mean we never get op.GetName == name_to_find so we return None
return None
def main() :
print find_by_name(doc.GetFirstObject(), "aa")
if __name__=='__main__':
main()