-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheckVisibility.py
executable file
·239 lines (192 loc) · 8.48 KB
/
checkVisibility.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
""" https://blender.stackexchange.com/questions/7198/save-the-2d-bounding-box-of-an-object-in-rendered-image-to-a-text-file """
import bpy
from bpy_extras.view3d_utils import location_3d_to_region_2d
import numpy as np
import bmesh
import time
import toml
def zoom_to_g(scene, camera, object):
camera.location, foo = camera.camera_fit_coords(scene, [co for corner in object.bound_box for co in corner])
def check_visibility(scene, camera_object, mesh_object, use_vertices = True, use_faces = False, use_edges = False):
bpy.ops.object.mode_set(mode="OBJECT")
if bpy.context.mode == 'EDIT_MESH':
bm = bmesh.from_edit_mesh(mesh_object.data)
verts = [ v.index for v in bm.verts if v.select ]
faces = [ f.index for f in bm.polygons if f.select ]
edges = [ e.index for e in bm.edges if e.select ]
else:
verts = [ v.index for v in mesh_object.data.vertices if v.select ]
#verts = count_visible_vertices_in_camera_view(camera_object, mesh_object)
faces = [ f.index for f in mesh_object.data.polygons if f.select ]
edges = [ e.index for e in mesh_object.data.edges if e.select ]
#print(mesh_object.name)
vert_visibility = len(verts)/len(mesh_object.data.vertices)
face_visibility = len(faces)/len(mesh_object.data.polygons)
edge_visibility = len(edges)/len(mesh_object.data.edges)
#print("PERCENTAGE VERTS ", vert_visibility)
#print("PERCENTAGE FACES ", face_visibility)
#print("PERCENTAGE EDGES ", edge_visibility)
num = 0
overall_visibility = 0
if use_vertices:
overall_visibility = overall_visibility + vert_visibility
num = num + 1
if use_faces:
overall_visibility = overall_visibility + face_visibility
num = num + 1
if use_edges:
overall_visibility = overall_visibility + edge_visibility
num = num + 1
overall_visibility = overall_visibility / num
print(mesh_object.name, " --> overall visibility ", overall_visibility , "\n")
return overall_visibility
def count_visible_vertices_in_camera_view(camera_object, obj):
# Aktuelle Kameraobjekt speichern
current_camera = bpy.context.scene.camera
# Aktuelle Kamera auf die gewünschte Kamera setzen
bpy.context.scene.camera = camera_object
# Sichtbarkeit der Mesh-Vertices zählen
visible_vertices = 0
for vertex in obj.data.vertices:
# Überprüfen, ob der Vertex im Viewport sichtbar ist
co_ndc = bpy.context.scene.camera.matrix_world @ vertex.co
co_clip = bpy.context.scene.camera.data.clip_start <= co_ndc.z <= bpy.context.scene.camera.data.clip_end
if co_clip:
# Überprüfen, ob der Vertex im Kamerabild sichtbar ist
co_screen = location_3d_to_region_2d(bpy.context.region, bpy.context.space_data.region_3d, vertex.co)
if co_screen:
visible_vertices += 1
# Kamera auf die ursprüngliche Kamera zurücksetzen
bpy.context.scene.camera = current_camera
return visible_vertices
############################### modified from https://blenderartists.org/t/select-all-faces-visible-from-camera/1210826
def view3d_find():
# returns first 3d view, normally we get from context
for area in bpy.context.window.screen.areas:
if area.type == 'VIEW_3D':
v3d = area.spaces[0]
rv3d = v3d.region_3d
for region in area.regions:
if region.type == 'WINDOW':
return region, rv3d
return None, None
def view3d_camera_border(scene):
obj = scene.camera
#cam = obj.data
#frame = cam.view_frame(scene)
frame = bpy.context.scene.camera.data.view_frame(scene=bpy.context.scene)
# move from object-space into world-space
frame = [obj.matrix_world @ v for v in frame]
# move into pixelspace
region, rv3d = view3d_find()
#print(region, rv3d)
frame_px = [location_3d_to_region_2d(region, rv3d, v) for v in frame]
return frame_px
#'''
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, corners, extend=True):
override = getOverride(context)
bpy.ops.view3d.select_box(override, wait_for_input=False, xmin=int(corners[0]), xmax=int(corners[1]), ymin=int(corners[2]), ymax=int(corners[3]), mode='SET')
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
bpy.ops.view3d.select_box(override, wait_for_input=False, xmin=int(corners[0]), xmax=int(corners[1]), ymin=int(corners[2]), ymax=int(corners[3]), mode='ADD')
return True
def prepareForSelection(override):
bpy.ops.object.mode_set(mode="OBJECT")
bpy.ops.object.select_all(action='DESELECT')
for ob in bpy.context.scene.objects:
if ob.hide_render == True:
ob.hide_set(True)
else:
ob.hide_set(False)
bpy.context.view_layer.objects.active = bpy.context.view_layer.objects.active
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.editmode_toggle()
override['area'].spaces.active.region_3d.view_perspective = 'CAMERA'
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations = 1)
override['area'].spaces.active.shading.show_xray = False
def getOverride(context):
view3dArea, view3dRegion = getView3dAreaAndRegion(context)
override = context.copy()
override['area'] = view3dArea
override['region'] = view3dRegion
return override
def getCorners(cam_corners):
'''
returns xmin,xmax,ymin,ymax
'''
print(cam_corners)
return [cam_corners[2][0],cam_corners[0][0],cam_corners[2][1],cam_corners[0][1]]
def prepare_camera(scene, cam, obj):
scene.camera = cam
cam.constraints["Track To"].target = obj
#lens = 1 / max(obj.dimensions) * abs(obj.location.z) * 80
lens = 1 / max(obj.dimensions) - obj.location.z
#print("setting lens to ", lens, " max dim ", max(obj.dimensions), " z loc ", obj.location.z)
bpy.data.cameras[cam.name].lens = lens
def restore_camera(scene, cam):
scene.camera = cam
def select_camera_view(scene, camera_object, mesh_object):
mesh_object.select_set(True)
bpy.context.view_layer.objects.active = mesh_object
prepare_camera(scene, camera_object, mesh_object)
# go to editmode
bpy.ops.object.mode_set(mode="EDIT")
vertex, edge, face = True, True, True
bpy.context.tool_settings.mesh_select_mode = (vertex, edge, face)
# set camera view
override = getOverride(bpy.context)
bpy.ops.view3d.view_camera(override)
prepareForSelection(override)
# get camera borders in view coordinates
cam_corners = getCorners(view3d_camera_border(bpy.context.scene))
# select stuff in borders
select_border(bpy.context, cam_corners, extend = False)
################
def load_objects(names, ignore_names=None, category=""):
mesh_obj=list()
if ignore_names != "" and ignore_names is not None:
available = [obj.name for obj in bpy.data.objects]
mesh_names = [x for x in available if x not in ignore_names]
elif names is not None:
mesh_names = names
else:
print("Unable to load ", category)
return mesh_obj
try:
mesh_objects = [bpy.data.objects[name] for name in mesh_names]
for mesh in mesh_objects:
mesh_obj.append(mesh)
except:
print("Error loading objects")
return mesh_obj
if __name__ == '__main__':
print("starting")
config = toml.load("/home/vision/Work/DataGen/DataGenAtworkSegmentation/configAtWork.toml")
bpy.context.view_layer.update()
scene = bpy.data.scenes[config['General']['Scene']]
camera_object = bpy.data.objects[config['General']['Camera']]
steps = config['General']['Steps']
lamp_obj = list()
special_obj = list()
mesh_obj = list()
lamp_obj = load_objects(config['Objects']['Lamps'], category="Lamps")
mesh_obj = load_objects(config['Objects']['Names'], config['Objects']['Ignore'], "Objects")
special_obj = load_objects(config['Objects']['Special'], category="Special")
decoy_obj = load_objects(config['Objects']['Decoy'], category="Decoy")
scn = bpy.context.scene
cam = bpy.data.objects['Camera.001']
obj = bpy.data.objects['large_black_alu']
#restore_camera(camera_object)
#check_visibility(scene, camera_object, mesh_obj.first())
#for obj in mesh_obj:
print("SELECTING ", obj.name)
select_camera_view(scene, cam, obj)
check_visibility(scene, cam, obj)
time.sleep(2)
restore_camera(scene, camera_object)
print("DONE")