PSD Layersets
-
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.https://developers.maxon.net/docs/py/2023_2/modules/c4d/CustomDataType/LayerSet/index.html
-
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 tiffThen after you just have to create a LayerSet and set thoses data.
Hope it's helped -
On 26/07/2017 at 08:25, xxxxxxxx wrote:
Thanks works like a charm!
-
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()
-
On 27/07/2017 at 04:27, xxxxxxxx wrote:
Thanks for the fast reply, exactly what i was looking for