Example #1
0
def draw_custom_3d_elements(mode):
    """Get's updated custom 3D elements and draws them

    :param mode: drawing mode for custom elements (can be: 'Normal' or 'X-ray')
    :type mode: str
    """
    if mode == "Normal":
        glEnable(GL_DEPTH_TEST)
        glClear(GL_DEPTH_BUFFER_BIT)
    else:  # X-ray mode
        disable_depth_test()

    scs_globals = _get_scs_globals()

    # TERRAIN POINTS
    glPointSize(5.0)

    for tp_position, tp_color in _terrain_points_storage.get_positions_and_colors():
        _primitive.draw_point(tp_position, tp_color)

    glPointSize(1.0)

    (prefab_locators, collision_locators, model_locators) = _get_custom_visual_elements()

    # reset point size to 1.0 and set line width to 2.0 before drawing curves and lines
    glPointSize(1.0)
    glLineWidth(2.0)

    # CURVES AND LINES
    if scs_globals.display_connections:
        _connections_group_wrapper.draw(prefab_locators)

    # reset line width to 1.0 after drawing curves and lines
    glLineWidth(1.0)

    # LOCATORS
    if scs_globals.display_locators:

        # PREFAB LOCATORS
        if prefab_locators:
            for obj in prefab_locators.values():
                _locators.prefab.draw_prefab_locator(obj, scs_globals)

        # COLLISION LOCATORS
        if collision_locators:
            for obj in collision_locators.values():
                _locators.collider.draw_collision_locator(obj, scs_globals)

        # MODEL LOCATORS
        if model_locators:
            for obj in model_locators.values():
                _locators.model.draw_model_locator(obj, scs_globals)
Example #2
0
def export(filepath, face_data, colors, width, height, opacity):
    offscreen = gpu.types.GPUOffScreen(width, height)
    offscreen.bind()

    try:
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
        draw_image(face_data, opacity)

        pixel_data = get_pixel_data_from_current_back_buffer(width, height)
        save_pixels(filepath, pixel_data, width, height)
    finally:
        offscreen.unbind()
        offscreen.free()
Example #3
0
    def clear(self):
        is_bound = self is _SnapOffscreen.bound
        if not is_bound:
            self.bind()

        bgl.glColorMask(bgl.GL_TRUE, bgl.GL_TRUE, bgl.GL_TRUE, bgl.GL_TRUE)
        bgl.glClearColor(0.0, 0.0, 0.0, 0.0)

        bgl.glDepthMask(bgl.GL_TRUE)
        bgl.glClearDepth(1.0);

        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)

        if not is_bound:
            self.unbind()
Example #4
0
def h_clip_begin(bounds, padding=[0, 0, 0, 0]):
    vp = bgl.Buffer(bgl.GL_INT, 4)
    bgl.glGetIntegerv(bgl.GL_VIEWPORT, vp)
    
    B = [bounds[0]+padding[0], bounds[1]+padding[1], bounds[2]-padding[2]*2, bounds[3]-padding[3]*2]
    
    # Do some math to invert the coords
    scp = [0, 0, int(B[2]), int(B[3])]
    scp[0] = int(B[0] + vp[0])
    scp[1] = int(vp[1] + (vp[3] - B[1] - B[3]))
    
    bgl.glEnable(bgl.GL_SCISSOR_TEST)
    bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
    bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_SCISSOR_BIT)
    bgl.glScissor(*scp)
Example #5
0
def h_mask_begin(bounds, radius=0):
    bgl.glEnable(bgl.GL_STENCIL_TEST)
    bgl.glColorMask(False, False, False, False)
    bgl.glDepthMask(False)
    bgl.glStencilFunc(bgl.GL_NEVER, 1, 0xFF)
    bgl.glStencilOp(bgl.GL_REPLACE, bgl.GL_KEEP, bgl.GL_KEEP)
    
    bgl.glStencilMask(0xFF)
    bgl.glClear(bgl.GL_STENCIL_BUFFER_BIT)
    
    h_round_rect(bounds, radius)
    
    bgl.glColorMask(True, True, True, True)
    bgl.glDepthMask(True)
    bgl.glStencilMask(0x00);
    bgl.glStencilFunc(bgl.GL_EQUAL, 0, 0xFF)
    
    bgl.glStencilFunc(bgl.GL_EQUAL, 1, 0xFF)
Example #6
0
def draw_custom_3d_elements(mode):
    """Get's updated custom 3D elements and draws them

    :param mode: drawing mode for custom elements (can be: 'Normal' or 'X-ray')
    :type mode: str
    """
    if mode == "Normal":
        glEnable(GL_DEPTH_TEST)
        glClear(GL_DEPTH_BUFFER_BIT)
    else:  # X-ray mode
        disable_depth_test()

    context = bpy.context

    (prefab_locators, collision_locators, model_locators) = _get_custom_visual_elements()

    # PREFAB LOCATORS
    if context.scene.scs_props.display_locators:
        if prefab_locators:
            for obj in prefab_locators.values():
                _locators.prefab.draw_prefab_locator(obj, context.scene.scs_props)

    # reset point size to 1.0 and set line width to 2.0 before drawing curves and lines
    glPointSize(1.0)
    glLineWidth(2.0)

    # CURVES AND LINES
    if context.scene.scs_props.display_connections:
        _connections_group_wrapper.draw(prefab_locators)

    # reset line width to 1.0 after drawing curves and lines
    glLineWidth(1.0)

    # COLLISION LOCATORS
    if context.scene.scs_props.display_locators:
        if collision_locators:
            for obj in collision_locators.values():
                _locators.collider.draw_collision_locator(obj, context.scene.scs_props)

    # MODEL LOCATORS
    if context.scene.scs_props.display_locators:
        if model_locators:
            for obj in model_locators.values():
                _locators.model.draw_model_locator(obj, context.scene.scs_props)
Example #7
0
    def offscreen_refresh(self, context):
        if self.offscreen is not None:
            self.offscreen.free()

        width = self.region.width
        height = self.region.height
        self.offscreen = gpu.types.GPUOffScreen(width, height)

        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

        with self.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())

                self.draw_gems(context)
Example #8
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
Example #9
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
Example #10
0
    def render_image(self):

        # Render the scene and load it into the script
        tmp_path = self.scene.render.filepath
        tmp_image = 'temp_img_store' + '.png'
        if tmp_image in bpy.data.images:
            bpy.data.images.remove(bpy.data.images[tmp_image])
        self.scene.render.filepath = self.path + tmp_image
        bpy.ops.render.render(write_still=True)
        renderedImage = bpy.data.images.load(self.path + tmp_image)
        renderedImage.colorspace_settings.name = 'Linear'

        # Vertex shader for cubemap frontimage to equirectangular
        vertex_shader = '''
            in vec3 aVertexPosition;
            in vec2 aVertexTextureCoord;
        
            out vec2 vTexCoord;
        
            void main() {
                vTexCoord = aVertexTextureCoord;
                gl_Position = vec4(aVertexPosition, 1);
            }
        '''

        # Generate the OpenGL shader
        pos = [(-1.0, -1.0, -1.0), (-1.0,  1.0, -1.0), \
               (1.0, -1.0, -1.0), (1.0,  1.0, -1.0)]
        coords = [(-2.0, -1.0), (-2.0,  1.0), \
                  (2.0, -1.0), (2.0,  1.0)]
        vertexIndices = [(0, 3, 1), (3, 0, 2)]

        shader = gpu.types.GPUShader(vertex_shader, self.frag_shader)
        batch = batch_for_shader(shader, 'TRIS', {"aVertexPosition": pos, \
                                                  "aVertexTextureCoord": coords}, \
                                                  indices=vertexIndices)

        # Load rendered image into OpenGL textures
        renderedImage.gl_load()

        # Create an offscreen render buffer and texture
        offscreen = gpu.types.GPUOffScreen(self.image_size[0],
                                           self.image_size[1])

        with offscreen.bind():
            #bgl.glClearColor(0,0,0,1)
            bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)

            shader.bind()

            def bind_and_filter(tex, bindcode, image=None, imageNum=None):
                bgl.glActiveTexture(tex)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, bindcode)
                bgl.glTexParameterf(bgl.GL_TEXTURE_2D,
                                    bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR)
                bgl.glTexParameterf(bgl.GL_TEXTURE_2D,
                                    bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR)
                # Turn on GL_CLAMP_TO_BORDER and delete paint black codes in fragment shader
                # would give a transparent background
                #bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_BORDER)
                #bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_BORDER)
                # Really dont know how to change the border color
                #bgl.glTexParameterfv(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_BORDER_COLOR, color)#???
                if image != None and imageNum != None:
                    shader.uniform_int(image, imageNum)

            # Bind and filter the renderedImage
            bind_and_filter(bgl.GL_TEXTURE0, renderedImage.bindcode,
                            "frontImage", 0)

            # Bind the resulting texture
            bind_and_filter(bgl.GL_TEXTURE1, offscreen.color_texture)

            # Render the image
            batch.draw(shader)

            # Unload the texture
            renderedImage.gl_free()

            # Read the resulting pixels into a buffer
            buffer = bgl.Buffer(bgl.GL_FLOAT,
                                self.image_size[0] * self.image_size[1] * 4)
            bgl.glGetTexImage(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA, bgl.GL_FLOAT,
                              buffer)

        # Unload the offscreen texture
        offscreen.free()

        # Remove the frontImage texture
        bpy.data.images.remove(renderedImage)
        # Turn on this line to delete tmp image everytime, turn off maybe will save some resource
        #os.remove(self.path + tmp_image)

        # Set file name
        image_name = "frameS{:06d}.png".format(self.scene.frame_current)
        # If it doesn't already exist, create an image object to store the resulting render
        if not image_name in bpy.data.images.keys():
            imageResult = bpy.data.images.new(image_name, self.image_size[0],
                                              self.image_size[1])
        imageResult = bpy.data.images[image_name]
        imageResult.scale(self.image_size[0], self.image_size[1])

        # Copy the pixels from the buffer to an image object
        imageResult.pixels = buffer

        # Save to file
        imageResult.file_format = 'PNG'
        imageResult.filepath_raw = self.path + image_name
        imageResult.save()

        bpy.data.images.remove(imageResult)

        self.scene.render.filepath = tmp_path
Example #11
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
Example #12
0
    def execute(self, context):
        bgl.glEnable(bgl.GL_PROGRAM_POINT_SIZE)

        scene = context.scene
        render = scene.render
        image_settings = render.image_settings

        original_depth = image_settings.color_depth
        image_settings.color_depth = '8'

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

        pcv = context.object.point_cloud_visualizer
        cloud = PCVManager.cache[pcv.uuid]
        cam = scene.camera
        if (cam is None):
            self.report({'ERROR'}, "No camera found.")
            return {'CANCELLED'}

        render_suffix = pcv.render_suffix
        render_zeros = pcv.render_zeros

        offscreen = GPUOffScreen(width, height)
        offscreen.bind()
        try:
            gpu.matrix.load_matrix(Matrix.Identity(4))
            gpu.matrix.load_projection_matrix(Matrix.Identity(4))

            bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)

            o = cloud['object']
            vs = cloud['vertices']
            cs = cloud['colors']
            ns = cloud['normals']

            dp = pcv.render_display_percent
            l = int((len(vs) / 100) * dp)
            if (dp >= 99):
                l = len(vs)
            vs = vs[:l]
            cs = cs[:l]
            ns = ns[:l]

            # sort by depth
            mw = o.matrix_world
            depth = []
            for i, v in enumerate(vs):
                vw = mw @ Vector(v)
                depth.append(world_to_camera_view(scene, cam, vw)[2])
            zps = zip(depth, vs, cs, ns)
            sps = sorted(zps, key=lambda a: a[0])
            # split and reverse
            vs = [a for _, a, b, c in sps][::-1]
            cs = [b for _, a, b, c in sps][::-1]
            ns = [c for _, a, b, c in sps][::-1]

            shader = GPUShader(vertex_shader, fragment_shader)
            batch = batch_for_shader(shader, 'POINTS', {
                "position": vs,
                "color": cs,
                "normal": ns,
            })
            shader.bind()

            view_matrix = cam.matrix_world.inverted()
            camera_matrix = cam.calc_matrix_camera(
                bpy.context.depsgraph,
                x=render.resolution_x,
                y=render.resolution_y,
                scale_x=render.pixel_aspect_x,
                scale_y=render.pixel_aspect_y,
            )
            perspective_matrix = camera_matrix @ view_matrix

            shader.uniform_float("perspective_matrix", perspective_matrix)
            shader.uniform_float("object_matrix", o.matrix_world)
            shader.uniform_float("point_size", pcv.render_point_size)
            shader.uniform_float("alpha_radius", pcv.alpha_radius)

            if (pcv.light_enabled and pcv.has_normals):
                cm = Matrix((
                    (
                        -1.0,
                        0.0,
                        0.0,
                        0.0,
                    ),
                    (
                        0.0,
                        -0.0,
                        1.0,
                        0.0,
                    ),
                    (
                        0.0,
                        -1.0,
                        -0.0,
                        0.0,
                    ),
                    (
                        0.0,
                        0.0,
                        0.0,
                        1.0,
                    ),
                ))
                _, obrot, _ = o.matrix_world.decompose()
                mr = obrot.to_matrix().to_4x4()
                mr.invert()
                direction = cm @ pcv.light_direction
                direction = mr @ direction
                shader.uniform_float("light_direction", direction)

                inverted_direction = direction.copy()
                inverted_direction.negate()

                c = pcv.light_intensity
                shader.uniform_float("light_intensity", (
                    c,
                    c,
                    c,
                ))
                shader.uniform_float("shadow_direction", inverted_direction)
                c = pcv.shadow_intensity
                shader.uniform_float("shadow_intensity", (
                    c,
                    c,
                    c,
                ))
                shader.uniform_float("show_normals", float(pcv.show_normals))
            else:
                z = (0, 0, 0)
                shader.uniform_float("light_direction", z)
                shader.uniform_float("light_intensity", z)
                shader.uniform_float("shadow_direction", z)
                shader.uniform_float("shadow_intensity", z)
                shader.uniform_float("show_normals", float(False))

            batch.draw(shader)

            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)

        except Exception as e:
            self.report({'ERROR'}, str(e))
            return {'CANCELLED'}

        finally:
            offscreen.unbind()
            offscreen.free()

        # image from buffer
        image_name = "pcv_output"
        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]

        # save as image file
        save_render(
            self,
            scene,
            image,
            render_suffix,
            render_zeros,
        )

        # restore
        image_settings.color_depth = original_depth

        return {'FINISHED'}
