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

    weird behavior in MaterialData Init() [SOLVED]

    SDK Help
    0
    19
    1.3k
    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 01/07/2015 at 06:02, xxxxxxxx wrote:

      Hi Mohamed,

      you already found out, that the constructor is a bad idea.
      But why not use Init()? If you have a problem with multiple initializations, you could simply have a flag in your class, which gets set after the initialization is done. Next time you enter Init() you simply check the flag and exit.

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

        On 01/07/2015 at 07:58, xxxxxxxx wrote:

        this is horrible!!!, the class is constructed multiple times, how will the flag work?
        I wanted to create a singleton flag for any purpose inside the class, but as the class is created everytime it calls matpreview, it doesn't work "all class members are thrown away and I can't rely on Init()"

        for example:
        Init() { m_update_preview = TRUE;}
        and in the mat preview render:
        if(m_update_preview) { m_update_preview = FALSE; render();}

        this is totally won't work, no class members are working as it is initialized multiple times, what should I do?

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

          On 01/07/2015 at 08:00, xxxxxxxx wrote:

          So you have global data, that is used by all instances your material class?
          In such cases I tend to use a globally static variable as a flag.

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

            On 01/07/2015 at 08:37, xxxxxxxx wrote:

            not global.

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

              On 02/07/2015 at 05:30, xxxxxxxx wrote:

              ???
              You don't want a global flag? Then, why not?
              You have no global data? Fine.
              But your problem are those repeated Init() calls, right?

              Regarding my suggestion of a flag as member variable. This could still work, if you correctly implement it in Read()/Write() and CopyTo().

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

                On 02/07/2015 at 09:23, xxxxxxxx wrote:

                I see, so descriptions can solve this? "trying to avoid overriding Read()/Write()"

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

                  On 02/07/2015 at 17:45, xxxxxxxx wrote:

                  to some extent, the problem is half solved, here is what I did:
                  used CopyTo() , which solved how the buttons work "in the video, I have 2 buttons, one that sets the flag to TRUE and one sets it to FALSE"

                  now the problem is: I want to set the flag to FALSE after the render, some code:

                    
                  		case MATPREVIEW_GENERATE_IMAGE:
                  			{
                  				MatPreviewGenerateImage* image = (MatPreviewGenerateImage* )data;
                  				if (image->pDoc)
                  				{
                  					Int32					w = image->pDest->GetBw();
                  					Int32					h = image->pDest->GetBh();
                    
                  					RenderData* rdata = image->pDoc->GetActiveRenderData();
                  					BaseContainer bcRender = rdata->GetData();
                    
                  					bcRender.SetFloat(RDATA_XRES, w);
                  					bcRender.SetFloat(RDATA_YRES, h);
                  					bcRender.SetInt32(RDATA_ANTIALIASING, ANTI_GEOMETRY);
                  					
                  					image->pDest->Clear(0, 0, 0);
                  					GePrint("m_update_preview = " + String::IntToString(m_update_preview));
                  					if(image->bLowQuality)
                  					{
                  						bcRender.SetBool(RDATA_RENDERENGINE, RDATA_RENDERENGINE_PREVIEWSOFTWARE);
                  						image->lResult = RenderDocument(image->pDoc, bcRender, nullptr, nullptr, image->pDest,
                  															 RENDERFLAGS_EXTERNAL | RENDERFLAGS_PREVIEWRENDER, image->pThread);
                  					}
                  					else if(m_update_preview == TRUE)
                  					{
                  						((SevenPhotonsMaterial* )node)->m_update_preview = FALSE;
                  						BaseVideoPost* myRenderer = BaseVideoPost::Alloc(ID_SEVENPHOTONS);
                  						rdata->InsertVideoPost(myRenderer);
                  						bcRender.SetInt32(RDATA_RENDERENGINE, ID_SEVENPHOTONS);
                    
                  						image->lResult = RenderDocument(image->pDoc, bcRender, nullptr, nullptr, image->pDest,
                  															 RENDERFLAGS_EXTERNAL, image->pThread);
                  					}
                  				}
                  				break;
                  			}  
                  		case MSG_DESCRIPTION_COMMAND:
                  			{
                  				DescriptionCommand* dc = (DescriptionCommand* )data;
                  				if (dc->id[0].id == SEVENPHOTONS_MAT_PREVIEW_UPDATE)
                  				{
                  					m_update_preview = TRUE;
                  					break;
                  				}
                  				else if (dc->id[0].id == SEVENPHOTONS_MAT_PREVIEW_UPDATE_STOP)
                  				{
                  					m_update_preview = FALSE;
                  					break;
                  				}
                  			}
                  

                  so with the 2 commands, it works fine, but it doesn't change to FALSE in the MATPREVIEW_GENERATE_IMAGE message, any ideas?

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

                    On 03/07/2015 at 05:45, xxxxxxxx wrote:

                    Hm? My questions may be stupid...
                    Are those cases in the same switch? Then why do you access m_update_preview directly in MSG_DESCRIPTION_COMMAND and via a node in MATPREVIEW_GENERATE_IMAGE?
                    Otherwise without knowing your class layout it's difficult to tell. Maybe you are resetting the flag in a copy?

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

                      On 03/07/2015 at 07:47, xxxxxxxx wrote:

                      not via a node
                      this: ((SevenPhotonsMaterial* )node)->m_update_preview = FALSE;
                      is the same as this: m_update_preview = FALSE;
                      it is a class member.
                      what I wanted to achieve is: when I hit update button,it renders "only once" //this one didn't work,
                      as it is perma updating, that's why I tried setting the flag to false once it enters "old singleton style"
                      when I hit cancel button,it breaks any rendering. //I achieved this

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

                        On 06/07/2015 at 09:01, xxxxxxxx wrote:

                        Hi Mohamed,

                        the reason you can't reset the flag is indeed, that you are working on a copy. MATPREVIEW_GENERATE_IMAGE is send to a clone of your material for rendering purposes.

                        That being said, I have to say, I have no solution, yet. I'm currently looking into MATPREVIEW_GET_DIRTY_COUNT and MATPREVIEW_COPY_USERDATA, if these might offer a solution. I will also discuss your case with the rest of the team tomorrow.

                        I'm sorry, this thread is taking so long and I still can't offer a solution. But I'm still optimistic, we'll find a solution.

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

                          On 23/07/2015 at 08:21, xxxxxxxx wrote:

                          Hi Mohamed,

                          finally I found the time to play around with this. Sorry, it took so long.
                          As said before, the problem is, that MATPREVIEW_GENERATE_IMAGE is send to a clone of your material. So you can't reset the flag, because you only reset it in the clone, not the original material.

                          My admittedly quite hacky approach is to have a BaseLink member (_linkOrig) in the material. Plus another boolean member (_flagRequestPreview) storing the "render request" flag.

                          In Init() I initialize as follows:

                          _linkOrig->SetLink(nullptr);
                          _flagRequestPreview = true; // assuming that a first initial preview is always wanted
                          

                          When the material is copied (CopyTo()), I set the link. Either to the source material (if not previously set) or to the stored link. Like so:

                          MaterialPreviewExample* sdata = static_cast<MaterialPreviewExample*>(snode->GetNodeData());
                          BaseList2D* bl2d = sdata->_linkOrig->GetLink(snode->GetDocument());
                          if (bl2d)
                            static_cast<MaterialPreviewExample*>(dest)->_linkOriginalMaterial->SetLink(bl2d);
                          else
                            static_cast<MaterialPreviewExample*>(dest)->_linkOriginalMaterial->SetLink(snode);
                          

                          In MSG_DESCRIPTION_COMMAND I do basically the same as you, simply setting _flagRequestPreview. Of course one could use a checkbox instead of two buttons, but that may be a matter of taste.

                          Then on MATPREVIEW_GENERATE_IMAGE I simply evaluate the link and use/reset the flag of the original material. Like so:

                          BaseList2D* bl2d = _linkOrig->GetLink(node->GetDocument());
                          if (!bl2d)
                            bl2d = _linkOrig->ForceGetLink();  // this will be the most probable path, as preview is rendered in another document
                            
                          Bool flagRender;
                            
                          if (bl2d)
                          {
                            MaterialPreviewExample* dOrig = static_cast<MaterialPreviewExample*>(bl2d->GetNodeData());
                            flagRender = dOrig->_flagRequestPreview;
                            dOrig->_flagRequestPreview = false;
                          }
                          else
                          {
                            flagRender = _flagRequestPreview;
                            _flagRequestPreview = false;
                          }
                          // Here: flagRender is true, only once after the button got pushed
                          

                          As I said, it's a bit hacky. But as it is only used for rendering of previews, I think, it should work ok.
                          Let me know, what you think.

                          Another option would be the use of message MATPREVIEW_PREPARE_SCENE. As far as I can see, this message is still send to the original material. But if you get this message, heavily depends on your preview implementation.

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

                            On 23/07/2015 at 09:01, xxxxxxxx wrote:

                            Hi Andreas,

                            thanks a lot for the help
                            I will check them tonight and see , most probably the link approach looks good "I will need that link for other stuff later 😄

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

                              On 23/07/2015 at 22:18, xxxxxxxx wrote:

                              it works very well, thanks Andreas
                              you can consider this solved.

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