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
    • Login
    1. Maxon Developers Forum
    2. esan
    • Profile
    • Following 0
    • Followers 0
    • Topics 4
    • Posts 15
    • Best 1
    • Controversial 0
    • Groups 0

    esan

    @esan

    exploring polygonal and polyphonal frequencies

    1
    Reputation
    24
    Profile views
    15
    Posts
    0
    Followers
    0
    Following
    Joined Last Online
    Location redmond washingtong Age 41

    esan Unfollow Follow

    Best posts made by esan

    • RE: Cant select newly created Instance

      @blastframe Ok was able to retrofit your version to get what I wanted, a bit of guesswork in here, but got the result im after lol

      import c4d
      from c4d import gui
      
      def createInstance():
          obj = op.GetDown()
          inst = c4d.BaseObject(c4d.Oinstance) # created Instance with Base Object
          inst[c4d.INSTANCEOBJECT_LINK] = obj # set Instance's reference link
          # set the name using the object passed to the function
          inst[c4d.ID_BASELIST_NAME] = "%s Instance"%obj[c4d.ID_BASELIST_NAME]
          return inst # return the Instance instance
      
      def AddLongDataType(obj): # create User Data Container named Picker
          if obj is None: return
      
          bc = c4d.GetCustomDataTypeDefault(c4d.DTYPE_LONG)
          bc[c4d.DESC_NAME] = "Picker"
      
          doc.AddUndo(c4d.UNDO_CHANGE, obj)
          obj.AddUserData(bc)
      
          c4d.EventAdd()
      
      def setQuickTab(obj, inst, data): # change User Date container to type Cycle, populate with Children Names
          descid = data[0][0]
          bc = data[0][1]
      
          children = obj.GetChildren()
      
          # Build new cycle options container dynamically
          cycle = c4d.BaseContainer()
      
          for i,child in enumerate(children):
            cycle.SetData(i, child.GetName())
      
          bc[c4d.DESC_CYCLE] = cycle
      
          doc.AddUndo(c4d.UNDO_CHANGE, obj)
          # Set modified description data container
          inst.SetUserDataContainer(descid, bc)
      
      def main(doc):
          obj = doc.GetActiveObject()
          if (obj == None):
              gui.MessageDialog("Please select the Root of the Assets you wish to Instance.")
              return
      
          doc.StartUndo()
          inst = createInstance()
          doc.InsertObject(inst)
          AddLongDataType(inst)
          data = inst.GetUserDataContainer()
          setQuickTab(obj, inst, data)
          
          doc.AddUndo(c4d.UNDO_NEW, inst)
          doc.EndUndo()
          c4d.EventAdd()
      
      if __name__=='__main__':
          main(doc)
      
      posted in Cinema 4D SDK
      esanE
      esan

    Latest posts made by esan

    • RE: Connect + Delete groups iteratively

      @m_magalhaes This is fantastic, it works and gives me a lot to dissect. I'll be further expanding on it to include Instance objects and cloners [have already had that working as theyre a simple "make editable"]. In my day to day i have to often share assets via FBX, and if my assets are built with instances/clonser/MoText [<-particularly messy], FBXs auto conversion of those assets create quite a messy hierarchy, roots on roots for days lol. This will help clean things up. Thanks!

      I think one issue i need to solve with this method is reapplying/maintaining the original objects applied Material.

      posted in Cinema 4D SDK
      esanE
      esan
    • Connect + Delete groups iteratively

      C4D R20

      I started the "SendModelCommand" path but trying to just get this stood up quickly with CallCommands first. The issue im having is obviously Connect + Delete happens on "All" selected objects, collapsing into one, when I want each to collapse into their own respective objects . My thoughts are to find all "MoText" under op root, store in an array and run the[ select > make editable >] select children of new hierarchy > connect+delete (deselect all?) stepping through the whole sequence per item. before moving onto the next item since connect+delete doesn't care about hierarchy, at least in CallCommand form anyway.

      I've made a couple of attempts at executing that logic, but am fairly new to writing python for C4D so haven't had success yet. Hoping i can be shown how to achieve my logic or be told/shown there's a much better way to go about it altogether.

      Thanks in advance!

      import c4d
      from c4d import gui
      from c4d import utils
      
      def selchildren(obj,next): # Scan obj hierarchy and select children
      
          while obj and obj != next:
      
              doc.AddUndo(c4d.UNDOTYPE_CHANGE_SMALL,obj)
      
              if obj.CheckType(1019268): #find MoText
                  obj.SetBit(c4d.BIT_ACTIVE)
      
              selchildren(obj.GetDown(),next)
      
              obj = obj.GetNext()
      
          c4d.EventAdd()
      
          return True
      
      
      
      def main():
      
      
          for obj in doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN):
              if selchildren(obj, obj.GetNext()):
                  obj.DelBit(c4d.BIT_ACTIVE)
                  c4d.CallCommand(12236) # Make Editable
                  c4d.CallCommand(16768, 16768) # Connect + Delte
                  
      
      # Execute main()
      if __name__=='__main__':
          main()
      
      posted in Cinema 4D SDK python r20
      esanE
      esan
    • RE: Xpresso Python Node . "Code" field

      @Cairyn

      Ah youre right, the Return was the cause of the errors, not the triple quotes. Got it all working now! (after taking a few tries to get the "indents" with the strings right)

      Thanks a ton!

      posted in Cinema 4D SDK
      esanE
      esan
    • RE: Xpresso Python Node . "Code" field

      @m_adam

      So final question. When i execute node[2][c4d.GV_PYTHON_CODE] = 'test string', all is well. When i try to exectute this as a function, i get errors. This setup gives me error " setitem expected str, not None"

      i wanted to do a multi-line string incapsulation but the triple quotes seem to be reserved for title/headers in this environment. How would i go about conveying that this function is a Str if making it a bucket of strings doesnt do it?

      def pythonNodeCode():
      
          'import c4d'
          
          'def main():'
      
          '    global Output2'
          '    global Input3'
       
          '    Output2 = c4d.BaseList2D.GetName(Input3)'
      
      def main():
      
          #skip a lot of other code
      
          node[2][c4d.GV_PYTHON_CODE] = pythonNodeCode()
      
      
      
      
      

      (i tried node[2][c4d.GV_PYTHON_CODE] = str(pythonNodeCode()) too just to make sure the obvious wasnt sitting in my face)

      edit: I achieved the intent with this, but still interested in the non-atrocious way to write it lol

       node[2][c4d.GV_PYTHON_CODE] = 'import c4d \n\ndef main():\n\n    global Output2\n    global Input3\n\n    Output2 = c4d.BaseList2D.GetName(Input3)'
      
      posted in Cinema 4D SDK
      esanE
      esan
    • RE: Xpresso Python Node . "Code" field

      @m_adam

      ahh, palm securely in face. Ya I had the GV_PYTHON_CODE but since I had spent so much time wrapping my head around this OperatorSetData in the node world prior I overcomplicated it from the start. Hadnt come across that console manual either, thanks a lot!

      posted in Cinema 4D SDK
      esanE
      esan
    • RE: Xpresso Python Node . "Code" field

      @Cairyn

      Sorry, i have a lot of permutations of this and the code snippet isn't from that exact node pictured, just grabbed examples at random since the point of the question was asking how to populate the Python Node Code field with my Python Script. Once that works then yes ill make all the proper ports/names to accommodate, that part i have figured out and got working, just inserting code into the field is what im missing. Thanks

      posted in Cinema 4D SDK
      esanE
      esan
    • Xpresso Python Node . "Code" field

      R20

      I need to add an "Object" port to an object node, but I guess since I have R20 with that particular python bug preventing it, I need to find a workaround. All I need to do is get the currently instanced objects name, fed back into the display name (and appending with another string in here). Ive seen that "UserData" workaround to get a makeshift Object port but that feels heavy handed for my case. Thought a python node with simple script can replace my Object node and Name port like so
      0bbef353-e55e-43bb-a3e9-991674a387d0-image.png

      And this works, but cant seem to figure out how to "set" this Python Code in this Node via my Python Script. Have made this snippet of code a function and was trying everything from OperatorSetData, and even the InsertObjects through In/Exclude method I was just shown for my Link List question. But nothing ive done yet seems to populate the field. Final Stretch! Thanks for all the help thus far, this script has already been an amazing learning experience.

      def main():
      
          global Output2
          global Input3
      
          Output2 = c4d.BaseList2D.GetName(Input3)
      
      posted in Cinema 4D SDK
      esanE
      esan
    • RE: OperatorSetData for "Lists"?

      @r_gigante Another quick question. is there still a bug on c4d.GV_OBJECT_OPERATOR_OBJECT_OUT? I dont get object ports on my nodes when trying to add this and I saw it was a long standing bug.

      ...just saw notes that the bug was fixed in R21. But I (and the people ill be distributing this script to) are all on R20, is there any patch or easy workaround to getting Object ports showing up? This is the last step needed to finish my script!

      thanks

      posted in Cinema 4D SDK
      esanE
      esan
    • RE: OperatorSetData for "Lists"?

      @r_gigante said in OperatorSetData for "Lists"?:

      inexdata.InsertObject(sphere, 1)

      Thanks so much for your reply, I started getting way off track trying other methods lol! I got it working with:

      inexdata = c4d.InExcludeData()
          
          for i, obj in enumerate(children):
              inexdata.InsertObject(children[i], 1)
              
          node[1][c4d.GV_LINK_LIST] = inexdata
      
      posted in Cinema 4D SDK
      esanE
      esan
    • OperatorSetData for "Lists"?

      Am i understanding this correctly? Im trying to populate an Xpresso Link List nodes (node[1])
      "Link List" field with the children of Tiles. Just a partial snippet of code here, i dont get any errors, the objects just dont populate.
      R20

      Ive tried many permutations, tried GeListNode as type, tried enumerating children, putting that in a list()...im guessing my "Children" arent an actual "List" type, and im blindly dancing around the right answer, just cant quite get it? Do i need to first make these children a "list" (and how would i go about that?), or do i need to "insert" into document at any point? Based on the documentation it sounds like OperatorSetData should take care of the insertion. Or maybe im assuming incorrectly that "simulates user dragging onto the node" means it can simulate dragging into attribute manager of the node? Just learning Python for C4D so just trying to wrap my head around it all. Thanks!

      Edit: Have given up on OperatorSetData and trying to follow some examples set by "Inserting" objects to IN/Exclude, though it has its own class to call on so working out those discrepancies, I tried a doc.InsertObject on a single child from the children list and console told me to "add them separately", so also trying to decipher that message since c4d.BaseObjects apparently don't like to be iterated, says console. Maybe a makeshift Python node acting as a Link List node is the way to go?

      obj = doc.SearchObject("Tiles")
          children = obj.GetChildren()
      
      node[1].OperatorSetData(c4d.GV_LINK_LIST, children ,c4d.GV_OP_DROP_IN_BODY)
      
      posted in Cinema 4D SDK python r20
      esanE
      esan