Guest User

Untitled

a guest
Jul 1st, 2025
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.12 KB | None | 0 0
  1. import bpy
  2. import bmesh
  3. import mathutils
  4. from bpy_extras import view3d_utils
  5.  
  6. def get_3d_viewport_area():
  7. for area in bpy.context.screen.areas:
  8. if area.type == 'VIEW_3D':
  9. for region in area.regions:
  10. if region.type == 'WINDOW':
  11. return area, region
  12. return None, None
  13.  
  14. def get_view_direction(region_3d):
  15. return -region_3d.view_rotation @ mathutils.Vector((0.0, 0.0, -1.0))
  16.  
  17. def face_visible_on_screen(region, rv3d, face, obj):
  18. """Returns True if any vertex of the face is inside the viewport."""
  19. for vert in face.verts:
  20. world_co = obj.matrix_world @ vert.co
  21. screen_pos = view3d_utils.location_3d_to_region_2d(region, rv3d, world_co)
  22. if screen_pos:
  23. x, y = screen_pos
  24. if 0 <= x <= region.width and 0 <= y <= region.height:
  25. return True
  26. return False
  27.  
  28. def select_offscreen_or_backfacing_inside():
  29. area, region = get_3d_viewport_area()
  30. if not area or not region:
  31. print("3D Viewport not found.")
  32. return
  33.  
  34. space = next((s for s in area.spaces if s.type == 'VIEW_3D'), None)
  35. if not space:
  36. print("VIEW_3D space not found.")
  37. return
  38.  
  39. rv3d = space.region_3d
  40. view_dir = get_view_direction(rv3d)
  41.  
  42. obj = bpy.context.object
  43. if obj is None or obj.type != 'MESH':
  44. print("No mesh object selected.")
  45. return
  46.  
  47. bpy.ops.object.mode_set(mode='EDIT')
  48. bm = bmesh.from_edit_mesh(obj.data)
  49. bm.faces.ensure_lookup_table()
  50.  
  51. for f in bm.faces:
  52. f.select = False
  53.  
  54. for face in bm.faces:
  55. normal_world = obj.matrix_world.to_3x3() @ face.normal
  56. dot = normal_world.normalized().dot(view_dir)
  57.  
  58. is_backfacing = dot > 0.2
  59. is_onscreen = face_visible_on_screen(region, rv3d, face, obj)
  60. is_offscreen = not is_onscreen
  61.  
  62. # ✅ Final logic
  63. if is_onscreen and not is_backfacing:
  64. face.select = True
  65.  
  66. bmesh.update_edit_mesh(obj.data)
  67. print("Selected: offscreen OR backfacing onscreen faces.")
  68.  
  69. select_offscreen_or_backfacing_inside()
  70.  
Advertisement
Add Comment
Please, Sign In to add comment