mat->GetPreview() in dialog [SOLVED]



  • On 10/12/2014 at 08:56, xxxxxxxx wrote:

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

    ---------
    I have a material with a Filter in the Luminance channel.
    With a dialog I can change the settings of the Filter in the material.
    Settings like Hue and Lightness.

    So in a command plugin with a dialog in Command:

    Bool MainDialog::Command(Int32 id, const BaseContainer& msg)
      
    //Get dialoginput
    GetFloat(ID_FILTER_HUE, C4DomeLS.filterHue);
    ....
      
    // set Filter values in mat (given material)
    // including
    // mat->Message(MSG_UPDATE);
    // mat->Update(true, true);
    // EventAdd(EVENT_FORCEREDRAW);
      
     SetLayerShaderInfo(mat, &C4DomeLS);
      
    // get mat preview and display it in the dialog
    BaseBitmap* bmp = mat->GetPreview(0);
    foldFilter->SetImage(bmp, true, false);	
      
    // for test reasons, show bmp also in preview
    ShowBitmap(bmp);
    

    What I see is that the material is updated ok and shown correct in the material manager, but not in the dialog. Also the ShowBitmap is not correct. I have to give the same dialog command again to show the correct result. The second timeis ok.

    It looks as doing the mat update and getting the preview in one command function is not possible (not synchronized / updated).

    Am I missing something here?

    -Pim



  • On 10/12/2014 at 10:03, xxxxxxxx wrote:

    Hello,

    the material preview is rendered in another, asynchronous thread. This thread will send the EVMSG_MATERIALPREVIEW core message that you could catch in your dialog. This message's argument is a pointer to the updated material.

      
              case EVMSG_MATERIALPREVIEW:  
                  {  
                      if(CheckCoreMessage(msg))  
                      {  
                          C4DAtom* element = (C4DAtom* )msg.GetVoid(BFM_CORE_PAR1);  
                            
                          if(element && element->GetClassification() == Mbase)  
                          {  
                              BaseMaterial* mat = (BaseMaterial* )element;  
                              GePrint(mat->GetName());  
                          }  
                      }  
                      break;  
                  }  
    

    Best wishes,
    Sebastian



  • On 10/12/2014 at 11:42, xxxxxxxx wrote:

    It works!
    Thanks for all the support.
    Supportis getting better and better, thanks!



  • On 10/12/2014 at 12:21, xxxxxxxx wrote:

    Is there a way to make the GeDialog update to show the current material preview without touching it?

    Suppose you have a bitmap button in your dialog that is showing the active material's preview image.
    While the dialog is open. If you change the material, the material's preview image changes. And a CoreMessage is sent out that the preview image was changed.
    However, I must touch the dialog in order for the bitmap button's image to update and reflect the changed preview image. Ouch!😠

    I've been trying to find a way to force the dialog to update. But No luck so far.

    Example code:

    Bool MyDialog::CreateLayout(void)  
    {  
      SetTitle("MY DIALOG");  
      
      //Creates a custom button with AddCustomGui()  
      GroupBegin(GRP_BMP_BTN,BFH_LEFT,2,0,"Material Preview",0);  
      {  
          BaseContainer bbc;              
          myButton = (BitmapButtonCustomGui* )AddCustomGui(GIZ_BMP_BTN, CUSTOMGUI_BITMAPBUTTON,"MY BUTTON", 0L,80,80,bbc);      
            
          if(!GetActiveDocument()->GetActiveMaterial()) myButton->SetImage(Osphere, FALSE);  
          else myButton->SetImage(GetActiveDocument()->GetActiveMaterial()->GetPreview(0), FALSE);  
      }  
      GroupEnd();  
      
            
      return TRUE;  
    }  
      
      
    Bool MyDialog::CoreMessage(LONG id,const BaseContainer &msg)  
    {  
      switch (id)  
      {  
          //If the CoreMessage sent out is from the material preview  
          case EVMSG_MATERIALPREVIEW:  
      
                  if(CheckCoreMessage(msg))  
                  {  
                      //Get the object that's sending out the CoreMessage  
                      C4DAtom *object = (C4DAtom* )msg.GetVoid(BFM_CORE_PAR1);  
      
                      //GePrint(LongToString(object->GetType()));            //5703 = Mmaterial  
                      //GePrint(LongToString(object->GetClassification()));  //5702 = Mbase  
      
                      //If the object sending out the core message is a material  
                      if(object && object->GetClassification() == Mbase)  
                      {  
                          //Cast the object into a BaseMaterial type of object  
                          BaseMaterial *mat = (BaseMaterial* )object;  
                          GePrint(mat->GetName());  
      
                          //Trying to reset the image in the dialog to match the materia preview...Not working!!!  
                          LayoutFlushGroup(GRP_BMP_BTN);  
                          LayoutChanged(GRP_BMP_BTN);  
                          this->InitValues();  
                          this->CreateLayout();  
                      }  
      
                  }break;  
      }  
      
      return GeDialog::CoreMessage(id,msg);  
    }  
    

    -ScottA



  • On 11/12/2014 at 01:31, xxxxxxxx wrote:

    Hello,

    simply call the Redraw() function of the custom gui element. For questions no longer related to the thread's original topic please open a new thread. Thanks.

    Best wishes,
    Sebastian



  • On 11/12/2014 at 10:11, xxxxxxxx wrote:

    Thanks.

    It turns out that the updating problem I'm having is coming from the fact that GetPreview() is not finished generating the preview image yet when I try to update the button's image in my dialog.
    Pre-existing images like Ocube and Osphere work just fine.
    But creating a new material, and then asking for it's preview image immediately, without giving C4D some time to finish creating it, is causing C4D to crash.

    I'm currently trying to find a solution for this.
    I'll post a new thread If I can't solve it.

    -ScottA


Log in to reply