Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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
    • Register
    • Login

    Cannot copy BaseLink from one parameter to another in ShaderData Read in C4D 2024

    Cinema 4D SDK
    c++ 2024
    2
    14
    1.5k
    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.
    • B
      bojidar
      last edited by bojidar

      Hi,

      So we used to do the following in NodeData::Read() whenever the id of a ShaderLink parameter had to be changed and preserve the shader from old scenes.

      BaseContainer &nodeData=static_cast<BaseShader*>(node)->GetDataInstanceRef();
      const BaseLink* oldLink=nodeData.GetBaseLink(oldParameter);
      if (oldLink != nullptr) {
      	GeData linkData;
      	linkData.SetBaseLink(*oldLink);
      	nodeData.SetData(newParameter, linkData);
      }
      nodeData.RemoveData(oldParameter);
      

      However, on Cinema4D 2024 this doesn't seem to work if the NodeData is a shader. The old BaseLink parameter gets removed, the new parameter is set but the link still points to nullptr after the document is loaded. It does look a bit weird, so is there something I am missing or a better way to do this?

      Thanks,
      Bozhidar

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

        Hey @bojidar,

        Thank you for reaching out to us. 2024 is a very broad field. Did this happen with 2023.X to 2024.0.0, the so called 2024.0.0 API migration, or did this happen in a more recent release for you, e.g., from 2024.3.2 to 2024.4.0?

        I am not aware of anything which would have impacted this, but we are again here on a broad field.

        1. You made sure that your nodeData.SetData(newParameter, linkData) statement is actually being hit?
        2. Did you make sure that the to be linked shader, oldLink, still does resolve? Or in other words that this shader is already present in the document?
        3. What is the return value of your BaseContainer::SetData call?
        // ...
        if (oldLink != nullptr) {
            const BaseList2D* const target= oldLink->GetLink(node->GetDocument(), Xbase)
            if (!target)
                return maxon::UnexpectedError(MAXON_SOURCE_LOCATION, "Upsy-daisy, lost shader link."_s);
        
            GeData linkData;
            linkData.SetBaseLink(*oldLink);
            if (!nodeData.SetData(newParameter, linkData))
                return maxon::UnexpectedError(MAXON_SOURCE_LOCATION, "Could not write parameter."_s);
        }
        

        Cheers,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • B
          bojidar
          last edited by bojidar

          From what I can see it works on 2023.2.1 and doesn't work in 2024.0. SetData is indeed called and returns true, however, oldLink->GetLink/ForceGetLink always return nullptr. So I guess the link isn't resolved? But when checking with the active object dialog example the shader is indeed there.

          ferdinandF 2 Replies Last reply Reply Quote 0
          • ferdinandF
            ferdinand @bojidar
            last edited by ferdinand

            Hey @bojidar,

            that could be a side-effect of the 2024.0.0 API changes. It is hard to give here good advice, I will ask tomorrow the Tech team who authored most of the low-level changes for 2024, if this rings any bells for them.

            Could you please check if the target shader is present at all in such imported scene? You can use the ActiveObject plugin from the C++ SDK or just write your own code which checks. Because when the shader is not present, it is normal that the link does not resolve (on the other hand the shader could be present, but something with the marker realizing the link went wrong).

            And finally, could you please provide a file with such problem, and tell us which of your products is affected (I think we have licenses for all of them)? Feel free to use email-support or our contact form when you want more privacy πŸ™‚

            Cheers,
            Ferdinand

            edit: overlooked that you did already check for the shader being present. something with the marker is then probably going wrong.

            MAXON SDK Specialist
            developers.maxon.net

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

              Hey @bojidar,

              okay, now I see that you just edited your posting yesterday after I asked for checking for the shader being present with the Active Object plugin. If that was just a coincident, don't worry, but if you did this intentionally, please do not do that, as otherwise the chances are high that we overlook your answer.

              We will also still need a scene file to help you here any further and the name of the plugin you are debugging.

              Cheers,
              Ferdinand

              MAXON SDK Specialist
              developers.maxon.net

              1 Reply Last reply Reply Quote 0
              • B
                bojidar
                last edited by

                Yeah, sorry I changed it right after posting the reply and didn't think it would be a problem.

                This is about V-Ray for Cinema4D. In this scene there is a softbox texture(in the V-Ray material diffuse slot). Here the base texture of the softbox(the checker in the screenshot) is lost after loading the scene in 2024 and using the code in the original post, but loads fine in older versions. The old TEXSOFTBOX_BASE_TEX_TEXTURE=613662896 became TEXSOFTBOX_BASE_TEX=1404507874 and the issue should be reproducible with any V-Ray build for C4D 2024 from the last year.
                41a596d2-b884-4d0f-8a4e-bc99a6295df8-image.png
                Note that this isn't something critical as we only do it in a few places, however, it is slightly annoying
                and mostly wrote to check if there is something obviously wrong with what we are doing πŸ™‚.

                ferdinandF 1 Reply Last reply Reply Quote 1
                • ferdinandF
                  ferdinand @bojidar
                  last edited by

                  Hey @bojidar,

                  will have a look, thanks. But when you say that it is not super critical for you, I will push the answer a bit. I will come back here latest by Friday the 26th with an update.

                  Cheers,
                  Ferdinand

                  MAXON SDK Specialist
                  developers.maxon.net

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

                    Hey,

                    sorry, was very busy last week, will have a look today.

                    Cheers,
                    Ferdinand

                    MAXON SDK Specialist
                    developers.maxon.net

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

                      Hey @bojidar,

                      first of all, I can confirm the issue, the file loads fine in 2023.2.2, does not load properly in 2024.4.0, but the checkerboard shader is still part of the scene graph.

                      I spent today some time on debugging this but did not get very far. The problem is that debugging this from the plugin side (the NodeData::Read call of your Vray binary) is not too insightful as the deed is already done there (the Hyperfile has already been loaded when it is passed to your NodeData::Read and the data in there is already broken). The other way would be to debug the actual file deserialization when the BaseLink is being read as a Hyperfile chunk when the c4d file is being loaded. But that is not so easy because there is exists no parameter ID in this context (I cannot just say if old_vray_param: DebugStop() because a Hpyerfile operates not in parameters but chunks). And even for an "empty" scene a s*** load links must be deserialized, so just setting a break point here does not lead anywhere. But I stumbled upon this:

                      5afc04ee-cc4a-40c1-91c0-db1046cd01e1-image.png

                      This is your plugins NodeData::Read being called upon scene loading to be further deserialized (i.e., the BaseLink has already been read). The disk level should not be 0 here. Because there should be at least two versions of your plugin, one with oldParameter, and one without. It could be very well that you not incrementing the version somehow screws with the Hyperfile deserialization here (you would have to do this in RegisterMaterialPlugin where you are likely still passing the default of 0). So, you should increment the counter for the 2024.4 version of your binary and see if this changes anything.

                      We also had a brief discussion today about if what you are doing is intended. Or in other words - if there is some optimization in our code which mutes reading parameter chunks within a disk level that do not match the description of the atom they are being read for. I do not see any code which would do that (as Hyperfile does not operate with the idea of parameters with IDs but with the idea of sequential chunks). But it would be still interesting to know if you have done this in the past (and it worked then) - deprecated a parameter within one disk level and then "rerouted" it in the next version of your binary?

                      Another thing to do (which I haven't done yet because I was today busy with cursing at the debugger) would be to write your material in 2023.2.2 with C4DAtom::Write to disk, so that one has a bit easier time to see in 2024.4 what happens when we call C4DAtom::Read on that specific data being deserialized.

                      The last option would be to rewrite the core of Cinema 4D to see the exact point when the hyper file chunk for that parameter is being read. But that is our last option.

                      Cheers,
                      Ferdinand

                      MAXON SDK Specialist
                      developers.maxon.net

                      1 Reply Last reply Reply Quote 0
                      • B
                        bojidar
                        last edited by bojidar

                        Hello,
                        Why is the disk level being 0 there a problem? Isn't that the value of the disk level in the scene we are reading? So since it's an old scene and we didn't have any custom ::Read logic in the build this scene was saved with it should to be 0(the default value)? Also shouldn't the value only be changed in RegisterShaderPlugin(since the problem here is the Softbox shader) and not RegisterMaterialPlugin as the post says? We always change the disk level when adding logic in NodeData::Read and I also noticed it might only be broken with nested shaders as we have recently done the same in our Camera tag and it works fine in 2024.

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

                          Hey @bojidar,

                          you told me that you did change the description of your plugin

                          whenever the id of a ShaderLink parameter had to be changed and preserve the shader from old scenes.

                          It is not the shader which changed, but your material. So you must compile your 2024 material plugin with an incremented disk level. You must increment your disk level every time you release the plugin with a new data container layout. A VRay plugin should therefore not have a disk level of zero (because that means you have shoved all versions of that plugin into that one level).

                          There is no guarantee that this will fix it, but there is quite a lot of code which is skipped in node deserialization when your disk level is zero or lower.

                          Cheers,
                          Ferdinand

                          MAXON SDK Specialist
                          developers.maxon.net

                          1 Reply Last reply Reply Quote 0
                          • B
                            bojidar
                            last edited by bojidar

                            Hey,
                            Sorry for the really delayed answer... Perhaps I didn't explain something well enough. What we changed was the id of a parameter as seen in the screenshot above in the Softbox shader from 613662896 to 1404507874 . The disk level used to be 0 before the change and then we set it to 1 after. So in more recent V-Ray versions we register the shader with disk level 1 and if I understand how the serialization works the level in the old scene should be 0 and Read should be called with a disklevel=0(since that is what ReigsterShaderPlugin was called with in the old V-Ray version). I was trying to do the same with another shader i.e. increment the disk level from 0 to 1 in RegisterShaderPlugin and do something along the lines of

                            if (diskLevel < 1) {
                                BaseContainer &nodeData=static_cast<BaseShader*>(node)->GetDataInstanceRef();
                                
                                const BaseLink* oldLink=nodeData.GetBaseLink(oldParameter);
                                
                                if (oldLink != nullptr) {
                                
                                	GeData linkData;
                                
                                	linkData.SetBaseLink(*oldLink);
                                
                                	nodeData.SetData(newParameter, linkData);
                                
                                }
                                
                                nodeData.RemoveData(oldParameter);
                            

                            and it just doesn't work in 2024.

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

                              Hm,

                              okay, so you say this Vray plugin node does not use disk level 0 in its 2024 version anymore? I did not check your registration call, my alarm bells just went off when I saw the 0 because even a 2023 Vray plugin should not have a disk level of zero. Given how well established VRay is, I would expect here at least a disk level of 1 or 2 for this particular node. Did you have major rewrite of Vray or has this node been particularly uneventful in its change history that it still had a disk level of 0 in 2023?

                              And this is not about the disk level code you write in your code, but the branching Cinema 4D takes when there is a disk level of zero. A lot of code simply does not run when your current disk level is zero. But when you say your plugin has now a disk level of one, or that you generally increment your disk levels properly, this all does not really matter.

                              The Tech team touched one part of the non-public underpinning of BaseLink for 2024. But I currently do not see how this could only impact links that are the values of orphaned parameters. Will have a look next week again.

                              Cheers,
                              Ferdinand

                              MAXON SDK Specialist
                              developers.maxon.net

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

                                Hey @bojidar,

                                So, I spent again some time on trying to debug this, and this time manually stepped through the deserialization of 1053286, i.e., your material type. And I am not really any wiser to what is going wrong there. This could be related to a change one of developers made for 2024 to GeAliasGoal, a precursor to what you see as a BaseLink in the public API.

                                But when I look at how it steps through the chunks of the hyper file for your material, I do not really ever see that parameter being deserialized. I think this is more a Tech team than an SDK team issue as they own that part of our APIs. I would have to ask you to file a bug report via our bug tracker for this. Please make sure to include:

                                1. Reproduction steps.
                                2. The file.

                                You can also include your code, but that is of less importance. Please give me then also a note when you have done this, so that I can attach the relevant people and make sure that they get access to a license of your software. I could also file the bug report for you, the problem would be then however, that you could not see it, as you can only see your own reports as an MRD. I.e., you could not take part in the comments/discussion attached to the issue. I would recommend that you submit it yourself. When you run into problems, ask Deyan, or reach out to us via mail.

                                Cheers,
                                Ferdinand

                                MAXON SDK Specialist
                                developers.maxon.net

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