I created a short series of getting started videos for anyone just starting out developing C++ plugins for Cinema 4D. I hope you find them useful.
https://www.youtube.com/playlist?list=PLEPTxkpDVvX0r292yn8xL39Cm3Wi3E69i
I created a short series of getting started videos for anyone just starting out developing C++ plugins for Cinema 4D. I hope you find them useful.
https://www.youtube.com/playlist?list=PLEPTxkpDVvX0r292yn8xL39Cm3Wi3E69i
Hi everyone,
I have released a plugin I use to create documentation for my plugins.
The plugin is free. Currently available for R20 for Windows. I will add an OSX version if people ask for it.
https://www.plugins4d.com/docs
If you use it for anything let me know. Also if you have any features requests then send them my way.
Cheers,
Kent
I have posted my source code for the integration of Peter Shirleys Ray Tracing In One Weekend series to github.
https://github.com/kentbarber/rtow4d
This might be of interest to anyone wanting to play around with writing their own ray tracer.
You can also download a compiled version from here: https://plugins4d.com/Product/FunRay
Cheers,
Kent
Try using the absolute path to where your sdk is: /Users/YourName/Documents/C4D/sdk
https://developers.maxon.net/docs/Cinema4DCPPSDK/html/page_maxonapi_projecttool.html
g_updateproject: Defines the folder the tool should work on. Currently the tool only accepts absolute paths. This is typically the location of the SDK including frameworks and plugins. See SDK Overview.
You can use SetPluginPriority to tell your plugins to load in a specific order. IE tell some plugins to load after others have been loaded. Useful in cases where one of your plugins may register a library that your other plugins need to access as they start up.
Yesterday I helped someone out with a question. Now they have marked it as deleted. The only reason I would help out on this forum is to help everyone and add to the knowledge pool here in this forum.
So please... do NOT delete your post if you received the answer you were looking for.
I just found that in S22 they have inverted the behaviour of a flag for GetAllAssets.
In R21 there existed a flag ASSETDATA_FLAG::MISSING.
From S22 onwards the functionality of this flag has been inverted and it is now called ASSETDATA_FLAG::NOMISSING.
The problem is that it sets the exact same bit.
So if you have a plugin that is compiled against R21 and your users use it in S22 then your code will not be getting the missing assets anymore, since this bit is set (if you use the MISSING flag) and it will now mean DO NOT get missing assets.
Compiling against the S22 SDK and removing the MISSING flag will fix your bugs if you have any.
Just something to watch out for if anyone is hearing of problems from your users relating to gather up assets. Mainly applies to people writing renderers and dealing with textures and materials.
Cheers,
Kent
I keep seeing comments from the sdk team telling people to please add tags to their posts.
Instead I would recommend you split the "Cinema 4D Development" category back into two like it was, C++ and Python.
Then if someone posts into C++ just add the C++ tag automatically. Likewise for Python.
I myself used to like coming in here and quickly see if there is any C++ questions I can help out on. This new combined approach makes that more difficult so I am no longer doing this. Yes I know I can click on a tag to see all posts, but thats just one more required hunt and click.
I used to really enjoy browsing through plugin cafe, just as much as I did cgtalk or c4dcafe. But this new look and the way it is organized it doesn't feel as nice. Super large fonts and text, images etc... means hardly any information on a single screen. So its hard to quickly see and browse through. But it looks like lots of sites are going this way, which is a shame. I am looking at all these forums less and less now because of this. Maybe I am just old, but I like my concise compact views with loads of info, rather than having to go through pages and pages (or worse this horrible endless scrolling mechanism sites have adopted) of oversized text and clunky cells. On top of that, actually creating this post is painful with this split view and only taking up a tiny part of my screen. But thats another issue.
This site used to feel like a community. But now it feels more like what I guess it was originally designed for... that being an SDK support site. So its almost like this site is a forum based version of a ticketing system like zendesk or freshdesk.
Anyway, this is my vote to move back to two categories. That at least would help.
I am not exactly sure how it works in Python but I will give you a run down of how Global Variables work in C++.
If you set a global variable in C++, and you are using it in a Generator Object, then that variable will be exactly the same in every object in every document that you have open. So if you change the value of it on any object (again in any document you have opened) it will be changed across everything. That is the definition of a global variable. It is global, it is the same everywhere.
Now it may not work exactly like this in python depending on how it is setup in C4D. But in general it is a bad idea to use this for ay variable in something like a generator object.
So even though it might be working for now in a basic test scene, it will come back to bite you once you use it for anything more complex, such as two or more objects.
It all comes down to what it is that you are trying to achieve and what this data is that you are using in a global variable.
In C++ you could use a SceneHook to hold scene wide data. But I don't think that is in Python yet, so the best option to use scene wide data is to use a PluginID as your way to access that data in the preferences for your scene.
For storing a matrix value to compare why don't you just use a local variable in the generator object itself?
Also I would avoid using the word "Save" when you discuss this data, since "saving" and "persistent" mean writing data to disk. And that is not what you are doing. But if you did want to save the value then just make the matrix a description in the resource files for your object generator and access it using the BaseContainer. Then it will be saved automatically.
Cheers,
Kent
Just came across a bug that took me about 2 hours to figure out.
The reason for this is (2). Instead of calling SetRoot(mygelisthead->GetFirst()...). I should have just passed in the GeListHead.
Then for (3) I should have returned the First element: GeListHead op = (GeListHead)root; return op->GetFirst();
With these changes it works, but that took a while to figure out.
Here is the link x_nerve mentioned for my tutorials. The first one compiles the SDK examples.
I was reading through this to see if you used a Debug build. Glad you finally found it. I assume what you were doing was compiling on one machine in Debug mode and then just copying the plugin to your second machine to try it out. That second machine wouldn't have had Visual Studio installed so it wouldn't have had the debug runtime dlls, so your plugin wouldn't have loaded. Always compile in Release mode if you are going to test your plugin on another machine, or if you are giving the plugin to someone to test out.
I am trying to figure out how to display ObjectData information when the object itself it is not directly in the Object Manager.
I have an ObjectData node that contains a GeListHead, which is parented to it. This object is actually in the scene and shows in the Object Manager list.
The GeListHead contains other ObjectData nodes.
I would like to be able to display the data for the child nodes of the GeListHead in the Attribute Manager. But I am finding that if I call ActiveObjectManager_SetObject then the nodes descriptions are only visable in the Attribute Manager until the next EventAdd is called, then it reverts back to whatever is selected in the Object Manager itself.
class MyObject : public ObjectData
{
public:
virtual Bool Init(GeListNode *node)
{
_objects->SetParent(node);
}
void ShowData()
{
BaseObject* pObj = (BaseObject* )_objects->GetFirst();
ActiveObjectManager_SetObject(ACTIVEOBJECTMODE::OBJECT, pObj, ACTIVEOBJECTMANAGER_SETOBJECTS_OPEN);
EventAdd();
}
private:
AutoAlloc<GeListHead> _objects;
};
Is ActiveObjectManager_SetObject able to be used this way?
Alternatively how does the Xpresso editor work? How does it ensure the selected Xpresso nodes data gets displayed in the Attribute Manager? Would it work if I used the same approach as above but instead used a TagData plugin that contains the GeListHead?
Thanks,
Kent
I am trying to do what is described in this old thread.
https://plugincafe.maxon.net/topic/6844/7627_how-to-use-handlemousedrag?_=1664942133957
Basically I have a c4d file on disk that I have the Filename for, I then start a HandleMouseDrag from my GeUserArea and want to be able to drop it into the Viewport or Object Manager and have it load.
So far with my testing none of the following types work.
So I have instead tried doing it via a different approach. I am loading the document, grabbing some models from the scene, adding them to an AtomArray and then doing a HandleMouseDrag using the type DRAGTYPE_ATOMARRAY. But this only seems to work when dropping into the Object Manager. If you drop it over the viewport then nothing happens.
Is there anyway to be able initiate a drag drop from a GeUserArea and have C4D merge the file that is dropped? Or is there a way to manually do it an have the Viewport accepted the dropped content? Needs to work in R20 to 2023.
Thanks!
@rui_mac said in Updating my r20 C++ plugins to r21 and up:
However, is there a description on how to start clean?
My first tutorial goes through from having absolutely nothing to being able to compile the sample SDK. It takes you through every step required without assuming any prior experience.
https://www.youtube.com/playlist?list=PLEPTxkpDVvX0r292yn8xL39Cm3Wi3E69i
Hi @ferdinand,
I will see if I can get a URL to you next week to debug on your end.
I went with C++ because that suited me better for the project. I compile libCurl already for every version of C4D from R20 to S26 so it is not a problem to keep using it. It works well. But I try to use the maxon API when I can if it works for my needs.
I know python has all of this nailed down. But I do all my development in C++ for a variety of reasons so I am sticking with that for now. I deal with Gigabytes of data transfer daily so there is a lot of complexity that I know how to deal with in C++, but in python I have only scratched the surface of it in regards to C4D integration. So threading and fine grained control over memory was always a worry if I was to jump ship.
@indexofrefraction said in Insert a shader into a shader hierarchy:
this "Active Object Dialog" plugin looks very interesting
if it would be understandably described how to compile it / the c++ sdk, we could check it out
but sadly this got so complicated that you need a degree in IT to do it. .-)
The first video in my tutorial series shows you how to compile the SDK example plugins.
Just had a look at maxon::FileUtilities::ReadFileToMemory and I can't use that unfortunately, since I am downloading large files and need to chunk download them to disk to show progress information. It looks like ReadFileToMemory downloads the full file in one go, so only useful for very small files. So I will have to go back to libCurl.
Hi @ferdinand,
Thanks for looking into it.
I can't share a URL since it is a file on Cloudflare. I could send one directly via email with a longer expiry time for people to test. But if there is no desire to fix the Maxon API then it may not be worth it? And since I also need it to work in R20 onwards a fix wouldn't help me anyway in this case.
I will try your suggestion of maxon::FileUtilities::ReadFileToMemory and see if that helps, but it feels like I may have to remove all my code that uses the Maxon API and go back to libCurl instead. The maxon API works fine for AWS S3, but seems unreliable for other providers.
Cheers,
Kent
I am trying to download a file and maxon::Url::OpenInputStream() returns an error with the message "partial get response (206) missing".
Does maxon::Url support partial content?
The same url when pasted into a webbrowser downloads the file just fine. So it seems to me that maxon::Url is not yet fully complete.
maxon::Url webFile("https:://myurltoafile");
iferr(maxon::InputStreamRef inputStream = webFile.OpenInputStream())
{
LogMessage(err.GetMessage(), MAXON_SOURCE_LOCATION);
return;
}