Hi @ferdinand,
I have spent some time rewriting the code incl using BaseLink instead of pointers. I am also validating all values put into the FindOrAddOverrideParam function. For background info we name the material tags to be able to know which are to have which material for the different variants of a product.
FindTags
Bool FindTagsContaining(BaseObject* topObject, BaseLinkArray* foundTags, maxon::String contains)
{
iferr_scope_handler
{
ApplicationOutput("Iterating tags finished with error: @",err);
return false;
};
BaseObject* child = topObject->GetDown();
if (child == nullptr)
return false;
while (child != nullptr) {
BaseTag* tag = child->GetTag(Ttexture);
if(tag != nullptr)
{
maxon::String tagName = tag->GetName();
if (tagName.Find(contains, 0)) {
foundTags->Append(tag);
}
}
FindTagsContaining(child,foundTags,contains);
child = child->GetNext();
}
return true;
}
GetMaterial
BaseMaterial* GetMaterial(maxon::AssetDescription assetDescription) {
iferr_scope_handler
{
ApplicationOutput("Stopped LoadMaterial() execution with the error: @", err);
return nullptr;
};
BaseDocument* doc = GetActiveDocument();
maxon::String matName = assetDescription.GetMetaString(maxon::OBJECT::BASE::NAME, maxon::LanguageRef()) iferr_return;
BaseMaterial* material = doc->SearchMaterial(matName);
if (material == nullptr) {
maxon::Url url = assetDescription.GetUrl() iferr_return;
if (url.IsEmpty())
return nullptr;
maxon::String* error = {};
maxon::Bool didMerge = MergeDocument(doc, MaxonConvert(url), SCENEFILTER::MATERIALS, nullptr, error);
material = doc->SearchMaterial(matName);
}
return material;
}
And finally the take creation:
BaseLinkArray editTags;
FindTagsContaining(productRoot, &editTags, "Edit_"_s);
// editTags is sent as a pointer to function below.
BaseTake* take = td->AddTake(takeName, parent, NULL);
BaseDocument* doc = GetActiveDocument();
DescID idMaterialAssignment = DescID(DescLevel(TEXTURETAG_MATERIAL));
for (Int i = 0; i < editTags->GetCount(); ++i)
{
C4DAtomGoal* const goal = editTags->GetIndex((Int32)i, doc);
if (goal == nullptr)
return nullptr;
BaseTag* tag = static_cast<BaseTag*>(goal);
const maxon::AssetDescription* materialDescription = editMaterials->FindValue(tag->GetName());
if (materialDescription == nullptr) {
ApplicationOutput("Material description was null for name: @", editMaterials->FindValue(tag->GetName()));
return nullptr;
}
BaseMaterial* mat = GetMaterial(*materialDescription);
if (mat == nullptr) {
ApplicationOutput("GetMaterial was null for name: @", editMaterials->FindValue(tag->GetName()));
return nullptr;
}
ApplicationOutput("Adding tag override for " + tag->GetName() + " of type " + tag->GetTypeName() + " with " + mat->GetName());
BaseOverride* overrideNode = take->FindOrAddOverrideParam(td, tag, idMaterialAssignment, GeData(mat));
if (overrideNode == nullptr) {
ApplicationOutput("Unable to create override for " + tag->GetName() + " with " + mat->GetName());
return nullptr;
}
overrideNode->UpdateSceneNode(td, idMaterialAssignment);
}
The output of the ApplictionOutputs would be something like:
Adding tag override for Edit_StrapMetal of type Material with Aluminium_Anodised_Anthracite_0123
Unable to create override for Edit_StrapMetal with Aluminium_Anodised_Anthracite_0123
To me everything looks good, is there any way I could get some info on why the override is null or some error log from FindOrAddOverrideParam?