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

    FieldLayer GetDirty

    Cinema 4D SDK
    c++ r20 sdk
    3
    10
    1.0k
    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.
    • J
      JohnTerenece
      last edited by JohnTerenece

      Hello.

      I am working on a plugin that utilizes a custom FieldList I create with the code below.

          cid = DescLevel(idField, CUSTOMDATATYPE_FIELDLIST, 0);
          if (!singleid || cid.IsPartOf(*singleid, NULL))
          {
              BaseContainer bc;
              bc = GetCustomDataTypeDefault(CUSTOMDATATYPE_FIELDLIST);
              bc.SetBool(DESC_FIELDLIST_NOCOLOR, TRUE);
              bc.SetBool(DESC_FIELDLIST_NODIRECTION, TRUE);
              bc.SetBool(DESC_FIELDLIST_NOROTATION, TRUE);
              
              bc.SetString(DESC_NAME, "Field"_s);
              bc.SetBool(DESC_ANIMATE, true);
              if (!description->SetParameter(cid, bc, fieldgroup))
                  return TRUE;
              
          }
      

      My issue comes in when I try to catch when one of the objects inside of the FieldList is dirty.

      The code below is how I am checking the layers in the FieldList. This code is working properly on things like the Linear Field but on layers like the Time Field Layer it doesn't catch when they are dirty.

      GeData data;
      	UInt32 falloffDirtySum = 0;
      	const DescID fieldParameterID(idFieldList);
      	if (op->GetParameter(fieldParameterID, data, DESCFLAGS_GET::NONE))
      	{
      		CustomDataType* const customData = data.GetCustomDataType(CUSTOMDATATYPE_FIELDLIST);
      		FieldList* const  fieldList = static_cast<FieldList*>(customData);
      		UInt32 falloffDirtySum = 0;
      		if (fieldList)
      		{
      			GeListHead *listHead = fieldList->GetLayersRoot();
      			if (listHead)
      			{
      				Int32 fieldIndex = 0;
      				Int32 fieldListCount = fieldList->GetCount();
      
      				FieldLayer *layer = static_cast<FieldLayer*>(listHead->GetFirst());
      				while (layer && fieldIndex < fieldListCount)
      				{
      					const FieldLayerLink layerLink = layer->GetLinkedObject(doc);
      					BaseObject *fieldObject = static_cast<BaseObject*>(layerLink._object);
      					if (fieldObject)
      					{
      						falloffDirtySum = falloffDirtySum + fieldObject->GetDirty(DIRTYFLAGS::CACHE | DIRTYFLAGS::DATA | DIRTYFLAGS::MATRIX);
      					}
      					layer = layer->GetNext();
      					fieldIndex++;
      				}
      
      			}
      		}
      		if (falloffDirtySum != prevFalloffDirtySum)
      		{
                              // Mark object as dirty
      			prevFalloffDirtySum = falloffDirtySum;
      		}
      	}
      

      Running my own tests I know that this code isn't working on these layers because they don't have a linked object to retrieve with GetLinkedObject() to give me something to use GetDirty() on. Using GetDirty() on the FieldLayers that don't have a linked object doesn't work either.

      Is there an alternative way to check dirtiness on FieldLayers that don't have a linked object?

      I've tried looking through the SDK and on the forums and none of the solutions in the posts I looked at that dealt with a similar topic worked for me.

      Any help would be greatly appreciated.

      John Terenece

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

        Hi,

        It looks like you are not implementing the falloff the correct way.

        If you are using GetDDescription to implement your Falloff tab you should use AddFalloffToDescription.

        To use it you will need to store a point to a C4D_Falloff structure that you will alloc in your Init function and Free it in your Free function.

        Once you have your pointer you can use GetDirty on C4D_Falloff. (inside your CheckDirty function if you are on an objectData)

        Cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • J
          JohnTerenece
          last edited by

          Thanks for the response.

          I know about using C4D_Falloff structure and that was my initial way of adding a Falloff.

          For my plugin I want to include other controls for a user that are placed alongside a Fieldlist like this if possible.

          Picture 4.png

          Is there a way to still achieve those same kind of results without needing to utilize AddFalloffToDescription or is that the only way to catch if items in the Fieldlist are dirty?

          John Terenece

          1 Reply Last reply Reply Quote 0
          • kbarK
            kbar
            last edited by kbar

            @m_magalhaes are you saying that to add FieldList to your description you must ALWAYS use a C4D_Falloff and AddFalloffToDescription?

            If that is the case then why is this not documented or mentioned anywhere in the fields docs? https://developers.maxon.net/docs/cpp/2023_2/page_manual_fieldlist.html

            Doesn't AddFalloffToDescription add a Falloff tab? This is not the same use case as using fields for other purposes. Such as what John is doing.

            I am adding fields to my plugins the same way as John is. This works fine for my purposes but I am not checking dirty flags, only sampling them.

            Sorry John, didn't mean to jump into your thread here, but it struck me as very strange.

            https://www.gamelogicdesign.com
            https://www.plugins4d.com

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

              Hi,

              Sorry i wasn't in the right track.
              First, no AddFalloffToDescription isn't mandatory, it's just another way to add the field tab the way we are doing it and the way the user might expect it. But thanks for asking, after having a better look i was expecting some nice features, but nothing new in the end.

              After digging down in the code, and taking as example the delay and time layer, there's no way to know if the layer is dirty or not in a better way than GetDirty() functions.

              If you have a c4d_falloff and check for dirtiness, it will retrieve the fieldList and call GetDIrty on it.
              So, in your case, you can directly do fieldList->GetDIrty(doc) that the same thing.

              This function, for each layer, will call their respectives CheckDirty functions. In the case of the delay and the time layer, it only be dirty if the time of the document have changed.

              Hope that answers the question.

              Cheers,
              Manuel

              MAXON SDK Specialist

              MAXON Registered Developer

              1 Reply Last reply Reply Quote 1
              • J
                JohnTerenece
                last edited by JohnTerenece

                Thanks for the response.

                I tried using fieldList->GetDirty(doc) with a time layer inside my fieldlist and the timeline active.

                GetDirty(doc) doesn't seem to catch the time layer as dirty or a layer like the Linear Field when I make changes to it. The only time it seems to catch the fieldlist as dirty is when I change the number of layers by inserting new ones or removing old ones.

                Is there a specific flag that needs to be set on the fieldlist when its created in order for GetDirty to function properly?

                John Terenece

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

                  Hi,

                  In which function do you check the dirtiness of the FieldList?

                  Cheers,
                  Manuel

                  MAXON SDK Specialist

                  MAXON Registered Developer

                  1 Reply Last reply Reply Quote 0
                  • J
                    JohnTerenece
                    last edited by

                    Inside of CheckDirty.

                    John Terenece

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

                      Hi,

                      I've overlooked one function, my apology. Something that the Falloff->GetDirty() does is to check if the BaseContainer of the gadget.
                      There's no way of doing it. The only workaround i found is to give the ID of your field parameters the value FIELDS.

                      That way even if you don't use _pFallOff->AddFalloffToDescription(description, bc, flags)) to add the description on your UI you can still check the dirtyness of the gadget.

                      The problem of course is that you can't have more than one field with this ID.

                      So, you can add the description like this:

                      DescID cid = DescLevel(FIELDS, CUSTOMDATATYPE_FIELDLIST, 0);
                      	if (!singleid || cid.IsPartOf(*singleid, NULL))
                      	{
                      		BaseContainer bc;
                      		bc = GetCustomDataTypeDefault(CUSTOMDATATYPE_FIELDLIST);
                      		bc.SetBool(DESC_FIELDLIST_NOCOLOR, TRUE);
                      		bc.SetBool(DESC_FIELDLIST_NODIRECTION, TRUE);
                      		bc.SetBool(DESC_FIELDLIST_NOROTATION, TRUE);
                      
                      		bc.SetString(DESC_NAME, "Field"_s);
                      		bc.SetBool(DESC_ANIMATE, true);
                      		if (!description->SetParameter(cid, bc, ID_OBJECTPROPERTIES))
                      			return TRUE;
                      
                      	}
                      

                      Cheers,
                      Manuel

                      MAXON SDK Specialist

                      MAXON Registered Developer

                      1 Reply Last reply Reply Quote 0
                      • J
                        JohnTerenece
                        last edited by

                        Thanks for the response, that seems to have solved the issue.

                        John Terenece

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