How can I change the order of Reflection layers



  • Hi,

    is there a way to change the order of reflection layers in a material?
    Or to create a new reflection layer at the end of the list, instead of always having it as first element?

    Thanks & greetings,
    Frank



  • Hi,

    I think the short answer is: No. The longer answer is: Yes, but it is incredibly cumbersome (and dicey). The following script will reverse the order of the reflectance layers for the selected material.

    import c4d
    
    # Main function
    def main():
        """
        """
        # Just get the first active material and check if it is a reflection layer
        # supporting material.
        material_selection = doc.GetActiveMaterials()
        if (material_selection == [] or 
            not material_selection[0].CheckType(c4d.Mmaterial)):
            return
        mat = material_selection[0]
    
        # Get all reflection layers and their data offset ids for that material
        reflection_layers = [mat.GetReflectionLayerIndex(lid)
                             for lid in range(mat.GetReflectionLayerCount())]
        data_ids = [layer.GetDataID() for layer in reflection_layers]
        
        # Get a copy of the materials data container
        mat_data = mat.GetData()
        
        # I will just reverse the order of the reflection layers (or more precisely
        # the order of the data) to show the principle. Some sort of insertation
        # logic should be trivial to implement for you.
        for old_id, new_id in zip(data_ids, reversed(data_ids)):
            # The reflection layer data is stored in the container of the material
            # with a stride of 512, so for example reflection layer X goes from 
            # SOME_ID to SOME_ID + 511. There are symbols for the stride IDs, check
            # https://tinyurl.com/yxvgmtmt for details.
    
            # A more safe approach would be to compile a list of that symbols,
            # rather than using that stride approach I use here.
            for i in range(512):
                # We just copy all data from our data container copy to the new
                # location, but there are data types we cannot handle in Python 
                # within that stride, so we need this rather ugly construction.
                # I have no clue what that data is, things might break horribly.
    
                # !!! THIS MEANS WE EFFECTIVELY WON'T COPY ALL DATA AND MIGHT 
                # GENERATE A CORRUPTED MATERIAL !!!
                try:
                    mat[new_id + i] = mat_data[old_id + i]
                except:
                    pass
        c4d.EventAdd()
    
    # Execute main()
    if __name__=='__main__':
        main()
    

    Cheers
    zipit



  • Thanks, that idea crossed my mind, too. And thank you for even providing code! I was hoping there was a clean way to do that.

    SDK team, any further insight about this? Is this possible in a clean way, or maybe in C++ ?

    Cheers,
    Frank



  • Hello,

    from our point of view there's nothing to move things around. We have only this manual

    I have to check to see if there's something hidden but got doubt about it.
    I'll be back with information if i find something :)

    Cheers,
    Manuel



  • hello,

    can we change this to solved ?

    Cheers,
    Manuel