def color_to_KK(color, lut_name):
    width = 1
    height = 1

    # Some Sauce
    vertex_default = '''
    in vec2 a_position;

    void main() {
        gl_Position = vec4(a_position, 0.0, 1.0);
    }
    '''

    # The Secret Sauce
    current_code = '''
    uniform vec3 inputColor;
    uniform sampler2D lut;

    vec3 to_srgb(vec3 c){
        c.rgb = max( 1.055 * pow( c.rgb, vec3(0.416666667,0.416666667,0.416666667) ) - 0.055, 0 );
        return c;
    }

    void main() {
        vec3 color = inputColor / 255;
        
        const vec3 coord_scale = vec3(0.0302734375, 0.96875, 31.0);
        const vec3 coord_offset = vec3( 0.5/1024, 0.5/32, 0.0);
        const vec2 texel_height_X0 = vec2( 0.03125, 0.0 );
        
        vec3 coord = color * coord_scale + coord_offset;
        
        vec3 coord_frac = fract( coord );
        vec3 coord_floor = coord - coord_frac;
        vec2 coord_bot = coord.xy + coord_floor.zz * texel_height_X0;
        vec2 coord_top = coord_bot + texel_height_X0;

        vec3 lutcol_bot = texture( lut, coord_bot ).rgb;
        vec3 lutcol_top = texture( lut, coord_top ).rgb;
        
        vec3 lutColor = mix(lutcol_bot, lutcol_top, coord_frac.z);
        
        
        vec3 shaderColor = lutColor;
        
        gl_FragColor = vec4(shaderColor.rgb, 1);
    }
    '''

    # This object gives access to off screen buffers.
    offscreen = gpu.types.GPUOffScreen(width, height)

    # Context manager to ensure balanced bind calls, even in the case of an error.
    # Only run if valid
    with offscreen.bind():

        # Clear buffers to preset values
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)

        # Initialize the shader
        # GPUShader combines multiple GLSL shaders into a program used for drawing.
        # It must contain a vertex and fragment shaders, with an optional geometry shader.
        shader = gpu.types.GPUShader(vertex_default, current_code)

        # Initialize the shader batch
        # It makes sure that all the vertex attributes necessary for a specific shader are provided.
        batch = batch_for_shader(
            shader,
            'TRI_FAN',
            {'a_position': ((-1, -1), (1, -1), (1, 1), (-1, 1))},
        )

        # Bind the shader object. Required to be able to change uniforms of this shader.
        shader.bind()

        try:
            # Specify the value of a uniform variable for the current program object.
            # In this case, a color tuple.
            shader.uniform_float('inputColor', color)
        except ValueError:
            pass

        try:
            lut_image = bpy.data.images[lut_name]

            # Make sure image has a bindcode
            if lut_image.bindcode == 0:
                for i in range(0, 20):
                    lut_image.gl_load()
                    if lut_image.bindcode != 0:
                        break

            # https://docs.blender.org/api/current/bgl.html
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, lut_image.bindcode)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER,
                                bgl.GL_LINEAR)

            # Specify the value of a uniform variable for the current program object.
            # In this case, an image.
            shader.uniform_int("lut", 0)
        except ValueError:
            pass

        # Run the drawing program with the parameters assigned to the batch.
        batch.draw(shader)

        # The Buffer object is simply a block of memory that is delineated and initialized by the user.
        buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 3)

        # Select a color buffer source for pixels.
        bgl.glReadBuffer(bgl.GL_BACK)

        # Read a block of pixels from the frame buffer.
        bgl.glReadPixels(0, 0, width, height, bgl.GL_RGB, bgl.GL_UNSIGNED_BYTE,
                         buffer)

    # Free the offscreen object. The framebuffer, texture and render objects will no longer be accessible.
    offscreen.free()

    # Get and return the pixels from the final buffer
    final_color = [v for v in buffer]
    final_color = np.array(final_color).reshape(width, height, -1)
    return final_color[0][0]

    # RGBA (1, 1, 1, 1) to RGB as int (255, 255, 255)
    def RGBA_to_RGB_int(rgba):
        rgba = np.round(rgba * 255).astype('int')
        rgba = np.delete(rgba, 3)
        return rgba

    # Make sure not to select a transparent pixel
    def filter_pixel(index_list, image):
        for i in index_list:
            if image[i][3] == 1:
                index = i
                break
        return index

    ########## SETUP ##########

    exposure = np.array([exposure[0], exposure[1], exposure[2], 1])

    # Init MC Texture
    mc_mask_data = np.array(mc_mask.pixels).reshape(-1, 4)
    mc_mask_data = mc_mask_data * exposure
    mc_mask_data = np.clip(mc_mask_data, 0, 1)

    # Init Main Texture
    bpy.data.images[texture.name].scale(mc_mask.size[0], mc_mask.size[1])
    texture_data = np.array(texture.pixels).reshape(-1, 4)

    # Init MC Color indexes
    red_index = -1
    green_index = -1
    blue_index = -1

    # Init MainTex Colors
    red_color = -1
    green_color = -1
    blue_color = -1

    # Init converted colors (light)
    red_converted_color_light = np.array([255, 0, 0, 255])
    green_converted_color_light = np.array([0, 255, 0, 255])
    blue_converted_color_light = np.array([0, 0, 255, 255])

    ########## FIND MC INDEXES ##########
    r, g, b = mc_mask_data[:, 0], mc_mask_data[:, 1], mc_mask_data[:, 2]
    r = r.max()
    g = g.max()
    b = b.max()

    # Red
    pixel_list = np.where(np.all(mc_mask_data == (r, 0, 0, 1), axis=-1))[0]
    if len(pixel_list) > 0:
        red_index = filter_pixel(pixel_list, texture_data)

    # Green
    pixel_list = np.where(np.all(mc_mask_data >= (0, g, 0, 1), axis=-1))[0]
    if len(pixel_list) > 0:
        green_index = filter_pixel(pixel_list, texture_data)
    else:
        # Green (Yellow)
        pixel_list = np.where(np.all(mc_mask_data == (r, g, 0, 1), axis=-1))[0]
        if len(pixel_list) > 0:
            green_index = filter_pixel(pixel_list, texture_data)

    # Blue
    pixel_list = np.where(np.all(mc_mask_data == (0, 0, b, 1), axis=-1))[0]
    if len(pixel_list) > 0:
        blue_index = filter_pixel(pixel_list, texture_data)
    else:
        # Blue (Cyan)
        pixel_list = np.where(np.all(mc_mask_data == (0, g, b, 1), axis=-1))[0]
        if len(pixel_list) > 0:
            blue_index = filter_pixel(pixel_list, texture_data)
        else:
            # Blue (Magenta)
            pixel_list = np.where(np.all(mc_mask_data == (r, 0, b, 1),
                                         axis=-1))[0]
            if len(pixel_list) > 0:
                blue_index = filter_pixel(pixel_list, texture_data)
            else:
                # Blue (White)
                pixel_list = np.where(
                    np.all(mc_mask_data == (r, g, b, 1), axis=-1))[0]
                if len(pixel_list) > 0:
                    blue_index = filter_pixel(pixel_list, texture_data)

    ########## SCALE INDEXES ##########

    # mc_w, mc_h = mc_mask.size
    # tex_w, tex_h = texture.size

    # scale = int((tex_w * tex_h) / (mc_w * mc_h))

    # red_index = red_index * scale
    # green_index = green_index * scale
    # blue_index = blue_index * scale

    ########## GET AND CONVERT COLORS FROM MAIN TEXTURE ##########

    if red_index >= 0:
        red_color = texture_data[red_index]
        red_color = RGBA_to_RGB_int(red_color)

        red_converted_color_light = color_to_KK(red_color, lut)

    if green_index >= 0:
        green_color = texture_data[green_index]
        green_color = RGBA_to_RGB_int(green_color)

        green_converted_color_light = color_to_KK(green_color, lut)

    if blue_index >= 0:
        blue_color = texture_data[blue_index]
        blue_color = RGBA_to_RGB_int(blue_color)

        blue_converted_color_light = color_to_KK(blue_color, lut)

    # print(red_index)
    # print(green_index)
    # print(blue_index)

    # print(red_converted_color_light)
    # print(green_converted_color_light)
    # print(blue_converted_color_light)

    return red_converted_color_light / 255, green_converted_color_light / 255, blue_converted_color_light / 255
Example #14
0
def generate_icon(name, verts=None, faces=None, coll="shape_types"):
    pcoll = preview_collections[coll]
    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
Example #15
0
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 = bpy.path.abspath(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
    print("Rendering Depth Buffer")
    if sceneProps.vector_depthtest:
        with offscreen.bind():
            # Clear Depth Buffer, set Clear Depth to Cameras Clip Distance
            set_OpenGL_Settings(True)
            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_FLOAT, width * height)

            draw_scene(self, context, projection_matrix)

            bgl.glReadBuffer(bgl.GL_BACK)
            bgl.glReadPixels(0, 0, width, height, bgl.GL_DEPTH_COMPONENT,
                             bgl.GL_FLOAT, texture_buffer)

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

        if False:
            imageName = 'depthBufferTest'
            if not imageName in bpy.data.images:
                bpy.data.images.new(imageName,
                                    width,
                                    height,
                                    alpha=False,
                                    float_buffer=True,
                                    is_data=True)
            image = bpy.data.images[imageName]

            image.scale(width, height)
            image.pixels = [v for v in texture_buffer]

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

    view = get_view()

    paperWidth = width / sceneProps.default_resolution
    paperHeight = height / sceneProps.default_resolution

    try:
        if view.res_type == 'res_type_paper':
            paperWidth = round(view.width * 39.370078740196853, 3)
            paperHeight = round(view.height * 39.370078740196853, 3)
    except:
        print('No View Present, using default resolution')

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

    if sceneProps.embed_scene_render:
        lastformat = scene.render.image_settings.file_format
        scene.render.image_settings.file_format = 'PNG'
        scene.render.use_file_extension = True
        bpy.ops.render.render(write_still=True)

        image_path = bpy.context.scene.render.filepath
        svg.add(
            svg.image(os.path.basename(image_path + '.png'), **{
                'width': width,
                'height': height
            }))

        scene.render.image_settings.file_format = lastformat

    # -----------------------------
    # Loop to draw all objects
    # -----------------------------
    draw3d_loop(context, objlist, svg=svg)
    draw_titleblock(context, svg=svg)

    svg.save(pretty=True)
    # restore default value
    sceneProps.is_render_draw = False
    sceneProps.is_vector_draw = False
    return True
Example #16
0
def render_main(self, context, animation=False):

    scene = context.scene
    sceneProps = scene.MeasureItArchProps
    sceneProps.is_render_draw = True

    clipdepth = context.scene.camera.data.clip_end
    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)

    # Draw all lines in Offsecreen
    renderoffscreen = 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)

    set_OpenGL_Settings(True)
    with renderoffscreen.bind():

        # Clear Depth Buffer, set Clear Depth to Cameras Clip Distance
        bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT)
        bgl.glClearDepth(clipdepth)

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

        # Draw Scene for the depth buffer
        draw_scene(self, context, projection_matrix)

        # Clear Color Buffer, we only need the depth info
        bgl.glClearColor(0, 0, 0, 0)
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)

        # -----------------------------
        # Loop to draw all objects
        # -----------------------------
        draw3d_loop(context, objlist)
        draw_titleblock(context)

        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)

    # -----------------------------
    # Create image
    # -----------------------------
    image_name = "measureit_arch_output"
    if image_name not in bpy.data.images:
        image = 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]

    renderoffscreen.free()
    # Saves image
    if image is not None and animation is True:
        ren_path = bpy.context.scene.render.filepath
        filename = "mit_frame"
        ftxt = "%04d" % scene.frame_current
        outpath = (ren_path + filename + ftxt + '.png')
        save_image(self, outpath, image)

    # restore default value
    set_OpenGL_Settings(False)
    sceneProps.is_render_draw = False
    return True, buffer
Example #17
0
    def draw_callback(self, context):
        """
        :type context: bpy.types.Context
        """

        prefs = QuickBooleanPreferences.get_instance()
        color = prefs.color
        snap_color = prefs.snap_color

        region = context.region

        glsettings = vagl.GLSettings(context)
        glsettings.push()

        bgl.glEnable(bgl.GL_BLEND)
        bgl.glColor4f(*color)

        show_reversed = False
        if self.reverse:
            if self.mode == 'POLYGON':
                if len(self.mouse_coords) >= 3:
                    show_reversed = True
            else:
                if len(self.mouse_coords) >= 2:
                    if self.mouse_coords[0] != self.mouse_coords[1]:
                        show_reversed = True
        if show_reversed:
            bgl.glEnable(bgl.GL_DEPTH_TEST)
            bgl.glClearDepth(1.0)
            bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT)
            bgl.glDepthMask(1)
            bgl.glColorMask(0, 0, 0, 0)

        lines = []
        if self.mouse_coords:
            if self.mode == 'LINE':
                w = region.width
                h = region.height
                p1, p2 = self.mouse_coords
                line = (p2 - p1).normalized()
                normal = Vector([-line[1], line[0]])
                corners = [Vector([0, 0]), Vector([w, 0]), Vector([w, h]),
                           Vector([0, h])]
                corners_ofs = [v - p1 for v in corners]
                dists = [v.project(line).dot(line) for v in corners_ofs]
                i = dists.index(min(dists))
                line_min = corners_ofs[i].project(line) + p1
                i = dists.index(max(dists))
                line_max = corners_ofs[i].project(line) + p1
                dists = [v.project(normal).dot(normal) for v in corners_ofs]
                i = dists.index(max(dists))
                normal_max_f = corners_ofs[i].project(normal).dot(normal)
                vec = normal * normal_max_f
                coords = [line_min, line_max, line_max + vec, line_min + vec]
                bgl.glBegin(bgl.GL_QUADS)
                for co in coords:
                    bgl.glVertex2f(*co)
                bgl.glEnd()
                lines = self.mouse_coords

            elif self.mode == 'BOX':
                p1, p2 = self.mouse_coords
                bgl.glRectf(p1[0], p1[1], p2[0], p2[1])
                lines = [p1,
                         Vector((p2[0], p1[1])),
                         Vector((p2[0], p2[1])),
                         Vector((p1[0], p2[1])),
                         p1]
            elif self.mode == 'CIRCLE':
                p1, p2 = self.mouse_coords
                bgl.glBegin(bgl.GL_TRIANGLE_FAN)
                bgl.glVertex2f(*p1)
                r = (p2 - p1).length
                coords = calc_circle_coords(p1, r, self.circle_segments,
                                            self.circle_direction)
                for co in coords:
                    bgl.glVertex2f(*co)
                bgl.glVertex2f(*coords[0])
                bgl.glEnd()
                lines = coords + [coords[0]]
            elif self.mode == 'POLYGON':
                if len(self.mouse_coords) >= 3:
                    tris = mathutils.geometry.tessellate_polygon(
                        [[co.to_3d() for co in self.mouse_coords]])

                    bgl.glBegin(bgl.GL_TRIANGLES)
                    for tri in tris:
                        for i in tri:
                            bgl.glVertex2f(*self.mouse_coords[i])
                    bgl.glEnd()
                if len(self.mouse_coords) > 1:
                    lines = self.mouse_coords + [self.mouse_coords[0]]

        if show_reversed:
            bgl.glColorMask(1, 1, 1, 1)
            bgl.glBegin(bgl.GL_QUADS)
            bgl.glVertex3f(0, 0, -1)
            bgl.glVertex3f(region.width, 0, -1)
            bgl.glVertex3f(region.width, region.height, -1)
            bgl.glVertex3f(0, region.height, -1)
            bgl.glEnd()
            bgl.glDisable(bgl.GL_DEPTH_TEST)

        bgl.glColor4f(*color[:3], 1.0)
        bgl.glPointSize(1)
        bgl.glLineWidth(1)
        if len(lines) > 1:
            bgl.glBegin(bgl.GL_LINE_STRIP)
            for co in lines:
                bgl.glVertex2f(*co)
            bgl.glEnd()
        if self.mode == 'POLYGON':
            if len(self.mouse_coords) == 1:
                bgl.glPointSize(5)
                bgl.glBegin(bgl.GL_POINTS)
                for co in self.mouse_coords:
                    bgl.glVertex2f(*co)
                bgl.glEnd()
                bgl.glPointSize(1)
                bgl.glLineWidth(1)

        if self.mco_ctrl:
            SIZE = 12
            bgl.glColor4f(*snap_color)
            bgl.glBegin(bgl.GL_LINE_LOOP)
            v = self.mco_mod
            x = v[0] - SIZE / 2
            y = v[1] - SIZE / 2
            bgl.glVertex2f(x, y)
            bgl.glVertex2f(x + SIZE, y)
            bgl.glVertex2f(x + SIZE, y + SIZE)
            bgl.glVertex2f(x, y + SIZE)
            bgl.glEnd()

        glsettings.pop()
        glsettings.font_size()
Example #18
0
    def modal(self, context, event):
        if event.type in {'ESC'}:
            self.cancel(context)
            return {'CANCELLED'}
        
        if event.type == 'TIMER':
            
            # If there is no reference to source on the text editor, create one
            if not self.source in bpy.data.texts:
                print(f'File name {self.source} not found. Will create an internal one')
                
                # If match an external file 
                if self.file_exist(self.source):
                    bpy.ops.text.open(filepath=self.source)

                # else create a internal file with the default fragment code
                else:
                    bpy.data.texts.new(self.source)
                    bpy.data.texts[self.source].write(self.default_code)
            
            # If the source file is external and it have been modify, reload it
            if not bpy.data.texts[self.source].is_in_memory and bpy.data.texts[self.source].is_modified:
                print(f'External file {self.source} have been modify. Reloading...')
                text = bpy.data.texts[self.source]
                ctx = context.copy()
                #Ensure  context area is not None
                ctx['area'] = ctx['screen'].areas[0]
                oldAreaType = ctx['area'].type
                ctx['area'].type = 'TEXT_EDITOR'
                ctx['edit_text'] = text
                bpy.ops.text.resolve_conflict(ctx, resolution='RELOAD')
                #Restore context
                ctx['area'].type = oldAreaType

            render = False
            recompile = False

            now = context.scene.frame_float / context.scene.render.fps
            
            # If shader content change 
            if self.current_code != bpy.data.texts[self.source].as_string():
                recompile = True

            if self.current_time != now:
                render = True

            if render or recompile:
                self.current_code = bpy.data.texts[self.source].as_string()
                self.current_time = now
            
                offscreen = gpu.types.GPUOffScreen(self.width, self.height)
                with offscreen.bind():
                    bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
    
                    # If there is no shader or need to be recompiled
                    if self.shader == None or recompile:
                        try:    
                            self.shader = gpu.types.GPUShader(self.vertex_default, self.current_code)
                        except Exception as Err:
                            print(Err)
                            self.shader = None
                    
                    # if there is a shader and no batch
                    if (self.shader != None and self.batch == None):
                        self.batch = batch_for_shader(
                            self.shader, 
                            'TRI_FAN', {
                                'a_position': ((-1, -1), (1, -1), (1, 1), (-1, 1))
                            },
                        )
                
                    if self.shader != None:
                        self.shader.bind()
            
                        try:
                            self.shader.uniform_float('u_time', self.current_time)
                        except ValueError:
                            pass
            
                        try:
                            self.shader.uniform_float('u_resolution', (self.width, self.height))
                        except ValueError: 
                            pass
            
                        self.batch.draw(self.shader)

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

                offscreen.free()

                if render:
                    name = self.source
                    if not name in bpy.data.images:
                        bpy.data.images.new(name, self.width, self.height)
                    image = bpy.data.images[name]
                    image.scale(self.width, self.height)
                    image.pixels = [v / 255 for v in buffer]
                    
        return {'PASS_THROUGH'}
Example #19
0
import gpu
import bgl
import random
from mathutils import Matrix
from gpu_extras.presets import draw_circle_2d

IMAGE_NAME = "Generated Image"
WIDTH = 512
HEIGHT = 512
RING_AMOUNT = 10


offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT)

with offscreen.bind():
    bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
    with gpu.matrix.push_pop():
        # reset matrices -> use normalized device coordinates [-1, 1]
        gpu.matrix.load_matrix(Matrix.Identity(4))
        gpu.matrix.load_projection_matrix(Matrix.Identity(4))

        for i in range(RING_AMOUNT):
            draw_circle_2d(
                (random.uniform(-1, 1), random.uniform(-1, 1)),
                (1, 1, 1, 1), random.uniform(0.1, 1), 20)

    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()
Example #20
0
    def execute(self, refholder):
        # pass
        tr = self.nodeTree.properties.TextureResolution
        print("begining execution " + str(tr))
        # compute A'
        mask = np.array([[0.05, 0.2, 0.05], [0.2, -1, 0.2], [0.05, 0.2, 0.05]])
        # Input data pixels
        A = self.inputs[0].getPixels()
        B = self.inputs[1].getPixels()

        # print(A)

        bgl.glGetIntegerv(bgl.GL_CURRENT_PROGRAM,
                          self.rdData[self.name]["prev_program"])
        bgl.glUseProgram(self.rdData[self.name]["program"])

        #set any uniforms needed
        bgl.glUniform1f(self.rdData[self.name]["feed_loc"],
                        self.inputs[2].value)
        bgl.glUniform1f(self.rdData[self.name]["kill_loc"],
                        self.inputs[3].value)
        bgl.glUniform1f(self.rdData[self.name]["da_loc"], self.inputs[4].value)
        bgl.glUniform1f(self.rdData[self.name]["db_loc"], self.inputs[5].value)
        bgl.glUniform1f(self.rdData[self.name]["dt_loc"], self.inputs[6].value)
        bgl.glUniform1f(self.rdData[self.name]["step_loc"], 1 / tr)

        bgl.glDisable(bgl.GL_SCISSOR_TEST)
        bgl.glViewport(0, 0, tr, tr)

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

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

        bgl.glEnable(bgl.GL_TEXTURE_2D)
        bgl.glActiveTexture(bgl.GL_TEXTURE0)

        channels = []
        if self.channels == '0':
            channels = [0]
        elif self.channels == '1':
            channels = [0, 1, 2]

        for j in channels:
            self.rdData[self.name]["npArray"][:, :, 0] = A[:, :, j]
            self.rdData[self.name]["npArray"][:, :, 1] = B[:, :, j]

            # Caution: Interfacing with Cython requires toList()
            self.rdData[self.name]["image"].pixels = self.rdData[
                self.name]["npArray"].flatten()

            self.rdData[self.name]["image"].gl_load(0, bgl.GL_LINEAR,
                                                    bgl.GL_LINEAR)

            bgl.glBindTexture(bgl.GL_TEXTURE_2D,
                              self.rdData[self.name]["image"].bindcode[0])
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                bgl.GL_REPEAT)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                bgl.GL_REPEAT)

            for i in range(self.inputs[7].value):
                bgl.glClearDepth(1.0)
                bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
                bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)

                bgl.glBegin(bgl.GL_TRIANGLES)

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

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

                bgl.glCopyTexImage2D(
                    bgl.GL_TEXTURE_2D,  #target
                    0,  #level
                    bgl.GL_RGBA,  #internalformat
                    0,  #x
                    0,  #y
                    tr,
                    tr,
                    0  #border
                )

                #glFlush glFinish or none here?
                bgl.glFinish()

            bgl.glReadPixels(0, 0, tr, tr, bgl.GL_RGBA, bgl.GL_FLOAT,
                             self.rdData[self.name]["buffer"])
            self.rdData[self.name]["image"].pixels = self.rdData[
                self.name]["buffer"][:]
            #write the image channel
            npImage = np.asarray(self.rdData[self.name]["image"].pixels,
                                 dtype="float")
            self.rdData[self.name]["npArray"] = npImage.reshape(
                tr, tr, self.rdData[self.name]["image"].channels)

            self.outputs[0].setPackedImageFromChannels(
                self.rdData[self.name]["npArray"][:, :, 0], j, flatten=True)
            self.outputs[1].setPackedImageFromChannels(
                self.rdData[self.name]["npArray"][:, :, 1], j, flatten=True)
            self.outputs[2].setPackedImageFromPixels(
                self.rdData[self.name]["npArray"])

            self.inputs[0].setPackedImageFromChannels(
                self.rdData[self.name]["npArray"][:, :, 0], j, flatten=True)
            self.inputs[1].setPackedImageFromChannels(
                self.rdData[self.name]["npArray"][:, :, 1], j, flatten=True)

            # ================================= Test bed
            # self.outputs[0].getTexture().image.copy()
            # self.outputs[1].getTexture().image.copy()
            # self.outputs[2].getTexture().image.copy()

            # nparr = np.asarray(self.outputs[0].getTexture().image.pixels, dtype="float")
            # nparr = nparr.reshape(tr, tr, 4)
            # print(nparr)

            self.rdData[self.name]["image"].gl_free()

        #restore the state so blender wont break
        bgl.glEnable(bgl.GL_SCISSOR_TEST)
        bgl.glUseProgram(self.rdData[self.name]["prev_program"][0])
        bgl.glActiveTexture(bgl.GL_TEXTURE0)
