Page 1 of 2 12 LastLast
Results 1 to 20 of 25
  1. #1

    [Scripts]Create camera image plane

    Hi!

    Working on a scifi live action movie (lots of greenscreen footage), so I've created some scripts for things we are doing frequently.

    The other script should be run with a camera selected and then creates an imageplane, sets up drivers to automatically scale it by the render aspect ratio and focal length of camera and distance (that would be the neg z of the imageplanes location) so it will cover the entire screen. It sets up a cycles material so it's ready to load an image sequence (I'm using lowres pngs where the green screen has been keyed out in my workflow).

    Limitation: no testing that the selected object is a camera (script will fail if it's not)


    EDIT: Now available as an addon in post 3!

    Code:
    import bpy
    from bpy_extras.image_utils import load_image
    from mathutils import Vector, Euler
    import math
    
    
    def SetupDriverVariables(driver, imageplane):
        camAngle = driver.variables.new()
        camAngle.name = 'camAngle'
        camAngle.type = 'SINGLE_PROP'
        camAngle.targets[0].id = imageplane.parent
        camAngle.targets[0].data_path="data.angle"
        
        depth = driver.variables.new()
        depth.name = 'depth'
        depth.type = 'TRANSFORMS'
        depth.targets[0].id = imageplane    
        depth.targets[0].data_path = 'location'
        depth.targets[0].transform_type = 'LOC_Z'
        depth.targets[0].transform_space = 'LOCAL_SPACE'
    
    #unfortunately not possible to add driver on scene object    
    #    resolution_x = driver.variables.new()
    #    resolution_x.name = 'resolution_x'
    #    resolution_x.type = 'SINGLE_PROP'
    #    resolution_x.targets[0].id =bpy.context.scene
    #    resolution_x.targets[0].data_path = 'render.resolution_x'
    #    resolution_y = driver.variables.new()
    #    resolution_y.name = 'resolution_y'
    #    resolution_y.type = 'SINGLE_PROP'
    #    resolution_y.targets[0].id =bpy.context.scene
    #    resolution_y.targets[0].data_path = 'render.resolution_y'
    #    pixel_x = driver.variables.new()
    #    pixel_x.name = 'pixel_x'
    #    pixel_x.type = 'SINGLE_PROP'
    #    pixel_x.targets[0].id =bpy.context.scene
    #    pixel_x.targets[0].data_path = 'render.pixel_aspect_x'
    #    pixel_y = driver.variables.new()
    #    pixel_y.name = 'pixel_y'
    #    pixel_y.type = 'SINGLE_PROP'
    #    pixel_y.targets[0].id =bpy.context.scene
    #    pixel_y.targets[0].data_path = 'render.pixel_aspect_y'
                
    
    def SetupDriversForImagePlane(imageplane):
        driver = imageplane.driver_add('scale',1).driver
        driver.type = 'SCRIPTED'
        SetupDriverVariables( driver, imageplane)
        #driver.expression ="-depth*math.tan(camAngle/2)*resolution_y*pixel_y/(resolution_x*pixel_x)"
        driver.expression ="-depth*tan(camAngle/2)*bpy.context.scene.render.resolution_y * bpy.context.scene.render.pixel_aspect_y/(bpy.context.scene.render.resolution_x * bpy.context.scene.render.pixel_aspect_x)"
        driver = imageplane.driver_add('scale',0).driver
        driver.type= 'SCRIPTED'
        SetupDriverVariables( driver, imageplane)
        driver.expression ="-depth*tan(camAngle/2)"
    
    # get selected camera (might traverse children of selected object until a camera is found?)
    # for now just pick the active object
    def createImagePlaneForCamera(camera):
        imageplane = None
        try:
            depth = 10
            
            
            #create imageplane
            bpy.ops.mesh.primitive_plane_add()#radius = 0.5)
            imageplane = bpy.context.active_object
            imageplane.name = "imageplane"
            bpy.ops.object.parent_set(type='OBJECT', keep_transform=False)
            bpy.ops.object.editmode_toggle()
            bpy.ops.mesh.select_all(action='TOGGLE')
            bpy.ops.transform.resize( value=(0.5,0.5,0.5))
            bpy.ops.uv.smart_project(angle_limit=66,island_margin=0, user_area_weight=0)
            bpy.ops.uv.select_all(action='TOGGLE')
            bpy.ops.transform.rotate(value=1.5708, axis=(0,0,1) )
            bpy.ops.object.editmode_toggle()
        
            
            imageplane.location = (0,0,-depth)
            imageplane.parent = camera
            
            
            #calculate scale
            #REPLACED WITH CREATING EXPRESSIONS
            SetupDriversForImagePlane(imageplane)
    
            #setup material
            if( len( imageplane.material_slots) == 0 ):
                bpy.ops.object.material_slot_add()
                #imageplane.material_slots.
            bpy.ops.material.new()
            mat_index = len(bpy.data.materials)-1
            imageplane.material_slots[0].material = bpy.data.materials[mat_index]
            material =  imageplane.material_slots[0].material
            # if not returned by new use imgeplane.material_slots[0].material
            material.name = 'mat_imageplane_'+camera.name
            material.use_nodes = True
            nodes = material.node_tree.nodes
            links = material.node_tree.links
            
            nodes.clear()
            emissive = nodes.new('ShaderNodeEmission')
            emissive.location = 0, 0
            transparent = nodes.new('ShaderNodeBsdfTransparent')
            transparent.location = 0,100
            mix = nodes.new('ShaderNodeMixShader')
            mix.location = 400,0
            links.new( emissive.outputs[0], mix.inputs[2] )
            links.new( transparent.outputs[0], mix.inputs[1] )
            outnode = nodes.new('ShaderNodeOutputMaterial')
            outnode.location = 800,0
            links.new( mix.outputs[0], outnode.inputs[0] )
            texture = nodes.new('ShaderNodeTexImage')
            texture.location = -400,0
            links.new( texture.outputs[0], emissive.inputs[0] )    
            links.new( texture.outputs[1], mix.inputs[0] )
            #texture.image = bpy.ops.image.open(filepath="c:\\nova\\keyed\\1\\1_5_1\\1_5_1.00000.png")
    
        
        except Exception as e:
            imageplane.select=False
            camera.select = True
            raise e    
        return {'FINISHED'}
    
    
    
    # main
    print("========================")
    print("   SCRIPT STARTING")
    print("========================")
    
    camera = bpy.context.active_object #bpy.data.objects['Camera']
    createImagePlaneForCamera(camera)
    By the way, is there some way to get the texture correctly (with alpha that is) shown in the viewport when selecting 'material' or 'textured' (if so, I haven't found it, I'm using rendered preview to test placement relative to my backgrounds)? Is there a script available to save an animation from the viewport when it's played (so I can use the textured mode instead of opengl rendering - difference in speed is large)?

    Best wishes and happy blending!
    /Torbjörn
    Last edited by tobbew; 06-Feb-14 at 16:31. Reason: addon created



  2. #2
    Member 3pointEdit's Avatar
    Join Date
    Sep 2005
    Location
    Brisbane, Australia
    Posts
    8,613
    Just found this, it looks really cool. I have been wondering how to create an active layout for the compositor, I guess this script would be helpful when trying to line up the footage.
    Cheers, David ___________"awesome in space and other places".
    ________Follow me on twitter @3pointedit
    _____________ Check the Youtube Channel for tutorials. Or my Sketchbook



  3. #3
    Hi tobbew,
    I'm interested in your script, but some screenshots or a video would be helpful to fully understand how it works. Thank you.



  4. #4
    Noticing there was an interest for the script I turned it into an addon and attached it.

    Install as any other addon, select your camera, tap space and select 'Create camera image plane' from the list of operators.
    Attached Files Attached Files



  5. #5
    Member 3pointEdit's Avatar
    Join Date
    Sep 2005
    Location
    Brisbane, Australia
    Posts
    8,613
    Oh wow, thanks. I really like it when people go to the trouble of making their script a proper addon. It makes it easier to promote Blender's cool dev community.
    Cheers, David ___________"awesome in space and other places".
    ________Follow me on twitter @3pointedit
    _____________ Check the Youtube Channel for tutorials. Or my Sketchbook



  6. #6
    @3pointEdit: You're welcome.
    @chloesdad: The script does not do anything magical, it creates a plane and setups some drivers so when the distance from the camera (-z) is changed the plane is automatically scaled to cover the screen and gives it a cycles material so i'll just have to load the texture. It's not complicated to do by hand, but I created a script since it's something I'd otherwise have to do a repeatedly. Of course a possibility might have been to just create it once and keep it in a blend file and then import the camera together with the plane. That would probably have worked as well, but I needed to learn some python to be able to make other repeated tasks faster in the future.



  7. #7
    Thanks Tobbew for your explanation.



  8. #8
    tobbew, when i load this script then warning message is shown - auto-run disabled: driver '-depth*tan(camAngle/2)'
    After that the image plane is in outliner but in the view there's no image plane - even after loading image sequence or single image to the shader.

    I think the problem is in object scale drivers script. I deleted object scale X and Y drivers and then i can manipulate scale of the image plane and after that image plane with texture is shown, but after thant when i move image plane there's no scaling to fit camera view and i need to do this all the time by hand.

    Mayby i do something wrong so can you create short video how to do this correctly?
    Last edited by Tomasz87; 22-Mar-14 at 23:08.



  9. #9
    Member 3pointEdit's Avatar
    Join Date
    Sep 2005
    Location
    Brisbane, Australia
    Posts
    8,613
    For drivers and some scripts you must goto user prefs > file > "auto run python scripts" and turn on that preference. It is off by default.
    Last edited by 3pointEdit; 23-Mar-14 at 22:03.
    Cheers, David ___________"awesome in space and other places".
    ________Follow me on twitter @3pointedit
    _____________ Check the Youtube Channel for tutorials. Or my Sketchbook



  10. #10
    Member 3pointEdit's Avatar
    Join Date
    Sep 2005
    Location
    Brisbane, Australia
    Posts
    8,613
    So I have been playing with the script. I wonder how you determine the distance to place the plane from camera? How does the script achieve placement along the z axis?

    Question-
    If I move the plane how would I return it to the initial location relative to the camera?

    I guess I can add a constraint after running the script, but would this conflict with whatever you are doing? I cannot see a driver or constraint that performs the rotation lock?
    EDIT:
    After running the script I added:
    1. Limit location set to -10 Z units min/max (I read that was the figure the script assigned)
    2. Limit rotation on all axis

    Then I free the plane by reducing the 'influence' to zero on both constraints. To restore the registered initial location you increase the 'influence' again.

    EDIT2:
    I can't work out how to reduce the influence of the Scale Driver in the script though? It would be nice if I could key frame this too?

    EDIT3:
    Ok so I just mute the drivers.
    Last edited by 3pointEdit; 23-Mar-14 at 22:28.
    Cheers, David ___________"awesome in space and other places".
    ________Follow me on twitter @3pointedit
    _____________ Check the Youtube Channel for tutorials. Or my Sketchbook



  11. #11
    Originally Posted by 3pointEdit View Post
    For drivers and some scripts you must goto user prefs > file > "auto run python scripts" and turn on that preference. It is off by default.
    Thanks! Now everything works!



  12. #12
    @3pointedit:
    I don't understand your question, to be honest. What are your trying to accomplish?

    The scripts sets up drivers with the goal to have it always cover the entire screen no matter what the distance from the camera is. In my own workflow it is not supposed to be moved except for depth (-z if I remember correctly, currently not on my own computer). The idea is to move the camera.

    I use it when I have lot's of angles of green screen footage and a 3d rendered environment.
    My workflow (not the only possible one, you may use it however you wish):
    1) film footage and prepare lowpoly background
    2) camera match the footage.
    3) key away the green screen and output a lowres proxy of the keyed footage as a png serie
    4) run the script on the camera, set up the Proxy footage for the material
    5) place the camera and adjust the depth to the camera image plane (since the plane is parented to the camera it will follow and meanwhile I can use the cycles viewport rendering to see through the green screen and see how the placing will be and scrub through the animation)
    6) model details and fix textures on parts visible in the camera angles or for objets outside whose shadows or reflections will affect the scene (if we had done a proper previs we'd already know, but we didn't)
    7 ) render final footage without the camera image plane and do proper post compositing

    The script does not do any placement along z except for a default which bears no specific meaning, but is supposed to be changed to what's appropriate for your scene. I'm working on (how originally around here :-) ) a hobby scifi short with all green screen environments.

    Originally Posted by 3pointEdit View Post
    So I have been playing with the script. I wonder how you determine the distance to place the plane from camera? How does the script achieve placement along the z axis?

    Question-
    If I move the plane how would I return it to the initial location relative to the camera?

    I guess I can add a constraint after running the script, but would this conflict with whatever you are doing? I cannot see a driver or constraint that performs the rotation lock?
    EDIT:
    After running the script I added:
    1. Limit location set to -10 Z units min/max (I read that was the figure the script assigned)
    2. Limit rotation on all axis

    Then I free the plane by reducing the 'influence' to zero on both constraints. To restore the registered initial location you increase the 'influence' again.

    EDIT2:
    I can't work out how to reduce the influence of the Scale Driver in the script though? It would be nice if I could key frame this too?

    EDIT3:
    Ok so I just mute the drivers.
    Last edited by tobbew; 25-Mar-14 at 05:54.



  13. #13
    Member 3pointEdit's Avatar
    Join Date
    Sep 2005
    Location
    Brisbane, Australia
    Posts
    8,613
    Oh I see. I wonder where I can look to see parenting? Anyway I like to use it for motion graphics, where I want the image, video or art work to be registered perfectly to the camera as a default position. Then I need the flexibility to animate away from that position and return to it. It's really cool that the scale driver makes the flat field behave as an ortho camera view, but I can still have 3d accurate perspective.

    any chance you could grab a screens to demonstrate your layout?
    Cheers, David ___________"awesome in space and other places".
    ________Follow me on twitter @3pointedit
    _____________ Check the Youtube Channel for tutorials. Or my Sketchbook



  14. #14
    Member cegaton's Avatar
    Join Date
    Jun 2013
    Location
    Los Angeles, CA
    Posts
    317
    tobbew,
    thanks for the script!



  15. #15
    Originally Posted by 3pointEdit View Post
    Oh I see. I wonder where I can look to see parenting? Anyway I like to use it for motion graphics, where I want the image, video or art work to be registered perfectly to the camera as a default position. Then I need the flexibility to animate away from that position and return to it. It's really cool that the scale driver makes the flat field behave as an ortho camera view, but I can still have 3d accurate perspective.

    any chance you could grab a screens to demonstrate your layout?
    you can see the parenting in the outliner (the image plane). I think you can see it also in the object properties. If you want to turn it on anf off you might want to use a parent constraint instead so you can animate its weight. Then you might also add an empty to the scene and also add a parent constrain with an inverted weight from the one from the camera so uou can animate the position with the empty and by animating the weight. You might want to change the scale equations to mix between the scale of the empty and the current formula based on the weight of the constrain



  16. #16
    Member 3pointEdit's Avatar
    Join Date
    Sep 2005
    Location
    Brisbane, Australia
    Posts
    8,613
    Hmmm, good ideas. Thanks for the tips.
    Cheers, David ___________"awesome in space and other places".
    ________Follow me on twitter @3pointedit
    _____________ Check the Youtube Channel for tutorials. Or my Sketchbook



  17. #17
    Originally Posted by 3pointEdit View Post
    Hmmm, good ideas. Thanks for the tips.
    having sevond thoughts just combining current method with a copy transforms, rotations and scale constraints from the empty could do it and might be both easier to setup and use. Haven't tried though.



  18. #18
    Member 3pointEdit's Avatar
    Join Date
    Sep 2005
    Location
    Brisbane, Australia
    Posts
    8,613
    OMG!! That is so clean and easy. Thank you!!
    EDIT
    It's worth saying again...Thankyou
    Cheers, David ___________"awesome in space and other places".
    ________Follow me on twitter @3pointedit
    _____________ Check the Youtube Channel for tutorials. Or my Sketchbook



  19. #19
    First of all, thank you very much for this script!
    It uses a function that I need!

    ( http://blenderartists.org/forum/show...to-camera-view )

    Originally Posted by tobbew View Post
    It's not complicated to do by hand,
    I'm not familiar with Python so I can't read what the code does, but how do you do this by hand?
    I mean, how would you scale a plane so that it fits exactly the camera?
    Or maybe you even know how to 'snap' a plane to the camera's "front plane" then?



  20. #20
    Hello tobbew, nice script.
    I found one 'gotcha'. If your preferences are set to add objects aligned to 'view', it will create a plane at an odd angle.
    If the preference is set to add object to 'world' it works.
    Outside of that, cool script.



Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •