Hi all,
I'm currently trying to find duplicate materials by comparing the values of its BaseContainer parameters.
Unfortunately, I can see that exact same objects have different memory addresses and it will always fail.
<c4d.BaseShader object called 'Absorption Medium/Absorption Medium' with ID 1029510 at **0x00000223328084F0**>
<c4d.BaseShader object called 'Absorption Medium/Absorption Medium' with ID 1029510 at **0x00000223328085F0**>
Have the following code:
import c4d
def get_data(mat):
"""
Get the parameters from the materials container and return a list.
"""
data = mat.GetDataInstance()
mat_params = []
for i in range(len(data) - 1):
index = data.GetIndexId(i)
try:
mat_params.append(data[index])
except AttributeError:
continue
return mat_params
def compare_data(lst_a, lst_b):
"""
Compare the data between lists a and b. If data is the same, than material is a duplicate.
"""
zipped = zip(lst_a, lst_b)
for params in zipped:
if params[0] != params[1]:
return False
return True
def main():
mat_lst = doc.GetMaterials()
duplicate_materials = []
for a, mat_a in enumerate(mat_lst):
data_a = get_data(mat_a)
for b, mat_b in enumerate(mat_lst):
if a != b:
data_b = get_data(mat_b)
data_difference = compare_data(data_a, data_b)
if data_difference:
duplicate_materials.append(mat_b)
assert not duplicate_materials, "You have {0} materials duplicated! " \
"See list below:\n\n{1}".format(len(duplicate_materials),
", ".join(mat.GetName() for mat in duplicate_materials))
if __name__ == '__main__':
main()
Wonder if you have any advice on how to deal with this issue or perhaps a different approach to duplicate objects.
Thank you in advance!
Andre