Bugs when shader plugin has 2 shaderlinks



  • On 08/02/2016 at 00:16, xxxxxxxx wrote:

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

    ---------
    Hi C4D community,

    I have written 2 very simple shader plugins:

    1. One of them has 2 shaderlinks.
    2. The other custom plugin has one COLOR field.

    When in user interface I try to place connect the shader of plugin2 to the shaderlink of plugin1 it connects. But when I unroll and try to edit the content of shader of plugin2 then it dissapears and disconnects from shaderlink of plugin1.

    When I edit the COLOR field of plugin2 connected to plugin1 in GUI this case errors are produced
    Critical: Stop [ge_container.h(329)] 
    This error message prints when compiled in Release mode of VS2013. In debug mode no error message, but bad GUI behavior is still there.

    But not crashed. When I connect shader of plugin2 to shaderlink of plugin1 AGAIN (and for both shaderlinks) then everything works fine.

    Btw: Cinema 4D R17.048 Visualize (not Studio).

    As you can see I want to implement a shader tree of custom shaders.



  • On 08/02/2016 at 00:24, xxxxxxxx wrote:

    Plugin1

    // example for a channel shader with access to basechannel
    // using standard GUI elements
      
    #include "c4d.h"
    #include "c4d_symbols.h"
    #include "main.h"
    #include "xtest.h"
      
    class XtestData : public ShaderData
    {
    public:
    	BaseShader* shaderA;
    	BaseShader* shaderB;
      
    public:
    	virtual Bool Init		(GeListNode* node);
    	virtual Bool Message(GeListNode* node, Int32 type, void* data);
    	virtual	Vector Output		(BaseShader* chn, ChannelData* cd);
    	virtual Bool Read(GeListNode* node, HyperFile* hf, Int32 level);
      
    	virtual	INITRENDERRESULT InitRender	(BaseShader* chn, const InitRenderStruct& irs);
    	virtual	void FreeRender	(BaseShader* chn);
      
    	virtual	SHADERINFO GetRenderInfo(BaseShader* sh);
    	virtual BaseShader*	GetSubsurfaceShader(BaseShader* sh, Float& bestmpl);
      
    	static NodeData* Alloc(void) 
    	{
    		return NewObjClear(XtestData);
    //		NodeData * node = NewObjClear(XtestData);
    //		XtestData * xnode = (XtestData * )node;
    //		xnode->shaderA = 0;
    //		xnode->shaderB = 0;
    //		return node;
    	}
    };
      
    SHADERINFO XtestData::GetRenderInfo(BaseShader* sh)
    {
    //	return SHADERINFO_DYNAMICSUBSHADERS;
    //	return SHADERINFO_0;
    	return SHADERINFO_BUMP_SUPPORT;
    }
      
    BaseShader*	XtestData::GetSubsurfaceShader(BaseShader* sh, Float& bestmpl)
    {
    //	if (shaderA != nullptr)
    //		return shaderA->GetSubsurfaceShader(bestmpl);
      
    //	if (shaderB != nullptr)
    //		return shaderB->GetSubsurfaceShader(bestmpl);
      
    	return nullptr;
    }
      
      
    Bool XtestData::Init(GeListNode* node)
    {
    //	if (!node) return false;
      
    	shaderA = 0;
    	shaderB = 0;
      
    	BaseContainer* data = ((BaseShader* )node)->GetDataInstance();
    //	if (!data) return false;
      
    	data->SetLink(XTEST_TEXTURE_A, nullptr);
    	data->SetLink(XTEST_TEXTURE_B, nullptr);
      
    	return true;
    }
      
    Bool XtestData::Read(GeListNode* node, HyperFile* hf, Int32 level)
    {
    	if (hf->GetFileVersion() < 8300)
    	{
    		if (!hf->ReadChannelConvert(node, XTEST_TEXTURE_A))
    			return false;		// convert old basechannel
      
    		if (!hf->ReadChannelConvert(node, XTEST_TEXTURE_B))
    			return false;		// convert old basechannel
    	}
      
    	return true;
    }
      
      
    Vector XtestData::Output(BaseShader* chn, ChannelData* cd)
    {
    //	if (!shaderA || !shaderB)
    		return Vector(1.0);
      
    //	Vector uv = cd->p;
      
      
    //	Vector res = shaderA->Sample(cd) + shaderB->Sample(cd);
    //	cd->p = uv;
      
    //	return res;
    }
      
    INITRENDERRESULT XtestData::InitRender(BaseShader* chn, const InitRenderStruct& irs)
    {
    //	if (!chn) return INITRENDERRESULT_OK;
      
    	BaseContainer* data = chn->GetDataInstance();
    //	if (!data) return INITRENDERRESULT_OK;
      
    	// cache values for fast access
    	shaderA = (BaseShader* )data->GetLink(XTEST_TEXTURE_A, irs.doc, Xbase);
    	shaderB = (BaseShader* )data->GetLink(XTEST_TEXTURE_B, irs.doc, Xbase);
      
    	INITRENDERRESULT resA = INITRENDERRESULT_OK;
    	INITRENDERRESULT resB = INITRENDERRESULT_OK;
      
    	if (shaderA) resA = shaderA->InitRender(irs);
    	if (shaderB) resB = shaderB->InitRender(irs);
      
    	if (resA != INITRENDERRESULT_OK) return resA;
    	if (resB != INITRENDERRESULT_OK) return resB;
      
    	return INITRENDERRESULT_OK;
    }
      
    void XtestData::FreeRender(BaseShader* chn)
    {
    	if (shaderA) shaderA->FreeRender(); 
    	if (shaderB) shaderB->FreeRender();
      
    	shaderA = 0;
    	shaderB = 0;
    }
      
    Bool XtestData::Message(GeListNode* node, Int32 type, void* msgdat)
    {
    //	if (!node) return false;
      
    	BaseContainer* data = ((BaseShader* )node)->GetDataInstance();
    //	if (!data) return false;
      
    	HandleInitialChannel(node, XTEST_TEXTURE_A, type, msgdat);
    	HandleInitialChannel(node, XTEST_TEXTURE_B, type, msgdat);
      
    	BaseShader * _shaderA = (BaseShader* )data->GetLink(XTEST_TEXTURE_A, node->GetDocument(), Xbase);
    	BaseShader * _shaderB = (BaseShader* )data->GetLink(XTEST_TEXTURE_B, node->GetDocument(), Xbase);
      
    	if (!shaderA) HandleShaderMessage(node, _shaderA, type, msgdat);
    	if (!shaderB) HandleShaderMessage(node, _shaderB, type, msgdat);
      
    	return true;
    }
      
    // be sure to use a unique ID obtained from www.plugincafe.com
      
    Bool RegisterXtest(void) 
    {
    	return RegisterShaderPlugin(PLUGIN_ID_TEST, String("test binary shader"), 0, XtestData::Alloc, "Xtest", 0);
    }
      
    
    


  • On 08/02/2016 at 00:25, xxxxxxxx wrote:

    Plugin2

    // example for a channel shader with access to basechannel
    // using standard GUI elements
      
    #include "c4d.h"
    #include "c4d_symbols.h"
    #include "main.h"
    #include "xtest_color.h"
      
    class XtestColorData : public ShaderData
    {
    //	INSTANCEOF(XtestColorData, ShaderData)
      
    public:
    	Vector color;
      
    public:
    	virtual Bool Init		(GeListNode* node);
    	virtual Bool Message(GeListNode* node, Int32 type, void* data);
    	virtual	Vector Output		(BaseShader* chn, ChannelData* cd);
    	virtual Bool Read(GeListNode* node, HyperFile* hf, Int32 level);
      
    	virtual	INITRENDERRESULT InitRender	(BaseShader* chn, const InitRenderStruct& irs);
    	virtual	void FreeRender	(BaseShader* chn);
      
    	virtual	SHADERINFO GetRenderInfo(BaseShader* sh);
    	virtual BaseShader*	GetSubsurfaceShader(BaseShader* sh, Float& bestmpl);
      
    	static NodeData* Alloc(void) 
    	{ 
    		return NewObjClear(XtestColorData);
    //		NodeData * node = NewObjClear(XtestColorData);
    //		XtestColorData * xnode = (XtestColorData * )node;
    //		xnode->color = Vector(0);
    //		return node;
    	}
    };
      
    SHADERINFO XtestColorData::GetRenderInfo(BaseShader* sh)
    {
    	return SHADERINFO_BUMP_SUPPORT;
    }
      
    BaseShader*	XtestColorData::GetSubsurfaceShader(BaseShader* sh, Float& bestmpl)
    {
    //	if (shader != nullptr)
    //		return shader->GetSubsurfaceShader(bestmpl);
      
    	return nullptr;
    }
      
      
    Bool XtestColorData::Init(GeListNode* node)
    {
    	if (!node) return false;
      
    	color = Vector(0.7);
      
    	BaseContainer* data = ((BaseShader* )node)->GetDataInstance();
    	if (!data) return false;
      
    	data->SetVector(XTEST_COLOR_A, Vector(0.7));
      
    //	data->SetFloat(XTEST_COLOR_AR, 0.7);
    //	data->SetFloat(XTEST_COLOR_AG, 0.7);
    //	data->SetFloat(XTEST_COLOR_AB, 0.7);
      
    	return true;
    }
      
    Bool XtestColorData::Read(GeListNode* node, HyperFile* hf, Int32 level)
    {
    	return true;
    }
      
      
    Vector XtestColorData::Output(BaseShader* chn, ChannelData* cd)
    {
    	return Vector(0);
    }
      
    INITRENDERRESULT XtestColorData::InitRender(BaseShader* chn, const InitRenderStruct& irs)
    {
    //	if (!chn) return INITRENDERRESULT_OK;
      
    	BaseContainer* data = chn->GetDataInstance();
      
    //	if (!data) return INITRENDERRESULT_OK;
      
    	color = data->GetVector(XTEST_COLOR_A);
      
    //	color.x = data->GetFloat(XTEST_COLOR_AR);
    //	color.y = data->GetFloat(XTEST_COLOR_AG);
    //	color.z = data->GetFloat(XTEST_COLOR_AB);
      
    	return INITRENDERRESULT_OK;
    }
      
    void XtestColorData::FreeRender(BaseShader* chn)
    {
    }
      
    Bool XtestColorData::Message(GeListNode* node, Int32 type, void* msgdat)
    {
    	BaseContainer* data = ((BaseShader* )node)->GetDataInstance();
      
    	return true;
    }
      
    // be sure to use a unique ID obtained from www.plugincafe.com
      
    Bool RegisterXtest_color(void) 
    {
    	return RegisterShaderPlugin(PLUGIN_TEST_COLOR, String("test color shader"), 0, XtestColorData::Alloc, "Xtest_color", 0);
    }
      
    
    


  • On 08/02/2016 at 02:47, xxxxxxxx wrote:

    Hello,

    the critical stop is triggered while calling an internal function that works on resolving a BaseLink. The issue is that the stored data is neither DA_ALIASLINK nor DA_NIL.

    Maybe the issue is a faulty initiation of the link parameters, I do not think that

      
    data->SetLink(XTEST_TEXTURE_A, nullptr);  
    

    is actually needed.

    Also there are here and there some other issues with your code. For example you should always include a call to the parent class' function in NodeData::Message(). Also your XtestData::Output() does nothing and returns nothing. And you should add nullptr-checks to all place where you access links or memory.

    Best wishes,
    Sebastian



  • On 08/02/2016 at 05:10, xxxxxxxx wrote:

    All checks for null ptrs added, data->SetLink(XTEST_TEXTURE_A, nullptr); is commented.

    Also your XtestData::Output() does nothing and returns nothing

    It returns Vector(1.0) which for debug is white for a while.

    Anyway I have fixed according to your recomendations and the bug is still there and it is the same.

    Simptoms again:
    When in GUI I connect Shader1 (with 2 shaderlinks) to one C4D material and then connect Shader2 (with color) to one of the shaderlinks of Shader1 and then try to edit the color - the Shader2 dissapears and disconnects from Shader1 shaderlink. These errors are printed:

    CRITICAL: Stop [ge_container.h(329)]
    CRITICAL: Stop [gui_xgeframe.cpp(930)]
    

    Yesterdaty I have also tried to test many things there and result is nothing.

    Here is the full source code for these 2 shader plugins
    https://www.dropbox.com/s/eky7sny6w0k8rkk/xtest_2_linking_shaders.rar?dl=0

    They are fixed. Please, can you run them and see what happens.

    Thanks,
    Anton



  • On 08/02/2016 at 09:32, xxxxxxxx wrote:

    Hello,

    using your code I could not reproduce any problems. Is there anything else to know? Does the problem also occur when you use your "Color" shader in another shader like the MoGraph  Multishader? Can you reproduce the issue with a project that only uses the code you provided?

    HandleInitialChannel is deprecated and not needed.

    Best wishes,
    Sebastian



  • On 08/02/2016 at 09:49, xxxxxxxx wrote:

    Sebastian, I have recently updated my Cinema 4D R17 visualise using it's internal process.

    This code was tested using a clean cinema4dsdk project with only these 2 shader plugins. 
    Both in Debug and Release build of VS2013. Only Release build prints errors (Debug is silent, but produces incorrect behavior).

    I also see this message when cinema4dsdk is compliled in Release mode:

    ZeroConf error: Couldn't get bonjour version [sys_bonjour.cpp(1411)] 
    


  • On 08/02/2016 at 13:00, xxxxxxxx wrote:

    In the first post I mentioned about Cinema R17 Studio. Actually not Studio, I have only Visualize if it makes sence.



  • On 09/02/2016 at 09:31, xxxxxxxx wrote:

    Hello,

    I tested you code again both as debug and release version with Visualize and could not find any error messages or faulty behavior. I'm afraid I cannot help much more.

    The last error you reported is related to Team Render. It seems that Bonjour is not installed on your system.

    Best wishes,
    Sebastian


Log in to reply