Icons reuse
-
Hi there,
I am working on a popup menu, and I want to add icon before the text, but questions is some icons I didn't find a symbol or id, like redshift nodes in node editor, I find some svg files in resources folder, but how can I reuse this in a popup menu, if they are not a build-in icon, my solution is RegisterIcon() with a id and use a simple warp:
- So how the icons in node editor works or where I get them with an id?
- How the UnregisterIcon works or when should we use this, should I un-reg icons when quit cinema? it seems this will be automatic done in background( when quit c4d and delete the RegisterIcon, next start the icon will be gone ).
# 1 def get_icon(source) -> c4d.bitmaps.BaseBitmap: ... c4d.gui.RegisterIcon(EXCEL_ICON, get_bitmap("excel")) # 2 def get_icon(source) -> str: return "&i" + str(source) + "&" # 3 bc.SetString(10, get_icon(5159)+"占位字符")
Cheers~
DunHou -
Hey @Dunhou,
Thank you for reaching out to us. The node editor (more precisely the nodes API) is using SVG files to express its icons. The concept of registered (bitmap) icons does not apply here. Node (templates) store their icon under the attribute
net.maxon.node.base.icon
as aCString
. The type is not wrapped for Python, and we therefore cannot read it here.Until we wrap
CString
for Python, there is not much you can do here. For things like Redshift or Scene Nodes, you could just grep the Cinema 4D folder forSVG
files and then hardcode the paths you need. For everything else, this is not so easy, as you for example do not know where a user might have installed Vray or Arnold (if you want to support them).PS: Unregistering icons is usually not something you have to do. Since all registrations are volatile over app instances, unregistering at shutdown is meaningless (because all registration data will not be serialized anyways). Unregistering icons can be useful when you want to make an icon inaccessible at runtime or want to update its bitmap.
Cheers,
FerdinandCode:
"""Demonstrates how to theoretically retrieve the icon URL of a node. This does not work because the type CString is not wrapped for Python and we therefore cannot read the node attribute. WARNING: This code snippet does not work as of 2024.1.0. """ #coding: utf-8 import c4d import maxon doc: c4d.documents.BaseDocument # The active document. def main() -> None: """Runs the example. """ # Get the Redshift graph for the first material in the document. material: c4d.BaseMaterial = doc.GetFirstMaterial() if not material: raise MemoryError(f"{material = }") nodeMaterial: c4d.NodeMaterial = material.GetNodeMaterialReference() graph: maxon.NodesGraphModelInterface = nodeMaterial.GetGraph( maxon.Id("com.redshift3d.redshift4c4d.class.nodespace")) if graph.IsNullValue(): raise RuntimeError("Could not add RS graph to material.") # Iterate over all true nodes in the graph and get their icon url attribute. root: maxon.GraphNode = graph.GetRoot() for node in root.GetInnerNodes(maxon.NODE_KIND.NODE, False): url: str = node.GetValue("net.maxon.node.base.icon") # If we try to do pretty much anything else than printing the type, this will throw an # error because #url is actually of type <class 'maxon.interface.UnknownDataType'> print(type(url)) if __name__ == "__main__": main()
-
Hi @ferdinand ,
Thanks for your explain, I would convert the svg files to png then regist them for a temp solution, and wait the attribute valid in python.
Thanks always for your awesome works.
Cheers~
DunHou