R21 BaseDraw::DrawPointArray draws squares versus circles in R20



  • Hello,

    I have yet again a strange behaviour with R21 which I cannot seem to explain.
    As always a sample implementation is provided below (without any optimization nor sanity checking)
    Same code copied into a R21 plugin and R20 plugin provide different results, see screenshot.

    I seem to remember having had the same issue on a Mac Mini running R16 (if I remember correctly). Where the Windows implementation resulted in circular dots, while the Mac displayed square dots. Back then, I assumed it was related to the fact the Mac Mini was using an Intel CPU graphic display, while the Windows machine had a NVidia Geforce 920m running.

    However, the R20 and R21 testing is done one the same Windows machine, running next to each other in their respective Visual Studio debug session.

    I am trying to think and guess what might be wrong in the R21 implementation, but I just cannot figure out what is missing. I simply copied the whole code, ran it in R20 ... and there all is OK.

    // ========================
    // Cinema 4D C++ plugin
    //
    // PluginName: Test
    // Dummy "empty" plugin
    // ========================
    
    // Main.cpp
    
    #include "c4d.h"
    
    // Dummy IDs - for demonstration purposes only
    #define MYSCENEHOOK_PLUGIN_ID	1000000
    
    // ====================================
    // SceneHook
    // ====================================
    
    class MySceneHook : public SceneHookData
    {
    	INSTANCEOF(MySceneHook, SceneHookData)
    
    public:
    	MySceneHook();
    	virtual Bool Draw(BaseSceneHook *node, BaseDocument *doc, BaseDraw *bd, BaseDrawHelp *bh, BaseThread *bt, SCENEHOOKDRAW flags);
    
    	static NodeData *Alloc(void) { return NewObjClear(MySceneHook); }
    };
    
    MySceneHook::MySceneHook() : SceneHookData()
    {
    }
    
    Bool MySceneHook::Draw(BaseSceneHook *node, BaseDocument *doc, BaseDraw *bd, BaseDrawHelp *bh, BaseThread *bt, SCENEHOOKDRAW flags)
    {
    	if (!node || !doc || !bd || !bh)
    		return false;
    	if (flags != SCENEHOOKDRAW::DRAW_PASS)
    		return true;
    
    	Int32 lLeft, lTop, lRight, lBottom;
    	bd->GetFrame(&lLeft, &lTop, &lRight, &lBottom);
    
    	bd->SetMatrix_Screen();
    
    	const Int32 pointCount = 5;
    	for (Int32 i = 0; i < pointCount; ++i)
    	{
    		Float pointSize = 10.0 * i;
    		bd->SetPointSize(pointSize);
    
    		iferr(Vector32* vPoints = NewMem(Vector32, pointCount))
    			return false;
    		vPoints[0] = Vector32(i * 50.0 + (lLeft + lRight) * 0.5, (lTop + lBottom) * 0.5, 0.0);
    
    		const Vector selprevColor = GetViewColor(VIEWCOLOR_SELECTION_PREVIEW);
    		bd->SetPen(selprevColor);
    
    		bd->DrawPointArray(pointCount, vPoints);
    
    		DeleteMem(vPoints);
    	}
    
    	// restore basedraw matrix
    	bd->SetMatrix_Matrix(nullptr, Matrix());
    
    	return true;
    }
    
    // ====================================
    // Plugin Main 
    // ====================================
    Bool PluginStart(void)
    {
    	ApplicationOutput("Test"_s);
    	
    	RegisterSceneHookPlugin(MYSCENEHOOK_PLUGIN_ID, "MySceneHook"_s, 0, MySceneHook::Alloc, EXECUTIONPRIORITY_GENERATOR, 0);
    
    	return true;
    }
    void PluginEnd(void)
    {
    }
    Bool PluginMessage(Int32 id, void * data)
    {
    	switch (id) {
    	case C4DPL_INIT_SYS:
    		if (!g_resource.Init())
    			return false;
    		return true;
    	case C4DMSG_PRIORITY:
    		return true;
    	case C4DPL_BUILDMENU:
    		break;
    	case C4DPL_ENDACTIVITY:
    		return true;
    	}
    	return false;
    }
    

    BaseDraw_DrawPointArray.png



  • Apologies for the somewhat incorrect code I provided.
    I know notice I had started wanting to draw 5 points, and made an appropriate loop. Then I noticed the point size had to be changed on a per point level, which wasn't possible with a single call to DrawPointArray.

    While the result is still the same, here's the intended code (for the drawing method only, all rest remains as original)

    Bool MySceneHook::Draw(BaseSceneHook *node, BaseDocument *doc, BaseDraw *bd, BaseDrawHelp *bh, BaseThread *bt, SCENEHOOKDRAW flags)
    {
    	if (!node || !doc || !bd || !bh)
    		return false;
    	if (flags != SCENEHOOKDRAW::DRAW_PASS)
    		return true;
    
    	Int32 lLeft, lTop, lRight, lBottom;
    	bd->GetFrame(&lLeft, &lTop, &lRight, &lBottom);
    
    	bd->SetMatrix_Screen();
    
    	const Int32 loopCount = 5;
    	const Int32 pointCount = 1;
    	for (Int32 i = 0; i < loopCount; ++i)
    	{
    		Float pointSize = 10.0 * i;
    		bd->SetPointSize(pointSize);
    
    		iferr(Vector32* vPoints = NewMem(Vector32, pointCount))
    			return false;
    		vPoints[0] = Vector32(i * 50.0 + (lLeft + lRight) * 0.5, (lTop + lBottom) * 0.5, 0.0);
    
    		const Vector selprevColor = GetViewColor(VIEWCOLOR_SELECTION_PREVIEW);
    		bd->SetPen(selprevColor);
    
    		bd->DrawPointArray(pointCount, vPoints);
    
    		DeleteMem(vPoints);
    	}
    
    	// restore basedraw matrix
    	bd->SetMatrix_Matrix(nullptr, Matrix());
    
    	return true;
    }
    


  • hello,

    To keep you inform, I'm asking the devs and this is taking more time than expected. Sorry for the delay.

    Cheers,
    Manuel



  • Hello

    Sorry for the delay, Christmas time didn't helped.
    I've opened a bug entry for that issue.
    I'll be back when i'll have more information.

    I've added the "Bug report" tag to this thread

    Cheers,
    Manuel