4
$\begingroup$

Is it possible to draw 3d lines/points with X-Ray in BGL?

Here is my custom 3d line in viewport:

enter image description here

As you can see it's drawn behind the monkey head. Is it possible to make it as X-Ray?

Here is the code i use: https://github.com/mifth/mifthtools/blob/ff2bd836267deb0c0d5f0c0bb28904876068bba3/blender/addons/mira_tools/mi_curve_test.py#L331-L349

$\endgroup$
  • $\begingroup$ i too would like to know this, so far i've been using 2d 'POST_PIXEL' and converted 3d coordinates to 2d screen coordinates $\endgroup$ – zeffii May 23 '15 at 15:50
  • 1
    $\begingroup$ POST_PIXEL is the only way AFAIK, but some OpenGL guru might prove me wrong (disable depth test?). $\endgroup$ – CodeManX May 23 '15 at 17:19
  • 1
    $\begingroup$ If you draw the curve after the mesh and disable the depth test(only for the curve) this should work. Can this be done without altering the C-code? I don't know. If the previous two commenters don't know, I'd ask Campbell next. BTW, I finally got around to checking out your Mira tool-set. It's impressive and moving quickly. Nice work. :) $\endgroup$ – MarcClintDion May 23 '15 at 19:56
4
$\begingroup$

as @CoDEmanX noted you can disable the depth test with bgl.glDisable(bgl.GL_DEPTH_TEST) while drawing and use the POST_VIEW.

here is an example code of a modified draw modal operator :


import bpy
import bgl
import blf
from mathutils import Vector
from bpy_extras import view3d_utils

def draw_callback_px(self, context, points):

    bgl.glEnable(bgl.GL_BLEND)
    bgl.glColor4f(1.0, 1.0, 1.0, 1.0)
    bgl.glLineWidth(2)
    bgl.glDisable(bgl.GL_DEPTH_TEST)

    bgl.glBegin(bgl.GL_LINE_STRIP)
    for x, y, z in self.points:
        bgl.glVertex3f(x, y, z)
    bgl.glEnd()

    # restore opengl defaults
    bgl.glLineWidth(1)
    bgl.glDisable(bgl.GL_BLEND)
    bgl.glEnable(bgl.GL_DEPTH_TEST)
    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 == 'LEFTMOUSE':
            if event.value == 'RELEASE':
                co_2d = Vector((event.mouse_region_x, event.mouse_region_y))
                viewport = context.area.regions[4]
                r3d = context.area.spaces[0].region_3d
                nor =  view3d_utils.region_2d_to_vector_3d(viewport, r3d, co_2d)
                v3 =  view3d_utils.region_2d_to_location_3d(viewport, r3d, co_2d, nor)

                self.points.append(v3) 

        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':
            self.points = []
            args = (self, context, self.points)
            self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_VIEW')
            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()
$\endgroup$
  • 1
    $\begingroup$ I'm really surprised, switching between bgl.glDisable(bgl.GL_DEPTH_TEST) and bgl.glEnable(bgl.GL_DEPTH_TEST) driven by a bool property even updates the viewport in real time... Awesome! +5 if I could, thanks @Chebhou $\endgroup$ – p2or Jun 24 '16 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.