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

    Python Generator: Handles

    Cinema 4D SDK
    3
    5
    783
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • I
      inevestenko
      last edited by

      Hi all,
      Is it possible to create a simple square spline parametric with handles in a Python Generator or it's works only with plugins via DRAWPASS_HANDLES like at this example Py-DoubleCircle

      ferdinandF 1 Reply Last reply Reply Quote 0
      • CairynC
        Cairyn
        last edited by

        A Python generator creates a virtual hierarchy of objects. You can not select any of these objects, only the generator itself. Therefore, the hypothetical handles will never come to pass. In other words: no.
        You can feed the Python generator with User Data to control certain input values, or you can read e.g. the position of helper objects outside the generator to make the generator react to. But to my knowledge, no handles. For that you will need a full plugin.

        1 Reply Last reply Reply Quote 0
        • I
          inevestenko
          last edited by

          This is what I was afraid, thanks for the answer!

          1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand @inevestenko
            last edited by ferdinand

            Hello @inevestenko,

            thank you for reaching out to us. And thank your @Cairyn for providing an answer. @Cairyn's answer is correct in the sense that a Python Generator object does not provide a callback for the viewport hook, i.e., a draw() function with which one could draw handle information.

            It is however possible to use a Python Generator Object and Interaction Tag combination to mimic a handles interface like provided by plugins. There are however a few concessions to make, most importantly that one cannot draw into the DRAWPASS_HANDLES with an Interaction Tag. One could use just a plain Python Programming Tag instead, which can draw into any pass, but there one would have to implement the event loop oneself. At the end you can find an example file and code for how to implement a cube object where the size can be manipulated via the viewport.

            Cheers,
            Ferdinand

            The result:
            123.gif

            The example file:
            py_interaction_tag.c4d

            The Python Generator Object code:

            """Python Generator Object example for mimicking a handle interface with 
            Python Scripting objects.
            
            As discussed in:
                https://developers.maxon.net/forum/topic/13347
            """
            
            import c4d
            
            def main():
                size = op[c4d.ID_USERDATA, 1]
                cube = c4d.BaseObject(c4d.Ocube)
                cube[PRIM_CUBE_LEN] = c4d.Vector(size)
                return cube
            

            The Python Interaction Tag code:

            """Python Interaction Tag example for mimicking a handle interface with 
            Python Scripting objects.
            
            As discussed in:
                https://developers.maxon.net/forum/topic/13347
            """
            
            import c4d
            from c4d import gui
            
            def mouseDown():
                """Executed when the user clicks into the object.
                """
                # We just cache the size of our cube at the moment, global attributes are
                # evil, this should be done more formally in a production environment, one
                # could for example use a userdata parameter to store this value or just
                # store it in the BaseContainer of a node.
                global startSize
                startSize = op[c4d.ID_USERDATA, 1]
            
            def mouseDrag():
                """Executed while dragging.
                """
                # Here we are going to be extra lazy and just use the tags delta parameter
                # to compute the drag distance, this could also be done more formally,
                # yielding better results.
                global startSize
                delta = tag[c4d.INTERACTIONTAG_WORLD_DELTA]
                op[c4d.ID_USERDATA, 1] = startSize + delta.GetLength()
            
            def draw(bd):
                """
                """
                # Bail when op is None, i.e., the tag is not attached to an object. 
                # Technically, we would also like to test here something like
                # 
                #   bd.GetDrawPass() != c4d.DRAWPASS_HANDLES:
                #       ...
                #       
                # But this draw() is only being called for DRAWPASS_OBJECT, so we
                # cannot draw into the "proper" handles pass.
                if op is None:
                    return
            
                # Setup the drawing matrix in the space of the object.
                bd.SetMatrix_Matrix(op, op.GetMg())
            
                # We are going to draw the size handle as a gizmo on the z-axis.
                # We have to halve the value because the cube object size is effectively
                # used as a radius and we nudge it a little, so that it is not "colliding"
                # with the polygons of the object due to us being in the object draw pass.
                size = op[c4d.ID_USERDATA, 1] * .5 + 1
                bd.SetPen(c4d.Vector(1, 1, 0))
                p = c4d.Vector(0, 0, size)
            
                bd.DrawHandle(p, c4d.DRAWHANDLE_BIG, 0)
            

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • ferdinandF
              ferdinand
              last edited by

              Hello @inevestenko,

              without any further questions, we will consider this topic as solved by Monday and flag it accordingly.

              Thank you for your understanding,
              Ferdinand

              MAXON SDK Specialist
              developers.maxon.net

              1 Reply Last reply Reply Quote 0
              • First post
                Last post