1

I am new to blender, I have an object that during the animation some armatures are going to be hidden by other parts, How I could find these hidden armatures? As you can see in the picture leftHandRing4 is not visible in the rendered image. https://i.stack.imgur.com/EEB9K.jpg

My problem is different from Python: Check if vertex is on camera field of view, my armatures are just hidden by the other parts and they are still in the camera view.

  • Hi. What do you want to check exactly? If heads/tails are visible or if the bones in the shape they have are visible? – lemon Sep 27 '20 at 09:43
  • Actually knowing if the head is visible or not – leyla khaleghi Sep 27 '20 at 15:06
  • Similar to this https://blender.stackexchange.com/questions/77607/how-to-get-the-3d-coordinates-of-the-visible-vertices-in-a-rendered-image-in-ble/77747#77747. Also check the second answer by Debaditya. Note that there is a scene raycast too. – lemon Sep 27 '20 at 15:08
  • So you want to find armature that are parent and inside meshes? Which other kind of cases (I've seen the picture you've added), I mean how are visible armatures? – lemon Sep 27 '20 at 15:41
  • Yes, exactly, they are inside meshes and parent, as you can see in the picture leftHandRing4 is not visible in the rendered image. – leyla khaleghi Sep 27 '20 at 15:46

2 Answers2

1

Not totally sure this answer the question, but here is some code to check if an armature has bone heads visible by the camera.

The alternative way to understand the question could be: which armature is not totally enclosed by a mesh.

enter image description here

But, the principles of the script:

  • create and use a sphere that will be placed and scaled at bone heads locations
  • parse armature bones, place the sphere, raycast on it
  • if a bone is hit, the armature is visible by the camera
  • select visible armatures
  • delete the sphere

Here is the script:

import bpy
import bmesh
from mathutils import Vector
from bpy_extras.object_utils import world_to_camera_view

Create a sphere that will be used to ray cast on

def create_sphere(view_layer, collection):

mesh = bpy.data.meshes.new('sphere')

bm = bmesh.new()
bmesh.ops.create_uvsphere(bm, u_segments=32, v_segments=16, diameter=1)
bm.to_mesh(mesh)
bm.free()

sphere = bpy.data.objects.new("sphere", mesh)

collection.objects.link(sphere)
view_layer.update()

return sphere

Sphere clean up

def delete_sphere(sphere): bpy.data.objects.remove(sphere, do_unlink=True)

Test the armature visibility

def test_armature(scene, view_layer, camera, sphere, armature): world_matrix = armature.matrix_world

# map the bones
for bone in armature.pose.bones:
    head = bone.head
    tail = bone.tail
    # scales and places the sphere 
    # This ratio seems to be the one to have a sphere at the good scale
    factor = Vector(armature.scale) * 0.05
    sphere.scale = factor * (head - tail).length
    sphere.location = world_matrix @ head
    view_layer.update()

    # calculates the sphere location in camera view 
    co2D = world_to_camera_view( scene, camera, sphere.location )

    # if inside visible cone
    if 0.0 <= co2D.x <= 1.0 and 0.0 <= co2D.y <= 1.0:
        # ray cast from camera to sphere
        from_location = camera.location
        direction = (sphere.location - camera.location).normalized()
        hit, loc, norm, idx, ob, M = scene.ray_cast(
                    view_layer,
                    from_location,
                    direction)

        # if hit the sphere, head is visible
        if hit and ob == sphere:
            return True

# No hit occured            
return False 


camera = bpy.data.objects['Camera'] scene = bpy.context.scene view_layer = bpy.context.view_layer

Create the sphere to ray cast on

sphere = create_sphere(view_layer, bpy.context.scene.collection)

Maps the armatures and select the ones that the camera can see

for armature in [obj for obj in scene.collection.all_objects if obj.type == "ARMATURE"]: visible = test_armature(scene, view_layer, camera, sphere, armature) armature.select_set(visible)

Clean up the sphere

delete_sphere(sphere)

Test file:

Note: this script is basically a variation (eventually enhancement) of these answers from Debaditya and from myself).

lemon
  • 60,295
  • 3
  • 66
  • 136
0

you can go to the viewport display settings , and then check In front setting do that you can see the bones in the front of all the mesh enter image description here

SHikha Mittal
  • 1,035
  • 8
  • 21