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

    C4D_Falloff in plugin description [SOLVED]

    SDK Help
    0
    4
    455
    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.
    • H
      Helper
      last edited by

      On 09/11/2016 at 09:07, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:    
      Platform:      
      Language(s) :

      ---------
      Hi, I'm trying to embed a falloff into a plugin, but it appears that nothing except for
      C4D_Falloff::AddFalloffToDescription() has any effect. I can see the Falloff description,
      but besides that, nothing else works.

      The falloff parameters are not initialized, no handles are displayed, the description doesn't act
      dynamically as it usually does (eg. showing different parameters when choosing a different
      falloff type), etc.

      Does someone have an example of how to do this correctly? My attemp below

      #pragma once
      #include "c4d.h"
      #include "c4d_falloffdata.h"
        
      class FalloffObjectData : public ObjectData {
      protected:
        AutoAlloc<C4D_Falloff> falloff;
      public:
        
        // ObjectData Overrides
        
        virtual DRAWRESULT Draw(BaseObject* op, DRAWPASS pass, BaseDraw* bd, BaseDrawHelp* bh) override {
          if (!op) return DRAWRESULT_ERROR;
          auto* bc = op->GetDataInstance();
          if (!bc) return DRAWRESULT_ERROR;
          if (!this->falloff->Draw(bd, bh, pass, bc)) return DRAWRESULT_ERROR;
          return DRAWRESULT_OK;
        }
        
        virtual Int32 GetHandleCount(BaseObject* op) override {
          if (!op) return 0;
          auto* bc = op->GetDataInstance();
          if (!bc) return 0;
          return this->falloff->GetHandleCount(bc);
        }
        
        virtual void GetHandle(BaseObject* op, Int32 index, HandleInfo& info) override {
          if (!op) return;
          auto* bc = op->GetDataInstance();
          if (!bc) return;
          this->falloff->GetHandle(index, bc, info);
        }
        
        virtual void SetHandle(BaseObject* op, Int32 index, Vector pos, HandleInfo const& info) override {
          if (!op) return;
          auto* bc = op->GetDataInstance();
          if (!bc) return;
          this->falloff->SetHandle(index, pos, bc, info);
        }
        
        // NodeData Overrides
        
        virtual Bool Init(GeListNode* node_) override {
          if (!this->falloff) return false;
          auto* op = static_cast<BaseObject*>(node_);
          if (!op) return false;
          auto* bc = op->GetDataInstance();
          if (!bc) return false;
          BaseContainer* falloff_vals = this->falloff->GetContainerInstance();
          if (!falloff_vals) return false;
          bc->MergeContainer(*falloff_vals);
          return ObjectData::Init(node_);
        }
        
        virtual Bool GetDDescription(GeListNode* node_, Description* desc, DESCFLAGS_DESC& flags) override {
          auto* op = static_cast<BaseObject*>(node_);
          if (!op || !desc) return false;
          auto* bc = op->GetDataInstance();
          if (!bc) return false;
          if (!desc->LoadDescription(op->GetType())) return false;
          flags |= DESCFLAGS_DESC_LOADED;
          if (!this->falloff->AddFalloffToDescription(desc, bc)) return false;
          return ObjectData::GetDDescription(node_, desc, flags);
        }
        
        virtual Bool Message(GeListNode* node_, Int32 msg, void* pdata) override {
          auto* op = static_cast<BaseObject*>(node_);
          if (!op) return false;
          auto* bc = op->GetDataInstance();
          if (!bc) return false;
          if (!this->falloff->Message(msg, bc, pdata)) return false;
          return ObjectData::Message(node_, msg, pdata);
        }
        
      };
      

      Thanks,
      -Niklas

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 10/11/2016 at 05:23, xxxxxxxx wrote:

        Hello,

        it seems that you have to handle the falloff object also in some additional functions.

        • You have to call InitFalloff() in your Init() function. The "doc" argument can be nullptr here.
        • You have to implement CheckDirty() and check the dirty state of the falloff object with GetDirty(). If the falloff object is dirty, the host object should be set dirty with SetDirty(DIRTYFLAGS_DATA). You can store the last dirty state of the falloff object with a member variable. This member variable has also to be handled in CopyTo().
        • You have to implement Execute() and call InitFalloff() there.
        • It also seems that one has to call InitFalloff() before AddFalloffToDescription() in GetDDescription()

        best wishes,
        Sebastian

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 10/11/2016 at 06:31, xxxxxxxx wrote:

          Hi Sebastian,

          thanks for the reply.

          • You're right, using InitFalloff() before anything else in every function makes everything work 🙂
          • Thanks, I'll do that as well.
          • Not sure why I would need to implement Execute() unless I actually have something that I want to do in Execute() and needs the falloff..?
          • Yep, that's true. 🙂
          #pragma once
          #include "c4d.h"
          #include "c4d_falloffdata.h"
            
          class FalloffObjectData : public ObjectData {
          protected:
            AutoAlloc<C4D_Falloff> falloff;
            Int32 falloff_dirty;
            
            Bool InitFalloff(GeListNode* node_) {
              if (!this->falloff) return false;
              auto* op = static_cast<BaseObject*>(node_);
              if (!op) return false;
              auto* bc = op->GetDataInstance();
              if (!bc) return false;
              return this->falloff->InitFalloff(bc, op->GetDocument(), op);
            }
            
            Int32 GetFalloffDirty(GeListNode* node_) {
              if (!this->falloff) return false;
              auto* op = static_cast<BaseObject*>(node_);
              if (!op) return false;
              auto* bc = op->GetDataInstance();
              if (!bc) return false;
              return this->falloff->GetDirty(bc);
            }
          public:
            
            FalloffObjectData() : ObjectData(), falloff(), falloff_dirty(0) {}
            virtual ~FalloffObjectData() {}
            
            // ObjectData Overrides
            
            virtual DRAWRESULT Draw(BaseObject* op, DRAWPASS pass, BaseDraw* bd, BaseDrawHelp* bh) override {
              if (!this->InitFalloff(op)) return DRAWRESULT_ERROR;
              BaseContainer* bc = op->GetDataInstance();
              if (!this->falloff->Draw(bd, bh, pass, bc)) return DRAWRESULT_ERROR;
              return ObjectData::Draw(op, pass, bd, bh);
            }
            
            virtual Int32 GetHandleCount(BaseObject* op) override {
              if (!this->InitFalloff(op)) return 0;
              BaseContainer* bc = op->GetDataInstance();
              Int32 count = this->falloff->GetHandleCount(bc);
              return count;
            }
            
            virtual void GetHandle(BaseObject* op, Int32 index, HandleInfo& info) override {
              if (!this->InitFalloff(op)) return;
              BaseContainer* bc = op->GetDataInstance();
              this->falloff->GetHandle(index, bc, info);
            }
            
            virtual void SetHandle(BaseObject* op, Int32 index, Vector pos, HandleInfo const& info) override {
              if (!this->InitFalloff(op)) return;
              BaseContainer* bc = op->GetDataInstance();
              this->falloff->SetHandle(index, pos, bc, info);
            }
            
            virtual void CheckDirty(BaseObject* op, BaseDocument* doc) override {
              ObjectData::CheckDirty(op, doc);
              Int32 dirty_count = this->GetFalloffDirty(op);
              if (dirty_count != this->falloff_dirty) {
                this->falloff_dirty = dirty_count;
                op->SetDirty(DIRTYFLAGS_DATA);
              }
            }
            
            // NodeData Overrides
            
            virtual Bool Init(GeListNode* node_) override {
              if (!ObjectData::Init(node_)) return false;
              if (!this->InitFalloff(node_)) return false;
              return true;
            }
            
            virtual Bool GetDDescription(GeListNode* node_, Description* desc, DESCFLAGS_DESC& flags) override {
              if (!ObjectData::Init(node_)) return false;
              if (!desc || !desc->LoadDescription(node_->GetType())) return false;
              flags |= DESCFLAGS_DESC_LOADED;
              if (!this->falloff->AddFalloffToDescription(desc, nullptr)) return false;
              return ObjectData::GetDDescription(node_, desc, flags);
            }
            
            virtual Bool Message(GeListNode* node_, Int32 msg, void* pdata) override {
              if (!this->InitFalloff(node_)) return false;
              if (!this->falloff->Message(msg, nullptr, pdata)) return false;
              return ObjectData::Message(node_, msg, pdata);
            }
            
          };
          

          Edit:

          • add parent constructor call
          • remove MergeContainer() call, InitFalloff surprisingly not only initializes the fallof data, but
            also the container if it hasn't been initialized with values before
          • fix falloff position not being respected in draw by passing "op" to InitFalloff()
          • add missing ObjectData::Draw() call
          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 13/11/2016 at 10:17, xxxxxxxx wrote:

            And all this info straight into the docs for future reference.. 😉

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