Python | Getting render cam to match object data

On 06/04/2013 at 21:16, xxxxxxxx wrote:

I have an ObjectData plugin that returns as an Ocamera.  The first challenge is that it looks great in the viewport but doesn't render out with any relation to what my cam is doing.  Lennart figured out to grab the active base draw to get that camera link and then copy the container from my cam to the mysterious render cam so the scene renders to match my cam.

HOWEVER:  My focal length and Sensor Size parameters error on the Basedraw camera when I give them a float, even though I give a float to my ObjectData camera.  It says it wants int or bool.  So if I wrap my float inside in int(), it doesn't error but any zooming is super wonkey from the conversion.

SO, is this a bug or am I not doing something correctly?

I made a stripped down plug-in which is attached.  I would love if anyone could figure out the mystery of why I cannot get the basedraw camera (presumably the render camera) to correctly match my object.

Add the plug-in to a scene, and look through the camera and hit play.  See how the edges of the frame are very glitchy.  Look at the code and remove the int() and it will fail only on the basedraw cam, but not on the regular cam.  Remove the basedraw cam altogether, then the view doesn't follow my cam.

Any thoughts?


On 07/04/2013 at 01:46, xxxxxxxx wrote:

def GetVirtualObjects(self, op, hh) :
        doc = op.GetDocument()
        t = doc.GetTime().Get()
        cam = c4d.BaseObject(c4d.Ocamera)
        cam[c4d.CAMERA_FOCUS] = float(t * 10.0 + 10.0)				
        cam[c4d.CAMERA_PROJECTION] = 0					
        cam[c4d.CAMERAOBJECT_APERTURE] = 36
        bdcam = doc.GetActiveBaseDraw()[c4d.BASEDRAW_DATA_CAMERA]
        if bdcam == op:
            bdcam[c4d.CAMERA_FOCUS] = cam[c4d.CAMERA_FOCUS]			
            bdcam[c4d.CAMERA_PROJECTION] = cam[c4d.CAMERA_PROJECTION]
        return cam

although i do not really see any sense in hacking into the viewport cam, because if it
is the active cam bdcam will be the same as cam.

On 07/04/2013 at 09:58, xxxxxxxx wrote:

Originally posted by xxxxxxxx

although i do not really see any sense in hacking into the viewport cam, because if it
is the active cam bdcam will be the same as cam.

As I stated in my post above, if you don't do this then the render out will not match the ObjectData cam.  It makes no sense to me either, but that's the case.  If I Don't copy the parameters to the viewport cam, then the viewport zoom and aperture (sensor size) will remain static and the render out of cinema will also remain static.  No motion what-so-ever.

If you have any ideas how to get around this, I'm absolutely open to it.

Try it.  Comment out the bdcam part and look through the cam and hit play.  The cams become independent.  Add an object in the shot and do a full render.  It won't zoom at all.  Add some quick code to the position or rotation of the cam and it won't show in render unless you copy all the params to the bdcam.

On 07/04/2013 at 10:26, xxxxxxxx wrote:

I tried your code.  it seems wrapping my CAMERA_FOCUS value in a float and reloading the plugin seems to do the trick which I'm grateful for.  But this whole thing seems so wonky to me.  Like you said, you would think they are the same cam.  But if I don't do this process, then the viewport and the render won't "sync" up.  So weird.

On 07/04/2013 at 10:41, xxxxxxxx wrote:

Aargh.  It works in this but test plugin.  But back in my main plugin, it fails the same with needing an int or bool.

I wrapped my data in float() and used the notation of bdcam[PARAM] = cam[PARAM].  Could care less.  Just same error about needing an int.  Frustrating.

On 07/04/2013 at 22:47, xxxxxxxx wrote:

use the bc reference if something with __setitem__ goes wrong.

    def GetVirtualObjects(self, op, hh) :
        doc = op.GetDocument()
        t = doc.GetTime().Get()
        zoom = float(t * 10.0 + 10.0)
        #Create Camera object
        cam = c4d.BaseObject(c4d.Ocamera)
        cam[c4d.CAMERA_FOCUS] = zoom				
        cam[c4d.CAMERA_PROJECTION] = 0					
        cam[c4d.CAMERAOBJECT_APERTURE] = 36.0
        cam[c4d.CAMERAOBJECT_TARGETDISTANCE] = 200.0
        bdcam = doc.GetActiveBaseDraw()[c4d.BASEDRAW_DATA_CAMERA]
        if bdcam == op:
            bc = bdcam.GetDataInstance()
            bc.SetReal(c4d.CAMERA_FOCUS, zoom)
            bc.SetLong(c4d.CAMERA_PROJECTION, 0)
            bc.SetReal(c4d.CAMERAOBJECT_APERTURE, 36.0)
            bc.SetReal(c4d.CAMERAOBJECT_TARGETDISTANCE, 200.0)
        return cam

On 07/04/2013 at 23:23, xxxxxxxx wrote:

Thanks for that, it solved the int error but it just does the int conversion itself it seems.  It still does the very jerky framelines when looking through the cam.  Which is why I hunted down this problem in the first place.  Lennart's suggestion was just to do GetData from the cam and SetData to the bdcam, which has the same result as doing this code: no errors, but its doing some kind of glitch or float to int conversion that makes the framelines "jiggle".

I'm at a loss :(  Thanks for your help though.

On 08/04/2013 at 00:04, xxxxxxxx wrote:

bd[c4d.BASEDRAW_DATA_CAMERA] holds your plugin object and not a camera object.

at least when you made it the active camera with view/active_object_as_camera. if 
you try to do it properly by setting the active viewport/ render camera manually c4d 
unsurprisingly crashes horribly.