Example #21
0
    def cubemap_to_equirectangular(self, imageList, outputName):

        # Define the vertex shader
        vertex_shader = '''
            in vec3 aVertexPosition;
            in vec2 aVertexTextureCoord;

            out vec2 vTexCoord;

            void main() {
                vTexCoord = aVertexTextureCoord;
                gl_Position = vec4(aVertexPosition, 1);
            }
        '''

        # Define the fragment shader for the 360 degree conversion
        fragment_shader_360 = '''
            #define PI 3.1415926535897932384626
            
            // Input cubemap textures
            uniform sampler2D cubeLeftImage;
            uniform sampler2D cubeRightImage;
            uniform sampler2D cubeBottomImage;
            uniform sampler2D cubeTopImage;
            uniform sampler2D cubeBackImage;
            uniform sampler2D cubeFrontImage;

            in vec2 vTexCoord;

            out vec4 fragColor;

            void main() {
            
                // Calculate the pointing angle
                float azimuth = vTexCoord.x * PI;
                float elevation = vTexCoord.y * PI / 2.0;
                
                // Calculate the pointing vector
                vec3 pt;
                pt.x = cos(elevation) * sin(azimuth);
                pt.y = sin(elevation);
                pt.z = cos(elevation) * cos(azimuth);
                
                // Select the correct pixel
                if ((abs(pt.x) >= abs(pt.y)) && (abs(pt.x) >= abs(pt.z))) {
                    if (pt.x <= 0.0) {
                        fragColor = texture(cubeLeftImage, vec2(((-pt.z/pt.x)+1.0)/2.0,((-pt.y/pt.x)+1.0)/2.0));
                    } else {
                        fragColor = texture(cubeRightImage, vec2(((-pt.z/pt.x)+1.0)/2.0,((pt.y/pt.x)+1.0)/2.0));
                    }
                } else if (abs(pt.y) >= abs(pt.z)) {
                    if (pt.y <= 0.0) {
                        fragColor = texture(cubeBottomImage, vec2(((-pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+1.0)/2.0));
                    } else {
                        fragColor = texture(cubeTopImage, vec2(((pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+1.0)/2.0));
                    }
                } else {
                    if (pt.z <= 0.0) {
                        fragColor = texture(cubeBackImage, vec2(((pt.x/pt.z)+1.0)/2.0,((-pt.y/pt.z)+1.0)/2.0));
                    } else {
                        fragColor = texture(cubeFrontImage, vec2(((pt.x/pt.z)+1.0)/2.0,((pt.y/pt.z)+1.0)/2.0));
                    }
                }
            }
        '''

        # Define the fragment shader for the 180 degree conversion
        fragment_shader_180 = '''
            #define PI 3.1415926535897932384626
            
            // Input cubemap textures
            uniform sampler2D cubeLeftImage;
            uniform sampler2D cubeRightImage;
            uniform sampler2D cubeBottomImage;
            uniform sampler2D cubeTopImage;
            uniform sampler2D cubeFrontImage;

            in vec2 vTexCoord;

            out vec4 fragColor;

            void main() {{
            
                // Calculate the pointing angle
                float fovd = {0};
                float fovfrac = fovd/360.0;
                float sidefrac = (fovd-90.0)/180;
                float azimuth = vTexCoord.x * PI * fovfrac;
                float elevation = vTexCoord.y * PI / 2.0;
                
                // Calculate the pointing vector
                vec3 pt;
                pt.x = cos(elevation) * sin(azimuth);
                pt.y = sin(elevation);
                pt.z = cos(elevation) * cos(azimuth);
                
                // Select the correct pixel
                if ((abs(pt.x) >= abs(pt.y)) && (abs(pt.x) >= abs(pt.z))) {{
                    if (pt.x <= 0.0) {{
                        fragColor = texture(cubeLeftImage, vec2((((-pt.z/pt.x))+(2.0*sidefrac-1.0))/(2.0*sidefrac),((-pt.y/pt.x)+1.0)/2.0));
                    }} else {{
                        fragColor = texture(cubeRightImage, vec2(((-pt.z/pt.x)+1.0)/(2.0*sidefrac),((pt.y/pt.x)+1.0)/2.0));
                    }}
                }} else if (abs(pt.y) >= abs(pt.z)) {{
                    if (pt.y <= 0.0) {{
                        fragColor = texture(cubeBottomImage, vec2(((-pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+(2.0*sidefrac-1.0))/(2.0*sidefrac)));
                    }} else {{
                        fragColor = texture(cubeTopImage, vec2(((pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+1.0)/(2.0*sidefrac)));
                    }}
                }} else {{
                    fragColor = texture(cubeFrontImage, vec2(((pt.x/pt.z)+1.0)/2.0,((pt.y/pt.z)+1.0)/2.0));
                }}
            }}
        '''.format(self.FOV)

        # Define the fragment shader for the dome conversion
        fragment_shader_dome = '''
            #define PI 3.1415926535897932384626
            
            // Input cubemap textures
            uniform sampler2D cubeLeftImage;
            uniform sampler2D cubeRightImage;
            uniform sampler2D cubeBottomImage;
            uniform sampler2D cubeTopImage;
            uniform sampler2D cubeFrontImage;
            uniform sampler2D cubeBackImage;

            in vec2 vTexCoord;

            out vec4 fragColor;

            void main() {{

                float fovd = {0};
                float fovfrac = fovd/360.0;
                float sidefrac = (fovd-90.0)/180;
                float hfov = fovfrac*PI;
                vec2 d = vTexCoord.xy;

                float r = length( d );
                if( r > 1.0 ) {{
                    fragColor = vec4(0.0, 0.0, 0.0, 1.0);
                    return;
                }}
                
                vec2 dunit = normalize( d );
                float phi = r * hfov;
                vec3 pt = vec3( 1.0, 1.0, 1.0 );
                pt.xy = dunit * sin( phi );
                pt.z = cos( phi );  // Select the correct pixel
                
                // Select the correct pixel
                if ((abs(pt.x) >= abs(pt.y)) && (abs(pt.x) >= abs(pt.z))) {{
                    if (pt.x <= 0.0) {{
                        fragColor = texture(cubeLeftImage, vec2((((-pt.z/pt.x))+(2.0*sidefrac-1.0))/(2.0*sidefrac),((-pt.y/pt.x)+1.0)/2.0));
                    }} else {{
                        fragColor = texture(cubeRightImage, vec2(((-pt.z/pt.x)+1.0)/(2.0*sidefrac),((pt.y/pt.x)+1.0)/2.0));
                    }}
                }} else if (abs(pt.y) >= abs(pt.z)) {{
                    if (pt.y <= 0.0) {{
                        fragColor = texture(cubeBottomImage, vec2(((-pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+(2.0*sidefrac-1.0))/(2.0*sidefrac)));
                    }} else {{
                        fragColor = texture(cubeTopImage, vec2(((pt.x/pt.y)+1.0)/2.0,((-pt.z/pt.y)+1.0)/(2.0*sidefrac)));
                    }}
                }} else {{
                    if (pt.z <= 0.0) {{
                        fragColor = texture(cubeBackImage, vec2(((pt.x/pt.z)+1.0)/2.0,((-pt.y/pt.z)+1.0)/2.0));
                    }} else {{
                        fragColor = texture(cubeFrontImage, vec2(((pt.x/pt.z)+1.0)/2.0,((pt.y/pt.z)+1.0)/2.0));
                    }}
                }}
            }}
        '''.format(self.FOV)

        # Generate the OpenGL shader
        pos = [
            (-1.0, -1.0, -1.0),  # left,  bottom, back
            (-1.0, 1.0, -1.0),  # left,  top,    back
            (1.0, -1.0, -1.0),  # right, bottom, back
            (1.0, 1.0, -1.0)
        ]  # right, top,    back
        coords = [
            (-1.0, -1.0),  # left,  bottom
            (-1.0, 1.0),  # left,  top
            (1.0, -1.0),  # right, bottom
            (1.0, 1.0)
        ]  # right, top
        vertexIndices = [(0, 3, 1), (3, 0, 2)]
        if self.is_dome:
            shader = gpu.types.GPUShader(vertex_shader, fragment_shader_dome)
        else:
            if self.no_back_image:
                shader = gpu.types.GPUShader(vertex_shader,
                                             fragment_shader_180)
            else:
                shader = gpu.types.GPUShader(vertex_shader,
                                             fragment_shader_360)
        batch = batch_for_shader(shader, 'TRIS', {"aVertexPosition": pos,\
                                                  "aVertexTextureCoord": coords},\
                                                  indices=vertexIndices)

        # Change the color space of all of the images to Linear
        # and load them into OpenGL textures
        imageLeft = imageList[0]
        imageLeft.colorspace_settings.name = 'Linear'
        imageLeft.gl_load()

        imageRight = imageList[1]
        imageRight.colorspace_settings.name = 'Linear'
        imageRight.gl_load()

        imageBottom = imageList[2]
        imageBottom.colorspace_settings.name = 'Linear'
        imageBottom.gl_load()

        imageTop = imageList[3]
        imageTop.colorspace_settings.name = 'Linear'
        imageTop.gl_load()

        imageFront = imageList[4]
        imageFront.colorspace_settings.name = 'Linear'
        imageFront.gl_load()

        if not self.no_back_image:
            imageBack = imageList[5]
            imageBack.colorspace_settings.name = 'Linear'
            imageBack.gl_load()

        # set the size of the final image
        width = self.image_size[0]
        height = self.image_size[1]

        # Create an offscreen render buffer and texture
        offscreen = gpu.types.GPUOffScreen(width, height)

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

            shader.bind()

            # Bind all of the cubemap textures and enable correct filtering and wrapping
            # to prevent seams
            bgl.glActiveTexture(bgl.GL_TEXTURE0)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageLeft.bindcode)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                bgl.GL_CLAMP_TO_EDGE)
            shader.uniform_int("cubeLeftImage", 0)

            bgl.glActiveTexture(bgl.GL_TEXTURE1)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageRight.bindcode)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                bgl.GL_CLAMP_TO_EDGE)
            shader.uniform_int("cubeRightImage", 1)

            bgl.glActiveTexture(bgl.GL_TEXTURE2)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageBottom.bindcode)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                bgl.GL_CLAMP_TO_EDGE)
            shader.uniform_int("cubeBottomImage", 2)

            bgl.glActiveTexture(bgl.GL_TEXTURE3)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageTop.bindcode)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                bgl.GL_CLAMP_TO_EDGE)
            shader.uniform_int("cubeTopImage", 3)

            bgl.glActiveTexture(bgl.GL_TEXTURE4)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageFront.bindcode)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                bgl.GL_CLAMP_TO_EDGE)
            shader.uniform_int("cubeFrontImage", 4)

            if not self.no_back_image:
                bgl.glActiveTexture(bgl.GL_TEXTURE5)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, imageBack.bindcode)
                bgl.glTexParameterf(bgl.GL_TEXTURE_2D,
                                    bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR)
                bgl.glTexParameterf(bgl.GL_TEXTURE_2D,
                                    bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR)
                bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                    bgl.GL_CLAMP_TO_EDGE)
                bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                    bgl.GL_CLAMP_TO_EDGE)
                shader.uniform_int("cubeBackImage", 5)

            # Bind the resulting texture
            bgl.glActiveTexture(bgl.GL_TEXTURE6)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, offscreen.color_texture)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                bgl.GL_CLAMP_TO_EDGE)

            # Render the image
            batch.draw(shader)

            # Unload the textures
            imageLeft.gl_free()
            imageRight.gl_free()
            imageBottom.gl_free()
            imageTop.gl_free()
            imageFront.gl_free()
            if not self.no_back_image:
                imageBack.gl_free()

            # Read the resulting pixels into a buffer
            buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
            bgl.glGetTexImage(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA, bgl.GL_FLOAT,
                              buffer)

        # Unload the offscreen texture
        offscreen.free()

        # Remove the cubemap textures:
        for image in imageList:
            bpy.data.images.remove(image)

        # Copy the pixels from the buffer to an image object
        if not outputName in bpy.data.images.keys():
            bpy.data.images.new(outputName, width, height)
        imageRes = bpy.data.images[outputName]
        imageRes.scale(width, height)
        imageRes.pixels = buffer
        return imageRes
