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).