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

    C++ Missing Information

    SDK Help
    0
    6
    635
    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 03/07/2013 at 05:56, xxxxxxxx wrote:

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

      ---------
      Hei folks,

      I find myself annoyed about missing information in the SDK documentation very often recently,
      because I had to invest a lot of time figuring out these tings myself. I want to post things here
      that I couldn't find in the documentation and was able to figure out myself or from information
      collected from other threads. You are welcome to join!

      I'll try to update the Table of Contents regularly. If you post, please make it one post for each
      topic. If you have to add information or update the post, just do it. I'd also like to ask you to
      not respond to this thread, but if any questions occure, create a new thread with a link to the
      topic in this post. This way the thread stays focues on the actual topic: collecting information
      missing from the SDK docs in one place. Thanks

      Table of Contents:

      • EffectorData
        * Drawing of C4D_Falloff does not follow the Effector object
      • GeDialog
        * Be careful with modal dialogs (platform differences)
      • GvOperatorData
        * Simple graph-view calculation example
      • Compilation
        * MSVC vs. Clang: Differences

      Cheers,
      -Niklas

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

        On 03/07/2013 at 05:59, xxxxxxxx wrote:

        EffectorData - Drawing of C4D_Falloff does not follow the Effector object

        Description : The EffectorData class has a C4D_Falloff member. Necessary calls are automatically
        forwarded to it (eg. C4D_Falloff::Draw() from EffectorData::Draw()). Though, there's one
        problem one might experience while developing an effector: When the effector object is not
        attached to any object (eg. effector list in a cloner, serving as a deformer), the visuals of the falloff
        in the viewport stay at the position the effector was last invoked from.

        Solution : Register the EffectorData plugin with the OBJECT_CALL_ADDEXECUTION flag. The
        implementation of EffecorData::Execute() will automatically update the internal C4D_Falloff object
        causing it to be drawn at the correct location.

        Example :

        RegisterEffectorPlugin(
                    Omyeffector,
                    GeLoadString(IDC_MYEFFECTOR_NAME),
                    OBJECT_MODIFIER | OBJECT_CALL_ADDEXECUTION,
                    MyEffectorData::Alloc,
                    "Omyeffector",
                    AutoBitmap("Omyeffector.tif"),
                    MYEFFECTOR_VERSION);

        Source : cinema4dsdk/source/object/dropeffector.cpp

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

          On 03/07/2013 at 06:52, xxxxxxxx wrote:

          GvOperatorData - Simple graph-view calculation example

          While I tried to figure this out, an example would have been more than I could have ever dreamt
          of. Remo was so kind to hand one over to me, which helped me figuring out a few things. Here is
          an example of mine:

          class MyOperatorData : public GvOperatorData {

          typedef GvOperatorData super;

          public:

          //| GvOperatorData Overrides

          virtual Bool InitCalculation(GvNode* node, GvCalc* calc, GvRun* run) {
                      if (!node || !calc || !run) return FALSE;
                      if (!GvBuildValuesTable(node, m_values, calc, run, GV_EXISTING_PORTS)) {
                          return FALSE;
                      }
                      return super::InitCalculation(node, calc, run);
                  }

          virtual void FreeCalculation(GvNode* node, GvCalc* calc) {
                      GvFreeValuesTable(node, m_values);
                      super::FreeCalculation(node, calc);
                  }

          virtual Bool Calculate(GvNode* node, GvPort* outPort, GvRun* run, GvCalc* calc) {
                      if (!node || !run || !calc) return FALSE;
                      if (!GvCalculateInValuesTable(node, run, calc, m_values)) {
                          return FALSE;
                      }

          Bool index = 0;
                      GvPort* indexPort = node->GetInPortFirstMainID(ID_MYPORT_INDEX);
                      if (indexPort && indexPort->GetInteger(&index, run)) ;
                      else {
                          // Either work with index = 0 or stop calculation. Returning FALSE
                          // will make the XPresso Node turn yellow!
                      }

          // Limit the index.
                      LONG count = GetFooBarArrayCountFromSomewhere();
                      if (index < 0) index = 0;
                      else if (index >= count) index = count - 1;

          if (!outPort) {
                          // If your node is an initiator, handle this step here. Eg. when
                          // your input-ports should be directed to values on an object or
                          // similar, you can retrieve the values here and fill in the object.
                          //
                          // Example (imagine an array of objects that can be addressed via
                          // via the index retrieved above) :

          Real value = 0.0;
                          GvPort* valuePort = node->GetInPortFirstMainID(ID_MYPORT_VALUE);
                          if (valuePort && valuePort->GetReal(&value, run)) ;
                          else {
                              // The port does either not exist or is not connected. If
                              // the port is described as an INPORT in the operator
                              // description resource, the value can even be retrieved when
                              // the port is not connected (since the value is defined in
                              // the Attributes Manager).
                              return FALSE;
                          }

          Real* data = GetFooBarArrayFromSomewhere();
                          data[index] = value;
                          return TRUE;
                      }
                      else {
                          // Set the data for an output port.
                          switch (outPort->GetMainID()) {
                              case ID_MYPORT_COUNT:
                                  return outPort->SetInteger(count, run);
                              default:
                                  break;
                          }
                      }

          // If we reached this statement, something went wrong.
                      return FALSE;
                  }

          private:

          GvValuesInfo m_values;

          };

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

            On 03/07/2013 at 06:57, xxxxxxxx wrote:

            GeDialog - Be careful with modal dialogs (platform differences)

            Especially interesting for developers working on Windows only and giving the code away for
            compilation or developers of Python plugins.

            On OSX, a modal dialog does not have a close button in the title bar, unlike the windows modal
            dialog! If you open a modal dialog on OSX without a hand-made close-button (simply add a Button
            widget), you have to force quit Cinema since there is no way to close the window.

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

              On 03/07/2013 at 09:10, xxxxxxxx wrote:

              For modal dialogs, use the AddDlgGroup() with any of the following options OR'd together: DLG_OK and DLG_CANCEL.  And then handle them in the Command() method.  I know that this isn't the best solution, but it makes it easier to handle that bad situation in OSX.

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

                On 14/07/2013 at 12:58, xxxxxxxx wrote:

                MSVC vs. Clang : Differences

                I thought I'd put things here that I came across while compiling plugins for Mac, written on Windows.
                Though most of them might not be related to the C4D SDK at all, I think it is useful if you have at least
                heard about them.

                Context Macros :

                The macros __FUNCTION__ and __PRETTY_FUNCTION__ are treated like string literals in MSVC and
                GCC 3.3 (and earlier), but as of GCC 3.4, they are treated like variables. In MSVC and GCC 3.3, this
                was possible:

                GePrint(__FUNCTION__": something went wrong!");
                

                This is not valid in GCC 3.4 any longer. (Clang is based on GCC)

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