Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Register
    • Login
    1. Home
    2. Filip
    F
    • Profile
    • Following 0
    • Followers 0
    • Topics 13
    • Posts 49
    • Best 5
    • Controversial 0
    • Groups 0

    Filip

    @Filip

    6
    Reputation
    117
    Profile views
    49
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Filip Unfollow Follow

    Best posts made by Filip

    • RE: Viewport render and camera FOV

      Hi again,
      Thanks for your input! I have found the solution now:

      The issue was not the camera field of view, but how I calculated the bounds of the viewplane (image plane). C4d fits the aspect ratio of the final render resolution into the size of the viewport in a specific way, that I reverse engineered. Here is the code for my solution, in case anyone else has the same problem:

      double f=double(resolution[1])/double(resolution[0]);
      double f2 =double(renderdata_resolution[1])/double(renderdata_resolution[0]);
      double c = f2 / f;
      
      double screen_window[4];
      screen_window[0] = -1*c;
      screen_window[1]=-f*c;
      screen_window[2] = 1*c;
      screen_window[3]=f*c;
      

      In the above code, "resolution" is the resolution, in pixels, of the viewport and "renderdata_resolution" is the resolution we would have if rendering to the picture viewer.

      /Filip

      posted in Cinema 4D SDK
      F
      Filip
    • SDK for node based materials, status?

      Hi!
      Are there any news on the SDK for node based materials? I'm interested in the following:

      • accessing all the nodes in a given material, as well as their connections.
        -creating my own custom nodes.

      Are these things possible with the current SDK?

      Cheers
      /Filip

      posted in Cinema 4D SDK r21 sdk
      F
      Filip
    • RE: Custom register plugin

      @WickedP said in Custom register plugin:

      I have a dialog plugin with a graphical interface. I'd like to be able to register plugins for my plugin, so that I can build them separately if needed, or perhaps so others in the future may be able to.

      Hi WickedP!
      We are doing something similar in the 3delightForCinema4D renderer plugin. (source available here: https://gitlab.com/3Delight/3delight-for-cinema-4d/. We have a custom plugin system, separate from the normal c4d one, that allows 3rd party modules to add functionality to our plugin.

      This is handled via the "PluginMessage" function. When c4d has loaded, our plugin sends a special message to all other plugins, and passes along a pointer to a "pluginmanager" structure. Other plugins can then respond to this message, and register their plugins via the pluginmanager. You can see how this works in our source code. Some hints on where to look:

      The "API" for our plugin system consists of a few header files, describing the supported plugin types (called "hooks" and "translators"):

      https://gitlab.com/3Delight/3delight-for-cinema-4d/-/tree/master/3Delight/API/include

      Here is the main file of the module that manages plugin loading: https://gitlab.com/3Delight/3delight-for-cinema-4d/-/blob/master/3Delight/source/main.cpp

      The "PluginMessage" function in this file is where the message to load custom plugins is sent (in response to "C4DPL_STARTACTIVITY".

      Here is the main file of an example separate module that registers a number of plugins:
      https://gitlab.com/3Delight/3delight-for-cinema-4d/-/blob/master/3Delight Geometry/source/main.cpp

      I hope this description is somewhat clear. We have found it to be a really straightforward but powerful way of designing a custom plugin system for c4d! Let me know if you have any questions.

      Best regards
      /Filip

      posted in Cinema 4D SDK
      F
      Filip
    • RE: Copying/Pasting GvNodes?

      "PS: There are also the copy buffer methods on GvNodeMaster if you want to preserve connections, copy multiple nodes at once etc.:"
      -That looks like it might be exactly what I need! Thanks a lot!

      posted in Cinema 4D SDK
      F
      Filip
    • RE: GvNodeMaster::Execute() returns error

      @ferdinand said in GvNodeMaster::Execute() returns error:

      Since you do your own stuff, this could for example fail in the DL_TERMINAL node you implemented in addition to some of the init stuff going wrong.

      I have confirmed that the error seems to come from my own GvOperatorData()-plugins (shader nodes). When I delete all my own nodes in the graph and only use the build in c4d xpresso nodes, then GvNodeMaster updates correctly. I will look into this, but now I know where to look! We can mark this as solved for now.

      "I can of course also just have a look at it, but I will not be able to run your project to see and tell you why it fails exactly"
      At this stage, I was just looking for general feedback on how and when the Execute() function was supposed to work correctly, i.e., if it needed to be called in a special context or similar. This is also why I did not post detailed code initially. I don´t fully agree that detailed code is always needed to discuss an issue, even if it of course sometimes helps in clarifying things! Anyway, thanks a lot for the good support, it is really helpful and I appreciate the availability of this forum - it really helps!

      Best regards
      /Filip

      posted in Cinema 4D SDK
      F
      Filip

    Latest posts made by Filip

    • RE: GvNodeMaster::Execute() returns error

      @ferdinand said in GvNodeMaster::Execute() returns error:

      Since you do your own stuff, this could for example fail in the DL_TERMINAL node you implemented in addition to some of the init stuff going wrong.

      I have confirmed that the error seems to come from my own GvOperatorData()-plugins (shader nodes). When I delete all my own nodes in the graph and only use the build in c4d xpresso nodes, then GvNodeMaster updates correctly. I will look into this, but now I know where to look! We can mark this as solved for now.

      "I can of course also just have a look at it, but I will not be able to run your project to see and tell you why it fails exactly"
      At this stage, I was just looking for general feedback on how and when the Execute() function was supposed to work correctly, i.e., if it needed to be called in a special context or similar. This is also why I did not post detailed code initially. I don´t fully agree that detailed code is always needed to discuss an issue, even if it of course sometimes helps in clarifying things! Anyway, thanks a lot for the good support, it is really helpful and I appreciate the availability of this forum - it really helps!

      Best regards
      /Filip

      posted in Cinema 4D SDK
      F
      Filip
    • RE: GvNodeMaster::Execute() returns error

      Here is the code for my MaterialData plugin:

      #include "DL_NodeMaterial.h"
      #include "customgui_matpreview.h"
      
      GvNodeMaster* DL_NodeMaterial::GetNodeMaster() {
      	return node_master;
      }
      
      Bool DL_NodeMaterial::Init(GeListNode* node) {
      	node_master = GvGetWorld()->AllocNodeMaster((BaseList2D*)(this->Get()));
      
      	//Create a terminal node for this material
      	node_master->CreateNode(node_master->GetRoot(), DL_TERMINAL, nullptr, 200,200); 
      
      	DL_SetDefaultMatpreview((BaseMaterial*)node);
      
      	return node_master != nullptr;
      
      }
      
      void DL_NodeMaterial::Free(GeListNode* node) {
      	GvGetWorld()->FreeNodeMaster(node_master);
      }
      
      Bool DL_NodeMaterial::Read(GeListNode *node, HyperFile *hf, Int32 level) {
      	return node_master->ReadObject(hf,true);
      }
      
      Bool DL_NodeMaterial::Write(GeListNode *node, HyperFile *hf) {
      	return node_master->WriteObject(hf);
      }
      
      Bool DL_NodeMaterial::CopyTo(NodeData *dest, GeListNode *snode, GeListNode *dnode, COPYFLAGS flags, AliasTrans *trn) {
      	DL_NodeMaterial* dst = (DL_NodeMaterial*)dest;
      	return node_master->CopyTo(dst->GetNodeMaster(), flags, trn);
      }
      
      
      
      
      Bool DL_NodeMaterial::Message(GeListNode *node, Int32 type, void *data){
      
      	if (GeIsMainThread()) {
      		ApplicationOutput("Main thread"_s);
      	}
      	else {
      		ApplicationOutput("Not main thread"_s);
      	}
      	GvCalcError err = node_master->Execute(GeGetCurrentThread())
      	ApplicationOutput("Errorcode: "_s);
      	ApplicationOutput(String::IntToString(err));
      
      	if (err == GV_CALC_ERR_INIT_FAILED) {
      		ApplicationOutput("Init failed"_s);
      	}
      	if (err == GV_CALC_ERR_NOT_INITIALIZED) {
      		ApplicationOutput("Not initialized"_s);
      	}
      
      	
      
      	return MaterialData::Message(node, type, data);
      }
      
      //Initializes resources for rendering.
      INITRENDERRESULT DL_NodeMaterial::InitRender(BaseMaterial* mat, const InitRenderStruct& irs)
      {
      	return INITRENDERRESULT::OK;
      }
      
      
      void DL_NodeMaterial::CalcSurface(BaseMaterial* mat, VolumeData* vd)
      {
      
      	Vector diff, spec;
      	vd->IlluminanceSimple(&diff, &spec, 0, 0, 0);
      
      	vd->col = 0.8*diff;
      }
      
      Bool RegisterDLNodeMaterial(void)
      {
      	return RegisterMaterialPlugin(ID_DL_NODEMATERIAL, "DL_NodeMaterial"_s, 0, DL_NodeMaterial::Alloc, "DL_NodeMaterial"_s, 0);
      }
      
      

      As you can see, it does not do much besides store and maintain a GvNodeMaster, which is then displayed and edited in a separate GeDialog.

      In the Message() method, I try to update the XPRESSO calculations of the stored GvNodeMaster, but without success. I tried your suggestions of passing a null-pointer for the thread, but this made no difference.

      I am assuming this about 3Delight and that you are trying to implement your own GraphView based material system? If that is the case there can be countless reasons why this is failing for you and we cannot really help you without your code.

      Yes, correct! I have functioning implementation of a basic node material system. When rendering, I parse the GvNodeMaster attached to a material and generate a corresponding OSL-shader graph for the renderer. This works as intended (and I am quite exited about it! 🙂 ). That part does not require the actual XPRESSO nodes to be evaluated (Execute() :ed), since I am doing the parsing myself.

      The reason I am asking about Execute() and performing the XPRESSO calculations is that it would be really nice to be able to drive shader parameters via the existing Cinema 4d xpresso nodes! I understood from the Redshift docs that this is supported for that renderer, so it appears possible. If not, it is not a dealbreaker for me, but it would be a really nice feature to support.

      So, any ideas on why the execution of the XPRESSO graph does not work would be really appreciated! In the final implementation, I am not sure that the graph execution would happen in the Message() function of the MaterialData, this is just my first step of trying to get it to work somewhere in the code.

      Cheers
      /Filip

      posted in Cinema 4D SDK
      F
      Filip
    • GvNodeMaster::Execute() returns error

      Hi!
      In my plugin, I have a MaterialData that owns a GvNodeMaster, and I would like to update the xpresso calculations in that GvNodeMaster. To this end, in the Message() function of the material data, I try to call Execute() on the GvNodeMaster, as follows:

      GvCalcError err = node_master->Execute(GeGetCurrentThread());
      

      This, however, always returns the error code GV_CALC_ERR_INIT_FAILED or GV_CALC_ERR_NOT_INITIALIZED. Are there some other steps I need to take before I can call Execute() on the node master?

      I guess the broader question here is: How do I correctly force an update on the calculations of a GvNodeMaster?

      Best regards
      /Filip Malmberg

      posted in Cinema 4D SDK c++ 2023
      F
      Filip
    • RE: Copying/Pasting GvNodes?

      "PS: There are also the copy buffer methods on GvNodeMaster if you want to preserve connections, copy multiple nodes at once etc.:"
      -That looks like it might be exactly what I need! Thanks a lot!

      posted in Cinema 4D SDK
      F
      Filip
    • Copying/Pasting GvNodes?

      Hi!
      I am writing a plugin that utilizes a custom node editor based on Xpresso (GvNodeMaster, GvNodeGUI, etc.), displayed in a GeDialog.

      Now I would like to implement Copy/Paste functionality, i.e. to be able to copy and paste selected GvNodes both within a single GvNodeMaster and between different GvNodeMasters. My GvNodeMasters are owned and stored within custom BaseMaterials.

      1. Is there some built in functionality I could use for this? The Xpresso editor implements this functionality, is there any way I can call those copy/paste functions?

      2. If not, how do I create a copy of a GvNode and insert it into another GvNodeMaster? Using GetClone() does not seem to work, which makes sense as GvNode according to the docs are not really normal BaseList2D:s*

      Any suggestions?

      Thanks!
      /Filip

      *) From the docs: "The GvNode is a double BaseList2D node. Internally it has an operator that corresponds to GvOperatorData. Use GetOperatorContainer() to access most parameters."

      posted in Cinema 4D SDK c++ 2023
      F
      Filip
    • RE: GvOperatorData, GetDDescription() problems

      "you are trying to write a node material wrapper for a render engine, right?"
      Yes, correct! I am working on node based shading for the 3Delight for Cinema 4d bridge plugin. The reason I want dynamic nodes is to allow using custom OSL shaders, with some metadata to describe the GUI. This allows users to add custom shaders, without having to touch C++. We currently have that implemented for non-node based shaders, and it is a feature I would like to keep.

      Thanks for the clarifications regarding the limitations of the XPRESSO-based alternative! It looks like I may have to reconsider using the new Nodes API. I opted for the XPRESSO option mainly because I am more familiar with the classic SDK, but maybe now is the time to take the plunge :-).

      Thanks for the response and support!
      /Filip

      posted in Cinema 4D SDK
      F
      Filip
    • RE: GvOperatorData, GetDDescription() problems

      So, I found this thread ("Item selection in GvOperatorData::FillPortsMenu") which suggests that I may need to implement the FillPortsMenu() and iGetPortDescription() functions myself to get this work. I have made some progress, and can now get the elements to show up in the port menu (when I click the top corners of the node in the Xpresso editor), but I have not yet implemented the functionality to actually add the ports to the node. Anyway, the approach seems promising.

      Is this the correct way to approach this, or is there a simpler way? I was kind of hoping/expecting that GvOperatorData would behave the same as other plugin types in this regard, and that the ports would be visible in the menu by default - is there such an option?

      Best regards
      /Filip

      posted in Cinema 4D SDK
      F
      Filip
    • RE: Creating and initializing nested ObjectData

      Do you need to able to place the "Parent" and "Child" objects anywhere in your scene hierarchy? Otherwise, could one possibility be to make "Child" a generator object, that implements GetVirtualObjects() to generate the desired null objects based on the "parent" object? The "parent" object would need to be placed under the "child" object in the hierarchy, which may or may not be a problem depending on the problem you are trying to solve.

      Or do you also need the generated nulls to be editable, i.e., not virtual objects created by a generator?

      Best regards
      /Filip

      posted in Cinema 4D SDK
      F
      Filip
    • GvOperatorData, GetDDescription() problems

      I am implementing a custom C++ Xpresso node, where the majority of the parameters/ports are to be generated dynamically via GetDDescription().

      The dynamically added elements correctly show up in the attribute manager, but my problem is that they do not show up as ports that can be added to the node in the Xpresso editor.

      A minimal example of the GetDDescription() that exhibits this problem looks like this:

      Bool NodeTest::GetDDescription(GeListNode * 	node, Description * 	description, DESCFLAGS_DESC & 	flags) {
      	if (!description->LoadDescription(node->GetType()))
      		return false;
      
      	flags |= DESCFLAGS_DESC::LOADED;
      
      	BaseContainer bc = GetCustomDataTypeDefault(DTYPE_LONG);
      	bc.SetInt32(DESC_ANIMATE, DESC_ANIMATE_ON);
      	String param_name = String("Dynamic int");
      	bc.SetString(DESC_NAME, param_name);
      	bc.SetString(DESC_SHORT_NAME, param_name);
      	bc.SetBool(DESC_INPORT, true);
      	bc.SetBool(DESC_EDITPORT, true);
      	description->SetParameter(DescLevel(1000, DTYPE_LONG, 0), bc, DescLevel(ID_GVPORTS));
      
      	return GvOperatorData::GetDDescription(node, description, flags);
      }
      

      Here, the "NodeTest" class is derived from GvOperatorData. When I implement a similar version of GetDDescription() for other plugin types, e.g., a BaseShader, the dynamically added element correctly show up both in the active object manager and as Xpresso ports. Also, if I add non-dynamic elements to the "NodeTest" class via a description resource, everything works correctly. It is just for elements added dynamically to the GvOperatorData-derived plugin that I am experiencing this issue.

      Any suggestions? Are there any special steps I need to take to make the elements appear as Xpresso ports?

      Best regards
      /Filip

      posted in Cinema 4D SDK sdk s26
      F
      Filip
    • RE: Custom XPRESSO graph editor, show nodes in object manager

      Great, thanks a lot for looking into this and for the detailed explanations!

      Now I know better what my options are! I am marking this thread as "solved".

      Best regards
      Filip Malmberg

      posted in Cinema 4D SDK
      F
      Filip