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

    Compare only parts of two BaseContainers()

    Cinema 4D SDK
    r20 r21 s22 r23 c++
    4
    6
    606
    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

      Hello,

      there is a lot of stuff in my plugin object's BaseContainer, e.g. the object's name, and other irrelevant stuff. Since the object is quite complex and takes a while to calculate, I want it to rebuild only when relevant attributes have changed.

      Is there a smart way already, to detect changes to certain values in a BaseContainer?

      If not, I'd probably end up writing a Compare() function for two BaseContainers that accepts a BaseArray of value IDs, and compare the values of each of those IDs from the two containers.
      Is there a way to get a list of all IDs defined in my object's resource header?

      I found COPYFLAGS::PRIVATE_CONTAINER_COPY_DIRTY and COPYFLAGS::PRIVATE_CONTAINER_COPY_IDENTICAL which sound promising, but they're marked as private and not explained in the SDK docs.

      Thanks for advice!

      Cheers,
      Frank

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

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

        Hi,

        I am not quite sure if I do understand you correctly. With "rebuilding the object" you are referring to rebuilding the cache of some BaseObject, right? And you want to know when "the important parameters" of the node have changed so that you can then rebuild the node on the next cache request?

        Have you considered using NodeData::SetDParameter? You could probably also listen to the messages sent to the node and react to them.

        Cheers,
        zipit

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • C4DSC
          C4DS
          last edited by C4DS

          Not sure if this might help or add to the confusion, but in the past I was surprised about this.

          I had always assumed a BaseContainer to be similar to what a Python dict represents.
          However, the behaviour encountered in above link indicates that next to the key-value, also the sequence of storing the key-values does pay importance in a BaseContainer ... something -if present in the documentation- I always seemed to have overlooked, or missed.

          So, doing a compare between two BaseContainers, while containing identical key-value seem to not being equal if those key-value are stored in a different sequence.
          Hence "comparing only parts of two BaseContainers" might result in some unexpected behaviours.

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

            Yeah, I read that thread, too 😄 And in deed, the BaseContainer is a sequential storage. That's why it has the FindIndex(), GetIndexId()and GetIndexData() members.

            And yes, with "rebuilding the object" I meant to rebuild my object's generator cache.

            I have tried the following solution now, and found that it's fast enough to not impact performance.

            Bool EqualContainerValues(const BaseContainer &a, const BaseContainer &b, const maxon::BaseArray<Int32> &ids)
            {
            	if (ids.GetCount() == 0)
            		return true;
            
            	for (maxon::BaseArray<Int32>::ConstIterator it = ids.Begin(); it != ids.End(); ++it)
            	{
            		const Int32 valueId = *it;
            		if (a.GetData(valueId) != b.GetData(valueId))
            			return false;
            	}
            
            	return true;
            }
            

            I simply memorise a copy of my object's BaseContainer, and when GetVirtualObjects() is called next time, I pass the current BaseContainer and the memorised copy of the previous BaseContainer to the above shown function, along with a BaseArray of IDs. It does the trick, and I'll use this until I stumble upon a better solution.

            Cheers,
            Frank

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

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

              hi,

              I would probably go with SetDParameter and if i see any parameter i'm tracking, i set the object dirty.
              But as long as it's working and performance are good enough..

              PRIVATE_CONTAINER_COPY_DIRTY copy also the dirty sum stored on the object.
              PRIVATE_CONTAINER_COPY_IDENTICAL is harder to decrypt. Seems that copy is going to be faster than the other.
              Both are used together in our code in the Mograph module (why i'm not surprised ?)

              About your code, you can use IsEmpty and a range-based loop. (a bit easier to read)

              Bool EqualContainerValues(const BaseContainer& a, const BaseContainer& b, const maxon::BaseArray<Int32>& ids)
              {
              	if (ids.IsEmpty())
              		return true;
              
              	for (const Int32 & valueId : ids)
              	{
              		if (a.GetData(valueId) != b.GetData(valueId))
              			return false;
              	}
              
              	return true;
              }
              

              MAXON SDK Specialist

              MAXON Registered Developer

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

                Nice, Manuel, thank you!

                I guess, I'll try the SetDParameter() approach, too, in good time.

                Cheers,
                Frank

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

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