Alternative to InitGLImage



  • On 25/01/2016 at 07:16, xxxxxxxx wrote:

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

    ---------
    Hello.

    I have a MaterialData plugin and inside the InitGLImage method i fill the BaseBitmap parameter to show the material to the viewport.  I use my own method that picks the colors and textures and produces the bitmap. There is a problem though.

    Sometimes, when the bitmap takes more than 30-40 ms to be produced from the MaterialData parameters, the InitGLImage for that material is executed repeatedly. There is not any EventAdd(EVENT_FORCEREDRAW) in the part of code that produces the bitmap, so something else causes this.
    In a scene with 20-30 materials with textures, colors, etc. InitGLImage is executed continuously for as long as Cinema 4D is open.

    How can i prevent this behavior? Is there any alternative to InitGLImage ?

    Thank you for your time.



  • On 26/01/2016 at 03:33, xxxxxxxx wrote:

    Hi,

    I already feel a bit bad about asking you always the same...
    Can you please provide us with some code, showing what you are doing in InitGLImage?



  • On 27/01/2016 at 02:39, xxxxxxxx wrote:

    Hello.

    First of all thank you for your patience.

    Here is the InitGLImage code of the material data plugin.

      
    void wait(LReal wait_time){
    	LReal start = GeGetMilliSeconds();
    	LReal end = start;
    	while (end - start < wait_time) {
    		end = GeGetMilliSeconds();
    	}
    }
      
      
    Bool SomeMaterial::InitGLImage(
    	BaseMaterial* mat, BaseDocument* doc, BaseThread* pThread, BaseBitmap* bmp, LONG doccolorspace, Bool linearworkflow
    ){
      
    	GePrint("InitGLImage");
    	LONG width = bmp->GetBw();
    	LONG height = bmp->GetBh();
    	bmp->Init(width, height); //(1)
    	BaseContainer doc_data = GetActiveDocument()->GetData(DOCUMENTSETTINGS_GENERAL);
    	BaseDocument* dummy_document = BaseDocument::Alloc();
    	dummy_document->SetData(DOCUMENTSETTINGS_GENERAL, doc_data);//(2)
    	wait(20); //(3)
      
    	//fill bitmap
    	char* data = new char[3*width*height];
    	for (int i=0; i<width*height; ++i) {
    		data[i] = 255; 
    	}
    	for (unsigned i=0; i<height; i++)
    		bmp->SetPixelCnt(0,i,width,(UCHAR * )(data+i*width),3,COLORMODE_RGB,PIXELCNT_0);
    	delete data;
    	return TRUE;
    }
    

    The strange part is that if you remove any of the (1) , (2) or (3), InitGLImage stops repeating itself.
    Another thing is that, if i open the file with "File > Merge..." instead of "File > Open...", the issue also stops appearing.

    What causes that problem ?

    I hope that helps.

    Thank you for your time.



  • On 28/01/2016 at 00:21, xxxxxxxx wrote:

    Hi,

    I'm sorry, I had no time to test your code, yet.
    But I noticed a few things in your code:
    Although explicitly documented, you do not set the returned bitmap dirty.
    And then I don't think, it is a good idea to block in this function. You get passed a BaseThread pointer, so you can do a TestBreak() within longer lasting operations. And you definitely should do so.

    Just some thoughts, perhaps you can try this on your end first.



  • On 28/01/2016 at 01:19, xxxxxxxx wrote:

    Hello.

    I have tested the setDirty but the issue still appears.
    Also, the only reason i have used wait(20); is to indicate that there is code there that calculate the image based on the material data. This code doesn't affect the issue though because if i comment it out and replace it with wait(20), the issue still occurs.

    There is probably something inside the specific scene i use that makes InitGLImage to be executed continuously. If i start a new C4D project and i merge the problematic scene, the issue is not reproduced.

    Thank you.



  • On 28/01/2016 at 04:54, xxxxxxxx wrote:

    Of course I don't know your project and to what extend this may or may not be influenced by scene data. But still, you seem to have a pretty long running function there (I already understood your waits are only exemplary). It is in any way recommended to do TestBreak() in there then. And maybe it's well worth a test to see, if it changes something for the old scene (the one before merge).


Log in to reply