7

I'd like to select only the visible vertices (from the camera), using python interface.

I use bpy.types.SpaceView3D.use_occlude_geometry = True to limit the selection, but when it is followed by bpy.ops.object.select_all(action='SELECT'), it results in all mesh vertices being selected and not only the visible ones.

I probably don't understand how to use the bpy.types.SpaceView3D.use_occlude_geometry or the selection operator correctly - will appreciate your help with it.

Anastasia

Ray Mairlot
  • 29,192
  • 11
  • 103
  • 125
Anastasia
  • 71
  • 2
  • 1
    Related http://blender.stackexchange.com/a/40826/15543 – batFINGER Oct 04 '16 at 16:34
  • Thanks, @batFINGER, it's related but I need to do everything via Python API. Is there any way to replace the manual vertex selection by a set of python commands? Thanks! – Anastasia Oct 04 '16 at 19:39

1 Answers1

12

First of all, as for the select_all behavior, that is by design.
Calling bpy.ops.object.select_all(action='SELECT') is the same thing as pressing the A key, which selects ALL items, even ones outside of the view frustum, even ones occluded and not visible.

To select visible vertices in python similar to border or circle select honoring bpy.types.SpaceView3D.use_occlude_geometry and bpy.ops.mesh.select_mode:

import bpy

def getView3dAreaAndRegion(context): for area in context.screen.areas: if area.type == "VIEW_3D": for region in area.regions: if region.type == "WINDOW": return area, region

def select_border(context, view3dAreaAndRegion=None, extend=True): if not view3dAreaAndRegion: view3dAreaAndRegion = getView3dAreaAndRegion(context) view3dArea, view3dRegion = view3dAreaAndRegion override = context.copy() override['area'] = view3dArea override['region'] = view3dRegion bpy.ops.view3d.select_border(override, gesture_mode=3, xmin=0, xmax=view3dArea.width, ymin=0, ymax=view3dArea.height, extend=extend) return view3dAreaAndRegion

Then to use this, just add after the function definitions:

select_border(bpy.context)

Blender >2.8

def getView3dAreaAndRegion(context):
  for area in context.screen.areas: 
      if area.type == "VIEW_3D":    
        for region in area.regions:
          if region.type == "WINDOW":
            print("Found WINDOW") 
            return area, region

def select_border(context, view3dAreaAndRegion=None, extend=True): if not view3dAreaAndRegion: view3dAreaAndRegion = getView3dAreaAndRegion(context) print(view3dAreaAndRegion) view3dArea, view3dRegion = view3dAreaAndRegion override = context.copy() override['area'] = view3dArea override['region'] = view3dRegion bpy.ops.view3d.select_box(override,xmin=0,xmax=view3dArea.width,ymin=0,ymax=view3dArea.height,mode='ADD')

and then, with a selected object in Edit mode, run

select_border(bpy.context)

Very important: This code needs to be run in a window that has a 3D Editor view in it. So if you're running the code editor in a separate detached window, it won't work !

Duarte Farrajota Ramos
  • 59,425
  • 39
  • 130
  • 187
swooby
  • 229
  • 2
  • 5