SOLVED Can I download a Tex in Asset Browser and add into select RS node mat?

Is it possible to download a designated tex in Asset Browser then add it into a node mat?

  1. Check the Tex on disk already
  2. If not on disk , find the Maxon Asset on network with named like si-v1_deposits_06_15cm.png
  3. Download it to disk and add it to select redshift Node as a bump map

Can I do this in S26.1(windows) with python?

Thanks(Hope I understand Form Rules this time,QAQ)

Thanks for your [email protected]
I use a github reference document download one year ago(It is some network problem that some time I cannot visit internet.) I will check the new Node and Asset python example first.

  1. Yes ,I am talking about asset browser. It is a new stuff to me , I will check out some example first
  2. I mean Node Editor , I think it is the furture of node in C4D(maybe xpresso can be move to new Node Editor in furture?), so please more py example on github😁
  3. Python document with Nodes is not handy for me now , I am working on some custom handy API like Arnold Render API ,Hope SDK will update soon.

Unfortunatlly ,I have no experence with C++().But I will try to read it anyway.

Thanks

Hello @dunhou,

Thank you for reaching out to us. And no worries, everything is fine with your posting. Thank you for making the effort to adhere to our forum rules, much appreciated!

About your Question

The general answer is, yes, this is possible. There are however a few ambiguous points in your posting.

  1. You state it quite clearly, but just to be sure, you are talking about the Asset Browser and assets it, right? Because there are also a few similar concepts in Cinema 4D.
  2. Assets must not be downloaded, at least not by the user, the Asset API hides away that detail. Assets are referenced by their asset ID and refer to content stored at an asset URL. This URL can be local, but it can also be on some server. Cinema 4D, the Asset API, will handle the resolving and caching of asset URL content.
  3. So, there is no checking if an asset is on disk to be done, and assets are also not referenced by file names as for example si-v1_deposits_06_15cm.png but asset identifiers, e.g., file_edb3eb584c0d905c.
  4. What is also not quite clear to me, is what you mean when you 'redshift Node'. Are you referring to the old Xpresso based node setups, now running in legacy mode as of S26, or are you referring to the new standard nodes of S26? It is possible to link a texture asset in both cases as the bump map, but it requires different approaches.

For the S26.1 C++ docs, we recently added a small manual for Redshift wich goes through exactly that case, creating a Redshift standard node material, and linking texture assets to the channels of the material. Although it is for C++ I would recommend having a look, as the Python code will be almost identical.

There is also a plethora of other things I would recommend having a look at, such as the Python Asset API examples and the Python Nodes API examples, as your goals are only a specialization of the things shown there.

If you have questions along the way, please do not hesitate to ask. The Nodes and Asset API are two fairly complex subjects, and their documentation on Python is still in its infancy. I will provide the necessary guidance or examples where necessary.

Cheers,
Ferdinand

Thanks for your [email protected]
I use a github reference document download one year ago(It is some network problem that some time I cannot visit internet.) I will check the new Node and Asset python example first.

  1. Yes ,I am talking about asset browser. It is a new stuff to me , I will check out some example first
  2. I mean Node Editor , I think it is the furture of node in C4D(maybe xpresso can be move to new Node Editor in furture?), so please more py example on github😁
  3. Python document with Nodes is not handy for me now , I am working on some custom handy API like Arnold Render API ,Hope SDK will update soon.

Unfortunatlly ,I have no experence with C++().But I will try to read it anyway.

Thanks

Hey @Dunhou,

great, as I said, we are aware that there are currently gaps in the Python documentation. Just try to start out, and then post what you got when you hit a wall. I will help you then, i.e., write a specific Python example, if necessary, and show you how to accomplish things in Python.

The basic information is there in the Asset API and Nodes API examples for Python I have posted above. The Redshift API is just a special case for that, and it is not fully documented yet (even in C++) because the underlying integration of Redshift into Cinema 4D has not been fully finalized yet. I have pushed the C++ Manual out because I knew users will be asking for it, but this C++ Manual is also only a temporary solution. For now, we will solve Redshift API questions with direct customer support in Python.

Cheers,
Ferdinand

@ferdinand Hello!

I continue this task and i have a problem with GetAssetUrl , here is the code :

from typing import Optional
import c4d
import maxon

doc: c4d.documents.BaseDocument  # The active document
op: Optional[c4d.BaseObject]  # The active object, None if unselected

def GetTextureInBrowser():
    
    sourceId = maxon.Id("file_d0a26639c950371a")

    repository = maxon.AssetInterface.GetUserPrefsRepository()
    #print(repository)
    sourceDescription = repository.FindLatestAsset(maxon.AssetTypes.File(), sourceId, maxon.Id(), maxon.ASSET_FIND_MODE.LATEST)
    #print(sourceDescription)
    #print(type(sourceDescription))
    language = maxon.Resource.GetCurrentLanguage()
    #print(language)
    assetName = sourceDescription.GetMetaString(maxon.OBJECT.BASE.NAME, language, "Default Asset Name")
    print(assetName)
    TextureUrl = maxon.AssetInterface.GetAssetUrl(sourceDescription,True)
    print(TextureUrl)