Example #22
0
    def update_all(self):
        self.drawn_count = 0
        self._offset_cur = 1

        bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)
    def execute(self, context):
        # import cProfile, pstats, io
        # pr = cProfile.Profile()
        # pr.enable()

        bgl.glEnable(bgl.GL_PROGRAM_POINT_SIZE)

        scene = context.scene
        render = scene.render
        image_settings = render.image_settings

        original_depth = image_settings.color_depth
        image_settings.color_depth = '8'

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

        pcv = context.object.point_cloud_visualizer
        cloud = PCVManager.cache[pcv.uuid]
        cam = scene.camera
        if (cam is None):
            self.report({'ERROR'}, "No camera found.")
            return {'CANCELLED'}

        render_suffix = pcv.render_suffix
        render_zeros = pcv.render_zeros

        offscreen = GPUOffScreen(width, height)
        offscreen.bind()
        # with offscreen.bind():
        try:
            gpu.matrix.load_matrix(Matrix.Identity(4))
            gpu.matrix.load_projection_matrix(Matrix.Identity(4))

            bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)

            o = cloud['object']
            vs = cloud['vertices']
            cs = cloud['colors']

            dp = pcv.display_percent
            l = int((len(vs) / 100) * dp)
            if (dp >= 99):
                l = len(vs)
            vs = vs[:l]
            cs = cs[:l]

            # sort by depth
            mw = o.matrix_world
            depth = []
            for i, v in enumerate(vs):
                vw = mw @ Vector(v)
                depth.append(world_to_camera_view(scene, cam, vw)[2])
            zps = zip(depth, vs, cs)
            sps = sorted(zps, key=lambda a: a[0])
            # split and reverse
            vs = [a for _, a, b in sps][::-1]
            cs = [b for _, a, b in sps][::-1]

            shader = GPUShader(vertex_shader, fragment_shader)
            batch = batch_for_shader(shader, 'POINTS', {
                "position": vs,
                "color": cs,
            })
            shader.bind()

            view_matrix = cam.matrix_world.inverted()
            camera_matrix = cam.calc_matrix_camera(
                bpy.context.depsgraph,
                x=render.resolution_x,
                y=render.resolution_y,
                scale_x=render.pixel_aspect_x,
                scale_y=render.pixel_aspect_y,
            )
            perspective_matrix = camera_matrix @ view_matrix

            shader.uniform_float("perspective_matrix", perspective_matrix)
            shader.uniform_float("object_matrix", o.matrix_world)
            # shader.uniform_float("point_size", pcv.point_size)
            shader.uniform_float("point_size", pcv.render_point_size)
            shader.uniform_float("alpha_radius", pcv.alpha_radius)
            batch.draw(shader)

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

        except Exception as e:
            self.report({'ERROR'}, str(e))
            return {'CANCELLED'}

        finally:
            offscreen.unbind()
            offscreen.free()
        # offscreen.free()

        # image from buffer
        image_name = "pcv_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]

        # save as image file
        save_render(
            self,
            scene,
            image,
            render_suffix,
            render_zeros,
        )

        # restore
        image_settings.color_depth = original_depth

        # pr.disable()
        # s = io.StringIO()
        # sortby = 'cumulative'
        # ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
        # ps.print_stats()
        # print(s.getvalue())

        return {'FINISHED'}
Example #24
0
    def _execute_inner(self, obs):
        dim = self.dim
        dimhalf = dim * .5
        offbuf = gpu.types.GPUOffScreen(dim, dim)
        sample = sample_sphere if self.dom == 'SPHERE' \
            else sample_hemisphere

        # Construct depthpass shader
        shader = gpu.types.GPUShader(
            vertexcode='''
            uniform mat4 mvp;
            in vec3 pos;
            void main() {
                gl_Position = mvp * vec4(pos, 1);
            }''',
            fragcode='''
            out vec4 col;
            void main() {
                col = vec4(0, 0, 1, 1);
            }'''
        )
        shader.bind()

        # Create batch from all objects in edit mode
        verts, indcs, geoinfo = combine_meshes(obs)
        batch = batch_for_shader(
            shader, 'TRIS',
            {"pos": verts},
            indices=indcs,
        )
        batch.program_set(shader)

        # Find the center and bounds of all objects to calculate the
        # encompassing radius of the (hemi-)sphere on which render
        # positions will be sampled
        bounds, centr = get_bounds_and_center(verts)
        rad = np.linalg.norm(bounds[:2]) * .5 + 1
        del indcs, bounds

        # Spawn debug sphere with calculated radius
        if self._debug_spawn_sphere:
            bpy.ops.mesh.primitive_uv_sphere_add(
                radius=rad,
                location=centr,
                )

        # Render the objects from several views and mark seen vertices
        visibl = np.zeros(len(verts), dtype=np.bool)
        for _ in range(self.samplecnt):
            # Generate random points on the chosen domain from which
            # to render the objects
            # Chose rotation so the 'camera' looks to the center
            samplepos, (theta, phi) = sample(rad)
            view_mat_inv = make_transf_mat(
                transl=samplepos + centr,
                rot=(phi, 0, theta + np.pi * .5),
                )

            # Spawn debug camera at sampled position
            if self._debug_spawn_cams:
                bpy.ops.object.camera_add()
                bpy.context.object.matrix_world = Matrix(view_mat_inv)

            # Build the Model View Projection matrix from chosen
            # render position and radius
            # The model matrix has already been applied to the vertices
            # befor creating the batch
            mvp = make_proj_mat(
                fov=90,
                clip_start=rad * .25,
                clip_end=rad * 1.5,
                dimx=dim,
                dimy=dim,
                ) @ np.linalg.inv(view_mat_inv)
            shader.uniform_float("mvp", Matrix(mvp))
            del view_mat_inv, samplepos, theta, phi

            with offbuf.bind():
                # Render the selected objects into the offscreen buffer
                bgl.glDepthMask(bgl.GL_TRUE)
                bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT)
                bgl.glEnable(bgl.GL_DEPTH_TEST)
                batch.draw()

                # Write texture back to CPU
                pxbuf = bgl.Buffer(bgl.GL_FLOAT, dim * dim)
                bgl.glReadBuffer(bgl.GL_BACK)
                bgl.glReadPixels(0, 0, dim, dim, bgl.GL_DEPTH_COMPONENT,
                                 bgl.GL_FLOAT, pxbuf)

            # Map depth values from [0, 1] to [-1, 1]
            pxbuf = np.asanyarray(pxbuf) * 2 - 1
            pxbuf.shape = (dim, dim)

            # Transform verts of active object to clip space
            tverts = mvp @ append_one(verts).T
            # Perspective divide to transform to NDCs [-1, 1]
            tverts /= tverts[3]

            # Find pixel coordinates of each vertex' projected position
            # by remapping x and y coordinates from NDCs to [0, dim]
            # Add .5 to make sure the flooring from conversion to int
            # is actually rounding
            uvs = tverts[:2] * dimhalf + (dimhalf + .5)
            uvs = uvs.astype(np.int32)

            # Map all vertices outside the view frustum to (0, 0)
            # so they don't sample the pixel array out of bounds
            invalid = np.any((uvs < 0) | (dim <= uvs), axis=0)
            uvs.T[invalid] = (0, 0)

            # For each vertex, get the depth at its projected pixel
            # and its distance to the render position
            imgdpth = pxbuf[(uvs[1], uvs[0])]
            camdist = tverts[2]
            # Set the distance of invalid vertices past [-1, 1] so they
            # won't be selected
            camdist[invalid] = 2

            # A vertex is visible if it's inside the view frustum
            # (valid) and not occluded by any face.
            # A vertex is occluded when its depth sampled from the
            # image is smaller than its distance to the camera.
            # A small error margin is added to prevent self-occlusion.
            # The result is logically or-ed with the result from other
            # render positions.
            visibl |= camdist <= (imgdpth + .001)

            # Create debug image of the rendered view
            if self._debug_create_img:
                # Grayscale to RGBA and [-1, 1] to [0, 1]
                pxbuf = np.repeat(pxbuf, 4) * .5 + .5
                pxbuf.shape = (dim, dim, 4)
                # Alpha channel is 1
                pxbuf[:, :, 3] = 1
                # Mark projected vertex positions in red
                pxbuf[(uvs[1], uvs[0])] = (1, 0, 0, 1)

                imgname = "Debug"
                if imgname not in bpy.data.images:
                    bpy.data.images.new(imgname, dim, dim)
                image = bpy.data.images[imgname]
                image.scale(dim, dim)
                image.pixels = pxbuf.ravel()

        # Split visible flag list back in original objects
        offbuf.free()
        start = 0
        for o, (end, _) in zip(obs, geoinfo):
            o.data.vertices.foreach_set('select', visibl[start:end])
            start = end
Example #25
0
def make_equirectangular_from_sky(base_path, sky_name):
    textures = [
        sky_name + "_up", sky_name + "_dn", sky_name + "_ft", sky_name + "_bk",
        sky_name + "_lf", sky_name + "_rt"
    ]
    cube = [None for x in range(6)]

    biggest_h = 1
    biggest_w = 1

    for index, tex in enumerate(textures):
        image = Image.load_file(base_path + "/" + tex)

        if image != None:
            cube[index] = image
            if image.gl_load():
                raise Exception()
            if biggest_h < image.size[1]:
                biggest_h = image.size[1]
            if biggest_w < image.size[0]:
                biggest_w = image.size[0]

    equi_w = min(8192, biggest_w * 4)
    equi_h = min(4096, biggest_h * 2)

    offscreen = gpu.types.GPUOffScreen(equi_w, equi_h)
    with offscreen.bind():
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
        with gpu.matrix.push_pop():
            # reset matrices -> use normalized device coordinates [-1, 1]
            gpu.matrix.load_matrix(Matrix.Identity(4))
            gpu.matrix.load_projection_matrix(Matrix.Identity(4))

            if cube[0] != None:
                bgl.glActiveTexture(bgl.GL_TEXTURE0)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, cube[0].bindcode)
            if cube[1] != None:
                bgl.glActiveTexture(bgl.GL_TEXTURE1)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, cube[1].bindcode)
            if cube[2] != None:
                bgl.glActiveTexture(bgl.GL_TEXTURE2)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, cube[2].bindcode)
            if cube[3] != None:
                bgl.glActiveTexture(bgl.GL_TEXTURE3)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, cube[3].bindcode)
            if cube[4] != None:
                bgl.glActiveTexture(bgl.GL_TEXTURE4)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, cube[4].bindcode)
            if cube[5] != None:
                bgl.glActiveTexture(bgl.GL_TEXTURE5)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, cube[5].bindcode)

            #now draw
            shader.bind()
            shader.uniform_int("tex_up", 0)
            shader.uniform_int("tex_dn", 1)
            shader.uniform_int("tex_ft", 2)
            shader.uniform_int("tex_bk", 3)
            shader.uniform_int("tex_lf", 4)
            shader.uniform_int("tex_rt", 5)
            shader.uniform_float("clamp_value", 1.0 / biggest_h)
            batch.draw(shader)

        buffer = bgl.Buffer(bgl.GL_FLOAT, equi_w * equi_h * 4)
        bgl.glReadBuffer(bgl.GL_BACK)
        bgl.glReadPixels(0, 0, equi_w, equi_h, bgl.GL_RGBA, bgl.GL_FLOAT,
                         buffer)

    offscreen.free()

    image = bpy.data.images.get(sky_name)
    if image == None:
        image = bpy.data.images.new(sky_name, width=equi_w, height=equi_h)
    image.scale(equi_w, equi_h)
    image.pixels = buffer
    image.pack()
    return image
