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
    • Recent
    • Tags
    • Users
    • Login

    ChannelShader acessing object attributes?

    Scheduled Pinned Locked Moved SDK Help
    17 Posts 0 Posters 1.5k 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 21/09/2008 at 19:17, xxxxxxxx wrote:

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

      ---------
      Hi, me again 😉

      I want a channelshader to get access to the object it's attached to (yes I read this thread).

      Using a plugin object, I have written some values in the objects' container. Like this:

      > obj->GetDataInstance()->SetReal(OBJ_MYSECRETOFFSET, Offset);

      In the ChannelShader, I try to retrieve the values like this:

      > Vector MyFunnyChannelshader::Output(PluginShader \*chn, ChannelData \*cd) \> { \>      RayObject \*robj = NULL; \>      BaseObject \*op; \>      LONG local_id = 0; \>      robj = cd->vd->ID_to_Obj(cd->vd->lhit, &local;\_id); \>      op = robj->link; \> \>      // Print object's name and the stored value \>      GePrint(op->GetName() + ": " + RealToString(op->GetDataInstance()->GetReal(OBJ_MYSECRETOFFSET, 0.0))); \> \>      return Vector(1.0, 0.0, 1.0); // Return some dummy color \> }

      The object's name is printed out fine while rendering, but the retrieved value is always 0. Also, the "op" pointer in MyFunnyChannelshader::Output points to different addresses than the "obj" pointer in the first code. It seems, all objects are copied for rendering; even when rendering in the editor?

      This is my first approach to a channel shader, so go easy on me 😉
      I'd be happy about any tips or hints. How can I put values into the objects that I can retrieve in my shader?

      Greetings,
      Jack

      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 22/09/2008 at 05:46, xxxxxxxx wrote:

        What you get in the volume data is the polygonal cache object of the original object. You have to use GetCacheparent to retrieve the original object. Something like this:

        > \> if(cd->vd) \> { \>      RayObject \*robj = NULL; \>      LONG local_id = 0; \>      robj = cd->vd->ID_to_Obj(cd->vd->lhit, &local;\_id); \> \>      if(robj && robj->link) \>      { \>           BaseObject \*op = NULL; \>           op = robj->link->GetCacheParent(); \> \>           if(op) \>           { \>                BaseContainer \*data = NULL; \>                data = op->GetDataInstance(); \>                //do something here \>           } \>      } \> } \>

        cheers,
        Matthias

        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 22/09/2008 at 07:03, xxxxxxxx wrote:

          Very super, that works perfectly for me!
          Many thanks, Matthias!

          Greetings,
          Jack

          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 25/09/2008 at 04:45, xxxxxxxx wrote:

            I just encounter a problem. This only works with primitives, as it seems.

            When I have cube primitives, the memory address of "op" in the shader (code is exactly as you postet it above) is the address of the cube primitive I wrote the data into. Working.

            But when I use polygon objects, the address of "op" in the shader is another one. Of course, the data I had written in the polygon object can not be retrieved, since "op" in the shader seems to point to another object.

            What can I do?

            + + +

            2nd question:
            How can I make your code work with sphere primitives that have the option "Render perfect" enabled?

            Greetings,
            Jack

            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 25/09/2008 at 04:56, xxxxxxxx wrote:

              Ah, OK, got it working. The data is then hosted in ->link and not in ->link->GetCacheParent().

              Anyway, my question about the 'perfect sphere' remains. How can this be done?

              Greetings,
              Jack

              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 25/09/2008 at 16:02, xxxxxxxx wrote:

                Oops, this is suddenly working now, too.

                Didn't debug it yet, but I guess when using perfect spheres the data is also contained in "link" and not in "cacheparent".

                Close this thread, I'm just mumbling to myself...

                Greetings,
                Jack

                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 21/05/2009 at 10:56, xxxxxxxx wrote:

                  Just have to push this old thread up again...

                  When the rendered object is an instance object, using the code from this thread I always get access to the container of the original instanced object. How can I detect if the rendered object is an instance object, and then access the instance object's container?

                  Also, instead of the old code:

                  > <code>robj = xvd->ID_to_Obj(xvd->lhit, &local;_id);</code>

                  ...I now use this:

                  > <code>robj = xvd->op;</code>

                  Seems to be exactly the same, didn't notice any difference. So why use ID_to_Obj()?

                  Anyway, the instance is the most important for me now 😉

                  Thanks in advance for information!

                  Greetings,
                  Jack

                  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 22/05/2009 at 15:02, xxxxxxxx wrote:

                    Does anybody have an idea?

                    Let's summarize (code stripped down to the essential parts) :

                    > \> Vector MyShader::Output(PluginShader \*chn, ChannelData \*cd) \> { \>      // Get volume data \>      VolumeData \*xvd = cd->vd; \> \>      // Get Ray object \>      RayObject \*robj = xvd->op; \> \>      // Get polygon cache \>      BaseObject \*pcache = robj->link; \> \>      // Container \>      BaseContainer \*dsource = NULL; \> \>      // Check if this object contains values for my shader \>      // (Check for Bool value that I write in all objects that should be shaded) \>      if (pcache->GetDataInstance()->GetBool(THIS_OBJ_IS_SHADED)) { \>           dsource = pcache->GetDataInstance(); \>      } \>      else { \>           dsource = pcache->GetCacheParent()->GetDataInstance(); \>      } \> \>      // Color calculations start here \>      // and read values from the object like this: \>      Real Value = dsource->GetReal(SOME_ID, 0.0); \> \>      // ... \>      // ... \>      // ... \>      return my_color_value; \> } \>

                    That works with all kind of objects, polygon objects, generators, perfect spheres, etc. But not with Instance objects. If I have an instance of an object, pcache always represents the linked original object instead of the instance object.

                    How can I detect if the rendered object is an instance object? I am sure there is a way.

                    Thanks for tips!

                    Cheers,
                    Jack

                    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 26/05/2009 at 03:25, xxxxxxxx wrote:

                      You have to go up all the cache hierarchy not just one step. Here some working code:

                      > \> Vector MandelbrotData::Output(PluginShader \*chn, ChannelData \*cd) \> { \>      if (cd->vd) \>      { \>           RayObject \*robj = NULL; \>           robj = cd->vd->op; \>           if (!robj) return 0.0; \> \>           BaseObject \*parent = NULL; \>           BaseObject \*op = NULL; \>           op = robj->link; \> \>           while (op) \>           { \>                parent = op; \>                op = op->GetCacheParent(); \>           } \> \>           if (parent && parent->GetType() == Oinstance) return Vector(1.0, 0.0, 0.0); \>      } \> \>      return 1.0; \> } \>

                      cheers,
                      Matthias

                      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 26/05/2009 at 04:03, xxxxxxxx wrote:

                        Ah, yes!

                        Thanks Matthias. I've been searching for this soooo long. Please excuse my offensive grizzling. Things can be so frustrating when one doesn't know the answer.

                        Again, thanks a thousand times! As always, you're going to be credited in my plugin's manual 😉

                        Cheers,
                        Jack

                        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 27/05/2009 at 05:16, xxxxxxxx wrote:

                          Hm, sorry to bug you again with this, but it does not work.

                          Instead of returning white (like in your example), I print a message to the console:

                          > <code>
                          > if (parent && parent->GetType() == Oinstance)
                          >     GePrint("Instance!");
                          > </code>

                          The message IS printed.

                          But the problem is, when I try to get the Instance object's Container like this:

                          > BaseContainer \*data = parent->GetDataInstance();

                          I always get a pointer to the same memory address, no matter which of the hundreds of instance objects is being rendered.
                          Is this the container of the original object instead of the instance object's container?

                          Any more ideas?

                          Greetings,
                          Jack

                          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 27/05/2009 at 05:26, xxxxxxxx wrote:

                            I have no idea why it is not working for you. It works perfectly fine here. Have you tried the exactly same code I posted? Maybe it's something else within your code?

                            cheers,
                            Matthias

                            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 27/05/2009 at 05:30, xxxxxxxx wrote:

                              Sorry, I altered my previous post.
                              It works, but not as expected. Please refresh the page, and read again. Sorry 😉

                              Cheers,
                              Jack

                              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 27/05/2009 at 06:30, xxxxxxxx wrote:

                                Sorry I can not confirm this. This code is working fine for me:

                                > \> Vector MandelbrotData::Output(PluginShader \*chn, ChannelData \*cd) \> { \>      if (cd->vd) \>      { \>           RayObject \*robj = NULL; \>           robj = cd->vd->op; \>           if (!robj) return 0.0; \> \>           BaseObject \*parent = NULL; \>           BaseObject \*op = NULL; \>           op = robj->link; \> \>           while (op) \>           { \>                parent = op; \>                op = op->GetCacheParent(); \>           } \> \>           if (parent/\* && parent->GetType() == Oinstance\*/) \>           { \>                BaseContainer \*data = NULL; \>                data = parent->GetDataInstance(); \> \>                GePrint(LongToString((LONG)data)); //print the address of the container \>                 \>                //return Vector(1.0, 0.0, 0.0); \>           } \>      } \> \>      return 1.0; \> } \>

                                cheers,
                                Matthias

                                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 27/05/2009 at 10:36, xxxxxxxx wrote:

                                  Ah, ok, it seems I did something wrong.
                                  Works not with normal objects, Ray objects (like the perfect sphere) and Instance objects. Thanks a lot!

                                  Cheers,
                                  Jack

                                  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/05/2009 at 14:04, xxxxxxxx wrote:

                                    Hi there, may I jump in here with my following question?
                                    I have a shader where I just use the object position to define a color. It works perfect until I use a generator plugin - than the shader just uses the position of the child object but not of the cloned objects.

                                    Can you give me a hint where to look?

                                    thanks in advance,
                                    cheers,
                                    Ello

                                    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/05/2009 at 14:36, xxxxxxxx wrote:

                                      hm.seems it just works when the child object is a polygonobject

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