I'd like to use bgl to draw dots points on 2d screen from 3d vertices in scene. I have lines working by using bgl.GL_LINE_LOOP but I couldn't find the full list of bgl.GL_* to loop up for points.
Asked
Active
Viewed 4,293 times
7
Radivarig
- 565
- 6
- 17
2 Answers
9
short answer:
bgl.glPointSize(5)
bgl.glBegin(bgl.GL_POINTS)
less shorter answer:
Open template operator_modal_draw.py
In draw_callback_px(self, context) I call my function
DrawByVertices("points", verts2d, [0.5, 1, 0.1, 0.5])
where verts2d are screen coordinates [(screen.x, screen.y), ..] in my case derived from vector3 like this
from bpy_extras.view3d_utils import location_3d_to_region_2d
#...
verts2d = []
for v in bm.verts:
new2dCo = location_3d_to_region_2d(context.region, \
context.space_data.region_3d, \
v.co)
verts2d.append([new2dCo.x,new2dCo.y])
.
def DrawByVertices(mode, verts2d, color):
bgl.glColor4f(*color)
bgl.glEnable(bgl.GL_BLEND)
if mode is "points":
bgl.glPointSize(5)
bgl.glBegin(bgl.GL_POINTS)
elif mode is "lines":
bgl.glLineWidth(2)
bgl.glBegin(bgl.GL_LINE_LOOP)
for x, y in verts2d:
bgl.glVertex2f(x, y)
bgl.glEnd()
bgl.glDisable(bgl.GL_BLEND)
#restore defaults
bgl.glLineWidth(1)
bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
return
Result is colored points drawn on screen over 3d vertex coordinates.
Radivarig
- 565
- 6
- 17
-
Note that the maximum value for point size is driver-specific and never larger than 20 afaik. – CodeManX Dec 30 '14 at 00:24
7
You can use OpenGL's feature for stippled lines to draw dotted / dashed lines:
import bpy
import bgl
import blf
def draw_callback_px(self, context):
bgl.glPushAttrib(bgl.GL_ENABLE_BIT)
# glPushAttrib is done to return everything to normal after drawing
bgl.glLineStipple(1, 0x9999)
bgl.glEnable(bgl.GL_LINE_STIPPLE)
font_id = 0 # XXX, need to find out how best to get this.
# draw some text
blf.position(font_id, 15, 30, 0)
blf.size(font_id, 20, 72)
blf.draw(font_id, "Hello Word " + str(len(self.mouse_path)))
# 50% alpha, 2 pixel width line
bgl.glEnable(bgl.GL_BLEND)
bgl.glColor4f(0.0, 0.0, 0.0, 0.5)
bgl.glLineWidth(2)
bgl.glBegin(bgl.GL_LINE_STRIP)
for x, y in self.mouse_path:
bgl.glVertex2i(x, y)
bgl.glEnd()
bgl.glPopAttrib()
# restore opengl defaults
bgl.glLineWidth(1)
bgl.glDisable(bgl.GL_BLEND)
bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
class ModalDrawOperator(bpy.types.Operator):
"""Draw a line with the mouse"""
bl_idname = "view3d.modal_operator"
bl_label = "Simple Modal View3D Operator"
def modal(self, context, event):
context.area.tag_redraw()
if event.type == 'MOUSEMOVE':
self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
elif event.type == 'LEFTMOUSE':
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
return {'FINISHED'}
elif event.type in {'RIGHTMOUSE', 'ESC'}:
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
return {'CANCELLED'}
return {'RUNNING_MODAL'}
def invoke(self, context, event):
if context.area.type == 'VIEW_3D':
# the arguments we pass the the callback
args = (self, context)
# Add the region OpenGL drawing callback
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
self.mouse_path = []
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
else:
self.report({'WARNING'}, "View3D not found, cannot run operator")
return {'CANCELLED'}
def register():
bpy.utils.register_class(ModalDrawOperator)
def unregister():
bpy.utils.unregister_class(ModalDrawOperator)
if __name__ == "__main__":
register()
If you want to draw circles in arbitrary size, you'll have to roll your own primitive drawing function for ellipses / circles (basically a regular polygon with as many edges as required to make it look round).
CodeManX
- 29,298
- 3
- 89
- 128
bgl.GL_*params to look up. Now that you mentioned, what is parameter for dotted lines? – Radivarig Dec 28 '14 at 23:22