if __name__ == '__main__':
    GetTextureInBrowser()

And the console output :

file_d0a26639c950371a/04ca11742bd8138d797a8d7be31bad60df044bf47ce8a364d5c1aee5ae2bca42
<class 'maxon.frameworks.asset.AssetDescription'>
Cable - USB
Traceback (most recent call last):
  File "scriptmanager", line 26, in <module>
  File "scriptmanager", line 21, in GetTextureInBrowser
  File "C:\Program Files\Maxon Cinema 4D R26\resource\modules\python\libs\python39\maxon\decorators.py", line 400, in Auto
    ExecMethod(self._data, *args)
TypeError: unable to convert builtins.bool to @<net.maxon.interface.assetdescription>C

It seems sourceDescription recognized as as a bool , but the type I print is a <class 'maxon.frameworks.asset.AssetDescription'> , did I do someting wrong?

Hello @dunhou,

Thank you for reaching out to us and pointing this out. There is a bug in the Python bindings of maxon.AssetInterface.GetAssetUrl, there is nothing you can do about it. I have added bug report for it, it will be fixed in an upcoming release.

In the meantime, you can also use maxon.AssetDescriptionInterface.GetUrl() as a workaround. See my example at the end of the post for details. I would also like to stress again, that there is no downloading to be done from your side. So, unless you want to use the texture asset in a material or read its pixel data, the URL will not be of much use to you. As the URLs provided by both methods will be in a scheme that only is understood by the Cinema 4D APIs, the ramdisk and asset schemes respectively.

Cheers,
Ferdinand

"""Demonstrates how to circumvent the Python API bug in AssetInterface.GetUrl by using
AssetDescriptionInterface.GetUrl as a temporary replacement. 

The URLs returned by these two methods are NOT the same, AssetInterface returns the asset URL in the
asset scheme, while AssetDescriptionInterface returns the URL of the physical location of the asset.
Usually users should not be poking around with the physical/raw asset Url and instead use the
asset scheme abstraction of it, but for now this will fix this problem. See [1] for details on the
subject.

The raw asset URL will either be a file scheme or ramdisk scheme URL. The former would be something
like "file://C:/MyAssetDB/1/asset.png" while the latter is a specialized URL scheme from the asset
API which allows you to treat files that are still on some server on the internet as if they were
already on your machine. Cinema 4D will load the content as soon as one attempts to access it.

I already stated this in the last posting, but there is no "downloading" to be done from your side.
You just access stuff and do not really have to care about how.

References:
    [1]: https://github.com/PluginCafe/cinema4d_cpp_sdk_extended/blob/master/plugins/example.assets/source/asset_api_examples/examples_metadata.cpp#:~:text=AccessAssetDescriptionData
"""

import c4d
import maxon
import itertools

doc: c4d.documents.BaseDocument  # The active document.

def GetTextureInBrowser():
    """
    """
    # The asset ID you did provide was not for a media (texture) asset, but some kind of c4d file 
    # based asset (I did not check what it was exactly).
    # sourceId: maxon.Id = maxon.Id("file_d0a26639c950371a") 

    # The "A019.TIF" texture in the Textures/Surfaces/Brick Wall category.
    assetId: maxon.Id = maxon.Id("file_d501e4ea3ca49737")

    # This was all correct, I just condensed it a bit.
    repository: maxon.AssetRepositoryRef = maxon.AssetInterface.GetUserPrefsRepository()
    asset: maxon.AssetDescription = repository.FindLatestAsset(
        maxon.AssetTypes.File(), assetId, maxon.Id(), maxon.ASSET_FIND_MODE.LATEST)
    name: str = asset.GetMetaString(maxon.OBJECT.BASE.NAME, maxon.Resource.GetCurrentLanguage(), "")

    # Because AssetInterface.GetUrl() is broken, we are using AssetDescriptionInterface.GetUrl() as
    # a replacement. There is however a difference between these two, and the one we are retrieving
    # here is the raw asset Url. This will work nonetheless in 99.9% of the cases, but you should
    # only use this in this form until we fix the bug. See see [1] for details on the asset data
    # model.
    url: maxon.Url = asset.GetUrl()
    fileName: str = url.GetUrl()

    # Create a material, link the texture asset in the color channel of the material, and insert the
    # material into the document.
    material: c4d.BaseMaterial = c4d.BaseMaterial(c4d.Mmaterial)
    shader: c4d.BaseShader = c4d.BaseShader(c4d.Xbitmap)
    if None in (material, shader):
        raise MemoryError("Could not allocated material or shader.")
    
    material.InsertShader(shader)
    doc.InsertMaterial(material)
    shader[c4d.BITMAPSHADER_FILENAME] = fileName
    material[c4d.MATERIAL_COLOR_SHADER] = shader

    # Load the asset into a bitmap.
    bitmap: c4d.bitmaps.BaseBitmap = c4d.bitmaps.BaseBitmap()
    if bitmap.InitWith(fileName)[0] != c4d.IMAGERESULT_OK:
        raise RuntimeError(f"Could not load bitmap from '{fileName}'.")
    
    # Iterate over the top left corner 5x5 pixel grid in the bitmap to read the pixels.
    rangeFive: tuple = tuple(range(5))
    for x, y in itertools.product(rangeFive, rangeFive):
        print (f"Pixel at {(x, y)} = {bitmap[x, y]}")

    # Load the image into the Picture viewer.
    c4d.bitmaps.ShowBitmap(bitmap)

    # Push and update event to Cinema 4D.
    c4d.EventAdd()


