2

Is it possible to get the screen XY coordinates in viewport for a vertex in orthographic view?

I get pixel locations as per a previous answer like this:

co2d = []
for v in cloth.data.vertices:
    p = bpy_extras.object_utils.world_to_camera_view(scene, camera, v.co)
    xy=list(p)
    xy[0] = xy[0] * 680
    xy[1] = xy[1] * 809
    co2d.append(xy)

(image width and height hardcoded here)

Where the camera is defined here:

def area_view_3d():
    areas = [a for a in bpy.context.screen.areas if a.type == "VIEW_3D"]
    if not areas:
        return
    return areas[0]

camera = area_view_3d().spaces[0].camera

but when I take the resulting coordinates and map them onto the screenshot it looks like this:

enter image description here

Clearly I get something that looks like coordinates, but isn't what I want.

What is it that I am getting wrong?

simone
  • 745
  • 4
  • 14
  • Will hunt down some dupes. Issue most likely is vert coords are local, the world to camera view wants globals... use ob.matrix_world @ verr.co – batFINGER Sep 06 '21 at 18:48
  • @batFINGER - thanks, I was thinking I am getting the wrong camera... banging around this one for hints: https://stackoverflow.com/questions/9028398/change-viewport-angle-in-blender-using-python – simone Sep 06 '21 at 18:51
  • @batFINGER - I'll read through. Just a question - is the linked answer about the render camera or the viewport one? I'm struggling between the two. Apropos - this one seems good too, but also render camera, and not orthogonal – simone Sep 06 '21 at 18:59
  • 1
    render, finally twigged on re-reading question .. 8) – batFINGER Sep 06 '21 at 19:00
  • made it clearer in question – simone Sep 06 '21 at 19:01
  • @batFINGER - print(camera.type, camera.data.type) prints CAMERA PERSP so I am getting a camera, but not the ortho one – simone Sep 06 '21 at 19:07
  • @batFINGER somewhere in here https://blender.stackexchange.com/questions/145353 there might be a solution – simone Sep 06 '21 at 19:23
  • Or https://blender.stackexchange.com/questions/107365/align-camera-to-view-precisely-and-automatically-without-manual-fiddling ... however think there is a better way – batFINGER Sep 06 '21 at 19:56

1 Answers1

1

3D location to region 2D

enter image description here

Test script.

import bpy
from mathutils import Vector, Matrix
from bpy_extras import view3d_utils
import bmesh
import numpy as np

context = bpy.context scene = context.scene ob = context.object mw = ob.matrix_world me = ob.data for a in context.screen.areas: if a.type == 'VIEW_3D': space = a.spaces.active r3d = space.region_3d plane_no = r3d.view_rotation @ Vector((0, 0, -1)) region = a.regions[-1] break else: assert False, "Requires a $D view"

plane_co = ob.matrix_world.translation

bm = bmesh.new() bm.from_mesh(me) bm.transform(ob.matrix_world) u, v = np.array( [view3d_utils.location_3d_to_region_2d( region, r3d, v.co) for v in bm.verts] ).T

bbox2d = ( (u.min(), v.min()), (u.max(), v.min()), (u.max(), v.max()),
(u.min(), v.max()), )

#bbox2d = [(0, 0), (100, 0), (100, 100), (0, 100)] bl, tr = (0, 0), (region.width, region.height)

import gpu from gpu_extras.batch import batch_for_shader from functools import partial

vertices = bbox2d

indices = ( (0, 1, 2), (2, 3, 0))

shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices)

def draw(): shader.bind() shader.uniform_float("color", (0, 1, 1, .10)) batch.draw(shader)

handle = bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')

def kill(handle): if handle: bpy.types.SpaceView3D.draw_handler_remove(handle, 'WINDOW') return 0

bpy.app.timers.register(partial(kill, handle), first_interval=2) a.tag_redraw()

batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • thanks! that works 99%: when I use the coordinates to draw on a screenshot things are offset vertically (i.e.: the dots are positioned lower than the vertices) see here: https://pasteboard.co/Kjt5hO5.png - is there a way to determine the offset? full gist of the script (with screenshot and dot making) here: https://gist.github.com/simonecesano/2cefcfac7485939a18249c4672e4a5ff. And in general thanks for the thorough answers – simone Sep 07 '21 at 07:54
  • Found out! up and down are inverted between Blender and OpenCV. Fixed the gist. Works 100% – simone Sep 07 '21 at 12:23