Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Hi everyone,
I'm trying to add my own color preferences and add them to the "Scheme Colors" section in the Cinema 4D preferences, similarly to what Hair does.
To do so, I successfully add and register a PrefsDialogObject. I used a description similar to the Hair one in prefshaircolor.res/prefshaircolor.h and it displays fine. The implementation is based on an earlier thread from the forum (and a bit of prior experience): https://plugincafe.maxon.net/topic/11737/default-startup-settings/4
PrefsDialogObject
prefshaircolor.res
prefshaircolor.h
It works pretty much fine, the preferences show up in the right place and I am able to control the colors in the list view the same way it works in all the other color preferences. I even added that "Reset..." button. The only problem is that the data in the ListViewData element does not appear to be restored properly when Cinema 4D starts up again. I tried other data types like Int32 and those are brought over into a new session just fine.
ListViewData
Int32
When looking at the BaseContainer with my Plugins' settings I see that when I call BaseContainer::GetData() on it, the resulting GeData is of type DA_MISSINGPLUG, which to me looks like Cinema 4D is somehow not able to restore the data element from the preferences. It looks a little like that might be because the ListViewData custom datatype hasn't been registered when the preferences are restored?
BaseContainer
BaseContainer::GetData()
GeData
DA_MISSINGPLUG
However, I am assuming that the regular Cinema 4D color scheme preferences somehow store their setting and when loading the Hair preferences via HairLibrary::GetPrefsInstance(), I see the container it returns contains elements of type CUSTOMDATA_LISTVIEW (1018397), so it somehow must be possible to store values of that type in the preferences.
HairLibrary::GetPrefsInstance()
CUSTOMDATA_LISTVIEW
Did anybody run into similar problems before and can help me? I'm feel like I must be missing something trivial here.
Thanks in advance for any help!
Best Timm
Hi @r_gigante!
Thanks for the elaborate answer, there is a lot to chew on here. I was wondering if you also had an answer to my first question:
@tdapper said in Making geometry available for IPR rendering:
We actually have been thinking about offering a mechanism for rendering vendors to retrieve the full geometry, my observations just made me think that there might be a better way (meaning: a standard way that wouldn't have to be vendor specific). Anyway, the way we thought about it was to use the function publishing interface and implement a call on our object, similarly to what the Hair module does. What would be your reasoning to prefer using messages instead?
Hi Ricardo,
Thanks for helping me out here. Couple followup questions:
BUILDFLAGS::INTERNALRENDER
BUILDFLAGS::EXTERNALRENDER
GetVirtualObjects()
Draw()
PolygonObject
ObjectData::DrawPolygonObject()
Thanks for your awesome support, @r_gigante!
Our plugins have two generator objects that both produce two vastly different representations for editor display and for rendering. We decide which one to create by the existence of BUILDFLAGS::INTERNALRENDER/BUILDFLAGS::EXTERNALRENDER. That produces problems with all sorts of IPR renderers, because they use the editor representation. However, I noticed, that this is being solved somehow. For example, when using Multi-Instances and setting them to display boxes in the viewport, most IPR renderers (I tried Arnold and heard it works in Redshift as well) do show the render geometry. Same appears to work happen (at least in Arnold) with the Subdiv object. The editor shows the editor detail, in the IPR I get the render subdivision.
I am not sure how this happens (or whether both of the above cases use the same mechanism), but I would like to figure out how this works, so we can do the same.
I am aware, that we could just create both, editor and render geometry always and just set the visibility flags in the cache. However, at least with one of our objects that would be less than ideal, because generating the full detail representation also takes a bit.
Hope someone can help, ideally with some insight on how the two examples, I described above, work.
I'm trying to create an Xref object from within Python, but somehow cannot set certain parameters (like the Reference and Proxy Reference). Is there a way to add an Xref to a scene using Python? A similar thread from the legacy forum seems to indicate it is not possible, but then that was years ago, so I hope this may be possible now.
Looking at this thread, it looks like the only way for me to register and use my own error types, requires me to put them into a separate framework, instead of just defining them as part of my project, as well as actually copying them into the SDK folder. Is it only me or is this mindblowingly clumsy and tedious? Or am I just getting this wrong? This makes the Cinema 4D error handling system so much harder to use and embrace.
It would be great to know whether this is just a misunderstanding on my side (which I sincerely hope it is). Also the documentation is not really clear on this there is example code how in the regular SDK docs which make it look like a piece of cake and they are lacking any reference to this disproportionate complexity introduced to just add twenty lines of code for a custom error handler.
I am trying to get all our developers to use and embrace the new error handling, but this feels like it will make my life pretty hard in this regard.
Any further clarification very much appreciated.
I am creating a job that does some potentially long-ish computation in a queue in the background. To that job I added an finish observer like this:
_job.ObservableFinished().AddObserver(ConcurrentGeneratorObjectData::WatchGeneratorFinished) iferr_ignore();
The _jobvariable in this example is of type maxon::JobResultRef<BaseObject*>.
_job
maxon::JobResultRef<BaseObject*>
The WatchGeneratorFinished() observer function just fires an EventAdd() when the job finishes, which is usually what I want. There are, however, certain events in the scene that I am listening to which indicate that this is not the behavior I want (e.g. an editor render being kicked off) in which case I would like to remove the observer (to potentially add it back again later). I did find a function ObservableBaseInterface::RemoveObserver(), which appears to do what I want, but I am having a hard time finding out how to use it. The ObservableFinishedBaseobject that is returned from JobResultRef<>::ObservableFinished()` function I am using does not seem to implement it. Is there a way for me to do this?
WatchGeneratorFinished()
EventAdd()
ObservableBaseInterface::RemoveObserver()
ObservableFinishedBase
Any pointers very much appreciated!