def image_to_KK(image, lut_name):
    width = image.size[0]
    height = image.size[1]

    # Some Sauce
    vertex_default = '''
    in vec2 a_position;
    in vec2 a_texcoord;

    void main() {
        gl_Position = vec4(a_position, 0.0, 1.0);
    }
    '''

    # The Secret Sauce
    current_code = '''
    uniform sampler2D tex0;
    uniform sampler2D lut;
    uniform vec2    u_resolution;

    vec3 to_srgb(vec3 c){
        c.rgb = max( 1.055 * pow( c.rgb, vec3(0.416666667,0.416666667,0.416666667) ) - 0.055, 0 );
        return c;
    }
    
    vec3 apply_lut(vec3 color) {
        const vec3 coord_scale = vec3(0.0302734375, 0.96875, 31.0);
        const vec3 coord_offset = vec3( 0.5/1024, 0.5/32, 0.0);
        const vec2 texel_height_X0 = vec2( 0.03125, 0.0 );
        
        vec3 coord = color * coord_scale + coord_offset;
        
        vec3 coord_frac = fract( coord );
        vec3 coord_floor = coord - coord_frac;
        vec2 coord_bot = coord.xy + coord_floor.zz * texel_height_X0;
        vec2 coord_top = coord_bot + texel_height_X0;

        vec3 lutcol_bot = texture2D( lut, coord_bot ).rgb;
        vec3 lutcol_top = texture2D( lut, coord_top ).rgb;
        
        vec3 lutColor = mix(lutcol_bot, lutcol_top, coord_frac.z);
        
        return lutColor;
    }

    void main() {
        vec4 texRGBA = texture2D(tex0, gl_FragCoord.xy / u_resolution);

        vec3 texColor = to_srgb(texRGBA.rgb);

        vec3 newColor = apply_lut(texColor);

        newColor = to_srgb(newColor);
        
        gl_FragColor = vec4(newColor.rgb, texRGBA.a);
    }
    '''

    # This object gives access to off screen buffers.
    offscreen = gpu.types.GPUOffScreen(width, height)

    # Context manager to ensure balanced bind calls, even in the case of an error.
    # Only run if valid
    with offscreen.bind():

        # Clear buffers to preset values
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)

        # Initialize the shader
        # GPUShader combines multiple GLSL shaders into a program used for drawing.
        # It must contain a vertex and fragment shaders, with an optional geometry shader.
        shader = gpu.types.GPUShader(vertex_default, current_code)

        # Initialize the shader batch
        # It makes sure that all the vertex attributes necessary for a specific shader are provided.
        batch = batch_for_shader(
            shader,
            'TRI_FAN',
            {'a_position': ((-1, -1), (1, -1), (1, 1), (-1, 1))},
        )

        # Bind the shader object. Required to be able to change uniforms of this shader.
        shader.bind()

        bgl.glUniform1i(bgl.glGetUniformLocation(shader.program, "tex0"), 0)
        bgl.glUniform1i(bgl.glGetUniformLocation(shader.program, "lut"), 1)

        try:
            # Make sure image has a bindcode
            if image.bindcode == 0:
                for i in range(0, 20):
                    image.gl_load()
                    if image.bindcode != 0:
                        break

            # https://docs.blender.org/api/current/bgl.html
            bgl.glActiveTexture(bgl.GL_TEXTURE0)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER,
                                bgl.GL_LINEAR)

            # Specify the value of a uniform variable for the current program object.
            # In this case, an image.
            shader.uniform_int("tex0", 0)
        except ValueError:
            pass

        try:
            lut_image = bpy.data.images[lut_name]

            # Make sure image has a bindcode
            if lut_image.bindcode == 0:
                for i in range(0, 20):
                    lut_image.gl_load()
                    if lut_image.bindcode != 0:
                        break

            # https://docs.blender.org/api/current/bgl.html
            bgl.glActiveTexture(bgl.GL_TEXTURE1)
            bgl.glBindTexture(bgl.GL_TEXTURE_2D, lut_image.bindcode)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                bgl.GL_CLAMP_TO_EDGE)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER,
                                bgl.GL_LINEAR)
            bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER,
                                bgl.GL_LINEAR)

            # Specify the value of a uniform variable for the current program object.
            # In this case, an image.
            shader.uniform_int("lut", 1)
        except ValueError:
            pass

        try:
            shader.uniform_float('u_resolution', (width, height))
        except ValueError:
            pass

        # Run the drawing program with the parameters assigned to the batch.
        batch.draw(shader)

        # The Buffer object is simply a block of memory that is delineated and initialized by the user.
        buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)

        # Select a color buffer source for pixels.
        bgl.glReadBuffer(bgl.GL_BACK)

        # Read a block of pixels from the frame buffer.
        bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA,
                         bgl.GL_UNSIGNED_BYTE, buffer)

    # Free the offscreen object. The framebuffer, texture and render objects will no longer be accessible.
    offscreen.free()

    # Return the final buffer-pixels
    pixels = [v / 255 for v in buffer]
    return pixels, width, height
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
Example #28
0
    def draw_lasso_shader(self):
        # create batches
        vertices = [Vector(v) for v in self.lasso_poly]
        vertices.append(Vector(self.lasso_poly[0]))

        lengths = [0]
        for a, b in zip(vertices[:-1], vertices[1:]):
            lengths.append(lengths[-1] + (a - b).length)

        bbox_vertices = ((self.lasso_xmin, self.lasso_ymax), (self.lasso_xmin,
                                                              self.lasso_ymin),
                         (self.lasso_xmax, self.lasso_ymin), (self.lasso_xmax,
                                                              self.lasso_ymax))

        fill_batch = batch_for_shader(fill_shader, 'TRI_FAN',
                                      {"pos": vertices})
        border_batch = batch_for_shader(border_shader, 'LINE_STRIP', {
            "pos": vertices,
            "len": lengths
        })
        stencil_batch = batch_for_shader(fill_shader, 'TRI_FAN',
                                         {"pos": bbox_vertices})

        matrix = gpu.matrix.get_projection_matrix()
        segment_color = (1.0, 1.0, 1.0, 1.0)
        gap_color = (0.2, 0.2, 0.2, 1.0)
        shadow_color = (0.3, 0.3, 0.3, 1.0)
        fill_color = (1.0, 1.0, 1.0, 0.04)

        # stencil mask
        # https://stackoverflow.com/a/25468363/5106051
        glClear(GL_STENCIL_BUFFER_BIT)
        glEnable(GL_STENCIL_TEST)
        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)
        glStencilFunc(GL_ALWAYS, 0, 1)
        glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT)
        glStencilMask(1)
        fill_shader.bind()
        fill_shader.uniform_float("u_ViewProjectionMatrix", matrix)
        fill_shader.uniform_vector_float(self.unif_fill_color,
                                         pack("4f", *fill_color), 4)
        fill_batch.draw(fill_shader)
        glStencilFunc(GL_EQUAL, 1, 1)
        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)

        # fill
        glEnable(GL_BLEND)
        stencil_batch.draw(fill_shader)
        glDisable(GL_BLEND)

        dashed = 0 if self.curr_behavior == 'CONTAIN' else 1

        if not dashed:
            # solid border shadow
            glLineWidth(3)
            border_shader.bind()
            border_shader.uniform_float("u_ViewProjectionMatrix", matrix)
            border_shader.uniform_int("u_Dashed", dashed)
            border_shader.uniform_vector_float(self.unif_segment_color,
                                               pack("4f", *shadow_color), 4)
            border_batch.draw(border_shader)
            glLineWidth(1)

            # solid border
            glDisable(GL_STENCIL_TEST)
            border_shader.uniform_vector_float(self.unif_segment_color,
                                               pack("4f", *segment_color), 4)
            border_batch.draw(border_shader)
        else:
            # dashed border
            glDisable(GL_STENCIL_TEST)
            border_shader.bind()
            border_shader.uniform_float("u_ViewProjectionMatrix", matrix)
            border_shader.uniform_int("u_Dashed", dashed)
            border_shader.uniform_vector_float(self.unif_segment_color,
                                               pack("4f", *segment_color), 4)
            border_shader.uniform_vector_float(self.unif_gap_color,
                                               pack("4f", *gap_color), 4)
            border_batch.draw(border_shader)
Example #29
0
    def draw(self, context):
        log("Draw")

        if not self.is_synced:
            return

        stage = self.stage
        if not stage:
            return

        view_settings = ViewSettings(context)
        if view_settings.width * view_settings.height == 0:
            return

        gf_camera = view_settings.export_camera()
        self.renderer.SetCameraState(
            gf_camera.frustum.ComputeViewMatrix(),
            gf_camera.frustum.ComputeProjectionMatrix())
        self.renderer.SetRenderViewport(
            (*view_settings.border[0], *view_settings.border[1]))
        self.renderer.SetRendererAov('color')
        self.render_params.renderResolution = (view_settings.width,
                                               view_settings.height)
        self.render_params.clipPlanes = [
            Gf.Vec4d(i) for i in gf_camera.clippingPlanes
        ]

        if self.shading_data.type == 'MATERIAL' and self.is_gl_delegate:
            l = Glf.SimpleLight()
            l.ambient = (0, 0, 0, 0)
            l.position = (*gf_camera.frustum.position, 1)

            mat = Glf.SimpleMaterial()

            self.renderer.SetLightingState((l, ), mat, (0, 0, 0, 0))

        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)

        self.render_engine.bind_display_space_shader(context.scene)

        if usd_utils.get_renderer_percent_done(self.renderer) == 0.0:
            self.time_begin = time.perf_counter()

        try:
            self.renderer.Render(stage.GetPseudoRoot(), self.render_params)

        except Exception as e:
            if isinstance(e, Tf.ErrorException
                          ) and "GL error: invalid operation" in str(e):
                pass  # we won't log error "GL error: invalid operation"
            else:
                log.error(e)

        self.render_engine.unbind_display_space_shader()

        # additional clear of GL depth buffer which provides blender to draw viewport grid
        bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT)

        elapsed_time = time_str(time.perf_counter() - self.time_begin)
        if not self.renderer.IsConverged():
            self.notify_status(
                f"Time: {elapsed_time} | "
                f"Done: {int(usd_utils.get_renderer_percent_done(self.renderer))}%",
                "Render")
        else:
            self.notify_status(f"Time: {elapsed_time}", "Rendering Done",
                               False)
def render_main(self, context, animation=False):

    # Save old info
    bgl.glEnable(bgl.GL_MULTISAMPLE)
    settings = bpy.context.scene.render.image_settings
    depth = settings.color_depth
    settings.color_depth = '16'

    scene = context.scene
    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)


    # --------------------------------------
    # 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]])

    view_matrix_3d = scene.camera.matrix_world.inverted()
    projection_matrix = scene.camera.calc_matrix_camera(context.view_layer.depsgraph, x=width, y=height)
    scene.measureit_arch_is_render_draw = True
    with offscreen.bind():
        # Clear Depth Buffer, set Clear Depth to Cameras Clip Distance
        bgl.glClearDepth(clipdepth)
        bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT)

        # Draw Scene If Necessary
        if scene.measureit_arch_use_depth_clipping is True:
            draw_scene(self, context, projection_matrix) 
        
        # Clear Color Keep on depth info
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)

        # -----------------------------
        # Loop to draw all objects
        # -----------------------------
        for myobj in objlist:
            if myobj.visible_get() is True:
                if 'DimensionGenerator' in myobj:
                    measureGen = myobj.DimensionGenerator[0]
                    for linDim in measureGen.alignedDimensions:
                        draw_alignedDimension(context, myobj, measureGen,linDim)
                    for dim in measureGen.angleDimensions:
                        draw_angleDimension(context, myobj, measureGen,dim)

                if 'LineGenerator' in myobj:
                    # Set 3D Projection Martix
                    gpu.matrix.reset()
                    gpu.matrix.load_matrix(view_matrix_3d)
                    gpu.matrix.load_projection_matrix(projection_matrix)

                    # Draw Line Groups
                    op = myobj.LineGenerator[0]
                    draw_line_group(context, myobj, op)
             
                if 'AnnotationGenerator' in myobj:
                    # Set 3D Projection Martix
                    gpu.matrix.reset()
                    gpu.matrix.load_matrix(view_matrix_3d)
                    gpu.matrix.load_projection_matrix(projection_matrix)

                    # Draw Line Groups
                    op = myobj.AnnotationGenerator[0]
                    draw_annotation(context, myobj, op)                

        # -----------------------------
        # Loop to draw all debug
        # -----------------------------
        if scene.measureit_arch_debug is True:
            selobj = bpy.context.selected_objects
            for myobj in selobj:
                if scene.measureit_arch_debug_objects is True:
                    draw_object(context, myobj, None, None)
                elif scene.measureit_arch_debug_object_loc is True:
                    draw_object(context, myobj, None, None)
                if scene.measureit_arch_debug_vertices is True:
                    draw_vertices(context, myobj, None, None)
                elif scene.measureit_arch_debug_vert_loc is True:
                    draw_vertices(context, myobj, None, None)
                if scene.measureit_arch_debug_edges is True:
                    draw_edges(context, myobj, None, None)
                if scene.measureit_arch_debug_faces is True or scene.measureit_arch_debug_normals is True:
                    draw_faces(context, myobj, None, None)
        
        # -----------------------------
        # Draw a rectangle frame
        # -----------------------------
        if scene.measureit_arch_rf is True:
            rfcolor = scene.measureit_arch_rf_color
            rfborder = scene.measureit_arch_rf_border
            rfline = scene.measureit_arch_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))

        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()

    scene.measureit_arch_is_render_draw = False
    # -----------------------------
    # Create image
    # -----------------------------
    image_name = "measureit_arch_output"
    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]

    # Saves image
    if image is not None and (scene.measureit_arch_render is True or animation is True):
        ren_path = bpy.context.scene.render.filepath
        filename = "mit_frame"
        ftxt = "%04d" % scene.frame_current
        outpath = (ren_path + filename + ftxt + ".png")
        save_image(self, outpath, image)

    # restore default value
    settings.color_depth = depth
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
Example #32
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, filepath=temp_filepath, compression=15)
    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})
