Parameters in predefined functions



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 02/02/2007 at 02:47, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R9.507 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    I got a little problem understanding the parameter handling in functions. In some functions there are parameters like BaseDocument* doc, BaseObject* op or Description *description. It seems to me that Cinema4d "knows" that 'doc' is this document or 'op' is the object the function belongs to. But what how can i manually call functions with these standart parameters?
    I want to create someting like the Mocca Pose Mixer Tag Interface. If you click on "Add Pose" a new line in the description file will be created.
    I thought i have to combine a Message and a GetDDescription function like this:
    There is my GetDDesctiption function which is able to create some entries in a descrtipion file:

        
        
         Bool TagCone::GetDDescription(GeListNode *node, Description *description, LONG &flags) 
    

    and there is my Message function which controls the buttons in the description file.

        
        
        
        
        Bool TagCone::Message(GeListNode *node, LONG type, void *data)
        
        
        
        
        {
        
        
        
        
          switch (type)
        
        
        
        
          {
        
        
        
        
             case MSG_DESCRIPTION_COMMAND:
        
        
        
        
            {
        
        
        
        
               DescriptionCommand *dc = (DescriptionCommand* ) data;
        
        
        
        
               Bool TagCone::Message(GeListNode *node, LONG type, void *data)
        
        
        
        
               {
        
        
        
        
                 GePrint("Yeah hit me again!!!");
        
        
        
        
                 GetDDescription(node,???,???);
        
        
        
        
               }
        
        
        
        
        .... 
    

    How you can see I want to call the GetDDescription Function out of my Message Function. The parameter node is used in both functions so i can pass it to the GetDDescription Function. But i don't know how i can pass the parameter "description" to the GetDDescription Function, cause the Message Function has no parameter "description". (And i don't know what i should do with this LONG &flags)
     
    Can someone tell me what i should do or tell me if there is another maybe simpler way (with only one function) to get an interface like in the Mocca Pose Mixer Tag ...



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 02/02/2007 at 12:07, xxxxxxxx wrote:

    GetDDescription() is called *fairly* often (sarcasm). If you add GePrint("GetDDescription"); to the top of your GetDDescription() function call and open C4D's Console, you'll see just how frequently is it indeed called.

    That said, you should never have to call this function directly. A good way to 'kick' your plugin to call GetDDescription() is to send a Message(MSG_CHANGE) for the plugin - node->Message(MSG_CHANGE);. You may also try node->GetDescription(desc,0);. Description* desc will need to be allocated/freed each time.

    For example, you add your dynamic description elements using GetD(ynamic)Description(). These are description elements not stored statically in the description .res file for the plugin. They need their own IDs that don't conflict with the static ones.

    MSG_DESCRIPTION_COMMAND is sent when a description button is clicked. If you are wanting to add dynamic elements on a button click, then you are heading in the correct direction. But instead of trying to call GetDDescription from there, get the node and do node->Message(MSG_CHANGE). In the GetDDescription() function is where you are going to assemble the dynamic elements - that is its purpose.

    // NodeData.GetDDescription - Descriptions and Parameters  
    //*---------------------------------------------------------------------------*  
    Bool IPPBase::GetDDescription(GeListNode* node, Description* description, LONG& flags)  
    //*---------------------------------------------------------------------------*  
    {  
         if (!(node && description))               return FALSE;  
         if (!description->LoadDescription(node->GetType())) return FALSE;  
      
         // Get Object containing Dials  
         BaseDocument*     baseDoc =               node->GetDocument();  
         if (!baseDoc)     return FALSE;  
         BaseObject*          obj =                    static_cast<BaseObject*>(node);  
         if (!obj)          return FALSE;  
         BaseContainer*     opBC =                    obj->GetDataInstance();  
         if (!opBC)          return FALSE;  
      
         // Add dial tags  
         BaseContainer*     pbc;  
         DescID               descID;  
         String               dname;  
         ULONG               type;  
         ULONG               tsf;  
         LONG               index;  
         BOOL               hideZero =               opBC->GetBool(IPP_HIDE_ZERODIALS);  
         BOOL               hide;  
         Real               value;  
      
         // Initialize BaseContainer static values  
         BaseContainer sliderBC =                    GetCustomDataTypeDefault(DTYPE_REAL);  
         sliderBC.SetLong(DESC_ANIMATE,               DESC_ANIMATE_ON);  
         sliderBC.SetBool(DESC_REMOVEABLE,          FALSE);  
         sliderBC.SetLong(DESC_CUSTOMGUI,          CUSTOMGUI_REALSLIDER);     // _REAL, _REALSLIDERONLY  
         sliderBC.SetReal(DESC_MIN,                    MINREAL);  
         sliderBC.SetReal(DESC_MAX,                    MAXREAL);  
    #ifdef     C4D_R85  
         sliderBC.SetBool(DESC_SCALEH,               TRUE);  
    #endif  
      
         BaseContainer editBC =                         GetCustomDataTypeDefault(DTYPE_BUTTON);  
         editBC.SetString(DESC_SHORT_NAME,          "Edit");  
         editBC.SetLong(DESC_CUSTOMGUI,               CUSTOMGUI_BUTTON);  
         editBC.SetLong(DESC_ANIMATE,               DESC_ANIMATE_OFF);  
         editBC.SetBool(DESC_REMOVEABLE,               FALSE);  
      
         // Filter visible body part dial groups  
         for (BaseTag* pt = obj->GetFirstTag(); pt; pt = pt->GetNext())  
         {  
              if (!pt->IsInstanceOf(ID_IPPDIALTAG))     continue;  
              pbc =          pt->GetDataInstance();  
              if (!pbc)     continue;  
      
              // Dial Index  
              index =          pbc->GetLong(IPPDIAL_INDEX);  
      
              // Dial Slider  
              dname =          pbc->GetString(IPPDIAL_DIALNAME);  
              sliderBC.SetString(DESC_NAME,          dname);  
              value =          pbc->GetReal(IPPDIAL_CURRENTVALUE);  
              tsf =          (ULONG)pbc->GetLong(IPPDIAL_TYPESUBFLAGS);  
              type =          tsf & 0x000000FFL;  
              hide =          tsf & DIAL_FLAGS_HIDDEN;  
              // Transforms  
              if          (tsf & DIAL_FLAGS_TRANSFORM)     descID =     DescID(DescLevel(GROUP_TRANSFORM));  
              // Morphs  
              else if (type == CHAN_TYPE_TARGETGEOM)  
              {  
                   if (hideZero && (value == 0.0f))     hide =     TRUE;  
                   descID =     DescID(DescLevel(GROUP_MORPH));  
              }  
              // Other  
              else  
              {  
                   if ((type == CHAN_TYPE_VALUEPARM) && hideZero && (value == 0.0f))     hide = TRUE;  
                   descID =     DescID(DescLevel(GROUP_OTHER));  
              }  
      
              if (hide)  
              {  
                   // - Set display state to hide  
                   sliderBC.SetBool(DESC_HIDE,               TRUE);  
                   editBC.SetBool(DESC_HIDE,               TRUE);  
              }  
              else  
              {  
                   sliderBC.SetString(DESC_SHORT_NAME, pt->GetName());  
                   sliderBC.SetLong(DESC_UNIT,               chanTypeParams[type].unit);  
                   // - Set Min/Max/Step for Slider  
                   sliderBC.SetReal(DESC_MINSLIDER,     pbc->GetReal(IPPDIAL_MIN));  
                   sliderBC.SetReal(DESC_MAXSLIDER,     pbc->GetReal(IPPDIAL_MAX));  
                   sliderBC.SetReal(DESC_STEP,               pbc->GetReal(IPPDIAL_STEP));  
                   // - Set display state to show  
                   sliderBC.SetBool(DESC_HIDE,               FALSE);  
                   editBC.SetBool(DESC_HIDE,               FALSE);  
                   editBC.SetString(DESC_NAME,               dname);  
                   // -- Set Master-Slave button to show whether dial is Master and/or Slave  
                   if          (tsf & DIAL_FLAGS_SLAVES)  
                   {  
                        if (tsf & DIAL_FLAGS_VALUEOP)     editBC.SetString(DESC_SHORT_NAME,     "Edit M/S");  
                        else                                   editBC.SetString(DESC_SHORT_NAME,     "Edit M/_");  
                   }  
                   else  
                   {  
                        if (tsf & DIAL_FLAGS_VALUEOP)     editBC.SetString(DESC_SHORT_NAME,     "Edit _/S");  
                        else                                   editBC.SetString(DESC_SHORT_NAME,     "Edit _/_");  
                   }  
              }  
              // Dial Slider  
              if (!description->SetParameter(DescLevel(index,DTYPE_REAL,0),          sliderBC,     descID))     return FALSE;  
              // Edit Button  
              if (!description->SetParameter(DescLevel(index+1,DTYPE_BUTTON,0),     editBC,          descID))     return FALSE;  
              opBC->SetReal(index,                    value);  
         }  
      
         flags |=     DESCFLAGS_DESC_LOADED|DESCFLAGS_DESC_RECURSIONLOCK;  
      
         return SUPER::GetDDescription(node,description,flags);  
    }
    

    Note that a set of tags is being used to set up a set of dynamic sliders and buttons on this plugin object.

    Your message would be something like:

    // NodeData.Message  
    //*---------------------------------------------------------------------------*  
    Bool IPPBase::Message(GeListNode* node, LONG type, void* data)  
    //*---------------------------------------------------------------------------*  
    {  
         if          (!node) return FALSE;  
         switch (type)  
         {  
              // One of the Buttons  
              case MSG_DESCRIPTION_COMMAND:  
              {  
                   if (!data)     return TRUE;  
                   LONG id = ((DescriptionCommand* )data)->id[0].id;  
                   switch (id)  
                   {  
                        // Force update of Attributes Manager descriptions  
                        // This will also force a call to GetDDescription()  
                        case DIALGROUP_KICK:  
                             AutoAlloc<Description>     desc;  
                             if (desc)     node->GetDescription(desc,0);  
                             break;  
                        ...  
                   }  
                   break;  
              }  
         }  
         return TRUE;  
    }
    

    If the AutoAlloc<> doesn't work with Description, you'll need to do it this way:

    Description* desc =     Description::Alloc();  
    if (desc)  
    {  
         node->GetDescription(desc,0);  
         Description::Free(desc);  
    }
    


  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 02/02/2007 at 14:08, xxxxxxxx wrote:

    GetDDescription will be called for every change of the description elements, except button clicks, you have to catch these within Message and change the description's container. Haven't looked through Robert's code but will do so after the weekend and will try to post another example.

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 06/02/2007 at 00:01, xxxxxxxx wrote:

    Thx a lot for this partricularized answer. I will try to solve my problem with this. When i got the solution i will post it here ...


Log in to reply