Solved 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

MAXON SDK Specialist

MAXON Registered Developer

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

MAXON SDK Specialist

MAXON Registered Developer