0
$\begingroup$

This is an extension question of the following question I asked earlier here. In this case, I have a cube and a camera. I want to extract whatever cube's portion falls inside the camera view. The python script provided below can give the expected output as shown in the image below.

enter image description here

However, the main issue is - there are some cut-out portions into the output object. It is happening as the whole cube does not fall inside the camera view and the excluded portion is clipped from the cube, thus, leaving open sides to the newly created object. Is there any way of closing the cut-out portion with a face without manually selecting vertices and pressing F? Can it be done editing any portion of the following scripts I am using?

import bpy
import bmesh

def camera_as_planes(scene, obj):
    """
    Return planes in world-space which represent the camera view bounds.
    """
    from mathutils.geometry import normal

    camera = obj.data
    # normalize to ignore camera scale
    matrix = obj.matrix_world.normalized()
    frame = [matrix @ v for v in camera.view_frame(scene=scene)]
    origin = matrix.to_translation()

    planes = []
    from mathutils import Vector
    is_persp = (camera.type != 'ORTHO')
    for i in range(4):
        # find the 3rd point to define the planes direction
        if is_persp:
            frame_other = origin
        else:
            frame_other = frame[i] + matrix.col[2].xyz

        n = normal(frame_other, frame[i - 1], frame[i])
        d = -n.dot(frame_other)
        planes.append((n, frame_other, d))

    if not is_persp:
        # add a 5th plane to ignore objects behind the view
        n = normal(frame[0], frame[1], frame[2])
        d = -n.dot(origin)
        planes.append((n, frame[0], d))

    return planes


context = bpy.context
scene = context.scene
dg = context.evaluated_depsgraph_get()
ob = context.object
camera = scene.camera
cloc = camera.matrix_world.translation

bm = bmesh.new()
bm.from_object(ob, dg)

bm.transform(ob.matrix_world)
for n, cf, _ in camera_as_planes(scene, scene.camera):
    bmesh.ops.bisect_plane(
            bm,
            geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
            plane_no=-n,
            plane_co=cf,
            clear_outer=True,
            )

# create a new object
ob = bpy.data.objects.new("Test", bpy.data.meshes.new("Test"))
bm.to_mesh(ob.data)
context.collection.objects.link(ob)

$\endgroup$
5
  • $\begingroup$ Adjust the camera clip distance. $\endgroup$
    – susu
    Aug 31 '20 at 19:47
  • $\begingroup$ If you mean moving the camera back or increasing the FOV then it is not an option as I have to have the clipped portion. If I move back the camera, it will cover the entire cube but it will be no use for the task I am planning to do. $\endgroup$
    – Sourav
    Aug 31 '20 at 19:50
  • $\begingroup$ No, clip distance determines up to what distance the camera will "see" things. There is a Clip start and a clip end distance. Seems to me that the strart clip distance's value needs to be smaller. $\endgroup$
    – susu
    Aug 31 '20 at 19:59
  • $\begingroup$ blender.stackexchange.com/questions/8553/… $\endgroup$
    – susu
    Aug 31 '20 at 19:59
  • $\begingroup$ thanks @susu . However, that does not solve the issue I am having. The info you shared deals more with the regular view you see on 3D view. The issue I have is more with what I get after running the script. Please check the blender file if you have spare time. $\endgroup$
    – Sourav
    Aug 31 '20 at 20:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.