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

    SDK Help
    0
    6
    768
    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 29/07/2017 at 07:50, xxxxxxxx wrote:

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

      ---------
      Hello,

      There are custom material plugins. And when they are assigned to objects their default projection is Spherical. I want default projection to be UVW (as for std Cinema materials).
      Same history as https://developers.maxon.net/forum/topic/8133/10594_set-material-default-projection-solved&PID=41173#41173

      // 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);
      }
      

      But that solution works only for simple cases.

      Consider a case. E.g. when we have a selection of polygons and try to assign own custom material with suggested method then SelectionTag is not created together with the TextureTag that we create on our own. Why? How to fix that?
      However when we don't write the pointer to mdd->result then we can't change default projection of texture but anything else works fine and Selection Tag too.

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

        On 29/07/2017 at 09:42, xxxxxxxx wrote:

        And here is my workaround:

        In MaterialData message I remember who is assigned where:

        		case MSG_MATERIALDRAGANDDROP:
        		{
        			MaterialDragAndDrop * mdd = (MaterialDragAndDrop * )(msgdat);
        			if (mdd != 0 && mat != 0)
        			{
        				BaseObject * obj = mdd->op;
        				if (obj != 0)
        				{
        					MY_COMMON_DATA * rendata = MyCommonDataInstance();
          
        					int next_id = rendata->mat_dnd_num;
        					rendata->mat_dnd.SetLink(next_id + 0, mat);
        					rendata->mat_dnd.SetLink(next_id + 1, obj);
        					rendata->mat_dnd_num += 2;
        				}
        			}
          
        			break;
        		}
        

        And in CoreMessage I intercept "change" message. It occurs for any change in scene also for previous one but with assigned and allocated Tags!

        void ChangeDefaultProjection(BaseDocument * doc)
        {
        	if (!doc) return;
          
        	MY_COMMON_DATA * rendata = MyCommonDataInstance();
        	if (rendata->mat_dnd_num <= 0) return;
          
        	for (int i = 0; i < rendata->mat_dnd_num; i += 2)
        	{
        		BaseMaterial * mat = (BaseMaterial * )rendata->mat_dnd.GetLink(i + 0, doc);
        		BaseObject * obj = (BaseObject * )rendata->mat_dnd.GetLink(i + 1, doc);
          
        		if (obj != 0 && mat != 0)
        		{
        			if (obj->IsInstanceOf(Obase) && mat->IsInstanceOf(Mbase))
        			{
        				BaseTag * tsearch = 0;
        				for (BaseTag * tag = obj->GetFirstTag(); tag; tag = tag->GetNext())
        				{
        					// search the last tag with this material
        					if (tag->IsInstanceOf(Ttexture)) {
        						BaseMaterial * mi = (BaseMaterial * )getParameterLink(*tag, TEXTURETAG_MATERIAL, 0);
        						if (mi == mat)
        							tsearch = tag;
        					}
        				}
          
        				if (tsearch != 0)
        					tsearch->SetParameter(TEXTURETAG_PROJECTION, TEXTURETAG_PROJECTION_UVW, DESCFLAGS_SET_0);
        			}
        		}
        	}
          
        	rendata->mat_dnd_num = 0; // flush the queue
        }
          
        Bool MyTimer::CoreMessage(Int32 id, const BaseContainer &bc)
        {
          
        	BaseDocument * doc = GetActiveDocument();
        	if (id == EVMSG_CHANGE)
        	{
        		ChangeDefaultProjection(doc);
        	}
        }
        

        It works for cases that I have tested. Pls, can anybody consult on any potential non-working scenarious in this method? However, I don't like such huge code constructions for so small needs.

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

          On 31/07/2017 at 05:36, xxxxxxxx wrote:

          Hi,

          in another support case (not in this forum) Sebastian came up with this solution:

          When you handle the MSG_MATERIALDRAGANDDROP message you have to handle the full creation of the (optional) TextureTag yourself. That's the point of that message.

          But if you just want that the UVW projection is set by default you could simply return the VOLUMEINFO_EVALUATEPROJECTION flag in GetRenderInfo(). In this case the tag's projection will be set to UVW.

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

            On 31/07/2017 at 07:20, xxxxxxxx wrote:

            Super! How could we guess about that 🙂 I will give it a try

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

              On 31/07/2017 at 09:44, xxxxxxxx wrote:

              Sometimes it's not about guessing, but just about asking 😉
              Nah, you are right of course, our docs could well be more informative in this area.

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

                On 01/08/2017 at 12:36, xxxxxxxx wrote:

                Don't worry! You are informative! Sometimes people hang inside the code editor and make gazillion of tests before the idea of asking on forum comes to mind :))
                Making tests in Cinema 4D environment are very cool because it launches in 1 second. No need for own standalone testing app.
                I tested the trick. It works as you describe. Thanks!

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