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

    Connecting Camera Focus Distance to Null Object with Python

    Cinema 4D SDK
    python r21
    3
    6
    913
    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.
    • C
      curripod00
      last edited by r_gigante

      Hi there. I wonder if anyone would be able to help a not-very-savvy coder figure out a tiny bit of Python code. For this code, I’m trying to import and position a camera into my scene. I then want to connect the 'focus distance' field of the camera to a null object which I have also imported into the scene. I thought it would be as easy as adding some variation of "camera[c4d.CAMERAOBJECT_TARGETOBJECT] = null" into my code, but no amount of tweaking seems to work for this. I feel like I'm missing a step. If anyone knows the answer please let me know. My code can be viewed below.

      import c4d
      from c4d import gui
      # Lighting Stage
      
      def main():
          def tool():
              return c4d.plugins.FindPlugin(doc.GetAction(), c4d.PLUGINTYPE_TOOL)
          def object():
              return doc.GetActiveObject()
          def tag():
              return doc.GetActiveTag()
          def renderdata():
              return doc.GetActiveRenderData()
          def prefs(id):
              return c4d.plugins.FindPlugin(id, c4d.PLUGINTYPE_PREFS)
      
          c4d.CallCommand(5140) # Create Camera Targeting Null
          object()[c4d.NULLOBJECT_DISPLAY] = 13
          object()[c4d.NULLOBJECT_RADIUS] = 80
          object()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] = 276
          object()[c4d.ID_BASELIST_NAME] = "Camera_Target"
      
          c4d.CallCommand(5103) # Create Camera with Redshift Tag
          object()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X] = 0
          object()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Y] = -0.175
          object()[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Z] = 0
          object()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_X] = 0
          object()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] = 433
          object()[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Z] = -884
          c4d.CallCommand(100004788, 50075) # New Tag
          tag()[c4d.REDSHIFT_POSTEFFECTS_DOF_OVERRIDE] = True
          tag()[c4d.REDSHIFT_POSTEFFECTS_DOF_ENABLED] = True
          tag()[c4d.REDSHIFT_POSTEFFECTS_DOF_RADIUS] = 8.5
      
          camera[c4d.CAMERAOBJECT_TARGETOBJECT] = null
      
      if __name__=='__main__':
          main()
          c4d.EventAdd()
      

      python.png

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

        Hi,

        the problem with your code is that you neither defined the symbol camera nor the symbol null which you used in your code. Script log code is also usually not a very good staring point (I assume this was derived from a script log) . I wrote a little piece of narrative code which roughly does what you want and which you might find helpful.

        """Run this in the script manager with an object in your scene, called
        "my_taregt".
        """
        import c4d
        
        
        def main():
            """
            """
            # "doc" is a predefined variable in Script Manager scripts, which
            # points to the currently active document. "BaseDocument.SearchObject"
            # is looking for the first object with the given name in the document.
            # There are better ways to select objects, but this is an easy one and
            # might be sufficient for your case. If you have an object named
            # "my_target" in your scene, the variable "target" will point to it.
            target = doc.SearchObject("my_target")
            # "target" will be "None" if we did not find it, this will just signal
            # that.
            if not target:
                raise IOError("Could not find target object.")
        
            # We can instantiate an object, a tag, a material or a shader with the
            # type BaseList2D. You have to pass in the ID of the node you want to
            # build. Here we are passing "c4d.Ocamera" to build a camera. Ocamera
            # is just an alias for the integer 5103, which you also used in your
            # CallCommand.
            # But unlike CallCommand constructing an object with the type BaseList2D
            # will give us a symbol under which we can access our object ("camera"
            # here).
            camera = c4d.BaseList2D(c4d.Ocamera)
            # Setting the target is just as easy as you thought, the problem in
            # your code was that you never defined something as "camera".
            camera[c4d.CAMERAOBJECT_TARGETOBJECT] = target
            # Setting the relative position and rotation could be shortened a bit,
            # but your way was totally fine.
            position = c4d.Vector(0, 433, -800)
            rotation = c4d.Vector(0, -0.175, 0)
            camera[c4d.ID_BASEOBJECT_REL_POSITION] = position
            camera[c4d.ID_BASEOBJECT_REL_ROTATION] = rotation
            # There are also two methods of the type BaseObject (our camera is such
            # an BaseObject) which do the same as the attribute access.
            camera.SetRelPos(position)
            camera.SetRelRot(rotation)
            # Since I do not own RedShift, I will just create an target expression
            # on the camera instead. This should look a bit familiar by now.
            tag = c4d.BaseList2D(c4d.Ttargetexpression)
            tag[c4d.TARGETEXPRESSIONTAG_LINK] = target
            # Now we just need to attach our tag to our camera ...
            camera.InsertTag(tag)
            # ... and insert that object into the active document.
            doc.InsertObject(camera)
            # Finally we need to tell Cinema, that we modified something.
            c4d.EventAdd()
        
        
        if __name__ == "__main__":
            main()
        
        

        Cheers,
        zipit

        MAXON SDK Specialist
        developers.maxon.net

        CairynC C 2 Replies Last reply Reply Quote 1
        • CairynC
          Cairyn
          last edited by

          @curripod00 said in Connecting Camera Focus Distance to Null Object with Python:

          camera[c4d.CAMERAOBJECT_TARGETOBJECT] = null

          This line cannot work because "null" is an undefined variable name (and "camera" actually too). It references nothing.
          Instead, you will need to find the actual target null by searching:

          camera = doc.SearchObject("Camera")
          camera[c4d.CAMERAOBJECT_TARGETOBJECT] = doc.SearchObject("Camera_Target")
          

          (I did not test that, just slapped together from memory.)

          This is still not very good code because it assumes that the new camera's name is "Camera" which is not very original and may be duplicate in the scene already. Feel free to call the camera something else by setting the name when you generate the object.

          Or instead of searching, you store the objects after generation in a variable. Following code should do it (I didn't test, as I don't have Redshift):

          import c4d
          from c4d import gui
          
          def main():
              def object():
                  return doc.GetActiveObject()
              def tag():
                  return doc.GetActiveTag()
          
              c4d.CallCommand(5140) # Create Camera Targeting Null
              cameraTarget = object()
              cameraTarget[c4d.NULLOBJECT_DISPLAY] = 13
              cameraTarget[c4d.NULLOBJECT_RADIUS] = 80
              cameraTarget[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] = 276
              cameraTarget[c4d.ID_BASELIST_NAME] = "Camera_Target"
          
              c4d.CallCommand(5103) # Create Camera with Redshift Tag
              camera = object()
              camera[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X] = 0
              camera[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Y] = -0.175
              camera[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Z] = 0
              camera[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_X] = 0
              camera[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Y] = 433
              camera[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Z] = -884
              c4d.CallCommand(100004788, 50075) # New Tag
              cameratag = tag()
              cameratag[c4d.REDSHIFT_POSTEFFECTS_DOF_OVERRIDE] = True
              cameratag[c4d.REDSHIFT_POSTEFFECTS_DOF_ENABLED] = True
              cameratag[c4d.REDSHIFT_POSTEFFECTS_DOF_RADIUS] = 8.5
          
              camera[c4d.CAMERAOBJECT_TARGETOBJECT] = cameraTarget
          
          if __name__=='__main__':
              main()
              c4d.EventAdd()
          

          Learn more about Python for C4D scripting:
          https://www.patreon.com/cairyn

          C 1 Reply Last reply Reply Quote 1
          • CairynC
            Cairyn @ferdinand
            last edited by

            @zipit okaaaay I get it: you NEVER EVER sleep! 😀

            1 Reply Last reply Reply Quote 0
            • C
              curripod00 @ferdinand
              last edited by

              @zipit This is fantastic, thank you for going through and explaining why my code was lacking, I have a better understanding of this process now and my camera focus works perfectly using your method. 👍 👏

              1 Reply Last reply Reply Quote 0
              • C
                curripod00 @Cairyn
                last edited by

                @Cairyn Thanks for this fantastic resource, I will definitely use this summer to level up with Python. 👍

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