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

    CustomData converted to GeData

    Scheduled Pinned Locked Moved SDK Help
    12 Posts 0 Posters 814 Views
    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 Offline
      Helper
      last edited by

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

      On 29/10/2012 at 15:02, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   13 
      Platform:    Mac  ;  
      Language(s) :     C++  ;

      ---------
      Hello all.

      I've got a question that seems really noobish, but I can't figure out how to do it.  I'm making a material with a proximal shader, and I want to add the objects that are created in a loop to the object field of it.

        
      BaseMaterial *mat = BaseMaterial::Alloc(Mmaterial);  
      BaseShader *shader;  
      InExcludeData *inex;  
          
      //Loop stuff  
       inex->InsertObject(obj, NULL);// the new object to the inexclude  
      //Loop stuff ends  
        
      GeData gedataInexclude;  //here's where I'm having trouble I need to convert an Inexclude to a GeData and I can't figure it out.   
        
      shader->SetParameter(1015, gedataInexclude, DESCFLAGS_SET_PARAM_SET);//SLA_PROXIMAL_OBJECTS I know I shouldn't do this part like this my my project won't load the res file  
          
      mat->SetParameter(MATERIAL_ALPHA_SHADER,shader,DESCFLAGS_SET_PARAM_SET);  
      mat->InsertShader(shader, NULL);   
      doc->InsertMaterial(mat);  
      

      So I'm stuck on converting the Inexclude to the GeData so I can use it in the SetParameter.  Here's what I've been trying to use:

        
      GeData* gedataInexclude;  
      gedataInexclude->SetCustomDataType(inex,CUSTOMDATATYPE_INEXCLUDE_LIST);  
      

      I keep getting errors that there's npo matching function calls and such.  I think the problem is I don't understand what SetCustomDataType is looking for.

      Any help would be great, thanks in advance!
      Dan

      (edit: fixed typo in title)

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

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

        On 30/10/2012 at 02:42, xxxxxxxx wrote:

        Originally posted by xxxxxxxx

         
        GeData* gedataInexclude;  
        gedataInexclude->SetCustomDataType(inex,CUSTOMDATATYPE_INEXCLUDE_LIST);  
        

        I think you should just swap the 2 parameters of calling SetCustomDataType(). The custom data type ID is expected first, then the custom data value.

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

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

          On 30/10/2012 at 09:24, xxxxxxxx wrote:

          Hi Yannick, thanks for the help, but that didn't work.

          I switch it from :

            
          InExcludeData *inex2;  
          GeData *gedataInexclude;  //here's where I'm having trouble I need to convert an Inexclude to a  GeData and I can't figure it out.   
          gedataInexclude->SetCustomDataType(inex2 , CUSTOMDATATYPE_INEXCLUDE_LIST);  
              
          

          To:

            
          InExcludeData *inex2;  
          GeData *gedataInexclude;  //here's where I'm having trouble I need to convert an Inexclude to a GeData and I can't figure it out.   
          gedataInexclude->SetCustomDataType(CUSTOMDATATYPE_INEXCLUDE_LIST,inex2);  
              
          

          And I'm getting this error. " error: no matching function for call to 'GeData::SetCustomDataType(int, InExcludeData*&)'note: candidates are: void GeData::SetCustomDataType(LONG, const CustomDataType&)"

          Do I need to covert  inex2 from and InExcludeData to a CustomDataType or something?  I've tried that ways I know of and those haven't worked.

          Thanks for the help.
          Dan

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

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

            On 30/10/2012 at 10:13, xxxxxxxx wrote:

            Hi Dan,

            CustomDataType is a parent class of InExcludeData but SetCustomDataType() expects a const value so we have to explicitly cast it.
            See the trick here: https://developers.maxon.net/forum/topic/4438/4102_problem-by-saving-data&PID=16747#16747

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

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

              On 30/10/2012 at 12:14, xxxxxxxx wrote:

              Thanks again, Yannick!  I thought I had tried that already but I guess not.  One more question if it's not to much trouble.  Now that I've assigned the inexclude to the shader I need to assign the shader to the material.

              I saw Scott's thread about it here, https://developers.maxon.net/forum/topic/5689/5725_how-to-get-at-shader-options  But he uses the basecontainer to set the parameter and we aren't supposed to do that now correct?  So how would it be done with SetParameter?  It's not a CustomDataType, I think, so it can't be done the same way as the Inexclude, right?

              Dan

              Edit:  In a related but separate topic, I have a Link description element and I'm trying to get the object out of it.  My current code:

                
                GeData objtemp;  
                op->GetParameter(DescLevel(LINKER), objtemp,  DESCFLAGS_GET_PARAM_GET);  
                BaseObject* obj = (BaseObject* )objtemp.GetLink(GetActiveDocument());  
              

              This code does cause a crash but it always returns NULL regardless of if there's an object in the link field or not.  Thanks for any possible help.

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

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

                On 31/10/2012 at 02:57, xxxxxxxx wrote:

                I think you should call GetParameter() with DESCFLAGS_GET_0 instead of DESCFLAGS_GET_PARAM_GET.

                Originally posted by xxxxxxxx

                One more question if it's not to much trouble.  Now that I've assigned the inexclude to the shader I need to assign the shader to the material.

                I saw Scott's thread about it here, https://developers.maxon.net/forum/topic/5689/5725_how-to-get-at-shader-options  But he uses the basecontainer to set the parameter and we aren't supposed to do that now correct?  So how would it be done with SetParameter?  It's not a CustomDataType, I think, so it can't be done the same way as the Inexclude, right?

                I don't understand, what do you want to do?

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

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

                  On 31/10/2012 at 09:06, xxxxxxxx wrote:

                  Thanks Yannick, that worked perfectly.

                  Sorry about being unclear.  I want to assign a shader to the texture field of a material, specifically around the Alpha channel.  In that thread Scott does it like this:

                    
                      
                      
                        BaseContainer *data = mat->GetDataInstance(); // Get the material's container    
                        BaseShader *shd = BaseShader::Alloc(Xsimplenoise); // Creates simple noise instance....For other types(fresnel,etc..). Look up  "enum Xbase"  in the SDK    
                        if(!shd) return FALSE;  
                          
                        data->SetLink(MATERIAL_COLOR_SHADER, shd); // Adds simple noise to the color channel in memory only    
                      
                  

                  But isn't using the base container to modify and object bad form?    Here's my current code:

                    
                    
                    shader->SetParameter(1015, tempinex, DESCFLAGS_SET_0);//SLA_PROXIMAL_OBJECTS  
                    //Something here to convert a baseshader to gedata  
                    mat->SetParameter(MATERIAL_ALPHA_SHADER,gedatashader,DESCFLAGS_SET_0);  
                  

                  It's not a CustomDataType and GeData doesn't have a method for converting it so I'm rather lost right now.

                  Thanks!
                  Dan

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

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

                    On 01/11/2012 at 02:20, xxxxxxxx wrote:

                    Hi Dan,

                    Material channel's shader are shader link. You can see in Scott's code that he calls SetLink() to set the container value.
                    So we have to construct the GeData with a BaseLink.

                    Here's how I would create and assign a noise shader to the alpha channel's shader of a material:

                    BaseShader *shd = BaseShader::Alloc(Xsimplenoise);
                    if (!shd) return FALSE;
                      
                    BaseMaterial *mat = doc->GetFirstMaterial();
                    if (!mat) return FALSE;
                      
                    AutoAlloc<BaseLink> link;
                    GeData data;
                      
                    link->SetLink(shd);
                    data.SetBaseLink(link);
                      
                    if (mat->SetParameter(MATERIAL_ALPHA_SHADER, data, DESCFLAGS_SET_0))
                    {
                        mat->InsertShader(shd, NULL);
                        mat->Message(MSG_UPDATE);
                        mat->Update(TRUE, TRUE);
                      
                        EventAdd();
                    }
                    
                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

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

                      On 02/11/2012 at 09:39, xxxxxxxx wrote:

                      Would one of you guys please post the code to load an object into the proximal's object list?
                      I tried to use the casting code on that link Yannick posted. But I can't get it right.

                      Here's a code example that will create a new material with a proximal shader in the color channel.
                      Everything works except the part where I'm trying to load the first object in the OM into the proximal's object list.

                      #include "..\..\..\..\resource\modules\sla\res\description\xslaproximal.h"  
                      #include "customgui_inexclude.h"  
                        
                        
                        
                        BaseMaterial *mat = BaseMaterial::Alloc(Mmaterial); //Generate a new material and assign a variable to it   
                        if(!mat) return TRUE;                               //Error handling  
                          
                        BaseContainer *data = mat->GetDataInstance();      //Get the material's container    
                        BaseShader *shd = BaseShader::Alloc(Xproximal);    //Creates a proximal instance. Look up "Enum Xbase" in the SDK for others  
                        if(!shd) return FALSE;    
                        
                        data->SetLink(MATERIAL_COLOR_SHADER, shd);         //Adds proximal the color channel in memory only  
                        mat->InsertShader(shd, NULL);                      //Inserts the shader into the material's color channel from memory  
                        doc->InsertMaterial(mat);                          //Adds the new material to the material Manager from memory  
                        
                        ((Material* )mat)->SetChannelState(CHANNEL_COLOR, TRUE); //Enables the channel..not usually needed for the color channel  
                        
                        // This section changes the proximal's attributes  
                        GeData d;                                                                          //A container that holds the data gotten from GetParameter() below  
                        shd->GetParameter(DescLevel(SLA_PROXIMAL_INCLUDE_SUBOBJECTS), d, DESCFLAGS_GET_0); //Get the Include SubObjects attribute and store the value in "d"  
                        
                        shd->SetParameter(DescLevel(SLA_PROXIMAL_INCLUDE_SUBOBJECTS), TRUE, DESCFLAGS_SET_0); //Enable Include Subobjects option  
                        
                        
                      ///////////////////////////////////// This part is wrong and crashes C4D! //////////////////////////////////////////////////  
                        
                        BaseObject *obj  = doc->GetFirstObject();           //The object that will be put into the proximal's InExclude list  
                        if(!obj) return FALSE;  
                        InExcludeData *objList = (InExcludeData* )data->GetCustomDataType(SLA_PROXIMAL_OBJECTS, CUSTOMDATATYPE_INEXCLUDE_LIST);// <---- Wrong!!  
                        objList->InsertObject(obj, DESCFLAGS_SET_0);  
                        
                      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
                        
                        
                        shd->Message(MSG_UPDATE);    //Update the shader changes  
                        EventAdd();  
                        mat->Message(MSG_UPDATE);    //Update the material changes  
                        mat->Update(TRUE, TRUE);     //Update the material's icon
                      

                      Thanks,
                      -ScottA

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

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

                        On 05/11/2012 at 06:15, xxxxxxxx wrote:

                        Hi Scott,

                        In yourcode, data  is the material's container, not Proximal shader's container.
                        We have also to carefully build the description IDs to get the parameters: you're not setting SLA_PROXIMAL_INCLUDE_SUBOBJECTS as expected.

                        Using GetParameter()/SetParameter() is the way to go to access, modify then assign in/exclude lists:

                        GeData d;
                        DescID id;
                        id = DescID(DescLevel(SLA_PROXIMAL_INCLUDE_SUBOBJECTS, DTYPE_BOOL, 0));
                          
                        shd->SetParameter(id, TRUE, DESCFLAGS_SET_0); // Enable Include Subobjects option
                          
                        BaseObject *obj  = doc->GetFirstObject();
                        if (!obj) return FALSE;
                          
                        id = DescID(DescLevel(SLA_PROXIMAL_OBJECTS, CUSTOMDATATYPE_INEXCLUDE_LIST, 0));
                        if (shd->GetParameter(id, d, DESCFLAGS_GET_0)) // Get proximal objects list
                        {
                            InExcludeData * objList = (InExcludeData* )d.GetCustomDataType(CUSTOMDATATYPE_INEXCLUDE_LIST);
                            if (!objList) return FALSE;
                            objList->InsertObject(obj, 0);
                            shd->SetParameter(id, d, DESCFLAGS_SET_0); // Set the modified objects list back into the parameters
                        }
                        
                        1 Reply Last reply Reply Quote 0
                        • H Offline
                          Helper
                          last edited by

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

                          On 05/11/2012 at 09:54, xxxxxxxx wrote:

                          Thank You Yannick. 🍺

                          In case anyone needs it.
                          Here's a working example of using a GeDialog plugin to create a new material with a proximal shader in the color channel.
                          Then it loads the selected object into the proximal's In/Ex list:

                          #include "..\..\..\..\resource\modules\sla\res\description\xslaproximal.h"  
                          #include "customgui_inexclude.h"  
                            
                            
                            BaseObject *obj  = doc->GetActiveObject();         //The object we will automatically add to the proximal's In/Ex list  
                            if (!obj) return FALSE;                            //If no object is selected..There's no point in making a new material..So we end it all right here  
                            
                            BaseMaterial *mat = BaseMaterial::Alloc(Mmaterial);//Generate a new material and assign a variable to it   
                            if(!mat) return TRUE;                              //Error handling  
                              
                            BaseContainer *data = mat->GetDataInstance();      //Get the material's container    
                            BaseShader *shd = BaseShader::Alloc(Xproximal);    //Creates a proximal instance. Look up "Enum Xbase" in the SDK for others  
                            if(!shd) return FALSE;    
                            
                            data->SetLink(MATERIAL_COLOR_SHADER, shd);         //Adds proximal the color channel in memory only  
                            mat->InsertShader(shd, NULL);                      //Inserts the shader into the material's color channel from memory  
                            doc->InsertMaterial(mat);                          //Adds the new material to the material Manager from memory  
                            
                            ((Material* )mat)->SetChannelState(CHANNEL_COLOR, TRUE); //Enables the channel..not usually needed for the color channel  
                            
                            GeData d;                                          //A container similar to a BaseContainer  
                            DescriptionCommand dc;                             //In/Ex lists are a descriptions. So we need to store it in this type of variable  
                            //DescID id;                                       //Only needed if "id" is not already included in the Command() function's parameters  
                            
                            //Alternative way to enable some of the non-description based options inside the proximal shader's attributes  
                            //shd->GetParameter(DescLevel(SLA_PROXIMAL_INCLUDE_SUBOBJECTS), d, DESCFLAGS_GET_0);   //Get the Include SubObjects attribute and store the value in "d"  
                            //shd->SetParameter(DescLevel(SLA_PROXIMAL_INCLUDE_SUBOBJECTS), TRUE, DESCFLAGS_SET_0);//Enable Include Subobjects option  
                             
                            dc.id = DescID(DescLevel(SLA_PROXIMAL_INCLUDE_SUBOBJECTS, DTYPE_BOOL, 0));             //Get the "Include SubObjects" attribute and store the value in "dc.id" variable  
                            shd->SetParameter(dc.id, TRUE, DESCFLAGS_SET_0);                                       //Enable Include SubObjects option  
                            
                            dc.id = DescID(DescLevel(SLA_PROXIMAL_OBJECTS, CUSTOMDATATYPE_INEXCLUDE_LIST, 0));     //Get proximal object's list of objects and store it in the dc.id variable  
                            if (shd->GetParameter(dc.id, d, DESCFLAGS_GET_0))                                      //If the list exists<---Just for error checking  
                            {  
                                //GePrint("Found the Object List");  
                                InExcludeData *objList = (InExcludeData* )d.GetCustomDataType(CUSTOMDATATYPE_INEXCLUDE_LIST); //Create an In/Ex list variable and store it in the "d" container  
                                if (!objList) return FALSE;  
                            
                                objList->InsertObject(obj, 0);                                                    //Insert the object into the proximal's In/Ex list  
                                shd->SetParameter(dc.id, d, DESCFLAGS_SET_0);                                     //Update the modified parameters  
                                LONG count = objList->GetObjectCount();                                           //Get the number of object's in the In/Ex list  
                                GePrint(LongToString(count));  
                            }  
                            
                            shd->Message(MSG_UPDATE);            //Update the changes made to the shader  
                            mat->Message(MSG_UPDATE);            //Update the changes made to the material  
                            mat->Update(TRUE, TRUE);             //Refresh the materials displayed icon  
                            EventAdd();
                          

                          -ScottA

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

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

                            On 08/11/2012 at 11:01, xxxxxxxx wrote:

                            Thanks a ton for all the help both of you!   I'd post my finished code, but Scott showed it so much better then I could. 👍

                            Thanks!
                            Dan

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