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. bentraje
    B
    • Profile
    • Following 0
    • Followers 1
    • Topics 241
    • Posts 738
    • Best 17
    • Controversial 0
    • Groups 0

    bentraje

    @bentraje

    19
    Reputation
    390
    Profile views
    738
    Posts
    1
    Followers
    0
    Following
    Joined Last Online

    bentraje Unfollow Follow

    Best posts made by bentraje

    • RE: LINK EFFECTORS TO CLONERS

      Hi,

      Not quite directly a revision of your code but this should help you get started.

      import c4d
      from c4d import gui
      
      # Main function
      def main():
          cloner = doc.SearchObject("Cloner") # Assuming there is already a Cloner Mograph Object 
          plain_effector = doc.SearchObject("Plain")# Assuming there is already a Plain Effector Object 
      
          effector_list = c4d.InExcludeData()
          effector_list.InsertObject(plain_effector, 1)
      
          cloner[c4d.ID_MG_MOTIONGENERATOR_EFFECTORLIST] = effector_list
          c4d.EventAdd()
      
      
      # Execute main()
      if __name__=='__main__':
          main()
      
      posted in Cinema 4D SDK
      B
      bentraje
    • RE: How to detect a new light and pram change?

      @Dunhou
      I fork that redshift light manager last time.
      https://github.com/bentraje/c4d_redshift_light_lister

      I just change the minimum for it to work on the latest C4D versions.
      It works on C4D 2023, last time I check, and on RS 3.5, but not all parameters are fully supported since I didn't refactor that much.

      2002c62c-f3a1-4565-9dd7-4136add8ceba-image.png

      posted in Cinema 4D SDK
      B
      bentraje
    • RE: requirenments for building Cinema 4D extension

      Cinema4D can accommodate plug-ins written in C++ or Python. However, it only accept scripts written in Python.

      posted in General Talk
      B
      bentraje
    • RE: Developing .obj sequence exporter for selected objects

      Probably not that helpful but there is an existing script for the C4D OBJ Sequence Exporter
      https://richh.co/c4d-native-obj-sequence-export-no-plugins/

      posted in Cinema 4D SDK
      B
      bentraje
    • RE: Disable a tag from Python

      Hi @blieque

      You can do is the Basic>Enable Checkbox in every object.
      If you drag it to the console, the parameter is [c4d.ID_BASEOBJECT_GENERATOR_FLAG]

      posted in Cinema 4D SDK
      B
      bentraje
    • RE: Modify the Default Untitled Python Script

      Thanks Adam for the confirmation.
      I'll just send it for Maxon Suggestion for now.

      Thanks!

      posted in Cinema 4D SDK
      B
      bentraje
    • RE: Get/Fetch Node from an Existing Xpresso Tag

      Thanks @m_adam. Works as expected.
      My bad, I was looking at the documentation hierarchy erroneously (i.e c4d > modules > graphview > GvNode)

      Just a note: I think the if Multiply: line is supposed to be if isMultiply:.

      Thanks again. Have a great day ahead!

      posted in Cinema 4D SDK
      B
      bentraje
    • RE: Get the Button GadgetID Directly Under the Mouse?

      Hi @m_adam

      Thanks for the patience. Your suggestions and reminders works are greatly appreciated.

      I guess the confusion stems mainly on my part because I posted slightly two different codes. You were responding to my initial post but I was thinking with the code from the succeeding post(the one in the rar file). Totally my bad.

      Anyhow, here is the working code (using the initial post) which works as I expected:

      import c4d
      
      class ColorButton(object):
      
          def __init__(self):
              self.width = None
              self.height = None
              self.color = None
              self.color = None
              self.btn_id = None
              self.menu_list = None
      
      
          def create(self, dlg, w, h, color, btn_id):
      
              self.width = w
              self.height = h
              self.color = color
              self.btn_id = btn_id
      
              bmp_color = c4d.bitmaps.BaseBitmap()
              bmp_color.Init(w, h)
      
              for y in xrange(w):
                  for x in xrange(h):
                      bmp_color.SetPixel(x, y, color[0], color[1], color[2])
      
              bcBitmapButton = c4d.BaseContainer()
              bcBitmapButton[c4d.BITMAPBUTTON_BUTTON] = True
      
              bmp_btn = dlg.AddCustomGui(self.btn_id, c4d.CUSTOMGUI_BITMAPBUTTON, "", c4d.BFH_CENTER | c4d.BFV_CENTER, w, h, bcBitmapButton)
      
              bmp_btn.SetImage(bmp_color, True)
      
          def create_menu(self):
      
              self.menu = c4d.BaseContainer()
      
              for menu_item in self.menu_list: 
                  counter = 0
                  IDM_MENU = c4d.FIRST_POPUP_ID + counter
                  self.menu.InsData(IDM_MENU, menu_item)
      
                  counter += 1
      
      class MyDialog(c4d.gui.GeDialog):
      
          def __init__(self):
              self.btn_id_list = []
              self.class_btn_id_dict = {}
      
          def CreateLayout(self):
      
              red_button = ColorButton()
              red_button.create(self, w=50,h=50,color=(255,0,0), btn_id=6000)
              red_button.menu_list = ['Menu1', 'Menu2', 'Menu3']
              self.btn_id_list.append(red_button.btn_id)
              self.class_btn_id_dict[6000] = red_button
      
              blue_button = ColorButton()
              blue_button.create(self, w=50,h=50,color=(0,0,255), btn_id=7000)
              blue_button.menu_list = ['Menu4', 'Menu5', 'Menu6', 'Menu7']
              self.btn_id_list.append(blue_button.btn_id)
              self.class_btn_id_dict[7000] = blue_button
      
      
              green_button = ColorButton()
              green_button.create(self, w=50,h=50,color=(0,255,0), btn_id=8000)
              green_button.menu_list = ['Menu8', 'Menu9']
              self.btn_id_list.append(green_button.btn_id)
              self.class_btn_id_dict[8000] = green_button
      
              return True
      
          def IsPositionOnGadget(self, gadgetId, x, y):
              # Be sure that the windows is opened,
              # in our case since we call it in BFM_INTERACTSTART it's ok
              buttonData = self.GetItemDim(gadgetId)
              
              if not buttonData["x"] < x < buttonData["x"] + buttonData["w"]:
                  return False
      
              if not buttonData["y"] < y < buttonData["y"] + buttonData["h"]:
                  return False
      
              return True
          
          def function_to_determine_gadgetId_under_mouse_cursor(self, x, y):
              for gadgetId in self.btn_id_list:
                  if self.IsPositionOnGadget(gadgetId, x, y):
                      return gadgetId
                  
          def Message(self, msg, result):
              if msg.GetId() == c4d.BFM_ADJUSTSIZE:
                self._x = msg[3] # Retrieve Y size of the GeDialog
                self._y = msg[4] # Retrieve Y size of the GeDialog
      
              # We are on the main thread here
              elif msg.GetId() == c4d.BFM_INTERACTSTART:
                  c4d.StopAllThreads()
      
                  state = c4d.BaseContainer()
                  self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSERIGHT, state)
      
                  if state.GetInt32(c4d.BFM_INPUT_VALUE) == True:
      
                      x = state.GetInt32(c4d.BFM_INPUT_X)
                      y = state.GetInt32(c4d.BFM_INPUT_Y)
                      g2l  = self.Global2Local() 
                      x += g2l['x']  
                      y += g2l['y']
      
                      gadgetId = self.function_to_determine_gadgetId_under_mouse_cursor(x=x,y=y)
      
                      if gadgetId in self.btn_id_list:
      
                           if self.IsPositionOnGadget(gadgetId=gadgetId, x=x, y=y):
      
                                button_class = self.class_btn_id_dict[gadgetId] 
                                button_class.create_menu()
      
      
                                l2s = self.Local2Screen()
                                print str(x+l2s['x']) + " :: " + str(y+l2s['y'])
                                self.KillEvents()
                                res = c4d.gui.ShowPopupDialog(cd=self, bc=button_class.menu, x=x+l2s['x'], y=y+l2s['y'])
                                return True
      
              return c4d.gui.GeDialog.Message(self, msg, result)
      
      if __name__ == "__main__":
          dlg = MyDialog()
          dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=20304050)
      
      posted in Cinema 4D SDK
      B
      bentraje
    • RE: Content Browser Like Navigation?

      @r_gigante

      Thanks for the reference.
      For anyone trying to achieve the same,
      here is a sample file.
      https://www.dropbox.com/sh/z1lzyphp8qnt9kw/AAB2P5gNo16IHafgc6xPEsy4a?dl=0

      Thanks again for @zipit for the help.

      posted in Cinema 4D SDK
      B
      bentraje
    • RE: Copy, Paste, Flip X a Pose Morph Target?

      @m_magalhaes @zipit

      I managed to flip the mesh (not necessarily a pose morph target since I'd have to know the API).
      Anyhow, here is a demo of it working:
      https://www.dropbox.com/s/bh4p26s4m9qwljw/c4d272_flip_miror_mesh.mp4?dl=0

      Here is wip script. It only works if the x-axis is dead set on 0.
      Also, it is slow since it has to loop within a loop.

      import c4d
      from c4d import gui
      
      
      # Main function
      def main():
          neutral_geo = doc.SearchObject('neutral_geo')
          posed_geo = doc.SearchObject('posed_geo')
          neutral_world_matrix = neutral_geo.GetMg()
          posed_world_matrix = posed_geo.GetMg()
          
          neut_lcl_pnts = neutral_geo.GetAllPoints()
          neut_gbl_pnts = [point * neutral_world_matrix for point in neut_lcl_pnts]
          
          posed_lcl_pnts = posed_geo.GetAllPoints()
          posed_gbl_pnts = [point * posed_world_matrix for point in posed_lcl_pnts]
              
          match_pnts = []
          left_pnts = []
          right_pnts = []
          
          for idx, point in enumerate(neut_gbl_pnts):
              if point[0] == 0.0: # ignore points at the world x axis
                  continue
              
              if point[0] > 0.0:
                  left_pnts.append((idx,point))
              
              if point[0] < 0.0:
                  right_pnts.append((idx,point))
                  
          
          for left in left_pnts:
              for right in right_pnts:
                  if left[1][1] == right[1][1]: # check if Y pos match
                      if left[1][2] == right[1][2]: # check if Z pos match
                         if left[1][0] == -1 * (right[1][0]):# check if X pos are inverse
                             match_pnts.append((left[0],right[0]))
              
              
          for pnt in match_pnts:
              
              reversed_left = posed_lcl_pnts[pnt[1]]
              reversed_left[0] = reversed_left[0] * -1
              reversed_right = posed_lcl_pnts[pnt[0]]
              reversed_right[0] = reversed_right[0] * -1
              
              
              posed_geo.SetPoint(pnt[0], reversed_left)
              posed_geo.SetPoint(pnt[1], reversed_right)
              
          posed_geo.Message(c4d.MSG_UPDATE)
           
          c4d.EventAdd()
      
      # Execute main()
      if __name__=='__main__':
          main()
      
      posted in Cinema 4D SDK
      B
      bentraje

    Latest posts made by bentraje

    • RE: Query Morph Order Based on the UI Order?

      Hi @ferdinand

      Thanks for the response.
      Found a workaround it.
      Basically, just name the poses properly in a sorting order.
      Query the GetName() method and perform my own sorting.

      Regards,
      Ben

      posted in Cinema 4D SDK
      B
      bentraje
    • Query Morph Order Based on the UI Order?

      Hi,

      By default when you perform morph.GetCount(), it returns a count based on the order they inserted.
      Is there a way to get the order based on the UI order?

      See illustration below:

      98988473-b3e7-46d3-a77a-8594be614c8a-image.png

      posted in Cinema 4D SDK 2024 python
      B
      bentraje
    • RE: Access Unfreeze All in the Object's Coordinate Tab?

      @ferdinand

      Gotcha. Thanks for the response.
      c4d.CallButton(op, c4d.ID_BASEOBJECT_FROZEN_RESET) works as expected.

      posted in Cinema 4D SDK
      B
      bentraje
    • Access Unfreeze All in the Object's Coordinate Tab?

      Hi,

      Is there a way to access the Unfreeze All Button in the Object's Coordinate Tab? Specifically, clicking it.
      Searching "Unfreeze All" in the documentation and the forum doesn't yield relevant (or direct results).

      b9a9dc1f-f737-4a60-94af-816097401cf8-image.png

      posted in Cinema 4D SDK 2023 windows python
      B
      bentraje
    • RE: GetCache Does Not Work Inside the Python Generator

      @ferdinand

      Thanks for the response. Your code works without the program freezing up (although I think it's GeGetCurrentThread instead of GetCurrentThread()). Other than that, it works as expected.

      Ah. I didn't think to just pass objects from different documents.

      I was thinking of something like this:

      1. All in the same document. Create a dummy object in the same document. In this way, the cache is already created because it now exist.
      2. Clone it. Store the data.
      3. Delete the dummy object in the same document.

      The problem was that in #3, the generator no longer has access to that object for some reason. So it keeps creating a dummy object lol

      Anyway, enough for my excuses. Sorry for the trouble and thanks again for your patience.

      posted in Cinema 4D SDK
      B
      bentraje
    • RE: GetCache Does Not Work Inside the Python Generator

      Hi @ferdinand

      I admit I'm on the slow side. It's a bit hard to comprehend on my level.

      Can I get a baseline answer (yes or no) on:

      The examples are for Python Script/Manager and not for Python Generator (which is what I am after).
      Is it doable in Python Generator?
      

      I can execute your script just find. It gives me caches etc. But when it comes to generator it does not.
      For example, as soon as I add BaseDocument.ExecutePasses the document freezes

      def PrintCacheTree():
         ...
      
      def GetCaches():
         ...
      
      def main():
          text = c4d.BaseObject(1019268)
          doc.InsertObject(text)
          doc.ExecutePasses(None, False, False, True, c4d.BUILDFLAGS_NONE) 
          GetCaches(text)
          return text
      
      posted in Cinema 4D SDK
      B
      bentraje
    • RE: GetCache Does Not Work Inside the Python Generator

      Hi @ferdinand

      I'm not sure I get it. The examples are for Python Script/Manager and not for Python Generator (which is what I am after).

      Anyhow, I'm guessing you are referring to GetCaches(node: c4d.BaseObject) from geometry_caches_s26.py

      If so I did try it in the Python Generator (not in the Python Script):

      def PrintCacheTree():
         ...
      
      def GetCaches():
         ...
      
      def main():
          text = c4d.BaseObject(1019268)
          GetCaches(text)
          return text
      

      The result still gives me none, of which I am unable to access the individual extrude parameters of each letters.

      Retrieving Caches:
      
      Text.GetCache() = None
      Text.GetDeformCache() = None
      
      Cache Tree of 'Text':
      
       Text(Text)
      
      Building Caches:
      
      Cache for newly allocated object: None
      Cache after executing the cache pass: <c4d.PolygonObject object called Cube/Polygon with ID 5100 at 2640357790656>
      
      
      posted in Cinema 4D SDK
      B
      bentraje
    • RE: GetCache Does Not Work Inside the Python Generator

      Hi @ferdinand

      Thanks for the respond.

      RE: Caches do not exist for freshly allocated objects
      Ah gotcha. Thanks for the confirmation.
      Based on your reply, I can do it through a python script (i.e. insert the object temporarily and just destroy it or something like that).

      But how do I go about it on Python Generator object? Is it possible?
      Ultimately, what I want is to have a procedural text object that allows me to modify the extrude parameter of each letter. Currently, the extrude parameter of a default text object applies to all letters.

      posted in Cinema 4D SDK
      B
      bentraje
    • GetCache Does Not Work Inside the Python Generator

      Hi,

      I have a Text object inside the Python Generator. I want to "bake" down (or equivalent to current state object commant) the text object so I can access it further but the GetCache seems to return none.

      # inside the python generator
      def main() -> c4d.BaseObject:
          text = c4d.BaseObject(1019268)
          text[c4d.PRIM_TEXT_TEXT] = "Generator"
      
          print (text.GetCache()) # returns None
          clone = text.GetClone()
          print (clone.GetCache()) # returns None
      
          # I also tried the `SendModellingCommand` but it gives me `False` instead of `True`
          base = c4d.utils.SendModelingCommand(c4d.MCOMMAND_CURRENTSTATETOOBJECT,[clone],c4d.MODELINGCOMMANDMODE_ALL,c4d.BaseContainer(),clone.GetDocument())
      
          print (clone) # returns False instead of True
      

      I'm guessting there is a prerequisite on the operation.
      What am I missing? 😢 😢 😢

      posted in Cinema 4D SDK r21 r25 python
      B
      bentraje
    • RE: Easier Way to Offset an Animation of an Object?

      @ferdinand

      yea python is much more forgiving than C++. i was just wondering if there was an already existing API for such task. 👍

      posted in Cinema 4D SDK
      B
      bentraje