Open source wrapper for Octane/Redshift/Arnold/Vray/Corona in Cinema 4D.
-
Hey @Dunhou,
This looks AWESOME! Thank you so much for all the awesome stuff you create!
I have pinned this topic, so that it remains visible.
Cheers,
Ferdinand -
this looks amazing. Can't wait to see arnold / RS
-
Hey @ferdinand , that's very honor to contribute to the community, and also thanks for your pin, that inspire me a lot too.
And a little plan I want to take your advice, what do you think the next update I should post, should I edit the first post, or just update the links when redshift/arnold is ready, and reply to the topic to show the main changes? which is better for more read convinence?
Cheers~
DunHou -
Hey @thomas , thanks for your like, redshift_helper is 80% for beta I think, I will try to post ASAP.
Cheers~
DunHou -
Hi community!
the renderEngine helper is beta now, I set version number to 1.0.0, it contains three renderer now:
- Octane
- Arnold ( MaterialHelper only support NodeGragh )
- Redshift ( MaterialHelper only support NodeGragh )
I personally not use Vray and Corona quite often, if anyone is a pro user of these , very welcome to add them to renderEngine
You can modify the aovs/materials with renderEngine quickly and easliy . See the examples above this topic.
Hope you can have fun with it, and any improvement and fix is very appreciated.
Cheers~
DunHou -
@Dunhou is it possible to get in touch for you for freelance development? I couldn't find any email or socials.
-
@thomas Hi, I had update my github readme file, and put my email on it
Cheers~
DunHou -
-
Hi community!
Th renderEngine library has been updated to the 1.0.4 version, there are some re-write functions and may not incompatible with older versions,see the main changes as follows:
- rename all node & material functions to Capitalize style.
- remove transaction in node_helper, use it in the final scripts.
- organize the functions in node_helper with comments ( node\port\wire\util )
- add some functions to check node or port info, like if it is connected , see the README.
- add a InserShader function to create a shader into a wire.
- re-write RemoveConnection in node_helper and support one argument(port) to remove connection.
- see the Version & Updates
Cheers~
DunHou -
-
-
Hi community!
Since my last post, I had some updates and fix to this library.
And the following picture shows the new node functions added to my Render Flow plugin based on the use of this library within few lines( just the node context ).
Have fun with it.
Cheers~
DunHou -
@Dunhou
It's realy cool and usefull, keep going bro -
Wow ... good stuff
My c4d Programing slowed down this year, but this might be something I want to use some day ... -
amazing!
-
-
Hi community!
New versions here!
I had change the name from renderEngine to Renderer, and also changed the main structure. see more in the very first of this topic. (renderEngine had been move to versions folder, if you still interested.)
This version is way more organized and user-friendly, you can use few lines of code to do something normal work, find an example below:
Cheers~
DunHou
Result:
Code:
import c4d import maxon from Renderer import Redshift, EasyTransaction, TextureHelper tex_helper: TextureHelper = TextureHelper() disp: maxon.Url = tex_helper.GetAssetUrl("file_fa9c42774dd05049") def HowToUse(): material: c4d.BaseMaterial = Redshift.Material("MyMaterial") with EasyTransaction(material) as tr: tr.AddDisplacementTree(filepath = disp, shadername = "DISP") tr.InsertMaterial() if __name__ == '__main__': HowToUse()
-
Hi community!
Here is a little example of how we modify aovs in Octane, find more examples in the top.
Have fun with it
Cheers~
DunHouResult:
Codes:
import c4d import maxon import Renderer from Renderer import Octane from pprint import pprint # How to create and modify octane aovs def modify_octane_aov(): # Get the doc host the aovs, in this case th active doc doc: c4d.documents.BaseDocument = c4d.documents.GetActiveDocument() # Set Octane AOVHelper instance aov_helper = Octane.AOV(doc) # Create a Octane aov item # the id can find from Renderer.constants.octane_id.py or in octane folder # If #name is None, defulat to type. diff_aov = aov_helper.create_aov_shader(aov_type = Octane.RNDAOV_DIFFUSE) # Add the DIFFUSE aov we just created to the Octane aov system aov_helper.add_aov(diff_aov) # Add some aovs aov_helper.add_aov(aov_helper.create_aov_shader(aov_type = Octane.RNDAOV_POST,aov_name = 'POST')) aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_DIF_D)) aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_DIF_I)) aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_REFL_D)) aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_REFL_I)) aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_WIRE)) aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_OBJECT_LAYER_COLOR)) aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_VOLUME)) # Remove last aov: volume aov_helper.remove_last_aov() # Remove specified aov: wire aov_helper.remove_aov_type(aov_type = Octane.RNDAOV_WIRE) # Add 2 custom aovs with id 1 and 2 aov_helper.add_custom_aov(customID = 1) aov_helper.add_custom_aov(customID = 2) # Get the custom aov with id 2 custom2 = aov_helper.get_custom_aov(customID = 2) if custom2: print(f'We find a Custom AOV with id 2 Named{custom2.GetName()}') # Print current aov info aov_helper.print_aov() if __name__ == '__main__': Renderer.ClearConsole() modify_octane_aov()
-
Hi community!
Here is a little example of how we modify scene objects in Arnold, find more examples in the top.
We want:
- Add a Arnold Sky with hdr
- Add a gobo light with a node-base gobo material, and a IES light
- Add a cube and add a custom mask to the driver
- Add a Scatter with custom instance shapes
- Auto export proxy with a BaseObject and load back the ass file (need to save project first)
Have fun with it
Cheers~
DunHouResults:
Codes:
import c4d import maxon import Renderer from Renderer import Arnold, TextureHelper from pprint import pprint # Create a TextureHelper instance tex_helper: TextureHelper = TextureHelper() # How to create and modify arnold scene def modify_arnold_scene(): # Get the doc host the scene, in this case th active doc doc: c4d.documents.BaseDocument = c4d.documents.GetActiveDocument() # Set arnold SceneHelper instance scene_helper = Arnold.Scene(doc) ### == Light == ### # Add a rig of hdr and rgb backdrop hdr_url: str = tex_helper.GetAssetStr(maxon.Id("file_d21cf4cfdec8c636")) scene_helper.add_dome_rig(texture_path = hdr_url, rgb = c4d.Vector(0,0,0)) # Add a light object and and some modify tags gobo_url: maxon.Url = tex_helper.GetAssetUrl("file_66b116a34a150e7e") gobo_light = scene_helper.add_gobo(texture_path = str(gobo_url), intensity=2, exposure=0) scene_helper.add_light_modifier(light = gobo_light, gsg_link = True, rand_color = True) # Add a IES light ies_url: str = tex_helper.GetAssetStr("file_6f300f2ba077da4a") ies = scene_helper.add_ies(texture_path = ies_url, intensity=1, exposure=0) ### == Tag == ### # Add a Cude object and an arnold tag with mask_name cube = c4d.BaseObject(c4d.Ocube) scene_helper.add_mask_tag(node=cube, mask_name='My Mask 01') doc.InsertObject(cube) ### == Object == ### # Add a scatter obejct with some children and count 12345 generate_object = c4d.BaseObject(c4d.Oplane) doc.InsertObject(generate_object) scatter_A = c4d.BaseObject(c4d.Oplatonic) scatter_B = c4d.BaseObject(c4d.Ooiltank) doc.InsertObject(scatter_A) doc.InsertObject(scatter_B) scatters: list[c4d.BaseObject] = [scatter_A, scatter_B] scene_helper.add_scatter(generator_node=generate_object, scatter_nodes=scatters, count=12345) # Add a object and set auto proxy the_object = c4d.BaseObject(c4d.Oplane) doc.InsertObject(the_object) the_object.SetName("Original Object") scene_helper.auto_proxy(nodes=the_object,remove_objects=False) if __name__ == '__main__': Renderer.ClearConsole() modify_arnold_scene() c4d.EventAdd()
-
Hi community!
Another little update, as we didn't have DataDescriptionDatabaseInterface as @ferdinand said in How can we get the default port of a GraphNode?
I add a ConverterPorts to Renderer, we can use this to get the "default " port of a node until the DataDescriptionDatabaseInterface is valid in python.
Note: It can only provide the str data of the port and it's not 100% rigorousCheers~
DunHou
Result:
Codes:
import c4d from Renderer import Redshift,EasyTransaction,ClearConsole def ConvertTest(): material: c4d.BaseMaterial = c4d.documents.GetActiveDocument().GetActiveMaterial() with EasyTransaction(material) as tr: nodes = tr.GetActiveNodes() for node in nodes: print(f"Node: {tr.GetName(node)}") print(f"Default Input: {tr.GetConvertInput(node)}") print(f"Default Output: {tr.GetConvertOutput(node)}") print("-"*10) if __name__ == '__main__': ClearConsole() ConvertTest()
-
Hi community!
I had add a basic support to V-Ray and Corona to fit the basic PBR usage, no Scene and AOV yet (AOV seems I can not get them in python, if someone knows where it stores, please let me know that).
Cheers~
DunHou -
Hi regarding Vray, I once wrote this plugin that have the duty to create ObjectId passes.
I did not try it since age, but previously Vray AOV where stored within a branch on the Render Engine.I don't have vray installed currently, but I guess if you compile the C++ SDK, with the help of the C++ SDK Active Object Example it should be trivial to inspect a Vray scene and find these AOV.
Cheers,
Maxime -
Hi community!
Thanks for @m_adam prompt, I had add a AOV to Vray as same as other renderers, see a basic example here, hope it can help
Cheer~
DunHou
Result:
Code:
import c4d import Renderer from Renderer import Vray def modify_vray_aov(): # Set Vray AOVHelper instance doc = c4d.documents.GetActiveDocument() vp: c4d.documents.BaseVideoPost = Renderer.GetVideoPost(doc, Renderer.ID_VRAY) aov_helper = Vray.AOV(vp) # Add the DIFFUSE aov diff_aov = aov_helper.create_aov_shader(aov_type = Vray.VRAY_AOV_DIFFUSE) aov_helper.add_aov(diff_aov) # Add some aovs aov_helper.add_aov(aov_helper.create_aov_shader(aov_type = Vray.VRAY_AOV_BACKGROUND, aov_name = 'BG')) aov_helper.add_aov(aov_helper.create_aov_shader(Vray.VRAY_AOV_SPECULAR)) aov_helper.add_aov(aov_helper.create_aov_shader(Vray.VRAY_AOV_REFLECTION)) aov_helper.add_aov(aov_helper.create_aov_shader(Vray.VRAY_AOV_SHADOW)) aov_helper.add_aov(aov_helper.create_aov_shader(Vray.VRAY_AOV_LIGHT_MIX)) # Remove last aov aov_helper.remove_last_aov() # Remove specified aov: diffuse aov_helper.remove_aov_type(aov_type = Vray.VRAY_AOV_DIFFUSE[0]) # Print current aov info aov_helper.print_aov() c4d.EventAdd() if __name__ == '__main__': Renderer.ClearConsole() modify_vray_aov()
-
Hi again,
Also another Corona AOV example here .
Finally preliminarily implemented using this library to approximate the operation of the renderer in Cinema 4D .
The learning process was very enjoyable, hope you also have fun with it
Cheers~
DunHou
Result:
Code:
import c4d import Renderer from Renderer import Corona def modify_corona_aov(): # Get the doc host the aovs, in this case th active doc vp doc: c4d.documents.BaseDocument = c4d.documents.GetActiveDocument() vp: c4d.documents.BaseVideoPost = Renderer.GetVideoPost(doc, Renderer.ID_CORONA) # Set Corona AOVHelper instance aov_helper = Corona.AOV(vp) # turn on the mutipass aov_helper.enable_mutipass(True) # Add the DIFFUSE aov diff_aov = aov_helper.create_aov_shader(aov_type = Corona.CORONA_MULTIPASS_TYPE_ALBEDO) aov_helper.add_aov(diff_aov) # Add some aovs aov_helper.add_aov(aov_helper.create_aov_shader(aov_type = Corona.CORONA_MULTIPASS_TYPE_EMISSION, aov_name = 'emmision aov')) aov_helper.add_aov(aov_helper.create_aov_shader(Corona.CORONA_MULTIPASS_TYPE_REFLECT)) aov_helper.add_aov(aov_helper.create_aov_shader(Corona.CORONA_MULTIPASS_TYPE_REFRACT)) aov_helper.add_aov(aov_helper.create_aov_shader(Corona.CORONA_MULTIPASS_TYPE_TRANSLUCENCY)) aov_helper.add_aov(aov_helper.create_aov_shader(Corona.CORONA_MULTIPASS_TYPE_ZDEPTH)) # Remove last aov: volume aov_helper.remove_last_aov() # Remove specified aov: wire aov_helper.remove_aov_type(aov_type = Corona.CORONA_MULTIPASS_TYPE_TRANSLUCENCY) # Print current aov info aov_helper.print_aov() Corona.AovManager() if __name__ == '__main__': Renderer.ClearConsole() modify_aorona_aov() c4d.EventAdd()