Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    How can I change the order of Reflection layers

    Cinema 4D SDK
    r21 classic api python
    4
    6
    817
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • fwilleke80F
      fwilleke80
      last edited by fwilleke80

      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

      www.frankwilleke.de
      Only asking personal code questions here.

      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by ferdinand

        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

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 1
        • fwilleke80F
          fwilleke80
          last edited by fwilleke80

          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

          www.frankwilleke.de
          Only asking personal code questions here.

          1 Reply Last reply Reply Quote 0
          • ManuelM
            Manuel
            last edited by

            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

            MAXON SDK Specialist

            MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • ManuelM
              Manuel
              last edited by

              hello,

              can we change this to solved ?

              Cheers,
              Manuel

              MAXON SDK Specialist

              MAXON Registered Developer

              1 Reply Last reply Reply Quote 0
              • M
                mogh
                last edited by

                Oh my, this is horrible 😉

                ...
                cheers mogh

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post