Loading Materials from AssetDescriptions into a Scene
-
Thanks for the help @ferdinand, the plugin rewrite from python is coming along nicely and I am able to fetch all AssetDescription* from the Asset API.
However reading the handbook I am unable to find a way to fetch a BaseMaterial* from the AssetDescription*. Are you able to guide me towards a solution? I need this to be able to create a Take with a specific material.
-
Hello @krfft,
thank you for reaching out to us. I did fork your question because it was a new question.
About your question: This part of the Asset API has unfortunately not been documented yet. Neither in form of a handbook or examples provided by us, nor in form of doc-strings provided by our developers. We plan to update the handbook soon, but what you must do in principle is use
AssetCreationInterface
and there the function CreateMaterialsOnDrag. Which was named a bit weirdly (at least from an SDK user point of view) and should be more interpreted asLoadMaterialAssetIntoDocument
. You could technically also use themaxon::Url
of a material asset to load in the asset document manually viaLoadDocument
, but you would then have to unpack some of the material data yourself.I will post an example in the next days, but I do not have the time to do it today.
Cheers,
Ferdinand -
Hello @krfft,
here the promised code. It is an extension of the Search Assets example which can be found in the Asset API Handbook.
I hope this helps and cheers,
FerdinandThe result:
The code:
static Int32 g_max_materials = 10; /// ------------------------------------------------------------------------------------------------ /// Loads in the first ten material assets into the active document which can be found in the user /// prefs repository. /// /// I did remove most of the comment fluff here, assuming you are already familiar with the rest. /// ------------------------------------------------------------------------------------------------ maxon::Result<void> LoadAssets() { iferr_scope; // Get the active document and do some setup stuff to search for all materials in the user prefs // repository. See FindAssets() example function in the Assets API exmaples for details. BaseDocument* doc = GetActiveDocument(); if (doc == nullptr) return maxon::UnexpectedError(MAXON_SOURCE_LOCATION, "No active document."_s); const maxon::AssetRepositoryRef& repository = maxon::AssetInterface::GetUserPrefsRepository(); const maxon::AssetType assetType = maxon::AssetTypes::File(); const maxon::Id assetFindId = {}; const maxon::Id assetVersion = {}; maxon::BaseArray<maxon::AssetDescription> results; repository.FindAssets( assetType, assetFindId, assetVersion, maxon::ASSET_FIND_MODE::LATEST, results) iferr_return; // Iterate over the results until we have found ten materials. maxon::Int counter = 0; for (maxon::AssetDescription assetDescription : results) { if (counter == g_max_materials) break; maxon::AssetMetaData metadata = assetDescription.GetMetaData(); maxon::Id subTypeId = metadata.Get(maxon::ASSETMETADATA::SubType) iferr_return; // This is a material asset. if (subTypeId == maxon::ASSETMETADATA::SubType_ENUM_Material) { // With a valid url. maxon::Url url = assetDescription.GetUrl() iferr_return; if (url.IsEmpty()) continue; // The url of the asset is in case of material assets a c4d file. So, we merge that asset // document with the active document. ApplicationOutput("@| Type: @, Url: @", counter, subTypeId, url); maxon::String* error = {}; maxon::Bool didMerge = MergeDocument( doc, MaxonConvert(url), SCENEFILTER::MATERIALS, nullptr, error); ApplicationOutput("@: Merged: @, Error: @", counter, didMerge, error); if (didMerge) counter++; } } return maxon::OK; }