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

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

Hi with the Release 2023.1 the bug with maxon.AssetInterface.GetAssetUrl have been resolved.

Cheers,
Maxime.