Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login
    1. Maxon Developers Forum
    2. till.niese
    3. Topics
    T
    • Profile
    • Following 0
    • Followers 0
    • Topics 5
    • Posts 12
    • Best 0
    • Controversial 0
    • Groups 0

    Topics created by till.niese

    • T

      Control whether a redshift shader node port is collapsed or not.

      Cinema 4D SDK
      • 2023 c++ • • till.niese
      4
      0
      Votes
      4
      Posts
      656
      Views

      ferdinandF

      Hello @till-niese,

      No, that is not possible for public API users. As I tried to indicate before, you are operating here on the data model of the graph with GraphModelInterface. There is also a GraphModelPresenterInterface which is the presenter and provides some GUI logic as selecting nodes and wires, but that interface is non-public.

      The toggle state of a widget is buried deep in the presenter and not even exposed over the interface. There are also the non-public attributes about which I talked before. I went ahead and wrote some code trying to emulate access in the public API [1], but unsurprisingly, there is nothing to be found in the public graphs, the code will not print anything.

      It is simply not possible to do what you want to do here, and it is quite common for our APIs to not expose GUI functionalities. In the case of the Node API, the complexities of the MVP application model are added on top of that. There can be multiple presenters coordinating multiple views on a singular model. Or in less fancy: One can have multiple node editors opened on the same graph.

      The toggle state of a port bundle/group is shared between all editors at the moment. And aside from a principal stance of the feasibility of exposing GUIs, there might be substantial problems with exposing the toggle state despite the external perception that is just "this one thing"; I do not know for sure since I am not familiar with the implementation details here, but I would not be surprised.

      In the Asset API we had a similar case with people wanting to know "the selected asset" and our answer then being "that is an ambiguous question because there can be more than one Asset Browser". In the Asset API the solution is to open your own Asset Browser where you can then get that state. There is AFAIK currently no alternative solution as such for your problem, e.g., a node command which would toggle the folding state of a port. We could think about adding such command, but I doubt that I will find many supporters for this idea.

      Cheers,
      Ferdinand

      [1]

      // graph is a maxon::NodesGraphModelRef/GraphModelRef instance // rustTexNode is a RS Texture GraphNode in #graph. maxon::GraphNode root = graph.GetRoot(); maxon::GraphNode portBundle = rustTexNode.GetInputs().FindChild( maxon::Id("com.redshift3d.redshift4c4d.nodes.core.texturesampler.tex0")) iferr_return; // Iterate over candidates where this widget data is internally to be found, a graph root, a true // node, and a port (bundle). for (const maxon::GraphNode& node : { root, rustTexNode, portBundle }) { // Iterate over some attribute identifiers where GUI widget data is stored internally. for (const maxon::String& attr : { "widgetDataBlackBox"_s, "widgetDataBlackBoxSM"_s, "widgetDataBlackBoxOut"_s }) { maxon::InternedId attrId; attrId.Init("widgetDataBlackBoxOut") iferr_return; // Get the widget data stored at the maxon attribute #attr and iterate over its entries, the // data will always be empty/null. const maxon::DataDictionary attrData = node.GetValue<maxon::DataDictionary>( attrId).GetValueOrNull() iferr_return; for (const auto& entry : attrData) { const maxon::Data key = entry.first.GetCopy() iferr_return; const maxon::Data value = entry.second.GetCopy() iferr_return; ApplicationOutput("node: @, attr: @, key: @, value: @, type: @", node, attr, key, value, value.GetType()); } } }
    • T

      Set the Preview of an Asset using an Image file.

      Cinema 4D SDK
      • 2023 python • • till.niese
      8
      0
      Votes
      8
      Posts
      1.3k
      Views

      ferdinandF

      Hello @tdapper,

      I still do not fully understand what you want to do, but in general, my answer does not change much. I do not want to be rude here, but in C++ you have everything you need. And what you want to do here, is fundamentally interfere with how the Asset API works. Such low-level access is traditionally the domain of the C++ API and not the Python API.

      Bottom line is that it's cool that the asset browser automatically creates thumbnails [...]

      That was less me showing off the features of the asset API and more pointing out its general approach.

      Therefore we are basically trying to replicate the functionality you get when you right-click on the thumbnail in the Asset Browser and Click "Update Thumbnail from File...".

      'Update Thumbnail from File...' will not prevent thumbnails from being overwritten either. So the only way to do so, would be to make the metadata entry read-only as pointed out in my first posting.

      Perhaps there is a way to just immediately kill the job that creates the thumbnail from being generated in the background or prevent that job from starting in the first place.

      If that is not possible, maybe there is a message we could intercept to know the thumbnail has been updated so we can run our workaround right after the thumbnail creation job is finished instead of waiting a hardcoded amount of time.

      Maybe there is another option that we're not clearly seeing right now?

      Neither your first nor second option are possible. The preview thumbnail job queue is non-public and there is no such thing as messages in the maxon API. There are Observables which realize the idea of events, but they are not exposed in Python nor are you able to stop a preview rendering with them.

      Again, I do not want to be rude here, but as pointed out in my first posting, what you want to do is not intended. You could get hacky from the Python API, but that is more or less up to you.

      982bbbbf-ca43-4f16-a85c-b9b5cb836a6f-image.png
      Fig. 1: The physical location of thumbnails for local assets is always the same, net.maxon.asset.previewimageurl.meta.png.

      With that knowledge one can infer the future pyhsical location of a thumbnail for a local asset.

      # Create a new object asset. asset: maxon.AssetDescription = maxon.AssetCreationInterface.CreateObjectAsset( obj, doc, storeAssetStruct, assetId, assetName, assetVersion, assetMetadata, True) # Get the physical location of the asset #asset, normally one should not touch # AssetDescriptionInterface.GetUrl(). Then get the directory of that path and infer the # preview thumbnail location from it. assetUrl: maxon.Url = asset.GetUrl() assetPath: maxon.Url = maxon.Url(assetUrl.GetSystemPath()) previewFile: maxon.Url = assetPath + maxon.Url("net.maxon.asset.previewimageurl.meta.png") # Print out the paths, #previewFile won't yet exist at this point, because the thumbnailing is # parallelized. print (f"{assetUrl = }") print (f"{assetPath = }") print (f"{previewFile = }") print (f"{os.path.exists(previewFile.GetUrl()) = }")

      Example output:

      assetUrl = file:///C:/Users/f_hoppe/AppData/Roaming/Maxon/2023.1.3_97ABE84B/userrepository/object_a2c9ff14d748481fb9a8ae03d7bfa9b7/1/asset.c4d assetPath = file:///C:/Users/f_hoppe/AppData/Roaming/Maxon/2023.1.3_97ABE84B/userrepository/object_a2c9ff14d748481fb9a8ae03d7bfa9b7/1/ previewFile = file:///C:/Users/f_hoppe/AppData/Roaming/Maxon/2023.1.3_97ABE84B/userrepository/object_a2c9ff14d748481fb9a8ae03d7bfa9b7/1/net.maxon.asset.previewimageurl.meta.png os.path.exists(previewFile.GetUrl()) = False

      With that knowledge you could start messing with that file. But that is obviously out of scope of support and a hack. Otherwise you will have to use the C++ API or file a bug report for your thumbnails being black in the first place.

      Cheers,
      Ferdinand

    • T

      CreateRepositoryFromUrl results in TypeError in 2023

      Cinema 4D SDK
      • python 2023 • • till.niese
      4
      0
      Votes
      4
      Posts
      593
      Views

      T

      Hi @m_adam, this works perfectly. Thank you for your fast response.

    • T

      MSG_MULTI_CLEARSUGGESTEDFOLDER not called for TeamRender

      Cinema 4D SDK
      • c++ r25 • • till.niese
      6
      0
      Votes
      6
      Posts
      779
      Views

      ManuelM

      hi,

      if I'm correct, you are trying to implement a NodeData plugin right?

      On this node, you are doing some action based on files that you store inside your own structure and not any baselink? Those files must be considered as assets.

      When you start a teamrender render, MSG_GETALLASSETS will broadcast to retrieve all the assets. You must react to the message so your assets will be collected. See this manual for more information.
      While collecting those assets, it can happen that assets have to be renamed if those assets share the same name but are in different directories. This will be done using MSG_RENAMETEXTURES. In that case, RenameTextureMessage will be sent as data and you will have to update the assets filename of your NodeData, either the baselink or your structure.

      Once collected, all the assets will be in the same directory as the .c4d file.

      Now the client will open the project and will try to retrieve the asset, it could happen that the message MSG_RENAMETEXTURES will be triggered again.

      Your code should work if the filename you retrieve from the hyperfile is updated.

      Cheers,
      Manuel

    • T

      Path delimiter behaves differntly on macOS and Windows for HyperFile ReadFilename

      Cinema 4D SDK
      • c++ r25 • • till.niese
      4
      0
      Votes
      4
      Posts
      591
      Views

      ferdinandF

      Hello @till-niese,

      I did not say or want to imply that this is expected, I will have to test it myself. In the meantime, you can use maxon::Url as shown above to normalize paths if that is of importance for you. I will report back here when I have tried replicating your findings. When there is a bug, we will have to decide if we will fix it. The classic API is a dormant API and the bug, if it is there, does not seem to critical. I cannot tell you right away "that is a bug, and we will fix it (or not)", as this involves multiple operating systems and serialization of paths, which both can be tricky subjects.

      Cheers,
      Ferdinand