Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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
    • Recent
    • Tags
    • Users
    • Register
    • Login
    1. Maxon Developers Forum
    2. ThomasB
    Offline
    • Profile
    • Following 1
    • Followers 0
    • Topics 35
    • Posts 130
    • Groups 0

    ThomasB

    @ThomasB

    4
    Reputation
    48
    Profile views
    130
    Posts
    0
    Followers
    1
    Following
    Joined
    Last Online
    Age 50
    Location Germany

    ThomasB Unfollow Follow

    Best posts made by ThomasB

    • RE: How to create python plugin in 2024?

      Yes, download the SDK and study the examples.
      I wrote my own software that allows me to simply select the type of plugin I want to create, enter the plugin ID and the plugin name. The program then creates the folder structure, all files with the correct content and the correct name automatically...that was the first thing I did because it is always extremely tedious.
      This then takes 10 seconds and I have a finished blueprint. Then I can start programming straight away.
      I usually make the Gui first using UserData to roughly create the design and then I write it down in the resfile in no time at all. It's relatively quick and even fun and you gradually grow into it, it emerges little by little.....

      Basically it wouldn't be a problem to write a script that writes the UserData interface into a Res, header and string file, I already have an idea for that... That would actually be easy to do.
      I'll get to it when I'm done with my update... and then maybe make it available to the community... However, a similar one is already there, but I can't remember where.

      Greetings
      Tom

      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • RE: Boole Object causes version 2024 to freeze

      @ferdinand
      Hello Ferdinand,
      Thank you very much first of all.
      yes, you're right, I worked extremely sloppily with the SMC method, of course I'll take the threading into account and also work with a Temp Document.

      Regarding the problem itself, I can only say that reinstalling CINEMA 4D solved our problem.

      Cheers

      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • RE: How do I get the cache of a cloner in an ObjectData Plugin

      @ferdinand
      oh man thanks I forgot this

      BaseDocument.ExecutePasses(bt=None, animation=False, expressions=False, caches=True, flags=c4d.BUILDFLAGS_NONE)
      

      I tried that before but it seems I have set the caches parameter wrong.
      Thank you very much....

      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • RE: Best way to hide a child and get best perfomance

      @Tpaxep
      besides that I have a code which works for your scenario.

      def GetVirtualObjects(self, op, hh):
      
          profile_orig = op.GetDown()
          if profile_orig is None:
              return None
      
          path_orig = profile_orig.GetNext()
          if path_orig is None:
              return None
      
          # you need to make clones of the children, don't use the orig
          # first make clones and then use the GACHC Methode below
          profile = profile_orig.GetClone()
          path = path_orig.GetClone()
      
          dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTYFLAGS_ALL)
      
          child_dirty = op.GetAndCheckHierarchyClone(hh, profile_orig, c4d.HIERARCHYCLONEFLAGS_ASSPLINE, True)         
      
          if not any([dirty, child_dirty["dirty"]]):
              return child_dirty["clone"]
      
          print("GVO Executed")
          # calculation of your geometry
          sweep = c4d.BaseObject(c4d.Osweep)
          tag = c4d.BaseTag(c4d.Tphong)
          tag[c4d.PHONGTAG_PHONG_USEEDGES] = False
          sweep.InsertTag(tag)
          path.InsertUnder(sweep)
          profile.InsertUnder(sweep)
      
          return sweep
      

      you can also track dirty manually:

      def GetVirtualObjects(self, op, hh):
      
              profile_orig = op.GetDown()
              if profile_orig is None:
                  return None
      
              path_orig = profile_orig.GetNext()
              if path_orig is None:
                  return None
      
              profile = profile_orig.GetClone()
              path = path_orig.GetClone()
      
              dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTYFLAGS_ALL)
      
              #Manually track dirty of the childs (Example)      
              child_dirty = False
              for child in op.GetChildren():
                  child_dirty = child.IsDirty(c4d.DIRTYFLAGS_DATA | c4d.DIRTYFLAGS_MATRIX)
                  if child_dirty:
                      break
      
              # After Dirty Touch the childs
              profile_orig.Touch()
              path_orig.Touch()
      
              if not any([dirty, child_dirty]):
                  return op.GetCache(hh)    
      
              print("GVO Executed")
              # calculation of your geometry
              sweep = c4d.BaseObject(c4d.Osweep)
              tag = c4d.BaseTag(c4d.Tphong)
              tag[c4d.PHONGTAG_PHONG_USEEDGES] = False
              sweep.InsertTag(tag)
              path.InsertUnder(sweep)
              profile.InsertUnder(sweep)
      
              return sweep
      
      posted in Cinema 4D SDK
      ThomasBT
      ThomasB

    Latest posts made by ThomasB

    • RE: Custom node-locked licensing: Bypassing checks for Team Renderer, Clients, Server safely?

      @ferdinand
      👍
      Yes, thanks, that indirect answer is enough for me. I was mainly wondering whether a check performed on both the client and the server is robust enough, or if it could be bypassed using Python, for instance. I’m well aware that it can be cracked somehow. I’m also already using ExportLicenses() for my node-locking system in combination.

      Thanks a lot for your help.

      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable

      @ferdinand
      crazy, this helps me a lot Ferdinand. Thank you so much 🙏 . I didn`t now that.
      Thanks for this function example.

      Edit:
      It works....
      How is a dumb plugin developer like me supposed to know that you have to clear those two bits right there of all places...
      But that's great, thanks. It helps me a huge amount for the future.

      Sincerely T.B.

      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • Custom node-locked licensing: Bypassing checks for Team Renderer, Clients, Server safely?

      Hi,

      I am using a custom node-locked licensing system (2 Nodes) for my Cinema 4D plugin. Since Team Render clients running on other machines shouldn't consume a license activation, I want to bypass the license check on startup for them.

      My plan is to check c4d.isClient() or rather, c4d.GeGetVersionType() right before the licensing routine and skip it if it returns true.

      Example:

      client = c4d.GeGetVersionType()
      if client == c4d.VERSIONTYPE_TEAMRENDER_CLIENT or client == c4d.VERSIONTYPE_TEAMRENDER_SERVER:
              print("yes free rendering for all")
              return True
      

      My question: Is c4d.isClient() or c4d.GeGeVersionType() reliable and secure against spoofing, meaning a user couldn't just fake this flag on a normal Cinema 4D master instance to bypass the node-lock? Or is there a better way to handle this for Team Renderer, Clients and Server?

      Thanks!

      posted in Cinema 4D SDK python 2023 2024 2025 2026 windows
      ThomasBT
      ThomasB
    • RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable

      @ferdinand
      I think we were talking at cross-purposes there. The problem was actually the light conversion using "Make Editable" on the plugin itself, not the Light Importer, which was the workaround I had already implemented. The problem where the lights are converted into null objects when making the plugin editable still persists.
      But you did mention the diff tool in an earlier reply and managed to get it working once using a TempDoc. So, I won't be able to avoid giving it another thorough test, but the release is coming up first.

      More on that in the

      .

      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable

      @ferdinand
      Ok , I will give it another try tomorrow.
      I will print this out again using this diff tool and compare it.


      I understand your point of view and your perseverance. 👍. But quite honestly, Ferdinand. That workaround might have to be removed again with Maxon's next fix, which in turn might necessitate a further update to my plugin, and so on. The plugin's strength lies in its extensibility. Therefore, my focus regarding the plugin is on extensions, rather than on removing workarounds or adding new features.

      Given the highly complex document structure and the various types of lights involved, a particularly complex method has to be written for this. Furthermore, as I mentioned earlier, some lights have other lights as child objects, and those in turn have their own, with the specific setup varying from building to building. And every light of the same type might even have slightly different settings as well. This isn't really how I wanted to handle it.


      But I will give it a try. I know, complaining doesn't help. So I'll test it again with two lights, just like you did. One light from the document and the other generated programmatically. Then I'll compare the two again.
      However, this will be the last feature before the release, as it simply needs to be ready for delivery.
      The lighting feature is a bit of a thorn in my side anyway, since it’s very resource-intensive—but you know what users are like (myself included!). They want the all-singing, all-dancing, do-it-all solution.

      All things considered, the plugin has turned out quite well and is on the verge of release. My actual implemented workaround for importing the lights into the scene works, too, and requires just a single click from the user. Since the lights for each level are contained within a null object, this light importer represents the most pragmatic approach for me, involving the least amount of effort.

      So, if I don't manage to fix the "bug" according to your requirements now, I’m going to release it anyway. Unfortunately, I can't live on thin air. 😊

      Respectfully,
      T.B.

      Person: I love AI, I want to do everything with AI...
      Developer: So you want to replace your brain with a language model? bye Bye! There's the door 👉

      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable

      @ferdinand

      Okay, great that you really dug into this. That could well have something to do with it.

      However, if you look at my latest test plugin—the C4D scene—the "Illumination" checkbox on the Redshift light is enabled, yet when you select "Make Editable," the light still turns into just a Null Object. So, regardless of whether the illumination is on or not..

      But as I mentioned earlier this only happens if the light originates from a temporary document in the code. Or rather, when the scene with the light is loaded into a temp_doc.

      • e.g. LoadDocument() or MergeDocument()

      That is why simply checking the "Illumination" box does not work.

      Cheers

      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable

      @ferdinand

      Yeah, thanks—there’s no rush; I have until the end of July before the plugin is released.

      But as I mentioned, manually swapping the lights doesn't work; the problem persists even if the scene is created in Cinema 4D 2026.3.1. The only way it would work is programmatically as you mentioned above—via code in the plugin that iterates through all the lights in the loaded scene and swaps the data. I’ll give it a try; if load times and performance suffer, or if the effort isn't worth it, I’ll stick with the "Lights Import" button method for now.


      Summary of the Core Issue

      So, when scenes are imported via LoadDocument or MergeDocument in the code and parts returned within the GVO, they are correctly converted into polygon objects (after "Make Editable")—but Redshift lights are not converted into Redshift lights; instead, they are converted into Null objects. Numerous tests have confirmed this, regardless of whether the scene was created in the latest version of C4D or an older one, such as 2023.
      ➡️A programmatic replacement of the lights is necessary after the virtual document has loaded.

      Best Regards
      T.B


      Edit:

      I’ve implemented a light replacer in the example plugin again.
      It searches self.temp_doc for all Redshift lights, iterates through the list, creates a completely new light programmatically, sets the key values ​​to match the old light, applies the GetDataInstance to the light in the temp doc, and sets the global matrix.
      ➡️As discussed, this approach doesn't work either; the lights are still being converted into Null objects.
      That means I would have to replace the lights entirely with programmatically generated ones, which would require replicating the entire light and temp_doc hierarchy—including cases where lights contain other lights or objects. The effort involved simply isn't worth the benefit. Sorry.

      In this case, it would be better to look for the cause of the problem.

      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable

      @ferdinand
      thank you for your time Ferdinand. We all really appreciate your work. Without you, there would be only half as many plugins for Cinema 4D.

      Oh man, I'm sorry about the corrupted scene.

      Did you programmatically modify this scene? Because your plugin only seems to load it.

      The Road to a Corrupted File

      • Since I prefer modeling in R23, I did my modeling work there and saved the scene in R23.
      • Then I opened it in the latest version, 2026.3.1.
      • It notified me that it needed to modify the Cinema 4D scene and that it might no longer work with older versions of Cinema 4D.
      • Then, I just saved over it normally using 2026.3.1. That version runs on the MRD license.
      • I just wanted to make sure it was saved using the latest version.
        ➡️Apparently, it didn't correctly convert the scene to the new Redshift core. I'll compare the two versions later using mxutils. For now, everything looks normal in the new scene.

      I didn't modify the scene via code.
      Otherwise, the only other explanation I can think of for the corrupted file structure is the ZIP compression or a temporary license problem, between R23 and the MRD License. R23 runs on a Commercial License, Redshift runs on MRD.

      New scene:
      However, I’ve now created and saved a completely new scene—exclusively in 2026.3.1—and uploaded it as a new plugin. The file cannot be corrupt at this stage. Using the mxutils methods reveals no issues.

      Result:
      However, the result is the same. Something seems to struggle with the conversion process during the "Make Editable" when those lights originate from a loaded virtual document.
      So, if I create the area light directly via code as you did and then press "C", then it works, it appears in the scene as a standard Redshift Area Light. But you simply can't generate everything via code, so I need the ability to take things from pre-made scenes.

      Important:
      I’ve gone a step further and implemented a button that simply extracts the light from the virtual document—or rather, the container—and inserts it into the scene. Oddly enough, the light is inserted correctly into the active document this way.
      The user could bring the lights into the scene before pressing "C"—that would be a workaround.
      However, the problem with "Make Editable" still persists.

      Download New Plugin Version

      I wish you a relaxing weekend. As a Maxon SDK specialist, your head must be spinning quite often.
      Cheers

      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • RE: Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable

      @ferdinand

      Okay, thank you Ferdinand for your reply.
      Okay, that's strange—it works in your video.

      I don't think the issue lies with my code; it simply loads a Cinema 4D scene in which the objects are already prepared.

      But here is the unprotected plugin.
      As previously mentioned, this is just a simple, simplified plugin to demonstrate that the problem behaves exactly as described above when using "Make Editable."
      Download unprotected plugin

      and the code if this helps out:

      from typing import Optional
      
      import c4d
      from c4d import plugins, bitmaps, BaseObject
      import os
      
      
      PLUGIN_ID = 1000200
      
      
      def load_house():
      
          house_path = os.path.join(path, "res", "models", "build_1.c4d")
          doc = None
          if os.path.exists(house_path):
              doc = c4d.documents.LoadDocument(house_path, c4d.SCENEFILTER_OBJECTS | c4d.SCENEFILTER_MATERIALS)
      
          return doc
      
      
      
      
      class RedshiftLightsTest(plugins.ObjectData):
      
          def __init__(self):
              self.SetOptimizeCache(True)
      
              self._temp_doc = load_house()
      
          def Init(self, op, isCloneInit):
      
      
              return True
      
          
      
          def GetVirtualObjects(self, op: BaseObject, hh: object) -> Optional[BaseObject]:
      
              cdirty = False
              for child in op.GetChildren():
      
                  cdirty = child.CheckCache(hh) or child.IsDirty(c4d.DIRTYFLAGS_DATA)
                  if cdirty:
      
                      break
      
              dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTYFLAGS_DATA | c4d.DIRTYFLAGS_ALL) or cdirty
              if not dirty:
                  return op.GetCache(hh)
      
      
              if self._temp_doc:
                  container = c4d.BaseObject(c4d.Onull)
      
                  base: c4d.BaseObject = self._temp_doc.GetFirstObject().GetDown().GetClone()
                  base.InsertUnder(container)
      
                  return container
              else:
                  return None
      
          def GetDDescription(self, op, description, flags):
              if not description.LoadDescription(op.GetType()):
      
                  return False
      
              single_id = description.GetSingleDescID()
              
      
              return False, (flags | c4d.DESCFLAGS_DESC_LOADED)            
      
         
      
          def GetDEnabling(self, op, did, t_data, flags, itemdesc):        
      
              return True
      
      
      if __name__ == "__main__":
          path, file = os.path.split(__file__)
          file = "icon.tif"
          new_path = os.path.join(path, "res", file)
          bitmap = bitmaps.BaseBitmap()
          bitmap.InitWith(new_path)
          plugins.RegisterObjectPlugin(id=PLUGIN_ID, str="redshift_lights_test", g=RedshiftLightsTest, description="redshift_lights_test", icon=bitmap,
                                       info=c4d.OBJECT_GENERATOR)
      
      
      posted in Cinema 4D SDK
      ThomasBT
      ThomasB
    • Programmatically created Redshift Lights in an Object Plugin converts lights into Null-Objekts without an function after making Objekt-Plugin editable

      Sorry first, I am not sure if this is the right place to post this. The Redshift forum was apparently not the right place. 🙄

      I don't know if this behavior is intentional or unavoidable, but there is a problem with Redshift lights in my opinion.

      Situation:
      When you create a Redshift light and press 'C', it converts it into a standard Cinema 4D light—or, if generated programmatically, into a useless Null object.
      It is programmatically impossible to generate a light (e.g., within an object plugin). When the object plugin is made "Editable"—for instance, to get the geometry—all Redshift lights are converted into Null objects and lose their functionality. Unlike the standard behavior, they aren't even converted into Cinema 4D lights.

      Steps:

      • The plugin loads a virtual scene containing prepared scene elements and lights.
      • It returns in a container all the needed elements
      • When the plugin is made "Editable" to recieve the geometry, all Redshift lights are converted into Null objects.
        ➡️ result: Light functionality is lost.

      Visual Examples:
      Plugin creates a building for night view:

      • as long as the plugin is running lights are working
        bug_redshift.jpg

      • a light in code looks like this in a virtual temp_doc:
        bug_redshift_light_in_code.jpg

      • after converting the plugin into geometry (c to make it editable) it converts the lights into this:
        bug_redshift_light_afterconversion.jpg

      Plugin Example:
      Here is a trivial plugin example which basically loads a scene and returns an element with a light.
      The scene structure of the document looks like that. The plugin returns the base element
      bug_house_stucture.jpg

      After making the plugin editabel the light_flurescent is converted into a null object, and not even a Cinema 4D light remains.
      Ideally, of course, the Redshift light would be fully preserved. That makes sense if you want to render with Redshift.

      It uses a temporary Plugin ID
      Download Plugin

      I don't need to explain the code in detail here; an element is simply returned in the GetVirtualObjects method:

          def GetVirtualObjects(self, op: BaseObject, hh: object) -> Optional[BaseObject]:
      
              cdirty = False
              for child in op.GetChildren():
      
                  cdirty = child.CheckCache(hh) or child.IsDirty(c4d.DIRTYFLAGS_DATA)
                  if cdirty:
      
                      break
      
              dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTYFLAGS_DATA | c4d.DIRTYFLAGS_ALL) or cdirty
              if not dirty:
                  return op.GetCache(hh)
      
      
              if self._temp_doc:
                  container = c4d.BaseObject(c4d.Onull)
      
                  base: c4d.BaseObject = self._temp_doc.GetFirstObject().GetDown().GetClone()
                  base.InsertUnder(container)
      
                  return container
              else:
                  return None
      

      Cheers
      T.B.

      posted in Cinema 4D SDK 2026 2025 2024 2023 python windows
      ThomasBT
      ThomasB