Example #33
0
#. Draw the generated texture using the new shader.
"""
import bpy
import gpu
import bgl
from mathutils import Matrix
from gpu_extras.batch import batch_for_shader
from gpu_extras.presets import draw_circle_2d

# Create and fill offscreen
##########################################

offscreen = gpu.types.GPUOffScreen(512, 512)

with offscreen.bind():
    bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
    with gpu.matrix.push_pop():
        # reset matrices -> use normalized device coordinates [-1, 1]
        gpu.matrix.load_matrix(Matrix.Identity(4))
        gpu.matrix.load_projection_matrix(Matrix.Identity(4))

        amount = 10
        for i in range(-amount, amount + 1):
            x_pos = i / amount
            draw_circle_2d((x_pos, 0.0), (1, 1, 1, 1), 0.5, 200)


# Drawing the generated texture in 3D space
#############################################

vertex_shader = '''
def render_main(self, context, animation=False):

    # Save old info
    scene = context.scene
    sceneProps= scene.MeasureItArchProps
    sceneProps.is_render_draw = True
    bgl.glEnable(bgl.GL_MULTISAMPLE)

    clipdepth = context.scene.camera.data.clip_end
    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)


    # --------------------------------------
    # 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]])

    view_matrix_3d = scene.camera.matrix_world.inverted()
    projection_matrix = scene.camera.calc_matrix_camera(context.view_layer.depsgraph, x=width, y=height)
    
    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)

        draw_scene(self, context, projection_matrix) 

        
        # Clear Color Keep on depth info
        bgl.glClearColor(0,0,0,0)
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)

        # -----------------------------
        # Loop to draw all objects
        # -----------------------------
        for myobj in objlist:
            if myobj.visible_get() is True:
                mat = myobj.matrix_world

                sheetGen = myobj.SheetGenerator
                for sheet_view in sheetGen.sheet_views:
                    draw_sheet_views(context,myobj,sheetGen,sheet_view,mat)

                if 'DimensionGenerator' in myobj:
                    measureGen = myobj.DimensionGenerator[0]
                    if 'alignedDimensions' in measureGen:
                        for linDim in measureGen.alignedDimensions:
                            draw_alignedDimension(context, myobj, measureGen,linDim,mat)
                    if 'angleDimensions' in measureGen:
                        for dim in measureGen.angleDimensions:
                            draw_angleDimension(context, myobj, measureGen,dim,mat)
                    if 'axisDimensions' in measureGen:
                        for dim in measureGen.axisDimensions:
                            draw_axisDimension(context, myobj, measureGen,dim,mat)
                    if 'boundsDimensions' in measureGen:
                        for dim in measureGen.boundsDimensions:
                            draw_boundsDimension(context, myobj, measureGen,dim,mat)
                    if 'arcDimensions' in measureGen:
                        for dim in measureGen.arcDimensions:
                            draw_arcDimension(context, myobj, measureGen,dim,mat)
                    if 'areaDimensions' in measureGen:
                        for dim in measureGen.areaDimensions:
                            draw_areaDimension(context, myobj, measureGen,dim,mat)

                if 'LineGenerator' in myobj:
                    # Set 3D Projection Martix
                    gpu.matrix.reset()
                    gpu.matrix.load_matrix(view_matrix_3d)
                    gpu.matrix.load_projection_matrix(projection_matrix)

                    # Draw Line Groups
                    op = myobj.LineGenerator[0]
                    draw_line_group(context, myobj, op, mat)
             
                if 'AnnotationGenerator' in myobj:
                    # Set 3D Projection Martix
                    gpu.matrix.reset()
                    gpu.matrix.load_matrix(view_matrix_3d)
                    gpu.matrix.load_projection_matrix(projection_matrix)

                    # Draw Line Groups
                    op = myobj.AnnotationGenerator[0]
                    draw_annotation(context, myobj, op, mat)                
       
        # 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)
        

        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_arch_output"
    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]

    # Saves image
    if image is not None and (scene.measureit_arch_render is True or animation is True):
        ren_path = bpy.context.scene.render.filepath
        filename = "mit_frame"
        ftxt = "%04d" % scene.frame_current
        outpath = (ren_path + filename + ftxt + '.png')
        save_image(self, outpath, image)

    # restore default value
    sceneProps.is_render_draw = False
    return True, buffer
Example #35
0
    def draw_callback(self, context):
        """
        :type context: bpy.types.Context
        """

        prefs = QuickBooleanPreferences.get_instance()
        color = prefs.color
        snap_color = prefs.snap_color

        region = context.region

        glsettings = vagl.GLSettings(context)
        glsettings.push()

        bgl.glEnable(bgl.GL_BLEND)
        bgl.glColor4f(*color)

        show_reversed = False
        if self.reverse:
            if self.mode == 'POLYGON':
                if len(self.mouse_coords) >= 3:
                    show_reversed = True
            else:
                if len(self.mouse_coords) >= 2:
                    if self.mouse_coords[0] != self.mouse_coords[1]:
                        show_reversed = True
        if show_reversed:
            bgl.glEnable(bgl.GL_DEPTH_TEST)
            bgl.glClearDepth(1.0)
            bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT)
            bgl.glDepthMask(1)
            bgl.glColorMask(0, 0, 0, 0)

        lines = []
        if self.mouse_coords:
            if self.mode == 'LINE':
                w = region.width
                h = region.height
                p1, p2 = self.mouse_coords
                line = (p2 - p1).normalized()
                normal = Vector([-line[1], line[0]])
                corners = [
                    Vector([0, 0]),
                    Vector([w, 0]),
                    Vector([w, h]),
                    Vector([0, h])
                ]
                corners_ofs = [v - p1 for v in corners]
                dists = [v.project(line).dot(line) for v in corners_ofs]
                i = dists.index(min(dists))
                line_min = corners_ofs[i].project(line) + p1
                i = dists.index(max(dists))
                line_max = corners_ofs[i].project(line) + p1
                dists = [v.project(normal).dot(normal) for v in corners_ofs]
                i = dists.index(max(dists))
                normal_max_f = corners_ofs[i].project(normal).dot(normal)
                vec = normal * normal_max_f
                coords = [line_min, line_max, line_max + vec, line_min + vec]
                bgl.glBegin(bgl.GL_QUADS)
                for co in coords:
                    bgl.glVertex2f(*co)
                bgl.glEnd()
                lines = self.mouse_coords

            elif self.mode == 'BOX':
                p1, p2 = self.mouse_coords
                bgl.glRectf(p1[0], p1[1], p2[0], p2[1])
                lines = [
                    p1,
                    Vector((p2[0], p1[1])),
                    Vector((p2[0], p2[1])),
                    Vector((p1[0], p2[1])), p1
                ]
            elif self.mode == 'CIRCLE':
                p1, p2 = self.mouse_coords
                bgl.glBegin(bgl.GL_TRIANGLE_FAN)
                bgl.glVertex2f(*p1)
                r = (p2 - p1).length
                coords = calc_circle_coords(p1, r, self.circle_segments,
                                            self.circle_direction)
                for co in coords:
                    bgl.glVertex2f(*co)
                bgl.glVertex2f(*coords[0])
                bgl.glEnd()
                lines = coords + [coords[0]]
            elif self.mode == 'POLYGON':
                if len(self.mouse_coords) >= 3:
                    tris = mathutils.geometry.tessellate_polygon(
                        [[co.to_3d() for co in self.mouse_coords]])

                    bgl.glBegin(bgl.GL_TRIANGLES)
                    for tri in tris:
                        for i in tri:
                            bgl.glVertex2f(*self.mouse_coords[i])
                    bgl.glEnd()
                if len(self.mouse_coords) > 1:
                    lines = self.mouse_coords + [self.mouse_coords[0]]

        if show_reversed:
            bgl.glColorMask(1, 1, 1, 1)
            bgl.glBegin(bgl.GL_QUADS)
            bgl.glVertex3f(0, 0, -1)
            bgl.glVertex3f(region.width, 0, -1)
            bgl.glVertex3f(region.width, region.height, -1)
            bgl.glVertex3f(0, region.height, -1)
            bgl.glEnd()
            bgl.glDisable(bgl.GL_DEPTH_TEST)

        bgl.glColor4f(*color[:3], 1.0)
        bgl.glPointSize(1)
        bgl.glLineWidth(1)
        if len(lines) > 1:
            bgl.glBegin(bgl.GL_LINE_STRIP)
            for co in lines:
                bgl.glVertex2f(*co)
            bgl.glEnd()
        if self.mode == 'POLYGON':
            if len(self.mouse_coords) == 1:
                bgl.glPointSize(5)
                bgl.glBegin(bgl.GL_POINTS)
                for co in self.mouse_coords:
                    bgl.glVertex2f(*co)
                bgl.glEnd()
                bgl.glPointSize(1)
                bgl.glLineWidth(1)

        if self.mco_ctrl:
            SIZE = 12
            bgl.glColor4f(*snap_color)
            bgl.glBegin(bgl.GL_LINE_LOOP)
            v = self.mco_mod
            x = v[0] - SIZE / 2
            y = v[1] - SIZE / 2
            bgl.glVertex2f(x, y)
            bgl.glVertex2f(x + SIZE, y)
            bgl.glVertex2f(x + SIZE, y + SIZE)
            bgl.glVertex2f(x, y + SIZE)
            bgl.glEnd()

        glsettings.pop()
        glsettings.font_size()
Example #36
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
Example #37
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 glsl_draw(self) -> None:
        glsl_draw_obj: Optional[GlslDrawObj] = None
        if GlslDrawObj.myinstance is None and GlslDrawObj.draw_func is None:
            glsl_draw_obj = GlslDrawObj()
            glsl_draw_obj.build_scene()
        else:
            glsl_draw_obj = GlslDrawObj.myinstance
        if glsl_draw_obj is None:
            raise Exception("glsl draw obj is None")
        light = glsl_draw_obj.light
        if light is None:
            raise Exception("no light exists")

        model_offset = Matrix.Translation((glsl_draw_obj.draw_x_offset, 0, 0))
        light_pos = [
            i + n for i, n in zip(light.location, [-glsl_draw_obj.draw_x_offset, 0, 0])
        ]
        batches = glsl_draw_obj.batches
        if batches is None:
            raise Exception("batches is None")
        depth_shader = glsl_draw_obj.depth_shader
        if depth_shader is None:
            raise Exception("depth shader is None")
        toon_shader = glsl_draw_obj.toon_shader
        if toon_shader is None:
            raise Exception("toon shader is None")
        offscreen = glsl_draw_obj.offscreen
        if offscreen is None:
            raise Exception("offscreen is None")
        # need bone etc changed only update
        depth_matrix = None

        light_lookat = light.rotation_euler.to_quaternion() @ Vector((0, 0, -1))
        # TODO このへん
        tar = light_lookat.normalized()
        up = light.rotation_euler.to_quaternion() @ Vector((0, 1, 0))
        tmp_bound_len = Vector(glsl_draw_obj.bounding_center).length
        camera_bias = 0.2
        loc = Vector(
            [
                glsl_draw_obj.bounding_center[i]
                + tar[i] * (tmp_bound_len + camera_bias)
                for i in range(3)
            ]
        )

        loc = model_offset @ loc
        v_matrix = lookat_cross(loc, tar, up)
        const_proj = 2 * max(glsl_draw_obj.bounding_size) / 2
        p_matrix = ortho_proj_mat(
            -const_proj, const_proj, -const_proj, const_proj, -const_proj, const_proj
        )
        depth_matrix = v_matrix @ p_matrix  # reuse in main shader
        depth_matrix.transpose()

        # region shader depth path
        with offscreen.bind():
            bgl.glClearColor(10, 10, 10, 1)
            bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)
            for bat in batches:
                mat = bat[0]
                mat.update()
                depth_bat = bat[2]
                depth_shader.bind()

                bgl.glEnable(bgl.GL_BLEND)
                if mat.alpha_method == "TRANSPARENT":
                    bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA)
                    bgl.glDepthMask(bgl.GL_TRUE)
                    bgl.glEnable(bgl.GL_DEPTH_TEST)
                elif mat.alpha_method == "OPAQUE":
                    bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ZERO)
                    bgl.glDepthMask(bgl.GL_TRUE)
                    bgl.glEnable(bgl.GL_DEPTH_TEST)
                elif mat.alpha_method == "CLIP":
                    bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ZERO)
                    bgl.glDepthMask(bgl.GL_TRUE)
                    bgl.glEnable(bgl.GL_DEPTH_TEST)

                if mat.cull_mode == "BACK":
                    bgl.glEnable(bgl.GL_CULL_FACE)
                    bgl.glCullFace(bgl.GL_BACK)
                else:
                    bgl.glDisable(bgl.GL_CULL_FACE)
                bgl.glEnable(bgl.GL_CULL_FACE)  # そも輪郭線がの影は落ちる?
                bgl.glCullFace(bgl.GL_BACK)

                depth_shader.uniform_float(
                    "obj_matrix", model_offset
                )  # obj.matrix_world)
                depth_shader.uniform_float("depthMVP", depth_matrix)

                depth_bat.draw(depth_shader)
        # endregion shader depth path

        # region shader main
        vp_mat = bpy.context.region_data.perspective_matrix
        projection_mat = bpy.context.region_data.window_matrix
        view_dir = bpy.context.region_data.view_matrix[2][:3]
        view_up = bpy.context.region_data.view_matrix[1][:3]
        normal_world_to_view_matrix = (
            bpy.context.region_data.view_matrix.inverted_safe().transposed()
        )
        aspect = bpy.context.area.width / bpy.context.area.height

        for is_outline in [0, 1]:
            for bat in batches:

                toon_bat = bat[1]
                toon_shader.bind()
                mat = bat[0]

                if is_outline == 1 and mat.float_dic["OutlineWidthMode"] == 0:
                    continue
                # mat.update() #already in depth path
                bgl.glEnable(bgl.GL_BLEND)
                bgl.glDepthMask(bgl.GL_TRUE)
                bgl.glEnable(bgl.GL_DEPTH_TEST)
                if mat.alpha_method == "TRANSPARENT":
                    bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA)
                elif mat.alpha_method == "OPAQUE":
                    bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ZERO)
                elif mat.alpha_method == "CLIP":
                    bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ZERO)

                if is_outline == 0:
                    if mat.cull_mode == "BACK":
                        bgl.glEnable(bgl.GL_CULL_FACE)
                        bgl.glCullFace(bgl.GL_BACK)
                    else:
                        bgl.glDisable(bgl.GL_CULL_FACE)
                else:
                    bgl.glEnable(bgl.GL_CULL_FACE)
                    bgl.glCullFace(bgl.GL_BACK)

                toon_shader.uniform_float(
                    "obj_matrix", model_offset
                )  # obj.matrix_world)
                toon_shader.uniform_float("projectionMatrix", projection_mat)
                toon_shader.uniform_float("viewProjectionMatrix", vp_mat)
                toon_shader.uniform_float("viewDirection", view_dir)
                toon_shader.uniform_float("viewUpDirection", view_up)
                toon_shader.uniform_float(
                    "normalWorldToViewMatrix", normal_world_to_view_matrix
                )
                toon_shader.uniform_float("depthMVP", depth_matrix)
                toon_shader.uniform_float("lightpos", light_pos)
                toon_shader.uniform_float("aspect", aspect)
                toon_shader.uniform_float("is_outline", is_outline)
                toon_shader.uniform_float("isDebug", 0.0)

                toon_shader.uniform_float(
                    "is_cutout", 1.0 if mat.alpha_method == "CLIP" else 0.0
                )

                float_keys = [
                    "CutoffRate",
                    "BumpScale",
                    "ReceiveShadowRate",
                    "ShadeShift",
                    "ShadeToony",
                    "RimLightingMix",
                    "RimFresnelPower",
                    "RimLift",
                    "ShadingGradeRate",
                    "LightColorAttenuation",
                    "IndirectLightIntensity",
                    "OutlineWidth",
                    "OutlineScaleMaxDistance",
                    "OutlineLightingMix",
                    "UV_Scroll_X",
                    "UV_Scroll_Y",
                    "UV_Scroll_Rotation",
                    "OutlineWidthMode",
                    "OutlineColorMode",
                ]

                for k in float_keys:
                    toon_shader.uniform_float(k, mat.float_dic[k])

                for k, v in mat.vector_dic.items():
                    toon_shader.uniform_float(k, v)

                bgl.glActiveTexture(bgl.GL_TEXTURE0)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, offscreen.color_texture)
                bgl.glTexParameteri(
                    bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE
                )  # TODO
                bgl.glTexParameteri(
                    bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE
                )
                toon_shader.uniform_int("depth_image", 0)

                for i, k in enumerate(mat.texture_dic.keys()):
                    bgl.glActiveTexture(bgl.GL_TEXTURE1 + i)
                    texture = mat.texture_dic[k]
                    bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture.bindcode)
                    bgl.glTexParameteri(
                        bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE
                    )  # TODO
                    bgl.glTexParameteri(
                        bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE
                    )
                    toon_shader.uniform_int(k, 1 + i)

                toon_bat.draw(toon_shader)
Example #39
0
    def update_all(self):
        self.drawn_count = 0
        self._offset_cur = 1

        bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
        bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)
Example #40
0
    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, do_unlink=True)

            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, do_unlink=True)
            # 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
Example #41
0
    def modal(self, context, event):
        # if event.type in {'ESC'}:
        #     self.cancel(context)
        #     return {'CANCELLED'}

        if event.type == 'TIMER':

            if not self.source in bpy.data.texts:
                print(
                    f'File name {self.source} not found. Ready to create one')

                if self.file_exist(self.source):
                    print("It's a file")
                    bpy.ops.text.open(filepath=self.source)
                    self.fromFile = True
                else:
                    bpy.data.texts.new(self.source)
                    print("It's not a file, populate with the default shader")
                    bpy.data.texts[self.source].write(self.default_shader)

            recompile = False

            if not bpy.data.texts[self.source].is_in_memory and bpy.data.texts[
                    self.source].is_modified:
                print("Have been modify")
                #                bpy.ops.text.resolve_conflict(resolution='RELOAD')
                #                self.file_reload(self.source)
                text = bpy.data.texts[self.source]
                ctx = context.copy()
                #                ctx["edit_text"] = text
                #                bpy.ops.text.reload(ctx)
                #Ensure  context area is not None
                ctx['area'] = ctx['screen'].areas[0]
                oldAreaType = ctx['area'].type
                ctx['area'].type = 'TEXT_EDITOR'
                ctx['edit_text'] = text
                bpy.ops.text.resolve_conflict(ctx, resolution='RELOAD')
                #Restore context
                ctx['area'].type = oldAreaType

            if self.current_shader != bpy.data.texts[self.source].as_string():
                recompile = True

            if recompile:
                print("Recompile... ")

                fragment_shader = bpy.data.texts[self.source].as_string()
                self.current_shader = fragment_shader

                offscreen = gpu.types.GPUOffScreen(self.width, self.height)

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

                    try:
                        shader = gpu.types.GPUShader(self.vertex_shader,
                                                     fragment_shader)
                    except Exception as Err:
                        print(Err)
                        recompile = False

                    if recompile:
                        batch = batch_for_shader(
                            shader,
                            'TRI_FAN',
                            {
                                'a_position':
                                ((-1, -1), (1, -1), (1, 1), (-1, 1))
                            },
                        )

                        shader.bind()

                        #                        try:
                        #                            shader.uniform_float('u_time', bpy.context.scene.frame_float/bpy.context.scene.render.fps)
                        #                        except ValueError:
                        #                            print('Uniform: u_time not used')

                        try:
                            shader.uniform_float('u_resolution',
                                                 (self.width, self.height))
                        except ValueError:
                            print('Uniform: u_resolution not used')

                        batch.draw(shader)

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

                offscreen.free()

                if recompile:
                    print("Success recompiling")
                    name = self.source.split(".")[0]

                    if not name in bpy.data.images:
                        bpy.data.images.new(name, self.width, self.height)
                    image = bpy.data.images[name]
                    image.scale(self.width, self.height)
                    image.pixels = [v / 255 for v in buffer]

        return {'PASS_THROUGH'}
Example #42
0
    def cubemap_to_equirectangular(self, imageList, outputName):

        # Define the vertex shader
        vertex_shader = '''
            in vec3 aVertexPosition;
            in vec2 aVertexTextureCoord;

            out vec2 vTexCoord;

            void main() {
                vTexCoord = aVertexTextureCoord;
                gl_Position = vec4(aVertexPosition, 1);
            }
        '''

        # Generate the OpenGL shader
        pos = [
            (-1.0, -1.0, -1.0),  # left,  bottom, back
            (-1.0, 1.0, -1.0),  # left,  top,    back
            (1.0, -1.0, -1.0),  # right, bottom, back
            (1.0, 1.0, -1.0)
        ]  # right, top,    back
        coords = [
            (-1.0, -1.0),  # left,  bottom
            (-1.0, 1.0),  # left,  top
            (1.0, -1.0),  # right, bottom
            (1.0, 1.0)
        ]  # right, top
        vertexIndices = [(0, 3, 1), (3, 0, 2)]
        shader = gpu.types.GPUShader(vertex_shader, self.frag_shader)

        batch = batch_for_shader(shader, 'TRIS', {"aVertexPosition": pos,\
                                                  "aVertexTextureCoord": coords},\
                                                  indices=vertexIndices)

        # Change the color space of all of the images to Linear
        # and load them into OpenGL textures
        for image in imageList:
            image.colorspace_settings.name = 'Linear'
            image.gl_load()

        # set the size of the final image
        width = self.image_size[0]
        height = self.image_size[1]

        # Create an offscreen render buffer and texture
        offscreen = gpu.types.GPUOffScreen(width, height)

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

            shader.bind()

            def bind_and_filter(tex, bindcode, image=None, imageNum=None):
                bgl.glActiveTexture(tex)
                bgl.glBindTexture(bgl.GL_TEXTURE_2D, bindcode)
                bgl.glTexParameterf(bgl.GL_TEXTURE_2D,
                                    bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR)
                bgl.glTexParameterf(bgl.GL_TEXTURE_2D,
                                    bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR)
                bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S,
                                    bgl.GL_CLAMP_TO_EDGE)
                bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T,
                                    bgl.GL_CLAMP_TO_EDGE)
                if image != None and imageNum != None:
                    shader.uniform_int(image, imageNum)

            # Bind all of the cubemap textures and enable correct filtering and wrapping
            # to prevent seams
            bind_and_filter(bgl.GL_TEXTURE0, imageList[0].bindcode,
                            "cubeLeftImage", 0)
            bind_and_filter(bgl.GL_TEXTURE1, imageList[1].bindcode,
                            "cubeRightImage", 1)
            bind_and_filter(bgl.GL_TEXTURE2, imageList[2].bindcode,
                            "cubeBottomImage", 2)
            bind_and_filter(bgl.GL_TEXTURE3, imageList[3].bindcode,
                            "cubeTopImage", 3)
            bind_and_filter(bgl.GL_TEXTURE4, imageList[4].bindcode,
                            "cubeFrontImage", 4)
            if not self.no_back_image:
                bind_and_filter(bgl.GL_TEXTURE5, imageList[5].bindcode,
                                "cubeBackImage", 5)

            # Bind the resulting texture
            bind_and_filter(bgl.GL_TEXTURE6, offscreen.color_texture)

            # Render the image
            batch.draw(shader)

            # Unload the textures
            for image in imageList:
                image.gl_free()

            # Read the resulting pixels into a buffer
            buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4)
            bgl.glGetTexImage(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA, bgl.GL_FLOAT,
                              buffer)

        # Unload the offscreen texture
        offscreen.free()

        # Remove the cubemap textures:
        for image in imageList:
            bpy.data.images.remove(image)

        # Copy the pixels from the buffer to an image object
        if not outputName in bpy.data.images.keys():
            bpy.data.images.new(outputName, width, height)
        imageRes = bpy.data.images[outputName]
        imageRes.scale(width, height)
        imageRes.pixels = buffer
        return imageRes
Example #43
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