-
Notifications
You must be signed in to change notification settings - Fork 439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[QUESTION]: How to get the material/node of a specific duplicated object #590
Comments
Hey @AlcatrAAz, there is currently no single bproc method that can duplicate all materials of a given object (although we maybe should add one), however you can simply duplicate each material of your duplicated object for i, material in enumerate(obj.get_materials()):
material_dup = material.duplicate()
obj.set_material(i, material_dup) |
Hey @cornerfarmer thank you for your fast answer! Okay this would be a workaround to create a material for every object. My question was more something like this: Instead of something like this: More like this: So that I can change only this specific node at this specific object and all other Materials of the duplicated objects remain the same. |
Hey @AlcatrAAz, when duplicating objects in blender, the material is not duplicated, but instead the same material is linked to all duplicated objects. Therefore, you cannot access the individual material of one specific object, as simply there is none. If you duplicate the materials, as I described above, then each object has its individual material and you can set object specific parameters via: obj.get_materials()[0].nodes["Hue Saturation Value"].inputs['Hue'].default_value = random.uniform(0, 1) |
Hey, one thing to understand is that a material is its own entity and is only linked to an object. So, when duplicate an object the link to this one existing material is also copied, this means no new material is created. This also means that a material can be linked to a hundred objects, which all then use the same material. If you now want that each object has its own material, you have to create it, as @cornerfarmer already showed. for obj in list_of_all_duplicated_objects: # iterate over all objects
for i, material in enumerate(obj.get_materials()): # duplicate each material of each object
material_dup = material.duplicate()
obj.set_material(i, material_dup) Afterwards you can iterate over all objects again and set whatever value you want. for obj in list_of_all_duplicated_objects: # iterate over all objects
for node in obj.get_nodes_with_type("ShaderNodeHueSaturation"):
node.inputs["Hue"].default_value = random.uniform(0, 1) Check this document here: https://github.com/DLR-RM/BlenderProc/blob/main/blenderproc/python/types/MaterialUtility.py PS: I did not test this code. Best, |
I assume this is closed now |
Hey @cornerfarmer @themasterlink sorry for the late replay, yes it worked and your help was very helpful. Thank you! |
In BlenderProc, Materials can be set for MeshObject instances. However, in Blender materials are independent of objects. If we duplicate a MeshObject in BlenderProc, it just duplicates a reference to the same Material. In OOP it's quite unexpected that changing an instance attribute can change another instance of the same type as happened here and in #792 So we would propose a breaking change but with an option to keep the current behavior, i.e. def duplicate(self, duplicate_materials: bool = True, duplicate_children: bool = True) -> "MeshObject": Any thoughts? |
As a user I would expect that I need to change all MeshObject materials and not just one, so I don't think we would break many people's code. |
👍🏽 I would appreciate duplication to create an independent instance that does not influence other objects. |
I wouldn't say thats uncommon in OOP. If you say mesh objects have references to material objects, then it is of course plausible that two mesh objects reference the same material. We also model it that way in blenderproc, we have a class MeshObject and a class Material. So material attributes are not really MeshObject attributes. Also, the material sharing between different objects is quite common in blenderproc. For example in the front3D loader each material is loaded only once and then shared between objects: see https://github.com/DLR-RM/BlenderProc/blob/main/blenderproc/python/loader/Front3DLoader.py#L184 I agree there should be definitely a parameter in the duplicate function which allows duplicating the materials. The only question is how to set the default value. |
Yes, I see the reason for not duplicating the materials in some cases such as Front3D and we should definitely keep that option.
Sounds good |
Hello everyone,
I have a question how I get the material or better a specific node of a specific duplicated object? In my case I load an object (with one material) from a .blend file and afterwards a duplicate it 100x (including the material). If I change one thing in the material it will change it for all duplicated objects. But I want to change/randomize for example the hue for every duplicated object, so that I have 100 objects with the same material but with different hues. Is this possible or do I have to create for every duplicated object a new material?
Any tips are apreciated :)
The text was updated successfully, but these errors were encountered: