Beispiel #1
0
def draw_callback_px(self, context):
    if self.moves % 3 == 0 and len(self.colors) < 32:
        self.mouse_path.append(self.mouse_pos)
        view = get_viewport()
        x, y = self.mouse_pos
        c = bgl.Buffer(bgl.GL_FLOAT, 4)
        bgl.glReadPixels(x + view[0], y + view[1], 1, 1, bgl.GL_RGB,
                         bgl.GL_FLOAT, c)
        self.colors.append(c.to_list())

    # 50% alpha, 2 pixel width line

    bgl.glEnable(bgl.GL_BLEND)
    bgl.glColor4f(1, 1, 1, 0.5)
    bgl.glLineWidth(4)

    bgl.glBegin(bgl.GL_LINE_STRIP)
    for x, y in self.mouse_path:
        bgl.glVertex2i(x, y)

    bgl.glEnd()

    # restore opengl defaults
    bgl.glLineWidth(1)
    bgl.glDisable(bgl.GL_BLEND)
    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
Beispiel #2
0
    def as_image(self, x, y, w, h, image_name):
        import bpy

        buffer = bgl.Buffer(bgl.GL_FLOAT, w * h)  # * 4)

        bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)
        check_error("glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)")

        bgl.glReadPixels(x, y, w, h, bgl.GL_RED_INTEGER, bgl.GL_UNSIGNED_INT,
                         buffer)
        check_error("glReadPixels as_image")

        if image_name not in bpy.data.images:
            image = bpy.data.images.new(image_name, w, h)
        else:
            image = bpy.data.images[image_name]
            #if image.size[:] != (w, h):
            image.scale(w, h)

        pix = []
        for v in buffer:
            # pix.extend([v / self._offset_cur, 0, 0, 1])
            pix.extend([v, 0, 0, 1])

        image.pixels = pix
        # image.pixels = [v / 255 for v in buffer]
        image.update()
def draw_callback_px(self, context):
    if self.moves % 3 == 0 and len(self.colors) < 32:
        self.mouse_path.append(self.mouse_pos)
        view = get_viewport()
        x, y = self.mouse_pos
        c = bgl.Buffer(bgl.GL_FLOAT, 4)
        bgl.glReadPixels(x + view[0], y + view[1], 1, 1, bgl.GL_RGB, bgl.GL_FLOAT, c)
        self.colors.append(c.to_list())

    # 50% alpha, 2 pixel width line

    bgl.glEnable(bgl.GL_BLEND)
    bgl.glColor4f(1, 1, 1, 0.5)
    bgl.glLineWidth(4)

    bgl.glBegin(bgl.GL_LINE_STRIP)
    for x, y in self.mouse_path:
        bgl.glVertex2i(x, y)

    bgl.glEnd()

    # restore opengl defaults
    bgl.glLineWidth(1)
    bgl.glDisable(bgl.GL_BLEND)
    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
Beispiel #4
0
def screenshot(x, y, w, h, mode=bgl.GL_FRONT, type=bgl.GL_BYTE):
    """スクリーンショットを撮ってRGBAのfloatバッファを返す
    :param x: Window.x
    :type x: int
    :param y: Window.y
    :type y: int
    :param w: Window.width
    :type w: int
    :param h: Window.height
    :type h: int
    :param mode: 読み込み先
    :type mode: int
    :param type: バッファの型。bgl.GL_BYTE, bgl.GL_INT, ...
    :type type: int
    :return: スクリーンショット。float RGBA
    :rtype: bgl.Buffer
    """
    buf = bgl.Buffer(type, w * h * 4)
    mode_bak = bgl.Buffer(bgl.GL_INT, 1)
    bgl.glGetIntegerv(bgl.GL_READ_BUFFER, mode_bak)
    bgl.glReadBuffer(mode)
    bgl.glReadPixels(x, y, w, h, bgl.GL_RGBA, type, buf)
    bgl.glFinish()
    bgl.glReadBuffer(mode_bak[0])
    return buf
def render_viewport(context, save_image_as_file=False, show_image=False):
    region = context.region
    x = region.x
    y = region.y
    width = region.width
    height = region.height

    out = prepare_blimage(width, height, Pref.blimgname)

    buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
    bgl.glReadPixels(x, y, width, height, bgl.GL_RGBA, bgl.GL_FLOAT, buffer)
    out.pixels = buffer[:]

    if save_image_as_file:
        save_image(out, context.scene)

    if show_image:

        def set_imageeditor_image():
            win = context.window
            for area_imeditor in [
                    area for area in win.screen.areas
                    if area.type == 'IMAGE_EDITOR'
            ]:
                for s in [
                        s for s in area_imeditor.spaces
                        if s.type == 'IMAGE_EDITOR'
                ]:
                    s.image = out
                    return

        set_imageeditor_image()
    def render_view_offscreen(self, context):
        sv3d = context.space_data
        # backup settings and set them to render
        overlays_were = sv3d.overlay.show_overlays
        sv3d.overlay.show_overlays = False
        shading_was = sv3d.shading.type
        sv3d.shading.type = 'RENDERED'

        width = context.region.width
        height = context.region.height
        offscreen = GPUOffScreen(width, height)
        scene = context.scene
        view_matrix = context.region_data.view_matrix
        projection_matrix = context.region_data.window_matrix

        with offscreen.bind():
            offscreen.draw_view3d(scene, context.view_layer,
                                  context.space_data, context.region,
                                  view_matrix, projection_matrix)

            buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)
            bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA,
                             bgl.GL_UNSIGNED_BYTE, buffer)

        offscreen.free()
        sv3d.overlay.show_overlays = overlays_were
        sv3d.shading.type = shading_was

        return list(buffer)
def render_offscreen(self, context, width, height, imgname=''):
    assert context.area.type == 'NODE_EDITOR' and context.space_data.tree_type == 'CompositorNodeTree'

    gos = gpu.offscreen.new(width,height)
    gos.bind(True)
    try:
        bgl.glMatrixMode(bgl.GL_PROJECTION)
        bgl.glLoadIdentity()
        bgl.glScalef(1/width*2,1/height*2,1.0)
        bgl.glTranslatef(-width/2,-height/2,0)

        draw_callback(self, context, {
                  'center': Vector((width/2, height/2))
                , 'zoom': 1.0
                , 'back_image_alpha': 1.0
                , 'image_size': (width, height)
                })

        buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
        x,y = 0,0
        bgl.glReadPixels(x, y, width, height , bgl.GL_RGBA, bgl.GL_FLOAT, buffer)

        out = prepare_blimage(width, height, imgname or Pref.default_output_image_name)
        out.pixels = buffer[:]
    finally:
        gos.unbind(True)
Beispiel #8
0
def screenshot(x, y, w, h, mode=bgl.GL_FRONT, type=bgl.GL_BYTE):
    """スクリーンショットを撮ってRGBAのfloatバッファを返す
    :param x: Window.x
    :type x: int
    :param y: Window.y
    :type y: int
    :param w: Window.width
    :type w: int
    :param h: Window.height
    :type h: int
    :param mode: 読み込み先
    :type mode: int
    :param type: バッファの型。bgl.GL_BYTE, bgl.GL_INT, ...
    :type type: int
    :return: スクリーンショット。float RGBA
    :rtype: bgl.Buffer
    """
    buf = bgl.Buffer(type, w * h * 4)
    mode_bak = bgl.Buffer(bgl.GL_INT, 1)
    bgl.glGetIntegerv(bgl.GL_READ_BUFFER, mode_bak)
    bgl.glReadBuffer(mode)
    bgl.glReadPixels(x, y, w, h, bgl.GL_RGBA, type, buf)
    bgl.glFinish()
    bgl.glReadBuffer(mode_bak[0])
    return buf
Beispiel #9
0
 def read_zbuffer(xy, wh=(1, 1), centered=False, src=None):
     if isinstance(wh, (int, float)):
         wh = (wh, wh)
     elif len(wh) < 2:
         wh = (wh[0], wh[0])
     
     x, y, w, h = int(xy[0]), int(xy[1]), int(wh[0]), int(wh[1])
     
     if centered:
         x -= w // 2
         y -= h // 2
     
     buf_size = w*h
     
     if src is None:
         # xy is in window coordinates!
         zbuf = bgl.Buffer(bgl.GL_FLOAT, [buf_size])
         bgl.glReadPixels(x, y, w, h, bgl.GL_DEPTH_COMPONENT, bgl.GL_FLOAT, zbuf)
     else:
         src, w0, h0 = src
         template = [0.0] * buf_size
         for dy in range(h):
             y0 = min(max(y + dy, 0), h0-1)
             for dx in range(w):
                 x0 = min(max(x + dx, 0), w0-1)
                 i0 = x0 + y0 * w0
                 i1 = dx + dy * w
                 template[i1] = src[i0]
         zbuf = bgl.Buffer(bgl.GL_FLOAT, [buf_size], template)
     
     return zbuf
    def capture(self, mouse_x=None, mouse_y=None):
        time_diff()
        self.__update_size()
        time_diff("__update_size")
        bgl.glReadBuffer(bgl.GL_FRONT)
        time_diff("glReadBuffer")
        bgl.glReadPixels(
            0,
            0,
            self.width,
            self.height,
            bgl.GL_RGBA,
            bgl.GL_UNSIGNED_BYTE,
            self.buffer,
        )
        time_diff("glReadPixels")
        # self.image.pixels = [v / 255 for v in self.buffer]
        remapped_buffer = remap(self.buffer, self.remapping_indexes)
        time_diff("remap")
        self.image.pixels = [v / 255 for v in remapped_buffer]

        if mouse_x is not None and mouse_y is not None:
            draw_cursor(self.image, mouse_x / self.width * IMAGE_WIDTH,
                        mouse_y / self.height * IMAGE_HEIGHT)

        time_diff("image.pixels")
Beispiel #11
0
def draw_scene(self, context, projection_matrix):
    bgl.glEnable(bgl.GL_DEPTH_TEST)
    bgl.glDepthFunc(bgl.GL_LESS)

    # Get List of Mesh Objects
    objs = []
    deps = bpy.context.view_layer.depsgraph
    for obj_int in deps.object_instances:
        obj = obj_int.object
        if obj.type == 'MESH' and obj.hide_render == False:

            mat = obj_int.matrix_world
            obj_eval = obj.evaluated_get(deps)
            mesh = obj_eval.to_mesh(preserve_all_data_layers=True,
                                    depsgraph=bpy.context.view_layer.depsgraph)
            mesh.calc_loop_triangles()
            tris = mesh.loop_triangles
            vertices = []
            indices = []

            for vert in mesh.vertices:
                # Multipy vertex Position by Object Transform Matrix
                vertices.append(mat @ vert.co)

            for tri in tris:
                indices.append(tri.vertices)

            #shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
            shader = gpu.types.GPUShader(Base_Shader_3D.vertex_shader,
                                         DepthOnlyFrag.fragment_shader)
            batch = batch_for_shader(shader,
                                     'TRIS', {"pos": vertices},
                                     indices=indices)
            batch.program_set(shader)
            batch.draw()
            gpu.shader.unbind()
            obj_eval.to_mesh_clear()

    #Write to Image for Debug
    debug = False
    if debug:
        scene = context.scene
        render_scale = scene.render.resolution_percentage / 100
        width = int(scene.render.resolution_x * render_scale)
        height = int(scene.render.resolution_y * render_scale)

        buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)
        bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)
        bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA,
                         bgl.GL_UNSIGNED_BYTE, buffer)

        image_name = "measureit_arch_depth"
        if image_name not in bpy.data.images:
            bpy.data.images.new(image_name, width, height)

        image = bpy.data.images[image_name]
        image.scale(width, height)
        image.pixels = [v / 255 for v in buffer]

    bgl.glDisable(bgl.GL_DEPTH_TEST)
Beispiel #12
0
    def modal(self, context, event):
        context.area.tag_redraw()

        if event.type == 'MOUSEMOVE' or event.type == 'INBETWEEN_MOUSEMOVE':
            if self.record:
                # note that we record the the mouse position relative to the window (not to the region)
                self.mouse_path.append((event.mouse_x, event.mouse_y))

        elif event.type == 'LEFTMOUSE':
            if event.value == 'PRESS' and not self.record:
                self.record = True
                self.mouse_path.append((event.mouse_x, event.mouse_y))
            else:  # release or second press while recording
                # bpy.types.SpaceImageEditor.draw_handler_remove(self._handle, 'WINDOW')
                if self.cursor_set: context.window.cursor_modal_restore()
                # we can only have 32 elements in a color band so we have to down sample the mouse points
                nmp = len(self.mouse_path)
                if nmp > 32:
                    d = (nmp // 32) + 1
                    self.mouse_path = self.mouse_path[::d]
                buf = bgl.Buffer(bgl.GL_FLOAT, [1, 3])
                if len(self.mouse_path) == 1:
                    self.mouse_path.append(self.mouse_path[0])
                elements = context.active_object.active_material.node_tree.nodes.active.color_ramp.elements
                # remove all elements (setpoints). Last one cannot be removed
                while len(elements) > 1:
                    elements.remove(elements[0])
                # set the color and the position of the first point
                # note that our recorded mouse positions are relative to the window but the framebuffer in our context
                # is also the whole window, in other words we do not have to add any offset.
                # unfortunately we can only read pixels from our own framebuffer that means we cannot sample pixels
                # outside our current window, not even another Blender window!
                wx = 0  #context.window.x
                wy = 0  #context.window.y
                x, y = self.mouse_path[0]
                bgl.glReadPixels(x + wx, y + wy, 1, 1, bgl.GL_RGB,
                                 bgl.GL_FLOAT, buf)
                e = elements[0]
                rgb = buf[0]
                e.color = (rgb[0], rgb[1], rgb[2], 1)
                e.position = 0.0
                # set the color of the other points, spacing them evenly
                delta = 1.0 / (len(self.mouse_path) - 1)
                i = 0
                for x, y in self.mouse_path[1:]:
                    i += 1
                    bgl.glReadPixels(x + wx, y + wy, 1, 1, bgl.GL_RGB,
                                     bgl.GL_FLOAT, buf)
                    rgb = buf[0]
                    e = elements.new(i * delta)
                    e.color = (rgb[0], rgb[1], rgb[2], 1)
                return {'FINISHED'}

        elif event.type in {'RIGHTMOUSE', 'ESC'}:
            if self.cursor_set:
                context.window.cursor_modal_restore()
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}
Beispiel #13
0
def getlum():
    
    g.readL = 0
    if hasattr(g,"initialized"):
        for j in range(SAMPLES):
            bgl.glReadPixels(int(g.xpoint[j]),int(g.ypoint[j]), 1, 1, bgl.GL_LUMINANCE, bgl.GL_FLOAT, pixels)
            g.readL += pixels[0]            
    g.readL /= SAMPLES
    def modal(self, context, event):
        context.area.tag_redraw()

        if event.type == "MOUSEMOVE" or event.type == "INBETWEEN_MOUSEMOVE":
            if self.record:
                # note that we record the the mouse position relative to the window (not to the region)
                self.mouse_path.append((event.mouse_x, event.mouse_y))

        elif event.type == "LEFTMOUSE":
            if event.value == "PRESS" and not self.record:
                self.record = True
                self.mouse_path.append((event.mouse_x, event.mouse_y))
            else:  # release or second press while recording
                # bpy.types.SpaceImageEditor.draw_handler_remove(self._handle, 'WINDOW')
                if self.cursor_set:
                    context.window.cursor_modal_restore()
                # we can only have 32 elements in a color band so we have to down sample the mouse points
                nmp = len(self.mouse_path)
                if nmp > 32:
                    d = (nmp // 32) + 1
                    self.mouse_path = self.mouse_path[::d]
                buf = bgl.Buffer(bgl.GL_FLOAT, [1, 3])
                if len(self.mouse_path) == 1:
                    self.mouse_path.append(self.mouse_path[0])
                elements = context.active_object.active_material.node_tree.nodes.active.color_ramp.elements
                # remove all elements (setpoints). Last one cannot be removed
                while len(elements) > 1:
                    elements.remove(elements[0])
                    # set the color and the position of the first point
                    # note that our recorded mouse positions are relative to the window but the framebuffer in our context
                    # is also the whole window, in other words we do not have to add any offset.
                    # unfortunately we can only read pixels from our own framebuffer that means we cannot sample pixels
                    # outside our current window, not even another Blender window!
                wx = 0  # context.window.x
                wy = 0  # context.window.y
                x, y = self.mouse_path[0]
                bgl.glReadPixels(x + wx, y + wy, 1, 1, bgl.GL_RGB, bgl.GL_FLOAT, buf)
                e = elements[0]
                rgb = buf[0]
                e.color = (rgb[0], rgb[1], rgb[2], 1)
                e.position = 0.0
                # set the color of the other points, spacing them evenly
                delta = 1.0 / (len(self.mouse_path) - 1)
                i = 0
                for x, y in self.mouse_path[1:]:
                    i += 1
                    bgl.glReadPixels(x + wx, y + wy, 1, 1, bgl.GL_RGB, bgl.GL_FLOAT, buf)
                    rgb = buf[0]
                    e = elements.new(i * delta)
                    e.color = (rgb[0], rgb[1], rgb[2], 1)
                return {"FINISHED"}

        elif event.type in {"RIGHTMOUSE", "ESC"}:
            if self.cursor_set:
                context.window.cursor_modal_restore()
            return {"CANCELLED"}

        return {"RUNNING_MODAL"}
 def read_zbuffer(xy, wh=(1, 1)): # xy is in window coordinates!
     if isinstance(wh, (int, float)):
         wh = (wh, wh)
     elif len(wh) < 2:
         wh = (wh[0], wh[0])
     x, y, w, h = int(xy[0]), int(xy[1]), int(wh[0]), int(wh[1])
     zbuf = bgl.Buffer(bgl.GL_FLOAT, [w*h])
     bgl.glReadPixels(x, y, w, h, bgl.GL_DEPTH_COMPONENT, bgl.GL_FLOAT, zbuf)
     return zbuf
 def read_zbuffer(xy, wh=(1, 1)):  # xy is in window coordinates!
     if isinstance(wh, (int, float)):
         wh = (wh, wh)
     elif len(wh) < 2:
         wh = (wh[0], wh[0])
     x, y, w, h = int(xy[0]), int(xy[1]), int(wh[0]), int(wh[1])
     zbuf = bgl.Buffer(bgl.GL_FLOAT, [w * h])
     bgl.glReadPixels(x, y, w, h, bgl.GL_DEPTH_COMPONENT, bgl.GL_FLOAT,
                      zbuf)
     return zbuf
Beispiel #17
0
def render_debug_cross(context, props: MasterProperties) -> (bgl.Buffer, int):
    """
    Render debug cross
    :returns buffer with image and draw call count
    """
    shaders = Shaders()

    offscreen = gpu.types.GPUOffScreen(props.resolution.resolution_x,
                                       props.resolution.resolution_y)
    draw_count = 0

    quad_batch = batch_quad(shaders.debug)

    with offscreen.bind():
        # black background
        bgl.glClearColor(0.0, 0.0, 0.0, 1.0)
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
        bgl.glEnable(bgl.GL_BLEND)
        bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE)

        shaders.debug.bind()

        for position in props.positions:
            pos = Vector((position.manual_x, position.manual_y))

            # set position from object
            if position.variant == 'auto' and position.auto_object is not None:
                world_pos = position.auto_object.matrix_world.to_translation()
                pos = bpy_extras.object_utils.world_to_camera_view(
                    context.scene, context.scene.camera, world_pos)

            uniforms = {
                "flare_position":
                pos.xy,
                "aspect_ratio":
                props.resolution.resolution_x / props.resolution.resolution_y,
            }

            set_float_uniforms(shaders.debug, uniforms)

            quad_batch.draw(shaders.debug)
            draw_count += 1

        # copy rendered image to RAM
        buffer = bgl.Buffer(
            bgl.GL_FLOAT,
            props.resolution.resolution_x * props.resolution.resolution_y * 4)
        bgl.glReadBuffer(bgl.GL_BACK)
        bgl.glReadPixels(0, 0, props.resolution.resolution_x,
                         props.resolution.resolution_y, bgl.GL_RGBA,
                         bgl.GL_FLOAT, buffer)

    return buffer, draw_count
Beispiel #18
0
    def get_image(self):
        """
        sends serialized image, uint8 image

        """
        _buffer = bgl.Buffer(bgl.GL_INT, 4)
        bgl.glGetIntegerv(bgl.GL_VIEWPORT, _buffer)
        bgl.glReadBuffer(bgl.GL_FRONT)
        pix = bgl.Buffer(bgl.GL_INT, _buffer[2] * _buffer[3])
        bgl.glReadPixels(_buffer[0], _buffer[1], _buffer[2], _buffer[3], bgl.GL_LUMINANCE, bgl.GL_INT, pix)
        array = numpy.zeros((self.screen_w * self.screen_h), dtype=numpy.uint8)
        array[0:self.screen_w * self.screen_h] = pix
        self.get_data((self.screen_w, self.screen_h))
        for i in range(0, len(array), 400):
            self.get_data(array[i:i + 400])
Beispiel #19
0
    def _read_buffer(self, mval):
        xmin = int(mval[0]) - self._dist_px
        ymin = int(mval[1]) - self._dist_px
        size_x = size_y = self.threshold

        if xmin < 0:
            #size_x += xmin
            xmin = 0

        if ymin < 0:
            #size_y += ymin
            ymin = 0

        bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)
        bgl.glReadPixels(xmin, ymin, size_x, size_y, bgl.GL_RED_INTEGER,
                         bgl.GL_UNSIGNED_INT, self._snap_buffer)
 def modal(self, context, event):
     if ((event.type in {'RIGHTMOUSE', 'ESC'})
             or (event.type == 'LEFTMOUSE' and event.value == 'RELEASE')):
         context.area.header_text_set()
         context.window.cursor_modal_restore()
         context.area.tag_redraw()
         return {'CANCELLED'}
     elif (event.type in {'LEFTMOUSE', 'MOUSEMOVE'}
           and event.value == 'PRESS'):
         bgl.glReadPixels(event.mouse_x, event.mouse_y, 1, 1, bgl.GL_RGB,
                          bgl.GL_FLOAT, self.buf)
         t = "{c[0]:.3f},{c[1]:.3f},{c[2]:.3f}".format(c=self.buf[0])
         context.area.header_text_set(t)
         context.area.tag_redraw()
         return {'RUNNING_MODAL'}
     return {'RUNNING_MODAL'}
Beispiel #21
0
Datei: zu.py Projekt: vktec/zu
    def render(self, dg):
        scene = dg.scene
        scale = scene.render.resolution_percentage / 100.0
        width = int(scene.render.resolution_x * scale)
        height = int(scene.render.resolution_y * scale)

        zu.blen_gl_enable()

        try:
            # Create drawing target
            self.genfb(width, height)

            # Prep Zu scene
            self.scene = zu.scene_new()
            view_mat = self.camera_model_matrix(scene.camera)
            view_mat.invert()
            win_mat = scene.camera.calc_matrix_camera(dg, x=width, y=height)
            cam = win_mat @ view_mat
            zu.scene_cam(self.scene, mat(cam))
            self.load_dg(dg)

            # Render
            bgl.glViewport(0, 0, width, height)
            zu.scene_draw(self.scene, self.fb)

            # Retrieve texture data
            pixels = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
            bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT,
                             pixels)

            # Copy pixel data to output
            result = self.begin_result(0, 0, width, height)
            layer = result.layers[0].passes["Combined"]
            pixels = pixels.to_list()
            layer.rect = list(
                zip(*[pixels[i::4]
                      for i in range(4)]))  # FIXME: holy f**k this is slow
            self.end_result(result)

        finally:
            del self.objects
            self.objects = None
            del self.scene
            self.scene = None
            bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, 0)
            self.delfb()
            zu.blen_gl_disable()
def render_opengl_image(image_name, cam, point_size):
    draw_manager = DrawManager.get_singleton()
    coords, colors = draw_manager.get_coords_and_colors()

    scene = bpy.context.scene
    render = bpy.context.scene.render

    width = render.resolution_x
    height = render.resolution_y
    # TODO Provide an option to render from the 3D view perspective
    # width = bpy.context.region.width
    # height = bpy.context.region.height

    offscreen = gpu.types.GPUOffScreen(width, height)
    with offscreen.bind():

        bgl.glPointSize(point_size)
        bgl.glEnable(bgl.GL_DEPTH_TEST)
        # bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
        # bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT)

        view_matrix = cam.matrix_world.inverted()
        projection_matrix = cam.calc_matrix_camera(
            bpy.context.evaluated_depsgraph_get(), x=width, y=height
        )
        perspective_matrix = projection_matrix @ view_matrix

        gpu.matrix.load_matrix(perspective_matrix)
        gpu.matrix.load_projection_matrix(Matrix.Identity(4))

        shader = gpu.shader.from_builtin("3D_FLAT_COLOR")
        shader.bind()
        batch = batch_for_shader(
            shader, "POINTS", {"pos": coords, "color": colors}
        )
        batch.draw(shader)

        buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)
        bgl.glReadPixels(
            0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer
        )

    offscreen.free()

    image = create_image_lazy(image_name, width, height)
    copy_buffer_to_pixel(buffer, image)
def ReadOutDepthMap():
    global HarambePointer
    global b
    global pix

    start_time = time.time()
    # select the front buffer (the game window)
    bgl.glReadPixels(b[0], b[1], b[2], b[3], bgl.GL_DEPTH_COMPONENT,
                     bgl.GL_FLOAT, pix)

    jj = (ctypes.c_float * len(pix))()
    jj[:] = pix
    kfj = ctypes.pointer(jj)

    WriteDepthMapBufFile(ctypes.c_void_p(HarambePointer), kfj, len(jj))

    print("--- %s seconds ---" % (time.time() - start_time))
def capture_under_cursor(buffer, mouse_x=0, mouse_y=0, type_flg="i") -> list:
    """
    フラットなrgba(float)のlistを返す
    """
    # GL_FLOATでバッファ作って読むと馬鹿みたいに重いのでGL_BYTE,GL_UNSIGNED_BYTEになってる
    bgl.glReadBuffer(bgl.GL_FRONT)
    bgl.glReadPixels(
        mouse_x,
        mouse_y,
        1,
        1,
        bgl.GL_RGBA,
        bgl.GL_UNSIGNED_BYTE,
        buffer,
    )
    if type_flg == "i":
        return [value for value in buffer]
    elif type_flg == "f":
        return [value / 255 for value in buffer]
Beispiel #25
0
def gen_screenshot_texture(x, y, w, h, mode=None):
    scissor_is_enabled = bgl.Buffer(bgl.GL_BYTE, 1)
    bgl.glGetIntegerv(bgl.GL_SCISSOR_TEST, scissor_is_enabled)
    scissor_box = bgl.Buffer(bgl.GL_INT, 4)
    bgl.glGetIntegerv(bgl.GL_SCISSOR_BOX, scissor_box)
    bgl.glEnable(bgl.GL_SCISSOR_TEST)
    bgl.glScissor(x, y, w, h)

    mode_bak = bgl.Buffer(bgl.GL_INT, 1)
    bgl.glGetIntegerv(bgl.GL_READ_BUFFER, mode_bak)
    if mode is not None:
        bgl.glReadBuffer(mode)

    pixels = bgl.Buffer(bgl.GL_BYTE, 4 * w * h)
    # RGBAにしないと斜めになる
    # GL_UNSIGNED_BYTEでないと色が僅かにずれる
    bgl.glReadPixels(x, y, w, h, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, pixels)
    bgl.glFinish()

    if mode is not None:
        bgl.glReadBuffer(mode_bak[0])

    # 反転。確認用
    # for i in range(4 * w * h):
    #     if (i % 4) != 3:
    #         pixels[i] = 255 - pixels[i]

    tex = gen_texture()
    bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex)
    bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA, w, h, 0, bgl.GL_RGBA,
                     bgl.GL_UNSIGNED_BYTE, pixels)
    bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)

    if not scissor_is_enabled[0]:
        bgl.glDisable(bgl.GL_SCISSOR_TEST)
    bgl.glScissor(*scissor_box)

    return tex
Beispiel #26
0
def gen_screenshot_texture(x, y, w, h, mode=None):
    scissor_is_enabled = bgl.Buffer(bgl.GL_BYTE, 1)
    bgl.glGetIntegerv(bgl.GL_SCISSOR_TEST, scissor_is_enabled)
    scissor_box = bgl.Buffer(bgl.GL_INT, 4)
    bgl.glGetIntegerv(bgl.GL_SCISSOR_BOX, scissor_box)
    bgl.glEnable(bgl.GL_SCISSOR_TEST)
    bgl.glScissor(x, y, w, h)

    mode_bak = bgl.Buffer(bgl.GL_INT, 1)
    bgl.glGetIntegerv(bgl.GL_READ_BUFFER, mode_bak)
    if mode is not None:
        bgl.glReadBuffer(mode)

    pixels = bgl.Buffer(bgl.GL_BYTE, 4 * w * h)
    # RGBAにしないと斜めになる
    # GL_UNSIGNED_BYTEでないと色が僅かにずれる
    bgl.glReadPixels(x, y, w, h, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, pixels)
    bgl.glFinish()

    if mode is not None:
        bgl.glReadBuffer(mode_bak[0])

    # 反転。確認用
    # for i in range(4 * w * h):
    #     if (i % 4) != 3:
    #         pixels[i] = 255 - pixels[i]

    tex = gen_texture()
    bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex)
    bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA, w, h, 0, bgl.GL_RGBA,
                     bgl.GL_UNSIGNED_BYTE, pixels)
    bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)

    if not scissor_is_enabled[0]:
        bgl.glDisable(bgl.GL_SCISSOR_TEST)
    bgl.glScissor(*scissor_box)

    return tex
def perform_gpu_test(frag_source, cpu_func):
    grid = accel.HashedGrid(3)
    assert grid is not None
    hash_grid_glsl = gpu_utils.load_shader_file("gridhash", "def")
    shader = gpu.types.GPUShader(vert_source,
                                 frag_source,
                                 libcode=hash_grid_glsl)
    screen_size = 128
    offscreen = gpu.types.GPUOffScreen(screen_size, screen_size)
    points = [[-1, -1], [-1, 1], [1, 1], [1, -1]]
    indices = ((0, 1, 2), (2, 3, 0))
    batch = gpu_extras.batch.batch_for_shader(shader,
                                              "TRIS", {'pos': points},
                                              indices=indices)
    for z in range(-5, 5):
        gpu_hashes = []
        with offscreen.bind():
            shader.uniform_int('z', z)
            shader.uniform_int('screen_size', screen_size)
            batch.draw(shader)
            # Starting from blender 3.0 we can:
            #   fb = gpu.state.active_framebuffer_get()
            #   buffer = fb.read_color(0,0, screen_size, screen_size, 4, 0, UBYTE)
            buffer = bgl.Buffer(bgl.GL_BYTE, screen_size * screen_size * 4)
            bgl.glReadPixels(0, 0, screen_size, screen_size, bgl.GL_RGBA,
                             bgl.GL_UNSIGNED_BYTE, buffer)
            x = buffer[:]
            gpu_hashes = [
                a + 256 * (b + 256 * (c + 256 * d))
                for a, b, c, d in zip(x[::4], x[1::4], x[2::4], x[3::4])
            ]
        i = 0
        for y in range(-screen_size // 2, screen_size // 2):
            for x in range(-screen_size // 2, screen_size // 2):
                cpu_hash = cpu_func(grid, [x, y, z])
                assert gpu_hashes[i] == cpu_hash
                i += 1
    def drawCallback(self, context):
        # use ImageTexture.evaluate / get Image.pixels in case of View2D?

        # seems unnecessary to restore afterwards.
        bgl.glViewport(*self.viewport)
        bgl.glScissor(*self.viewport)

        b = bgl.Buffer(bgl.GL_FLOAT, 3)
        for p in itertools.chain(self.points, self.current_mouse_points):
            bgl.glReadPixels(p[0], p[1], 1, 1, bgl.GL_RGB, bgl.GL_FLOAT, b)
            p[-1] = self.convertColorspace(context, b.to_list())

        points_drawn = 0
        max_points_to_draw = PTS_LIMIT - self.remaining
        last_point_drawn = None
        for p in self.points:
            if points_drawn == max_points_to_draw:
                break
            self.drawPoint(*p[2:5])
            last_point_drawn = p
            points_drawn += 1

        # under cursor -> probably not wanted
        for p in self.current_mouse_points[:-1]:
            if points_drawn == max_points_to_draw:
                break
            self.drawPoint(*p[2:5])
            last_point_drawn = p
            points_drawn += 1

        segments_drawn = 0
        if len(self.points) > 1:
            ps = iter(self.points)
            next(ps)
            for p1, p2 in zip(self.points, ps):
                if segments_drawn == max_points_to_draw - 1:
                    break
                self.drawSegment(p1[2], p1[3], p2[2], p2[3], False)
                segments_drawn += 1

        if self.current_mouse_points:
            p1 = self.points[-1]
            p2 = self.current_mouse_points[0]
            if segments_drawn < max_points_to_draw - 1:
                self.drawSegment(p1[2], p1[3], p2[2], p2[3], True)
                segments_drawn += 1
                if len(self.current_mouse_points) > 1:
                    ps = iter(self.current_mouse_points)
                    next(ps)
                    for p1, p2 in zip(self.current_mouse_points, ps):
                        if segments_drawn == max_points_to_draw - 1:
                            break
                        self.drawSegment(p1[2], p1[3], p2[2], p2[3], True)
                        segments_drawn += 1

        if points_drawn == max_points_to_draw:
            # this means even the point under the cursor _is_ already
            # surnumerary, thus we have to draw the last segment in red
            if self.current_mouse_points:
                p1 = last_point_drawn
                p2 = self.current_mouse_points[-1]
                self.drawSegment(p1[2], p1[3], p2[2], p2[3], True, True)

        if context.window_manager.crd_show_values:
            for p, i in zip(itertools.chain(self.points, self.current_mouse_points), range(points_drawn)):
                blf.position(0, p[2] + 10, p[3] - 10, 0)
                bgl.glColor4f(0.8, 0.8, 0.8, 1.0)
                blf.size(0, 10, context.user_preferences.system.dpi)
                blf.draw(0, "(%.3f, %.3f, %.3f)" % tuple(p[-1]))
            if points_drawn <= max_points_to_draw:
                # we want to draw the current color anyways
                if self.current_mouse_points:
                    p = self.current_mouse_points[-1]
                    blf.position(0, p[2] + 10, p[3] - 10, 0)
                    bgl.glColor4f(0.8, 0.8, 0.8, 1.0)
                    blf.size(0, 10, context.user_preferences.system.dpi)
                    blf.draw(0, "(%.3f, %.3f, %.3f)" % tuple(p[-1]))

        bgl.glColor4f(0.8, 0.8, 0.8, 1.0)
        blf.size(0, 20, context.user_preferences.system.dpi)
        if context.window_manager.crd_use_intermediate:
            blf.position(0, 10, 60, 0)
            blf.draw(0, "Oversamples:")
            blf.position(0, 160, 60, 0)
            blf.draw(0, str(context.window_manager.crd_intermediate_amount))
        blf.position(0, 10, 30, 0)
        blf.draw(0, "Path Type:")
        blf.position(0, 160, 30, 0)
        blf.draw(0, {"POLYLINE": "Polyline", "CUBIC_SPLINE": "Cubic Spline"}[context.window_manager.crd_path_type])
Beispiel #29
0
def render_main(self, context, animation=False):
    # Save old info
    settings = bpy.context.scene.render.image_settings
    depth = settings.color_depth
    settings.color_depth = '8'

    # Get object list
    scene = context.scene
    objlist = context.scene.objects
    # --------------------
    # Get resolution
    # --------------------
    render_scale = scene.render.resolution_percentage / 100
    width = int(scene.render.resolution_x * render_scale)
    height = int(scene.render.resolution_y * render_scale)

    # --------------------------------------
    # Loop to draw all lines in Offsecreen
    # --------------------------------------
    offscreen = gpu.types.GPUOffScreen(width, height)
    view_matrix = Matrix([[2 / width, 0, 0, -1], [0, 2 / height, 0, -1],
                          [0, 0, 1, 0], [0, 0, 0, 1]])

    with offscreen.bind():
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
        gpu.matrix.reset()
        gpu.matrix.load_matrix(view_matrix)
        gpu.matrix.load_projection_matrix(Matrix.Identity(4))

        # -----------------------------
        # Loop to draw all objects
        # -----------------------------
        for myobj in objlist:
            if myobj.visible_get() is True:
                if 'MeasureGenerator' in myobj:
                    op = myobj.MeasureGenerator[0]
                    draw_segments(context, myobj, op, None, None)
        # -----------------------------
        # Loop to draw all debug
        # -----------------------------
        if scene.measureit_debug is True:
            selobj = bpy.context.selected_objects
            for myobj in selobj:
                if scene.measureit_debug_objects is True:
                    draw_object(context, myobj, None, None)
                elif scene.measureit_debug_object_loc is True:
                    draw_object(context, myobj, None, None)
                if scene.measureit_debug_vertices is True:
                    draw_vertices(context, myobj, None, None)
                elif scene.measureit_debug_vert_loc is True:
                    draw_vertices(context, myobj, None, None)
                if scene.measureit_debug_edges is True:
                    draw_edges(context, myobj, None, None)
                if scene.measureit_debug_faces is True or scene.measureit_debug_normals is True:
                    draw_faces(context, myobj, None, None)
        # -----------------------------
        # Draw a rectangle frame
        # -----------------------------
        if scene.measureit_rf is True:
            rfcolor = scene.measureit_rf_color
            rfborder = scene.measureit_rf_border
            rfline = scene.measureit_rf_line

            bgl.glLineWidth(rfline)
            x1 = rfborder
            x2 = width - rfborder
            y1 = int(ceil(rfborder / (width / height)))
            y2 = height - y1
            draw_rectangle((x1, y1), (x2, y2), rfcolor)

        buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)
        bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)
        bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA,
                         bgl.GL_UNSIGNED_BYTE, buffer)

    offscreen.free()

    # -----------------------------
    # Create image
    # -----------------------------
    image_name = "measureit_output"
    if not image_name in bpy.data.images:
        bpy.data.images.new(image_name, width, height)

    image = bpy.data.images[image_name]
    image.scale(width, height)
    image.pixels = [v / 255 for v in buffer]

    # Saves image
    if image is not None and (scene.measureit_render is True
                              or animation is True):
        ren_path = bpy.context.scene.render.filepath
        filename = "mit_frame"
        if len(ren_path) > 0:
            if ren_path.endswith(path.sep):
                initpath = path.realpath(ren_path) + path.sep
            else:
                (initpath, filename) = path.split(ren_path)

        ftxt = "%04d" % scene.frame_current
        outpath = path.realpath(path.join(initpath, filename + ftxt + ".png"))
        save_image(self, outpath, image)

    # restore default value
    settings.color_depth = depth
Beispiel #30
0
def render_opengl(self, context):
    from math import ceil

    layers = []
    scene = context.scene
    for x in range(0, 20):
        if scene.layers[x] is True:
            layers.extend([x])

    objlist = context.scene.objects
    render_scale = scene.render.resolution_percentage / 100

    width = int(scene.render.resolution_x * render_scale)
    height = int(scene.render.resolution_y * render_scale)

    # I cant use file_format becuase the pdf writer needs jpg format
    # the file_format returns 'JPEG' not 'JPG'
    #     file_format = context.scene.render.image_settings.file_format.lower()
    ren_path = bpy.path.abspath(bpy.context.scene.render.filepath) + ".jpg"

    #     if len(ren_path) > 0:
    #         if ren_path.endswith(os.path.sep):
    #             initpath = os.path.realpath(ren_path) + os.path.sep
    #         else:
    #             (initpath, filename) = os.path.split(ren_path)
    #         outpath = os.path.join(initpath, "ogl_tmp.png")
    #     else:
    #         self.report({'ERROR'}, "Invalid render path")
    #         return False

    img = get_render_image(ren_path)

    if img is None:
        self.report({'ERROR'}, "Invalid render path:" + ren_path)
        return False

    tile_x = 240
    tile_y = 216
    row_num = ceil(height / tile_y)
    col_num = ceil(width / tile_x)

    cut4 = (col_num * tile_x * 4) - width * 4
    totpixel4 = width * height * 4

    viewport_info = bgl.Buffer(bgl.GL_INT, 4)
    bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info)

    img.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST)

    # 2.77 API change
    if bpy.app.version >= (2, 77, 0):
        tex = img.bindcode[0]
    else:
        tex = img.bindcode

    if context.scene.name in bpy.data.images:
        old_img = bpy.data.images[context.scene.name]
        old_img.user_clear()
        bpy.data.images.remove(old_img)

    img_result = bpy.data.images.new(context.scene.name, width, height)

    tmp_pixels = [1] * totpixel4

    #---------- Loop for all tiles
    for row in range(0, row_num):
        for col in range(0, col_num):
            buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
            bgl.glDisable(
                bgl.GL_SCISSOR_TEST
            )  # if remove this line, get blender screenshot not image
            bgl.glViewport(0, 0, tile_x, tile_y)

            bgl.glMatrixMode(bgl.GL_PROJECTION)
            bgl.glLoadIdentity()

            # defines ortographic view for single tile
            x1 = tile_x * col
            y1 = tile_y * row
            bgl.gluOrtho2D(x1, x1 + tile_x, y1, y1 + tile_y)

            # Clear
            bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
            bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)

            bgl.glEnable(bgl.GL_TEXTURE_2D)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex)

            # defines drawing area
            bgl.glBegin(bgl.GL_QUADS)

            bgl.glColor3f(1.0, 1.0, 1.0)
            bgl.glTexCoord2f(0.0, 0.0)
            bgl.glVertex2f(0.0, 0.0)

            bgl.glTexCoord2f(1.0, 0.0)
            bgl.glVertex2f(width, 0.0)

            bgl.glTexCoord2f(1.0, 1.0)
            bgl.glVertex2f(width, height)

            bgl.glTexCoord2f(0.0, 1.0)
            bgl.glVertex2f(0.0, height)

            bgl.glEnd()

            for obj in objlist:
                if obj.mv.type == 'VISDIM_A':
                    for x in range(0, 20):
                        if obj.layers[x] is True:
                            if x in layers:
                                opengl_dim = obj.mv.opengl_dim
                                if not opengl_dim.hide:
                                    draw_dimensions(context, obj, opengl_dim,
                                                    None, None)
                            break

            #---------- copy pixels to temporary area
            bgl.glFinish()
            bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT,
                             buffer)  # read image data
            for y in range(0, tile_y):
                # final image pixels position
                p1 = (y * width * 4) + (row * tile_y * width *
                                        4) + (col * tile_x * 4)
                p2 = p1 + (tile_x * 4)
                # buffer pixels position
                b1 = y * width * 4
                b2 = b1 + (tile_x * 4)

                if p1 < totpixel4:  # avoid pixel row out of area
                    if col == col_num - 1:  # avoid pixel columns out of area
                        p2 -= cut4
                        b2 -= cut4

                    tmp_pixels[p1:p2] = buffer[b1:b2]

    img_result.pixels = tmp_pixels[:]
    img.gl_free()

    img.user_clear()
    bpy.data.images.remove(img)
    os.remove(ren_path)
    bgl.glEnable(bgl.GL_SCISSOR_TEST)

    #---------- restore opengl defaults
    bgl.glLineWidth(1)
    bgl.glDisable(bgl.GL_BLEND)
    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)

    if img_result is not None:
        return img_result
Beispiel #31
0
    def snap_get(self, mval, main_snap_obj = None):
        ret = None, None, None
        self.mval[:] = mval
        snap_vert = self._snap_mode & VERT != 0
        snap_edge = self._snap_mode & EDGE != 0
        snap_face = self._snap_mode & FACE != 0

        _Internal.gpu_Indices_enable_state()
        self._offscreen.bind()

        #bgl.glDisable(bgl.GL_DITHER) # dithering and AA break color coding, so disable #
        #multisample_enabled = bgl.glIsEnabled(bgl.GL_MULTISAMPLE)
        #bgl.glDisable(bgl.GL_MULTISAMPLE)
        bgl.glEnable(bgl.GL_DEPTH_TEST)

        proj_mat = self.rv3d.perspective_matrix.copy()
        if self.proj_mat != proj_mat:
            self.proj_mat = proj_mat
            _Internal.gpu_Indices_set_ProjectionMatrix(self.proj_mat)
            self.update_drawing()

        ray_dir, ray_orig = self.get_ray(mval)
        for i, snap_obj in enumerate(self.snap_objects[self.drawn_count:], self.drawn_count):
            obj = snap_obj.data[0]
            try:
                bbmin = Vector(obj.bound_box[0])
                bbmax = Vector(obj.bound_box[6])
            except ReferenceError:
                self.snap_objects.remove(snap_obj)
                continue

            if bbmin != bbmax:
                MVP = proj_mat @ snap_obj.mat
                mat_inv = snap_obj.mat.inverted()
                ray_orig_local = mat_inv @ ray_orig
                ray_dir_local = mat_inv.to_3x3() @ ray_dir
                in_threshold = _Internal.intersect_boundbox_threshold(
                        self, MVP, ray_orig_local, ray_dir_local, bbmin, bbmax)
            else:
                proj_co = _Internal.project_co_v3(self, snap_obj.mat.translation)
                dist = self.mval - proj_co
                in_threshold = abs(dist.x) < self._dist_px and abs(dist.y) < self._dist_px
                #snap_obj.data[1] = primitive_point

            if in_threshold:
                if len(snap_obj.data) == 1:
                    from .mesh_drawing import GPU_Indices_Mesh
                    is_bound = obj.display_type == 'BOUNDS'
                    draw_face = snap_face and not is_bound and obj.display_type != 'WIRE'
                    draw_edge = snap_edge and not is_bound
                    draw_vert = snap_vert and not is_bound
                    snap_obj.data.append(GPU_Indices_Mesh(self.depsgraph, obj, draw_face, draw_edge, draw_vert))

                snap_obj.data[1].set_draw_mode(snap_face, snap_edge, snap_vert)
                snap_obj.data[1].set_ModelViewMatrix(snap_obj.mat)

                if snap_obj == main_snap_obj:
                    snap_obj.data[1].Draw(self._offset_cur, -0.0001)
                else:
                    snap_obj.data[1].Draw(self._offset_cur)
                self._offset_cur += snap_obj.data[1].get_tot_elems()

                tmp = self.snap_objects[self.drawn_count]
                self.snap_objects[self.drawn_count] = self.snap_objects[i]
                self.snap_objects[i] = tmp

                self.drawn_count += 1

        bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)

        bgl.glReadPixels(
                int(self.mval[0]) - self._dist_px, int(self.mval[1]) - self._dist_px,
                self.threshold, self.threshold, bgl.GL_RED_INTEGER, bgl.GL_UNSIGNED_INT, self._snap_buffer)

        #bgl.glReadBuffer(bgl.GL_BACK)
        #import numpy as np
        #a = np.array(self._snap_buffer)
        #print(a)

        snap_obj, index = self._get_nearest_index()
        #print("index:", index)
        if snap_obj:
            ret = self._get_loc(snap_obj, index)

        bgl.glDisable(bgl.GL_DEPTH_TEST)

        self._offscreen.unbind()
        _Internal.gpu_Indices_restore_state()

        return (snap_obj, *ret)
Beispiel #32
0
def render_lens_flare(context, props: MasterProperties) -> (bgl.Buffer, int):
    """
    Renders lens flare effect to buffer
    :returns buffer with effect
    """
    max_x = props.resolution.resolution_x
    max_y = props.resolution.resolution_y

    # render kinda circles
    blades = props.camera.blades
    if blades == 0:
        blades = 256

    shaders = Shaders()

    offscreen = gpu.types.GPUOffScreen(max_x, max_y)
    ghost_fb = gpu.types.GPUOffScreen(max_x, max_y)

    ghost_batch = batch_from_blades(blades, shaders.ghost)
    quad_batch = batch_quad(shaders.flare)

    draw_count = 0

    noise_tex = NoiseTexture()

    # clear framebuffer
    with offscreen.bind():
        # black background
        bgl.glClearColor(0.0, 0.0, 0.0, 1.0)
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
        bgl.glEnable(bgl.GL_BLEND)
        bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE)

    for position in props.positions:
        pos = Vector((position.manual_x, position.manual_y))

        # set position from object
        if position.variant == 'auto' and position.auto_object is not None:
            world_pos = position.auto_object.matrix_world.to_translation()
            pos = bpy_extras.object_utils.world_to_camera_view(
                context.scene, context.scene.camera, world_pos)

        flare_vector = pos.xy - Vector((0.5, 0.5))
        flare_vector.normalize()

        # first render ghosts one by one
        for ghost in props.ghosts:
            # calculate position
            ghost_x = ((pos.x - 0.5) * 2.0) * ghost.offset
            ghost_y = ((pos.y - 0.5) * 2.0) * ghost.offset
            # add perpendicular offset
            ghost_x += flare_vector.y * ghost.perpendicular_offset
            ghost_y += -flare_vector.x * ghost.perpendicular_offset

            with ghost_fb.bind():
                render_ghost(props, ghost, shaders.ghost, ghost_batch,
                             flare_vector, pos)
                draw_count += 1

            with offscreen.bind():
                # now copy to final buffer
                bgl.glActiveTexture(bgl.GL_TEXTURE0)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, ghost_fb.color_texture)

                # disable wrapping
                bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                    bgl.GL_CLAMP_TO_BORDER)
                bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                    bgl.GL_CLAMP_TO_BORDER)

                border_color = bgl.Buffer(bgl.GL_FLOAT, 4,
                                          [0.0, 0.0, 0.0, 1.0])

                bgl.glTexParameterfv(bgl.GL_TEXTURE_2D,
                                     bgl.GL_TEXTURE_BORDER_COLOR, border_color)

                bgl.glActiveTexture(bgl.GL_TEXTURE2)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D,
                                  props.spectrum_image.bindcode)

                bgl.glActiveTexture(bgl.GL_TEXTURE1)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, noise_tex.gl_code)

                copy_ghost(shaders.copy, quad_batch, ghost, props,
                           Vector((ghost_x, ghost_y)))
                draw_count += 1

        # finally render flare on top
        with offscreen.bind():
            bgl.glActiveTexture(bgl.GL_TEXTURE0)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, noise_tex.gl_code)

            render_flare(props, pos.xy, shaders.flare, quad_batch)
            draw_count += 1

    with offscreen.bind():
        # copy rendered image to RAM
        buffer = bgl.Buffer(bgl.GL_FLOAT, max_x * max_y * 4)
        bgl.glReadBuffer(bgl.GL_BACK)
        bgl.glReadPixels(0, 0, max_x, max_y, bgl.GL_RGBA, bgl.GL_FLOAT, buffer)

    offscreen.free()
    ghost_fb.free()
    noise_tex.free()

    return buffer, draw_count
Beispiel #33
0
def render_main(self, context, animation=False):
    # noinspection PyBroadException,PyBroadException
    try:
        # Get visible layers
        layers = []
        scene = context.scene
        for x in range(0, 20):
            if scene.layers[x] is True:
                layers.extend([x])

        # Get object list
        objlist = context.scene.objects
        # --------------------
        # Get resolution
        # --------------------
        scene = bpy.context.scene
        render_scale = scene.render.resolution_percentage / 100

        width = int(scene.render.resolution_x * render_scale)
        height = int(scene.render.resolution_y * render_scale)

        # ---------------------------------------
        # Get output path
        # ---------------------------------------
        ren_path = bpy.context.scene.render.filepath
        if len(ren_path) > 0:
            if ren_path.endswith(os.path.sep):
                initpath = os.path.realpath(ren_path) + os.path.sep
            else:
                (initpath, filename) = os.path.split(ren_path)
            outpath = os.path.join(initpath, "measureit_tmp_render.png")
        else:
            self.report({'ERROR'},
                        "MeasureIt: Unable to save temporary render image. Define a valid render path")
            return False

        # Get Render Image
        img = get_render_image(outpath)
        if img is None:
            self.report({'ERROR'},
                        "MeasureIt: Unable to save temporary render image. Define a valid render path")
            return False

        # -----------------------------
        # Calculate rows and columns
        # -----------------------------
        tile_x = 240
        tile_y = 216
        row_num = ceil(height / tile_y)
        col_num = ceil(width / tile_x)
        print("MeasureIt: Image divided in " + str(row_num) + "x" + str(col_num) + " tiles")

        # pixels out of visible area
        cut4 = (col_num * tile_x * 4) - width * 4  # pixels aout of drawing area
        totpixel4 = width * height * 4  # total pixels RGBA

        viewport_info = bgl.Buffer(bgl.GL_INT, 4)
        bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info)

        # Load image on memory
        img.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST)
        tex = img.bindcode

        # --------------------------------------------
        # Create output image (to apply texture)
        # --------------------------------------------
        if "measureit_output" in bpy.data.images:
            out_img = bpy.data.images["measureit_output"]
            if out_img is not None:
                out_img.user_clear()
                bpy.data.images.remove(out_img)

        out = bpy.data.images.new("measureit_output", width, height)
        tmp_pixels = [1] * totpixel4

        # --------------------------------
        # Loop for all tiles
        # --------------------------------
        for row in range(0, row_num):
            for col in range(0, col_num):
                buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
                bgl.glDisable(bgl.GL_SCISSOR_TEST)  # if remove this line, get blender screenshot not image
                bgl.glViewport(0, 0, tile_x, tile_y)

                bgl.glMatrixMode(bgl.GL_PROJECTION)
                bgl.glLoadIdentity()

                # defines ortographic view for single tile
                x1 = tile_x * col
                y1 = tile_y * row
                bgl.gluOrtho2D(x1, x1 + tile_x, y1, y1 + tile_y)

                # Clear
                bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
                bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)

                bgl.glEnable(bgl.GL_TEXTURE_2D)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex)

                # defines drawing area
                bgl.glBegin(bgl.GL_QUADS)

                bgl.glColor3f(1.0, 1.0, 1.0)
                bgl.glTexCoord2f(0.0, 0.0)
                bgl.glVertex2f(0.0, 0.0)

                bgl.glTexCoord2f(1.0, 0.0)
                bgl.glVertex2f(width, 0.0)

                bgl.glTexCoord2f(1.0, 1.0)
                bgl.glVertex2f(width, height)

                bgl.glTexCoord2f(0.0, 1.0)
                bgl.glVertex2f(0.0, height)

                bgl.glEnd()

                # -----------------------------
                # Loop to draw all lines
                # -----------------------------
                for myobj in objlist:
                    if myobj.hide is False:
                        if 'MeasureGenerator' in myobj:
                            # verify visible layer
                            for x in range(0, 20):
                                if myobj.layers[x] is True:
                                    if x in layers:
                                        op = myobj.MeasureGenerator[0]
                                        draw_segments(context, myobj, op, None, None)
                                    break

                if scene.measureit_rf is True:
                    bgl.glColor3f(1.0, 1.0, 1.0)
                    rfcolor = scene.measureit_rf_color
                    rfborder = scene.measureit_rf_border
                    rfline = scene.measureit_rf_line

                    bgl.glLineWidth(rfline)
                    bgl.glColor4f(rfcolor[0], rfcolor[1], rfcolor[2], rfcolor[3])

                    x1 = rfborder
                    x2 = width - rfborder
                    y1 = int(math.ceil(rfborder / (width / height)))
                    y2 = height - y1
                    draw_rectangle((x1, y1), (x2, y2))

                # --------------------------------
                # copy pixels to temporary area
                # --------------------------------
                bgl.glFinish()
                bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT, buffer)  # read image data
                for y in range(0, tile_y):
                    # final image pixels position
                    p1 = (y * width * 4) + (row * tile_y * width * 4) + (col * tile_x * 4)
                    p2 = p1 + (tile_x * 4)
                    # buffer pixels position
                    b1 = y * width * 4
                    b2 = b1 + (tile_x * 4)

                    if p1 < totpixel4:  # avoid pixel row out of area
                        if col == col_num - 1:  # avoid pixel columns out of area
                            p2 -= cut4
                            b2 -= cut4

                        tmp_pixels[p1:p2] = buffer[b1:b2]

        # -----------------------
        # Copy temporary to final
        # -----------------------
        out.pixels = tmp_pixels[:]  # Assign image data
        img.gl_free()  # free opengl image memory

        # delete image
        img.user_clear()
        bpy.data.images.remove(img)
        # remove temp file
        os.remove(outpath)
        # reset
        bgl.glEnable(bgl.GL_SCISSOR_TEST)
        # -----------------------
        # restore opengl defaults
        # -----------------------
        bgl.glLineWidth(1)
        bgl.glDisable(bgl.GL_BLEND)
        bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
        # Saves image
        if out is not None and (scene.measureit_render is True or animation is True):
            ren_path = bpy.context.scene.render.filepath
            filename = "mit_frame"
            if len(ren_path) > 0:
                if ren_path.endswith(os.path.sep):
                    initpath = os.path.realpath(ren_path) + os.path.sep
                else:
                    (initpath, filename) = os.path.split(ren_path)

            ftxt = "%04d" % scene.frame_current
            outpath = os.path.join(initpath, filename + ftxt + ".png")

            save_image(self, outpath, out)

        return True

    except:
        print("Unexpected error:" + str(sys.exc_info()))
        self.report({'ERROR'}, "MeasureIt: Unable to create render image")
        return False
def render_main_svg(self, context, animation=False):

    # Save old info
    scene = context.scene
    sceneProps= scene.MeasureItArchProps
    sceneProps.is_render_draw = True
    sceneProps.is_vector_draw = True

    clipdepth = context.scene.camera.data.clip_end
    path = scene.render.filepath
    objlist = context.view_layer.objects

    # --------------------
    # Get resolution
    # --------------------

    render_scale = scene.render.resolution_percentage / 100
    width = int(scene.render.resolution_x * render_scale)
    height = int(scene.render.resolution_y * render_scale)

    offscreen = gpu.types.GPUOffScreen(width, height)
    
    view_matrix_3d = scene.camera.matrix_world.inverted()
    projection_matrix = scene.camera.calc_matrix_camera(context.view_layer.depsgraph, x=width, y=height)

    # Render Depth Buffer
    with offscreen.bind():
        # Clear Depth Buffer, set Clear Depth to Cameras Clip Distance
        bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT)
        bgl.glClearDepth(clipdepth)
        bgl.glEnable(bgl.GL_DEPTH_TEST)
        bgl.glDepthFunc(bgl.GL_LEQUAL)  

        gpu.matrix.reset()
        gpu.matrix.load_matrix(view_matrix_3d)
        gpu.matrix.load_projection_matrix(projection_matrix)

        texture_buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)

        draw_scene(self, context, projection_matrix) 

        bgl.glReadBuffer(bgl.GL_BACK)
        bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, texture_buffer)

        if 'depthbuffer' in sceneProps:
            del sceneProps['depthbuffer']
        sceneProps['depthbuffer'] = texture_buffer
    offscreen.free()

    if True:
        if not str('test') in bpy.data.images:
            bpy.data.images.new(str('test'), width, height)
        image = bpy.data.images[str('test')]
        image.scale(width, height)
        image.pixels = [v / 255 for v in texture_buffer]



    # Setup Output Path
    ren_path = bpy.context.scene.render.filepath
    filename = "mit_vector"
    ftxt = "%04d" % scene.frame_current
    outpath = (ren_path + filename + ftxt + '.svg')

    # Setup basic svg
    svg = svgwrite.Drawing(
            outpath,
            debug=False,
            size=('{}mm'.format(width), '{}mm'.format(height)),
            viewBox=('0 0 {} {}'.format(width,height)),
            id='root',
        )



    # -----------------------------
    # Loop to draw all objects
    # -----------------------------
    for myobj in objlist:
        if myobj.visible_get() is True:
            mat = myobj.matrix_world
            if 'DimensionGenerator' in myobj:
                measureGen = myobj.DimensionGenerator[0]
                if 'alignedDimensions' in measureGen:
                    for linDim in measureGen.alignedDimensions:
                        draw_alignedDimension(context, myobj, measureGen,linDim,mat,svg=svg)
                if 'angleDimensions' in measureGen:
                    for dim in measureGen.angleDimensions:
                        draw_angleDimension(context, myobj, measureGen,dim,mat,svg=svg)
                if 'axisDimensions' in measureGen:
                    for dim in measureGen.axisDimensions:
                        draw_axisDimension(context, myobj, measureGen,dim,mat,svg=svg)
                if 'boundsDimensions' in measureGen:
                    for dim in measureGen.boundsDimensions:
                        draw_boundsDimension(context, myobj, measureGen,dim,mat,svg=svg)
                if 'arcDimensions' in measureGen:
                    for dim in measureGen.arcDimensions:
                        draw_arcDimension(context, myobj, measureGen,dim,mat,svg=svg)
                if 'areaDimensions' in measureGen:
                    for dim in measureGen.areaDimensions:
                        draw_areaDimension(context, myobj, measureGen,dim,mat,svg=svg)

            if 'LineGenerator' in myobj:
                # Draw Line Groups
                op = myobj.LineGenerator[0]
                draw_line_group(context, myobj, op, mat,svg=svg)
            
            #if 'AnnotationGenerator' in myobj:
            #    op = myobj.AnnotationGenerator[0]
            #    draw_annotation(context, myobj, op, mat)                
        
        if False:
            # Draw Instance 
            deps = bpy.context.view_layer.depsgraph
            for obj_int in deps.object_instances:
                if obj_int.is_instance:
                    myobj = obj_int.object
                    mat = obj_int.matrix_world

                    if 'LineGenerator' in myobj:
                        lineGen = myobj.LineGenerator[0]
                        draw_line_group(context,myobj,lineGen,mat)
                    
                    if sceneProps.instance_dims:
                        if 'AnnotationGenerator' in myobj:
                            annotationGen = myobj.AnnotationGenerator[0]
                            draw_annotation(context,myobj,annotationGen,mat)

                        if 'DimensionGenerator' in myobj:
                            DimGen = myobj.DimensionGenerator[0]
                            for alignedDim in DimGen.alignedDimensions:
                                draw_alignedDimension(context, myobj, DimGen, alignedDim,mat)
                            for angleDim in DimGen.angleDimensions:
                                draw_angleDimension(context, myobj, DimGen, angleDim,mat)
                            for axisDim in DimGen.axisDimensions:
                                draw_axisDimension(context,myobj,DimGen,axisDim,mat)
            
 

    svg.save(pretty=True)
    # restore default value
    sceneProps.is_render_draw = False
    sceneProps.is_vector_draw = False
    return True
def render_opengl(self, context):
    from math import ceil

    layers = []
    scene = context.scene
    for x in range(0, 20):
        if scene.layers[x] is True:
            layers.extend([x])

    objlist = context.scene.objects
    render_scale = scene.render.resolution_percentage / 100

    width = int(scene.render.resolution_x * render_scale)
    height = int(scene.render.resolution_y * render_scale)
    
    # I cant use file_format becuase the pdf writer needs jpg format
    # the file_format returns 'JPEG' not 'JPG'
#     file_format = context.scene.render.image_settings.file_format.lower()
    ren_path = bpy.path.abspath(bpy.context.scene.render.filepath) + ".jpg"
    
#     if len(ren_path) > 0:
#         if ren_path.endswith(os.path.sep):
#             initpath = os.path.realpath(ren_path) + os.path.sep
#         else:
#             (initpath, filename) = os.path.split(ren_path)
#         outpath = os.path.join(initpath, "ogl_tmp.png")
#     else:
#         self.report({'ERROR'}, "Invalid render path")
#         return False

    img = get_render_image(ren_path)
    
    if img is None:
        self.report({'ERROR'}, "Invalid render path:" + ren_path)
        return False

    tile_x = 240
    tile_y = 216
    row_num = ceil(height / tile_y)
    col_num = ceil(width / tile_x)
    
    cut4 = (col_num * tile_x * 4) - width * 4  
    totpixel4 = width * height * 4 

    viewport_info = bgl.Buffer(bgl.GL_INT, 4)
    bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info)
    
    img.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST)

    # 2.77 API change
    if bpy.app.version >= (2, 77, 0):
        tex = img.bindcode[0]
    else:
        tex = img.bindcode
    
    if context.scene.name in bpy.data.images:
        old_img = bpy.data.images[context.scene.name]
        old_img.user_clear()
        bpy.data.images.remove(old_img)
             
    img_result = bpy.data.images.new(context.scene.name, width, height)        
    
    tmp_pixels = [1] * totpixel4

    #---------- Loop for all tiles
    for row in range(0, row_num):
        for col in range(0, col_num):
            buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
            bgl.glDisable(bgl.GL_SCISSOR_TEST)  # if remove this line, get blender screenshot not image
            bgl.glViewport(0, 0, tile_x, tile_y)

            bgl.glMatrixMode(bgl.GL_PROJECTION)
            bgl.glLoadIdentity()

            # defines ortographic view for single tile
            x1 = tile_x * col
            y1 = tile_y * row
            bgl.gluOrtho2D(x1, x1 + tile_x, y1, y1 + tile_y)

            # Clear
            bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
            bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)

            bgl.glEnable(bgl.GL_TEXTURE_2D)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex)

            # defines drawing area
            bgl.glBegin(bgl.GL_QUADS)

            bgl.glColor3f(1.0, 1.0, 1.0)
            bgl.glTexCoord2f(0.0, 0.0)
            bgl.glVertex2f(0.0, 0.0)

            bgl.glTexCoord2f(1.0, 0.0)
            bgl.glVertex2f(width, 0.0)

            bgl.glTexCoord2f(1.0, 1.0)
            bgl.glVertex2f(width, height)

            bgl.glTexCoord2f(0.0, 1.0)
            bgl.glVertex2f(0.0, height)

            bgl.glEnd()

            for obj in objlist:
                if obj.mv.type == 'VISDIM_A':
                    for x in range(0, 20):
                        if obj.layers[x] is True:
                            if x in layers:
                                opengl_dim = obj.mv.opengl_dim
                                if not opengl_dim.hide:
                                    draw_dimensions(context, obj, opengl_dim, None, None)
                            break 

            #---------- copy pixels to temporary area
            bgl.glFinish()
            bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT, buffer)  # read image data
            for y in range(0, tile_y):
                # final image pixels position
                p1 = (y * width * 4) + (row * tile_y * width * 4) + (col * tile_x * 4)
                p2 = p1 + (tile_x * 4)
                # buffer pixels position
                b1 = y * width * 4
                b2 = b1 + (tile_x * 4)

                if p1 < totpixel4:  # avoid pixel row out of area
                    if col == col_num - 1:  # avoid pixel columns out of area
                        p2 -= cut4
                        b2 -= cut4

                    tmp_pixels[p1:p2] = buffer[b1:b2]

    img_result.pixels = tmp_pixels[:]
    img.gl_free()

    img.user_clear()
    bpy.data.images.remove(img)
    os.remove(ren_path)
    bgl.glEnable(bgl.GL_SCISSOR_TEST)

    #---------- restore opengl defaults
    bgl.glLineWidth(1)
    bgl.glDisable(bgl.GL_BLEND)
    bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
    
    if img_result is not None:            
        return img_result
Beispiel #36
0
    def snap_get(self, mval, main_snap_obj = None):
        ret = None, None, None
        self.mval[:] = mval
        snap_vert = self._snap_mode & VERT != 0
        snap_edge = self._snap_mode & EDGE != 0
        snap_face = self._snap_mode & FACE != 0

        _Internal.gpu_Indices_enable_state()
        self._offscreen.bind()

        #bgl.glDisable(bgl.GL_DITHER) # dithering and AA break color coding, so disable #
        #multisample_enabled = bgl.glIsEnabled(bgl.GL_MULTISAMPLE)
        #bgl.glDisable(bgl.GL_MULTISAMPLE)
        bgl.glEnable(bgl.GL_DEPTH_TEST)

        proj_mat = self.rv3d.perspective_matrix.copy()
        if self.proj_mat != proj_mat:
            self.proj_mat = proj_mat
            _Internal.gpu_Indices_set_ProjectionMatrix(self.proj_mat)
            self.update_drawing()

        ray_dir, ray_orig = self.get_ray(mval)
        for i, snap_obj in enumerate(self.snap_objects[self.drawn_count:], self.drawn_count):
            obj = snap_obj.data[0]
            try:
                bbmin = Vector(obj.bound_box[0])
                bbmax = Vector(obj.bound_box[6])
            except ReferenceError:
                self.snap_objects.remove(snap_obj)
                continue

            if bbmin != bbmax:
                MVP = proj_mat @ snap_obj.mat
                mat_inv = snap_obj.mat.inverted()
                ray_orig_local = mat_inv @ ray_orig
                ray_dir_local = mat_inv.to_3x3() @ ray_dir
                in_threshold = _Internal.intersect_boundbox_threshold(
                        self, MVP, ray_orig_local, ray_dir_local, bbmin, bbmax)
            else:
                proj_co = _Internal.project_co_v3(self, snap_obj.mat.translation)
                dist = self.mval - proj_co
                in_threshold = abs(dist.x) < self._dist_px and abs(dist.y) < self._dist_px
                #snap_obj.data[1] = primitive_point

            if in_threshold:
                if len(snap_obj.data) == 1:
                    from .mesh_drawing import GPU_Indices_Mesh
                    is_bound = obj.display_type == 'BOUNDS'
                    draw_face = snap_face and not is_bound and obj.display_type != 'WIRE'
                    draw_edge = snap_edge and not is_bound
                    draw_vert = snap_vert and not is_bound
                    snap_obj.data.append(GPU_Indices_Mesh(self.depsgraph, obj, draw_face, draw_edge, draw_vert))

                snap_obj.data[1].set_draw_mode(snap_face, snap_edge, snap_vert)
                snap_obj.data[1].set_ModelViewMatrix(snap_obj.mat)

                if snap_obj == main_snap_obj:
                    snap_obj.data[1].Draw(self._offset_cur, -0.0001)
                else:
                    snap_obj.data[1].Draw(self._offset_cur)
                self._offset_cur += snap_obj.data[1].get_tot_elems()

                tmp = self.snap_objects[self.drawn_count]
                self.snap_objects[self.drawn_count] = self.snap_objects[i]
                self.snap_objects[i] = tmp

                self.drawn_count += 1

        bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)

        bgl.glReadPixels(
                int(self.mval[0]) - self._dist_px, int(self.mval[1]) - self._dist_px,
                self.threshold, self.threshold, bgl.GL_RED_INTEGER, bgl.GL_UNSIGNED_INT, self._snap_buffer)

        #bgl.glReadBuffer(bgl.GL_BACK)
        #import numpy as np
        #a = np.array(self._snap_buffer)
        #print(a)

        snap_obj, index = self._get_nearest_index()
        #print("index:", index)
        if snap_obj:
            ret = self._get_loc(snap_obj, index)

        bgl.glDisable(bgl.GL_DEPTH_TEST)

        self._offscreen.unbind()
        _Internal.gpu_Indices_restore_state()

        return (snap_obj, *ret)
def render_main(self, context, animation=False):
    # Save old info
    settings = bpy.context.scene.render.image_settings
    depth = settings.color_depth
    settings.color_depth = '8'

    # Get object list
    scene = context.scene
    objlist = context.scene.objects
    # --------------------
    # Get resolution
    # --------------------
    render_scale = scene.render.resolution_percentage / 100
    width = int(scene.render.resolution_x * render_scale)
    height = int(scene.render.resolution_y * render_scale)

    # --------------------------------------
    # Loop to draw all lines in Offsecreen
    # --------------------------------------
    offscreen = gpu.types.GPUOffScreen(width, height)
    view_matrix = Matrix([
        [2 / width, 0, 0, -1],
        [0, 2 / height, 0, -1],
        [0, 0, 1, 0],
        [0, 0, 0, 1]])

    with offscreen.bind():
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
        gpu.matrix.reset()
        gpu.matrix.load_matrix(view_matrix)
        gpu.matrix.load_projection_matrix(Matrix.Identity(4))

        # -----------------------------
        # Loop to draw all objects
        # -----------------------------
        for myobj in objlist:
            if myobj.visible_get() is True:
                if 'MeasureGenerator' in myobj:
                    op = myobj.MeasureGenerator[0]
                    draw_segments(context, myobj, op, None, None)
        # -----------------------------
        # Loop to draw all debug
        # -----------------------------
        if scene.measureit_debug is True:
            selobj = bpy.context.selected_objects
            for myobj in selobj:
                if scene.measureit_debug_objects is True:
                    draw_object(context, myobj, None, None)
                elif scene.measureit_debug_object_loc is True:
                    draw_object(context, myobj, None, None)
                if scene.measureit_debug_vertices is True:
                    draw_vertices(context, myobj, None, None)
                elif scene.measureit_debug_vert_loc is True:
                    draw_vertices(context, myobj, None, None)
                if scene.measureit_debug_edges is True:
                    draw_edges(context, myobj, None, None)
                if scene.measureit_debug_faces is True or scene.measureit_debug_normals is True:
                    draw_faces(context, myobj, None, None)
        # -----------------------------
        # Draw a rectangle frame
        # -----------------------------
        if scene.measureit_rf is True:
            rfcolor = scene.measureit_rf_color
            rfborder = scene.measureit_rf_border
            rfline = scene.measureit_rf_line

            bgl.glLineWidth(rfline)
            x1 = rfborder
            x2 = width - rfborder
            y1 = int(ceil(rfborder / (width / height)))
            y2 = height - y1
            draw_rectangle((x1, y1), (x2, y2), rfcolor)

        buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)
        bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)
        bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)

    offscreen.free()

    # -----------------------------
    # Create image
    # -----------------------------
    image_name = "measureit_output"
    if not image_name in bpy.data.images:
        bpy.data.images.new(image_name, width, height)

    image = bpy.data.images[image_name]
    image.scale(width, height)
    image.pixels = [v / 255 for v in buffer]

    # Saves image
    if image is not None and (scene.measureit_render is True or animation is True):
        ren_path = bpy.context.scene.render.filepath
        filename = "mit_frame"
        if len(ren_path) > 0:
            if ren_path.endswith(path.sep):
                initpath = path.realpath(ren_path) + path.sep
            else:
                (initpath, filename) = path.split(ren_path)

        ftxt = "%04d" % scene.frame_current
        outpath = path.realpath(path.join(initpath, filename + ftxt + ".png"))
        save_image(self, outpath, image)

    # restore default value
    settings.color_depth = depth
Beispiel #38
0
 def drawBoltGPU(self, lines, pixels, coord, w, h):
     vertexSource = '''
         in vec3 position;
         void main() 
         {
             gl_Position = vec4(position, 1.0);
         }
         '''
     geometrySource = '''
         layout(lines) in;
         layout(triangle_strip, max_vertices = 4) out;
         void main() 
         {
             float width = gl_in[1].gl_Position.z;
             vec2 line = gl_in[1].gl_Position.xy - gl_in[0].gl_Position.xy;
             vec2 normal = normalize(vec2(line.y, -line.x))*(width/2.0);
             for(int i=0; i<4; i++)
             {
                 vec2 coords = gl_in[i/2].gl_Position.xy+(1-2*(i%2))*normal;
                 gl_Position = vec4(coords, 0.0, 1.0);
                 EmitVertex();
             }
             EndPrimitive();
         }
         '''
     fragmentSource = '''
         out vec4 fragColor;
         void main()
         {
             fragColor = vec4(1.0,1.0,1.0,1.0);
         }
         '''
     positions = []
     for segment in lines.segments:
         pts = lines.getCoords(segment)[0]
         ptA = np.divide(pts[0], np.array([w, h])) * 2 - 1.0
         ptB = np.divide(pts[1], np.array([w, h])) * 2 - 1.0
         width = bl_math.clamp(
             self.thickness *
             (1.0 - (segment.level / (self.falloff * lines.getMaxLevel()))),
             0, self.thickness) / w
         positions.append((ptA[0], ptA[1], width))
         positions.append((ptB[0], ptB[1], width))
     offscreen = gpu.types.GPUOffScreen(w, h)
     shaders = gpu.types.GPUShader(vertexSource,
                                   fragmentSource,
                                   geocode=geometrySource)
     batch = batch_for_shader(shaders, 'LINES',
                              {"position": tuple(positions)})
     with offscreen.bind():
         bgl.glClearColor(0.0, 0.0, 0.0, 1.0)
         bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
         with gpu.matrix.push_pop():
             gpu.matrix.load_matrix(mathutils.Matrix.Identity(4))
             gpu.matrix.load_projection_matrix(mathutils.Matrix.Identity(4))
             shaders.bind()
             batch.draw(shaders)
         buffer = bgl.Buffer(bgl.GL_FLOAT, w * h * 4)
         bgl.glReadBuffer(bgl.GL_BACK)
         bgl.glReadPixels(0, 0, w, h, bgl.GL_RGBA, bgl.GL_FLOAT, buffer)
     pixels.foreach_set(buffer)
     offscreen.free()
def get_pixel_data_from_current_back_buffer(width, height):
    buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)
    bgl.glReadBuffer(bgl.GL_BACK)
    bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
    return buffer
    def render_main(self, context, objlist, animation=False):
        # noinspection PyBroadException,PyBroadException
        # Save old info
        scene = context.scene
        render = scene.render
        settings = render.image_settings
        depth = settings.color_depth
        settings.color_depth = '8'
        # noinspection PyBroadException
        try:

            # Get visible layers
            layers = []
            for x in range(0, 20):
                if scene.layers[x] is True:
                    layers.extend([x])

            # --------------------
            # Get resolution
            # --------------------
            render_scale = render.resolution_percentage / 100

            width = int(render.resolution_x * render_scale)
            height = int(render.resolution_y * render_scale)
            # ---------------------------------------
            # Get output path
            # ---------------------------------------
            temp_path = path.realpath(bpy.app.tempdir)
            if len(temp_path) > 0:
                outpath = path.join(temp_path, "archipack_tmp_render.png")
            else:
                self.report({
                    'ERROR'
                }, "Archipack: Unable to save temporary render image. Define a valid temp path"
                            )
                settings.color_depth = depth
                return False

            # Get Render Image
            img = self.get_render_image(outpath)
            if img is None:
                self.report({
                    'ERROR'
                }, "Archipack: Unable to save temporary render image. Define a valid temp path"
                            )
                settings.color_depth = depth
                return False

            # -----------------------------
            # Calculate rows and columns
            # -----------------------------
            tile_x = 240
            tile_y = 216
            row_num = ceil(height / tile_y)
            col_num = ceil(width / tile_x)
            print("Archipack: Image divided in " + str(row_num) + "x" +
                  str(col_num) + " tiles")

            # pixels out of visible area
            cut4 = (col_num * tile_x *
                    4) - width * 4  # pixels aout of drawing area
            totpixel4 = width * height * 4  # total pixels RGBA

            viewport_info = bgl.Buffer(bgl.GL_INT, 4)
            bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info)

            # Load image on memory
            img.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST)

            # 2.77 API change
            if bpy.app.version >= (2, 77, 0):
                tex = img.bindcode[0]
            else:
                tex = img.bindcode

            # --------------------------------------------
            # Create output image (to apply texture)
            # --------------------------------------------
            if "archipack_output" in bpy.data.images:
                out_img = bpy.data.images["archipack_output"]
                if out_img is not None:
                    out_img.user_clear()
                    bpy.data.images.remove(out_img)

            out = bpy.data.images.new("archipack_output", width, height)
            tmp_pixels = [1] * totpixel4

            # --------------------------------
            # Loop for all tiles
            # --------------------------------
            for row in range(0, row_num):
                for col in range(0, col_num):
                    buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
                    bgl.glDisable(
                        bgl.GL_SCISSOR_TEST
                    )  # if remove this line, get blender screenshot not image
                    bgl.glViewport(0, 0, tile_x, tile_y)

                    bgl.glMatrixMode(bgl.GL_PROJECTION)
                    bgl.glLoadIdentity()

                    # defines ortographic view for single tile
                    x1 = tile_x * col
                    y1 = tile_y * row
                    bgl.gluOrtho2D(x1, x1 + tile_x, y1, y1 + tile_y)

                    # Clear
                    bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
                    bgl.glClear(bgl.GL_COLOR_BUFFER_BIT
                                | bgl.GL_DEPTH_BUFFER_BIT)

                    bgl.glEnable(bgl.GL_TEXTURE_2D)
                    bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex)

                    # defines drawing area
                    bgl.glBegin(bgl.GL_QUADS)

                    bgl.glColor3f(1.0, 1.0, 1.0)
                    bgl.glTexCoord2f(0.0, 0.0)
                    bgl.glVertex2f(0.0, 0.0)

                    bgl.glTexCoord2f(1.0, 0.0)
                    bgl.glVertex2f(width, 0.0)

                    bgl.glTexCoord2f(1.0, 1.0)
                    bgl.glVertex2f(width, height)

                    bgl.glTexCoord2f(0.0, 1.0)
                    bgl.glVertex2f(0.0, height)

                    bgl.glEnd()

                    # -----------------------------
                    # Loop to draw all lines
                    # -----------------------------
                    for o, d in objlist:
                        if o.hide is False:
                            # verify visible layer
                            for x in range(0, 20):
                                if o.layers[x] is True:
                                    if x in layers:
                                        context.scene.objects.active = o
                                        # print("%s: %s" % (o.name, d.manip_stack))
                                        manipulators = d.manip_stack
                                        if manipulators is not None:
                                            for m in manipulators:
                                                if m is not None:
                                                    m.draw_callback(
                                                        m,
                                                        context,
                                                        render=True)
                                    break

                    # -----------------------------
                    # Loop to draw all debug
                    # -----------------------------
                    """
                    if scene.archipack_debug is True:
                        selobj = bpy.context.selected_objects
                        for myobj in selobj:
                            if scene.archipack_debug_vertices is True:
                                draw_vertices(context, myobj, None, None)
                            if scene.archipack_debug_faces is True or scene.archipack_debug_normals is True:
                                draw_faces(context, myobj, None, None)
                    """
                    """
                    if scene.archipack_rf is True:
                        bgl.glColor3f(1.0, 1.0, 1.0)
                        rfcolor = scene.archipack_rf_color
                        rfborder = scene.archipack_rf_border
                        rfline = scene.archipack_rf_line

                        bgl.glLineWidth(rfline)
                        bgl.glColor4f(rfcolor[0], rfcolor[1], rfcolor[2], rfcolor[3])

                        x1 = rfborder
                        x2 = width - rfborder
                        y1 = int(ceil(rfborder / (width / height)))
                        y2 = height - y1
                        draw_rectangle((x1, y1), (x2, y2))
                    """
                    # --------------------------------
                    # copy pixels to temporary area
                    # --------------------------------
                    bgl.glFinish()
                    bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA,
                                     bgl.GL_FLOAT, buffer)  # read image data
                    for y in range(0, tile_y):
                        # final image pixels position
                        p1 = (y * width * 4) + (row * tile_y * width *
                                                4) + (col * tile_x * 4)
                        p2 = p1 + (tile_x * 4)
                        # buffer pixels position
                        b1 = y * width * 4
                        b2 = b1 + (tile_x * 4)

                        if p1 < totpixel4:  # avoid pixel row out of area
                            if col == col_num - 1:  # avoid pixel columns out of area
                                p2 -= cut4
                                b2 -= cut4

                            tmp_pixels[p1:p2] = buffer[b1:b2]

            # -----------------------
            # Copy temporary to final
            # -----------------------
            out.pixels = tmp_pixels[:]  # Assign image data
            img.gl_free()  # free opengl image memory

            # delete image
            img.user_clear()
            bpy.data.images.remove(img)
            # remove temp file
            remove(outpath)
            # reset
            bgl.glEnable(bgl.GL_SCISSOR_TEST)
            # -----------------------
            # restore opengl defaults
            # -----------------------
            bgl.glLineWidth(1)
            bgl.glDisable(bgl.GL_BLEND)
            bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
            # Saves image
            if out is not None:
                # and (scene.archipack_render is True or animation is True):
                ren_path = bpy.context.scene.render.filepath
                filename = "ap_frame"
                if len(ren_path) > 0:
                    if ren_path.endswith(path.sep):
                        initpath = path.realpath(ren_path) + path.sep
                    else:
                        (initpath, filename) = path.split(ren_path)

                ftxt = "%04d" % scene.frame_current
                outpath = path.realpath(
                    path.join(initpath, filename + ftxt + ".png"))

                self.save_image(outpath, out)

            settings.color_depth = depth
            return True

        except:
            settings.color_depth = depth
            print("Unexpected error:" + str(exc_info()))
            self.report({
                'ERROR'
            }, "Archipack: Unable to create render image. Be sure the output render path is correct"
                        )
            return False
Beispiel #41
0
def generate_icon(name, verts=None, faces=None):
    pcoll = preview_collections["shape_types"]
    if name in pcoll:
        thumb = pcoll.get(name)
    else:
        thumb = pcoll.new(name)
    thumb.image_size = (200, 200)

    if verts is not None:
        import bgl

        polygon_color = bpy.context.user_preferences.themes[0].view_3d.edge_facesel
        edge_color = bpy.context.user_preferences.themes[0].view_3d.edge_select
        vertex_color = bpy.context.user_preferences.themes[0].view_3d.vertex_select
        clear_color = bpy.context.user_preferences.themes[0].user_interface.wcol_menu.inner

        viewport_info = bgl.Buffer(bgl.GL_INT, 4)
        bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info)
        buffer = bgl.Buffer(bgl.GL_FLOAT, 200 * 200 * 4)

        bgl.glDisable(bgl.GL_SCISSOR_TEST)
        bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA)
        bgl.glEnable(bgl.GL_LINE_SMOOTH)
        bgl.glEnable(bgl.GL_POINT_SMOOTH)
        bgl.glViewport(0, 0, 200, 200)

        bgl.glMatrixMode(bgl.GL_MODELVIEW)
        bgl.glPushMatrix()
        bgl.glLoadIdentity()

        bgl.glMatrixMode(bgl.GL_PROJECTION)
        bgl.glPushMatrix()
        bgl.glLoadIdentity()
        bgl.gluOrtho2D(0, 0, 0, 0)

        bgl.glLineWidth(4.0)
        bgl.glPointSize(10.0)

        bgl.glClearColor(*clear_color)
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)

        if faces is None:
            bgl.glBegin(bgl.GL_POLYGON)
            bgl.glColor3f(*polygon_color)
            for vert in verts:
                bgl.glVertex2f(*vert)
            bgl.glEnd()
        else:
            bgl.glBegin(bgl.GL_TRIANGLES)
            bgl.glColor3f(*polygon_color)
            for face in faces:
                bgl.glVertex2f(*verts[face[0]])
                bgl.glVertex2f(*verts[face[1]])
                bgl.glVertex2f(*verts[face[2]])
            bgl.glEnd()

        bgl.glBegin(bgl.GL_LINE_LOOP)
        bgl.glColor3f(*edge_color)
        for vert in verts:
            bgl.glVertex2f(*vert)
        bgl.glEnd()

        bgl.glBegin(bgl.GL_POINTS)
        bgl.glColor3f(*vertex_color)
        for vert in verts:
            bgl.glVertex2f(*vert)
        bgl.glEnd()

        bgl.glReadPixels(0, 0, 200, 200, bgl.GL_RGBA, bgl.GL_FLOAT, buffer)
        bgl.glEnable(bgl.GL_SCISSOR_TEST)
        bgl.glLineWidth(1.0)
        bgl.glPointSize(1.0)

        buffer = buffer[:]
        for idx in range(0, 200 * 200 * 4, 4):
            if (
                buffer[idx] == clear_color[0]
                and buffer[idx + 1] == clear_color[1]
                and buffer[idx + 2] == clear_color[2]
            ):
                buffer[idx + 3] = 0.0

        thumb.image_pixels_float = buffer
Beispiel #42
0
def render_map(self, context):
    import tempfile

    image_name = "Gem Map"
    width = self.width
    height = self.height
    ratio_w = width / self.region.width
    ratio_h = height / self.region.height
    padding = 30
    x = padding
    y = height - padding
    temp_filepath = os.path.join(tempfile.gettempdir(), "gem_map_temp.png")

    asset.render_preview(width,
                         height,
                         temp_filepath,
                         compression=15,
                         gamma=2.2)
    render_image = load_image(temp_filepath)
    render_image.gl_load()

    mat_offscreen = Matrix()
    mat_offscreen[0][0] = 2 / width
    mat_offscreen[0][3] = -1
    mat_offscreen[1][1] = 2 / height
    mat_offscreen[1][3] = -1

    shader = gpu.shader.from_builtin("2D_UNIFORM_COLOR")
    shader_img = gpu.shader.from_builtin("2D_IMAGE")
    offscreen = gpu.types.GPUOffScreen(width, height)

    with offscreen.bind():
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)

        with gpu.matrix.push_pop():
            gpu.matrix.load_matrix(mat_offscreen)
            gpu.matrix.load_projection_matrix(Matrix())

            # Background
            # --------------------------------

            shader.bind()
            shader.uniform_float("color", (1.0, 1.0, 1.0, 1.0))
            batch = batch_for_shader(
                shader, "TRI_FAN",
                {"pos": self.rect_coords(0, 0, width, height)})
            batch.draw(shader)

            # Render result
            # --------------------------------

            bgl.glEnable(bgl.GL_BLEND)

            bgl.glActiveTexture(bgl.GL_TEXTURE0)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, render_image.bindcode)

            shader_img.bind()
            shader_img.uniform_int("image", 0)

            args = {
                "pos": self.rect_coords(0, 0, width, height),
                "texCoord": self.rect_coords(0, 0, 1, 1),
            }

            batch = batch_for_shader(shader_img, "TRI_FAN", args)
            batch.draw(shader_img)

            # Gem map
            # --------------------------------

            self.draw_gems(context, ratio_w=ratio_w, ratio_h=ratio_h)
            self.onscreen_gem_table(x, y, color=(0.0, 0.0, 0.0, 1.0))

        buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)
        bgl.glReadBuffer(bgl.GL_BACK)
        bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA,
                         bgl.GL_UNSIGNED_BYTE, buffer)

    offscreen.free()

    if image_name not in bpy.data.images:
        bpy.data.images.new(image_name, width, height)

    image = bpy.data.images[image_name]
    image.scale(width, height)
    image.pixels = [v / 255 for v in buffer]

    if self.use_save and bpy.data.is_saved:
        filepath = bpy.data.filepath
        filename = os.path.splitext(os.path.basename(filepath))[0]
        save_path = os.path.join(os.path.dirname(filepath),
                                 filename + " Gem Map.png")

        image.filepath_raw = save_path
        image.file_format = "PNG"
        image.save()

    render_image.gl_free()
    bpy.data.images.remove(render_image)

    if os.path.exists(temp_filepath):
        os.remove(temp_filepath)

    # Restore OpenGL defaults
    # ----------------------------

    bgl.glDisable(bgl.GL_BLEND)

    # Show in a new window
    # ----------------------------

    asset.show_window(width, height, space_data={"image": image})
Beispiel #43
0
    def snap_get(self, mval):
        ret = None, None
        self.mval[:] = mval
        snap_vert = self._snap_mode & VERT != 0
        snap_edge = self._snap_mode & EDGE != 0
        snap_face = self._snap_mode & FACE != 0

        _Internal.gpu_Indices_enable_state()
        self._offscreen.bind()

        #bgl.glDisable(bgl.GL_DITHER) # dithering and AA break color coding, so disable #
        #multisample_enabled = bgl.glIsEnabled(bgl.GL_MULTISAMPLE)
        #bgl.glDisable(bgl.GL_MULTISAMPLE)
        bgl.glEnable(bgl.GL_DEPTH_TEST)

        proj_mat = self.rv3d.perspective_matrix.copy()
        if self.proj_mat != proj_mat:
            self.proj_mat = proj_mat
            _Internal.gpu_Indices_set_ProjectionMatrix(self.proj_mat)
            self.update_all()

        ray_dir, ray_orig = self.get_ray(mval)
        for i, snap_obj in enumerate(self.snap_objects[self.drawn_count:], self.drawn_count):
            obj = snap_obj.data[0]
            bbmin = Vector(obj.bound_box[0])
            bbmax = Vector(obj.bound_box[6])

            if bbmin != bbmax:
                MVP = proj_mat * snap_obj.mat
                mat_inv = snap_obj.mat.inverted()
                ray_orig_local = mat_inv * ray_orig
                ray_dir_local = mat_inv.to_3x3() * ray_dir
                in_threshold = _Internal.intersect_boundbox_threshold(self, MVP, ray_orig_local, ray_dir_local, bbmin, bbmax)
            else:
                proj_co = _Internal.project_co_v3(self, snap_obj.mat.translation)
                dist = self.mval - proj_co
                in_threshold = abs(dist.x) < self._dist_px and abs(dist.y) < self._dist_px
                #snap_obj.data[1] = primitive_point

            if in_threshold:
                if len(snap_obj.data) == 1:
                    from .mesh_drawing import GPU_Indices_Mesh
                    snap_obj.data.append(GPU_Indices_Mesh(obj, snap_face, snap_edge, snap_vert))
                snap_obj.data[1].set_draw_mode(snap_face, snap_edge, snap_vert)
                snap_obj.data[1].set_ModelViewMatrix(snap_obj.mat)
                snap_obj.data[1].Draw(self._offset_cur)
                self._offset_cur += snap_obj.data[1].get_tot_elems()

                self.snap_objects[self.drawn_count], self.snap_objects[i] = self.snap_objects[i], self.snap_objects[self.drawn_count]
                self.drawn_count += 1

        bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)
        bgl.glReadPixels(
                int(self.mval[0]) - self._dist_px, int(self.mval[1]) - self._dist_px,
                self.threshold, self.threshold, bgl.GL_RED_INTEGER, bgl.GL_UNSIGNED_INT, self._snap_buffer)
        bgl.glReadBuffer(bgl.GL_BACK)

        snap_obj, index = self._get_nearest_index()
        #print(index)
        if snap_obj:
            ret = self._get_loc(snap_obj, index)

        self._offscreen.unbind()
        _Internal.gpu_Indices_restore_state()

        return snap_obj, ret[0], ret[1]