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

    Set Material Default Projection [SOLVED]

    SDK Help
    0
    15
    1.6k
    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 14/09/2014 at 23:25, xxxxxxxx wrote:

      Why use a MessageData plugin and SpecialEventAdd? You use the right message already. Look
      at its documentation, here[URL-REMOVED]. You can create your own tag and fill it into the "result" member of the
      passed MaterialDragAndDrop structure to prevent the creation of a default tag.

      -Niklas


      [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

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

        On 15/09/2014 at 07:37, xxxxxxxx wrote:

        Yeah I saw that in the docs Niklas.
        But it doesn't tell me anything at all about how to actually use it. So I had to invent my own method.

        If that struct is capable of changing the material's texture tag options. I'd like to know how?

        -ScottA

        Edit- I also hate using the material's name as the thing it looks for. Because the user can change it.
        So I'm still looking for a better way to find the material that a ttag belongs to.

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

          On 15/09/2014 at 08:47, xxxxxxxx wrote:

          I guess getting the name of the material from the tag "link field" should be doable

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

            On 15/09/2014 at 10:07, xxxxxxxx wrote:

            There has to be a better way than using the name property.
            I wouldn't even need it if Maxon documented the MaterialDragAndDrop struct properly.

                if(type == MSG_MATERIALDRAGANDDROP)   
              {  
                 MaterialDragAndDrop mdd;  
                 mdd.doc = GetActiveDocument();  
                 mdd.op = mdd.doc->GetActiveObject();  
                 mdd.result = mdd.op->GetTag(Ttexture);  
              
                 GePrint(mdd.result->GetName());  //<---Crash!!!  
              }
            

            Obviously I'm doing it wrong. And it's crashing because the tag doesn't exist yet.
            But how the heck are we supposed to use this struct code to get the tag the material generates?
            The docs don't tell us squat how to use it. Less than squat.
            Squat looks at the docs and says "Man, that ain't squat". 😠

            -ScottA

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

              On 15/09/2014 at 10:51, xxxxxxxx wrote:

              you need to do checks about GetActiveObject() and GetTag() , I see if no object it will crash, but not sure also if the whole process is correct

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

                On 15/09/2014 at 11:10, xxxxxxxx wrote:

                Well. That was just a quick and dirty example.
                I can add error checking to resolve the crash. But I still can't access the texture tag and change it using the struct as the docs seem to hint at. But never exaplin how to actually do it.

                  
                  if(type == MSG_MATERIALDRAGANDDROP)  
                  {  
                     MaterialDragAndDrop mdd;  
                     mdd.doc = GetActiveDocument();  
                     if(!mdd.doc) return FALSE;  
                     mdd.op = mdd.doc->GetActiveObject();  
                     if(!mdd.op) return FALSE;  
                  
                     //Nope..doesn't work   
                     //It doesn't crash...but it doesn't change the tag's projection option either. Because the tag does not exist yet!!!  
                     mdd.result = mdd.op->GetTag(Ttexture);  
                     if(mdd.result) mdd.result->SetParameter(DescLevel(TEXTURETAG_PROJECTION), GeData(TEXTURETAG_PROJECTION_UVW), DESCFLAGS_SET_0);  
                  }
                

                I'm sure I'm using it wrong.

                -ScottA

                *Edit:
                Thanks for your input guys.
                I'm feeling very angry and grumpy at Maxon right now for their crappy docs. So please excuse me if I come off as rude or snappy in this thread.

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

                  On 15/09/2014 at 11:31, xxxxxxxx wrote:

                  I'm not sure if this may work or not, but I think MaterialDragAndDrop should be a pointer, constructed inside the texture tag constructor, and when you encounter the message MSG_MATERIALDRAGANDDROP your problem will vanish because the tag is there

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

                    On 15/09/2014 at 11:56, xxxxxxxx wrote:

                    Sorry Scott, but the documentation is as clear as it can get.

                    MSG_MATERIALDRAGANDDROP
                    Received by a material upon dropping an instance of the material onto an object. The material can choose to create a tag of its own, or trigger other actions, instead of letting CINEMA 4D create a normal material assignment. The corresponding data is MaterialDragAndDrop.

                    For example Sketch and Toon creates its own type of tag and returns it in result. CINEMA 4D creates the undo for it and activates it. Inserting the tag is done by the material.

                    And in the description of MaterialDragAndDrop:

                    BaseTag* result
                    If you choose to create a tag of your own, point this pointer to it. CINEMA 4D will create the undo and activate the tag. (You still have to insert the tag manually onto the object.)

                      
                    // note: nullptr checks omitted
                    Bool MyMaterial::Message(GeListNode* node, Int32 type, void* pData)
                    {
                      if(type == MSG_MATERIALDRAGANDDROP)
                      {
                        BaseMaterial* mat = static_cast<BaseMaterial*>(node);
                        MaterialDragAndDrop* mdd = static_cast<MaterialDragAndDrop*>(pData);
                        mdd->result = mdd->op->MakeTag(Ttexture);
                        mdd->result->SetParameter(TEXTURETAG_MATERIAL, mat, DESCFLAGS_SET_0);
                        mdd->result->SetParameter(TEXTURETAG_PROJECTION, TEXTURETAG_PROJECTION_UVW, DESCFLAGS_SET_0);
                        return true;
                      }
                      return MaterialData::Message(node, type, pData);
                    }
                    
                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 15/09/2014 at 12:25, xxxxxxxx wrote:

                      Thanks Niklas. That works. 👍

                      But I disagree about the docs. The docs are not even remotely saying what you've written there.
                      What on earth made you think of using this code based on the docs saying use your own pointer?:
                      MaterialDragAndDrop *mdd = static_cast<MaterialDragAndDrop*>(pData);

                      Since when does use your own pointer = void *pData?
                      I don't see the connection at all. That's as clear as mud to me.

                      -ScottA

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

                        On 15/09/2014 at 23:00, xxxxxxxx wrote:

                        Originally posted by xxxxxxxx

                        Thanks Niklas. That works. 👍

                        But I disagree about the docs. The docs are not even remotely saying what you've written there.
                        What on earth made you think of using this code based on the docs saying use your own pointer?:
                        MaterialDragAndDrop *mdd = static_cast<MaterialDragAndDrop*>(pData);

                        Since when does use your own pointer = void *pData?
                        I don't see the connection at all. That's as clear as mud to me.

                        -ScottA

                        It's Cinema's message system. I've seen you using it correctly before already, too. The documentation
                        tells you:

                        1. MSG_MATERIALDRAGANDDROP is a message type that is sent to NodeData plugins.
                        2. The data that is passed to the NodeData::Message() call is MaterialDragAndDrop
                        3. The MaterialDragAndDrop::result member can be set to a custom tag, preventing the
                          caller (in this case Cinema 4D itself) to create the default tag.
                        4. If you create a custom tag, it does everything else that is required (undo step, selection, ...)

                        And as you should know, there is void* parameter for the NodeData::Message() method that
                        points to the data of the message. Depending on the message type, you can cast it to a different
                        pointer type in order to access the underlying data.

                        To show a different example:

                        if (type == MSG_GETCUSTOMICON)
                        {
                          /* The void* parameter for the Message() function is the
                           * address of a GetCustomIconData structure which the message
                           * sender expects us to fill with the required information. */
                          GetCustomIconData* data = static_cast<GetCustomIconData*>(pData);
                          IconData* icon = data->dat;
                          if (icon->bmp)
                          {
                            m_customIcon->CopyTo(icon->bmp);
                          }
                          else
                          {
                            icon->bmp = m_customIcon->GetClone();
                          }
                          icon->x = 0;
                          icon->y = 0;
                          icon->w = icon->bmp->GetBw();
                          icon->h = icon->bmp->GetBh();
                          data->filled = true;
                          return true;
                        }
                        

                        Best,
                        -Niklas

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

                          On 16/09/2014 at 10:27, xxxxxxxx wrote:

                          OK. Thanks for explaining what when through your head.
                          It helps me to know what other people are thinking when they use the docs. So I can learn how to decrypt them better.

                          As I keep saying to you. You're cheating.!Wink[URL-REMOVED]
                          You're not reading the docs. You are taking what you've learned from other people. Then using that information to "decrypt" what's not actually physically written in the page.

                          I know you don't share the same opinion. And you think it's fun to figure out these little puzzles.
                          But IMO the C4D docs require far too much of this. And it's really annoying when you're just trying to get something simple done. And don't want to play the "Solve the docs" puzzle game.
                          IMO. Any time the reader has to rely on this much previously learned knowledge. The docs are not clear enough and they fail.

                          -ScottA


                          [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

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