if __name__ == '__main__':
    GetTextureInBrowser()

@ferdinand Thanks

I do want to use tex in node materials , I read the Redhisft C++ page then check with url. Code above also can't work on my machine.

I run your code and return a error in console ,I don't know if it is my config problem
c4d : R26.107
sys : win10 21H2

Traceback (most recent call last):
  File "scriptmanager", line 61, in <module>
  File "scriptmanager", line 28, in GetTextureInBrowser
  File "C:\Program Files\Maxon Cinema 4D R26\resource\modules\python\libs\python39\maxon\decorators.py", line 409, in ReferenceConvert
    ExecMethod(self._data, *args)
RuntimeError: virtual interfaces cannot create null values.

@ferdinand Sorry for that , I restart Cinema few times, It works ,I think it is a problem with AssetDB loading prosess , some times assetDB loaded few seconds, and sometimes it will loading until next restart(maybe restart some times) I don't know it is a setting problem or a Cinema4D bug, sometimes new asset seems much slower than old broswer,(S26 is much faster than R26)

Hey @dunhou,

I do not fully understand your problem, but if you want to make sure that the asset databases have been loaded (so that your searches do not run into nothing), you should call maxon.AssetDataBasesInterface.WaitForDatabaseLoading() before you try to retrieve a repository or make any queries. I would really recommend reading the Python or C++ code examples we provided on GitHub, because I went there over all this stuff.

Cheers,
Ferdinand

@ferdinand Maybe the broblem in not the code but the Cinema Application, Some friends also told me when they load Aseets(especially at a large Asset data like 20G in disk) , It always take a long time or even not load unless restart C4D.

You are right, I should call WaitForDatabaseLoading() function for safe. That's my stupid , I didn't notice the loading failed in state bar😧

I do check the Python examples in GitHub , but I think maybe it is a dcc of my config problem, some friends also said assets broswer is a little slower . (perhaps due to china a internet far away from maxon server) .hope it will be fix in uncoming C4D

Hey, as I mentioned above , I worked on a custom api for Redshift to me to use more easily . And now , a very basic one I have test and worked as I expect.

But I am not a professional python or redshift user , so It might be not professional for everyone , specially in this devloper forum. Anyway I have fun with this "early beta work" and learn a lot of things I never pay a tention to ,So I think It is good to post a Github Link to share it . Then new developr like me might find a little fun to move on , Or if someone read this and have interst to improve it , That is so cool .

By the way , It has two liitle example to use or test it . Have fun

Hey @dunhou,

thank you for reaching out to us. First of all: Thank you for sharing your code! This is much appreciated. And I would not be so hard on yourself, there is IMHO no such thing as a 'professional Python user'; there are only developers who provide solutions and those who do not, and you clearly are among the first group 😉 .

However, and I cut you here some slack in previous postings in this topic, I would like to remind you about our Forum Guidelines, specifically that a topic should be about a singular and sparsely defined subject, and new questions or subjects should constitute a new topic. This topic is now about many things, which makes its content less accessible.

This would also be in your own interest because a new topic in the General Talk forum, called for example '[Open Source] Python Nodes API Redshift Helper Functions' would give your work much more deserved visibility than a buried reference in this thread.

You do not have to act upon it here, this is just a reminder for the future to be a bit more liberal with opening new topics.

Cheers,
Ferdinand

@ferdinand Thanks for your remind .

I would re-post a new Topic in General Talk , because I am now interest in Octane nodes , for some reasons , there is no official sdk for Octane at all , It is hard to scripting like create a procedual materials , I decide to move on myself . When it also have a basic structure as Redshift nodes api , I'd like to post it for if someone like to improve it . Obviously It's not a little works to do . It's more easier for others to lookup in a right place .

Cheers.

Hey @dunhou,

as I said, we do not require you to do so here, but when you think you have something interesting for others or just have a question which is outside of scope of support (e.g., a question on how Python for loops work, just as a stupid example), then you are more than welcome to post in the General Talk forum.

You can more or less post anything in General Talk, as long as it has some (faint) connection to Cinema 4D plugin development. So, you are more than welcome to create your own topic there for the stuff you are doing. In General Talk most of the forum rules do not apply, like for example the single topic restriction we have set up for Cinema 4D SDK and Cineware SDK. The rules of conduct obviously still apply, e.g., do not infringe on other people's copyright, do not post hate speech, or blatantly rude comments, etc.

Cheers,
Ferdinand