def __init__(self, name, srcVertex, srcFragment, funcStart=None, funcEnd=None, checkErrors=True, bindTo0=None): self.drawing = Drawing.get_instance() self.name = name self.shaderProg = bgl.glCreateProgram() self.shaderVert = bgl.glCreateShader(bgl.GL_VERTEX_SHADER) self.shaderFrag = bgl.glCreateShader(bgl.GL_FRAGMENT_SHADER) self.checkErrors = checkErrors srcVertex = '\n'.join(l.strip() for l in srcVertex.split('\n')) srcFragment = '\n'.join(l.strip() for l in srcFragment.split('\n')) bgl.glShaderSource(self.shaderVert, srcVertex) bgl.glShaderSource(self.shaderFrag, srcFragment) dprint('RetopoFlow Shader Info: %s (%d)' % (self.name, self.shaderProg)) logv = self.shader_compile(name, self.shaderVert) logf = self.shader_compile(name, self.shaderFrag) if len(logv.strip()): dprint(' vert log:\n' + '\n'.join( (' ' + l) for l in logv.splitlines())) if len(logf.strip()): dprint(' frag log:\n' + '\n'.join( (' ' + l) for l in logf.splitlines())) bgl.glAttachShader(self.shaderProg, self.shaderVert) bgl.glAttachShader(self.shaderProg, self.shaderFrag) if bindTo0: bgl.glBindAttribLocation(self.shaderProg, 0, bindTo0) bgl.glLinkProgram(self.shaderProg) self.shaderVars = {} lvars = [l for l in srcVertex.splitlines() if l.startswith('in ')] lvars += [ l for l in srcVertex.splitlines() if l.startswith('attribute ') ] lvars += [ l for l in srcVertex.splitlines() if l.startswith('uniform ') ] lvars += [ l for l in srcFragment.splitlines() if l.startswith('uniform ') ] for l in lvars: m = re.match( '^(?P<qualifier>[^ ]+) +(?P<type>[^ ]+) +(?P<name>[^ ;]+)', l) assert m m = m.groupdict() q, t, n = m['qualifier'], m['type'], m['name'] locate = bgl.glGetAttribLocation if q in { 'in', 'attribute' } else bgl.glGetUniformLocation if n in self.shaderVars: continue self.shaderVars[n] = { 'qualifier': q, 'type': t, 'location': locate(self.shaderProg, n), 'reported': False, } dprint(' attribs: ' + ', '.join( (k + ' (%d)' % self.shaderVars[k]['location']) for k in self.shaderVars if self.shaderVars[k]['qualifier'] in {'in', 'attribute'})) dprint(' uniforms: ' + ', '.join( (k + ' (%d)' % self.shaderVars[k]['location']) for k in self.shaderVars if self.shaderVars[k]['qualifier'] in {'uniform'})) self.funcStart = funcStart self.funcEnd = funcEnd self.mvpmatrix_buffer = bgl.Buffer(bgl.GL_FLOAT, [4, 4])
class GPU_Indices: shader = gpu.types.GPUShader(vert_3d, primitive_id_frag) unif_MVP = bgl.glGetUniformLocation(shader.program, 'MVP') unif_offset = bgl.glGetUniformLocation(shader.program, 'offset') attr_pos = bgl.glGetAttribLocation(shader.program, 'pos') attr_primitive_id = bgl.glGetAttribLocation(shader.program, 'primitive_id') # returns of public API # knot_co = bgl.Buffer(bgl.GL_FLOAT, 3) seg_co = bgl.Buffer(bgl.GL_FLOAT, (2, 3)) origin_co = bgl.Buffer(bgl.GL_FLOAT, 3) def __init__(self, obj): self._NULL = VoidBufValue(0) self.MVP = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) # self.obj = obj self.first_index = 0 self.vbo_segs = None self.vbo_segs_co = None self.vbo_origin = None self.vbo_origin_co = None self.num_segs = 0 self.num_origins = 0 self._draw_segs = False self._draw_origins = False self.is_mesh = False self.snap_mode = 0 self.vao = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenVertexArrays(1, self.vao) bgl.glBindVertexArray(self.vao[0]) _arrays = _Object_Arrays(obj) if _arrays.segs_co: self.vbo_segs_co = bgl.Buffer(bgl.GL_INT, 1) self.num_segs = len(_arrays.segs_co) bgl.glGenBuffers(1, self.vbo_segs_co) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs_co[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_segs * 24, _arrays.segs_co, bgl.GL_STATIC_DRAW) segs_indices = np.repeat(np.arange(self.num_segs, dtype='f4'), 2) self.vbo_segs = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_segs) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs[0]) bgl.glBufferData( bgl.GL_ARRAY_BUFFER, self.num_segs * 8, np_array_as_bgl_Buffer(segs_indices), bgl.GL_STATIC_DRAW ) del segs_indices self._draw_segs = True # objects origin if _arrays.origin_co: self.vbo_origin_co = bgl.Buffer(bgl.GL_INT, 1) self.num_origins = len(_arrays.origin_co) bgl.glGenBuffers(1, self.vbo_origin_co) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin_co[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_origins * 12, _arrays.origin_co, bgl.GL_STATIC_DRAW) orig_indices = np.arange(self.num_origins, dtype='f4') self.vbo_origin = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_origin) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin[0]) bgl.glBufferData( bgl.GL_ARRAY_BUFFER, self.num_origins * 4, np_array_as_bgl_Buffer(orig_indices), bgl.GL_STATIC_DRAW ) del orig_indices self.is_mesh = _arrays.is_mesh self._draw_origins = True del _arrays bgl.glBindVertexArray(0) def get_tot_elems(self): tot = 0 if self.draw_segs: tot += self.num_segs if self.draw_origin: tot += self.num_origins return tot @property def draw_segs(self): return self._draw_segs and self.vbo_segs_co is not None def set_snap_mode(self, snap_mode): self.snap_mode = snap_mode @property def draw_origin(self): return (self._draw_origins or (self._draw_segs and self.is_mesh)) and self.vbo_origin_co is not None def set_draw_mode(self, draw_segs, draw_origin): self._draw_segs = draw_segs self._draw_origins = draw_origin @classmethod def set_ProjectionMatrix(cls, P): cls.P = P def set_ModelViewMatrix(self, MV): self.MVP[:] = self.P @ MV def bind(self, co, buf_id, offset): bgl.glUniform1f(self.unif_offset, float(offset)) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, co[0]) bgl.glVertexAttribPointer(self.attr_pos, 3, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) bgl.glEnableVertexAttribArray(self.attr_pos) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, buf_id[0]) bgl.glVertexAttribPointer(self.attr_primitive_id, 1, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) bgl.glEnableVertexAttribArray(self.attr_primitive_id) def draw(self, index_offset): self.first_index = index_offset bgl.glUseProgram(self.shader.program) bgl.glBindVertexArray(self.vao[0]) bgl.glUniformMatrix4fv(self.unif_MVP, 1, bgl.GL_TRUE, self.MVP) # bgl.glUniform1f(self.unif_size, float(2.0)) if self.draw_segs: self.bind(self.vbo_segs_co, self.vbo_segs, index_offset) bgl.glDrawArrays(bgl.GL_LINES, 0, self.num_segs * 2) index_offset += self.num_segs if self.draw_origin: self.bind(self.vbo_origin_co, self.vbo_origin, index_offset) bgl.glDrawArrays(bgl.GL_POINTS, 0, self.num_origins) index_offset += self.num_origins bgl.glBindVertexArray(0) def get_seg_co(self, index): bgl.glBindVertexArray(self.vao[0]) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs_co[0]) bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 24, 24, self.seg_co) bgl.glBindVertexArray(0) return self.seg_co def get_origin_co(self, index): bgl.glBindVertexArray(self.vao[0]) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin_co[0]) bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 12, 12, self.origin_co) bgl.glBindVertexArray(0) return self.origin_co def __del__(self): del self._NULL if self.vbo_segs_co: bgl.glDeleteBuffers(1, self.vbo_segs_co) bgl.glDeleteBuffers(1, self.vbo_segs) if self.vbo_origin_co: bgl.glDeleteBuffers(1, self.vbo_origin_co) bgl.glDeleteBuffers(1, self.vbo_origin) bgl.glDeleteVertexArrays(1, self.vao)
class PreviousGLState: buf = bgl.Buffer(bgl.GL_INT, (4, 1)) cur_program = buf[0] cur_vao = buf[1] cur_vbo = buf[2] cur_ebo = buf[3]
def draw_to_viewport(view_min, view_max, show_extra, label_counter, tilegrid, sprytile_data, cursor_loc, region, rv3d, middle_btn, context): """Draw the offscreen texture into the viewport""" projection_mat = sprytile_utils.get_ortho2D_matrix( 0, context.region.width, 0, context.region.height) # Prepare some data that will be used for drawing grid_size = VIEW3D_OP_SprytileGui.loaded_grid.grid tile_sel = VIEW3D_OP_SprytileGui.loaded_grid.tile_selection padding = VIEW3D_OP_SprytileGui.loaded_grid.padding margin = VIEW3D_OP_SprytileGui.loaded_grid.margin is_pixel = sprytile_utils.grid_is_single_pixel( VIEW3D_OP_SprytileGui.loaded_grid) # Draw work plane VIEW3D_OP_SprytileGui.draw_work_plane(projection_mat, grid_size, sprytile_data, cursor_loc, region, rv3d, middle_btn) # Setup GL for drawing the offscreen texture bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, VIEW3D_OP_SprytileGui.texture) # Backup texture settings old_mag_filter = Buffer(bgl.GL_INT, 1) glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, old_mag_filter) old_wrap_S = Buffer(GL_INT, 1) old_wrap_T = Buffer(GL_INT, 1) glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, old_wrap_S) glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, old_wrap_T) # Set texture filter bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_NEAREST) bgl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) bgl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glEnable(bgl.GL_BLEND) # Draw the preview tile if middle_btn is False: VIEW3D_OP_SprytileGui.draw_preview_tile(context, region, rv3d, projection_mat) # Calculate actual view size view_size = int(view_max.x - view_min.x), int(view_max.y - view_min.y) # Save the original scissor box, and then set new scissor setting scissor_box = bgl.Buffer(bgl.GL_INT, [4]) bgl.glGetIntegerv(bgl.GL_SCISSOR_BOX, scissor_box) bgl.glScissor( int(view_min.x) + scissor_box[0] - 1, int(view_min.y) + scissor_box[1] - 1, view_size[0] + 1, view_size[1] + 1) bgl.glEnable(bgl.GL_SCISSOR_TEST) # Draw the tile select UI VIEW3D_OP_SprytileGui.draw_tile_select_ui( projection_mat, view_min, view_max, view_size, VIEW3D_OP_SprytileGui.tex_size, grid_size, tile_sel, padding, margin, show_extra, is_pixel) # restore opengl defaults bgl.glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]) bgl.glDisable(bgl.GL_SCISSOR_TEST) bgl.glLineWidth(1) bgl.glTexParameteriv(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, old_mag_filter) bgl.glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, old_wrap_S) bgl.glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, old_wrap_T) # Draw label font_id = 0 font_size = 16 pad = 5 if label_counter > 0: import math def ease_out_circ(t, b, c, d): t /= d t -= 1 return c * math.sqrt(1 - t * t) + b box_pad = font_size + (pad * 2) fade = label_counter fade = ease_out_circ(fade, 0, VIEW3D_OP_SprytileGui.label_frames, VIEW3D_OP_SprytileGui.label_frames) fade /= VIEW3D_OP_SprytileGui.label_frames color = (0.0, 0.0, 0.0, 0.75 * fade) vtx = [ (view_min.x, view_max.y + box_pad), (view_min.x, view_max.y), (view_max.x, view_max.y + +box_pad), (view_max.x, view_max.y) ] VIEW3D_OP_SprytileGui.draw_full_quad(vtx, projection_mat, color) blf.color(font_id, 1.0, 1.0, 1.0, 1.0 * fade) blf.size(font_id, font_size, 72) x_pos = view_min.x + pad y_pos = view_max.y + pad label_string = "%dx%d" % (tilegrid.grid[0], tilegrid.grid[1]) if tilegrid.name != "": label_string = "%s - %s" % (label_string, tilegrid.name) blf.position(font_id, x_pos, y_pos, 0) blf.draw(font_id, label_string) if tilegrid.grid[0] == 1 and tilegrid.grid[1] == 1: size_text = "%dx%d" % (tile_sel[2], tile_sel[3]) blf.size(font_id, font_size, 72) size = blf.dimensions(font_id, size_text) x_pos = view_max.x - size[0] - pad y_pos = view_max.y + pad blf.position(font_id, x_pos, y_pos, 0) blf.draw(font_id, size_text) bgl.glDisable(bgl.GL_BLEND) bgl.glDisable(bgl.GL_TEXTURE_2D)
def buffer(self, pos, norm, sel, idx): sizeOfFloat, sizeOfInt = 4, 4 self.count = 0 count = len(pos) counts = list(map(len, [pos, norm, sel])) goodcounts = all(c == count for c in counts) assert goodcounts, ('All arrays must contain ' 'the same number of elements %s' % str(counts)) if count == 0: return try: buf_pos = bgl.Buffer(bgl.GL_FLOAT, [count, 3], pos) buf_norm = bgl.Buffer(bgl.GL_FLOAT, [count, 3], norm) buf_sel = bgl.Buffer(bgl.GL_FLOAT, count, sel) if idx: # WHY NO GL_UNSIGNED_INT????? buf_idx = bgl.Buffer(bgl.GL_INT, count, idx) if self.DEBUG_PRINT: print('buf_pos = ' + shorten_floats(str(buf_pos))) print('buf_norm = ' + shorten_floats(str(buf_norm))) except Exception as e: print( 'ERROR (buffer): caught exception while ' 'buffering to Buffer ' + str(e)) raise e try: bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_pos) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, count * 3 * sizeOfFloat, buf_pos, bgl.GL_STATIC_DRAW) self._check_error('buffer: vbo_pos') bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_norm) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, count * 3 * sizeOfFloat, buf_norm, bgl.GL_STATIC_DRAW) self._check_error('buffer: vbo_norm') bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_sel) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, count * 1 * sizeOfFloat, buf_sel, bgl.GL_STATIC_DRAW) self._check_error('buffer: vbo_sel') if idx: bgl.glBindBuffer(bgl.GL_ELEMENT_ARRAY_BUFFER, self.vbo_idx) bgl.glBufferData(bgl.GL_ELEMENT_ARRAY_BUFFER, count * sizeOfInt, buf_idx, bgl.GL_STATIC_DRAW) self._check_error('buffer: vbo_idx') except Exception as e: print( 'ERROR (buffer): caught exception while ' 'buffering from Buffer ' + str(e)) raise e finally: bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, 0) bgl.glBindBuffer(bgl.GL_ELEMENT_ARRAY_BUFFER, 0) del buf_pos, buf_norm, buf_sel if idx: del buf_idx if idx: self.count = len(idx) self.render_indices = True else: self.count = len(pos) self.render_indices = False
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
def delete_texture(self): n_id = node_id(self) if n_id in self.texture: names = bgl.Buffer(bgl.GL_INT, 1, [self.texture[n_id]]) bgl.glDeleteTextures(1, names)
) CreateDepthBufMapFile = lib[1] WriteDepthMapBufFile = lib[7] UnmapDepthBufFile = lib[6] CreateDepthBufMapFile.restype = ctypes.c_void_p WriteDepthMapBufFile.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int ] HarambePointer = CreateDepthBufMapFile(0, 0) bgl.glReadBuffer(bgl.GL_FRONT) # allocate 4 integers to capture the box (x,y,width,height) of the GL_FRONT b = bgl.Buffer(bgl.GL_INT, 4) # capture the GL_FRONT bounding box bgl.glGetIntegerv(bgl.GL_VIEWPORT, b) pix = bgl.Buffer(bgl.GL_FLOAT, b[2] * b[3]) print((b[2], b[3])) print((b[2] * b[3])) def ReadOutDepthMap(): global HarambePointer global b global pix start_time = time.time()
if c[0][0] < 0.1 and c[0][1] < 0.1 and c[0][2] < 0.1: bgl.glColor3f(1, 1, 1) else: bgl.glColor3f(0, 0, 0) bgl.glEnable(bgl.GL_BLEND) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(x_loc + 20 - 1, y_loc + 20 - 1) bgl.glVertex2f(x_loc + 20 + width + 1, y_loc + 20 - 1) bgl.glVertex2f(x_loc + 20 + width, y_loc + 20 + height + 1) bgl.glVertex2f(x_loc + 20 - 1, y_loc + 20 + height) bgl.glVertex2f(x_loc + 20 - 1, y_loc + 20 - 1) bgl.glEnd() c = bgl.Buffer(bgl.GL_FLOAT, [1, 3]) selected_col = bgl.Buffer(bgl.GL_FLOAT, [1, 3]) col_list = [] class ModalPickerOperator(bpy.types.Operator): """Kaleidoscope Color Picker Tool""" bl_idname = "kaleidoscope.color_picker" bl_label = "Kaleidoscope Color Picker Modal" def modal(self, context, event): context.area.tag_redraw() global start_draw if event.type == 'MOUSEMOVE': global x_loc
def write_sysinfo(filepath): import sys import textwrap import subprocess import bpy import bgl # pretty repr def prepr(v): r = repr(v) vt = type(v) if vt is bytes: r = r[2:-1] elif vt is list or vt is tuple: r = r[1:-1] return r output = open(filepath, 'w', encoding="utf-8") header = "= Blender %s System Information =\n" % bpy.app.version_string lilies = "%s\n\n" % ((len(header) - 1) * "=") output.write(lilies[:-1]) output.write(header) output.write(lilies) def title(text): return "\n%s:\n%s" % (text, lilies) # build info output.write(title("Blender")) output.write( "version: %s, branch: %s, commit date: %s %s, hash: %s, type: %s\n" % ( bpy.app.version_string, prepr(bpy.app.build_branch), prepr(bpy.app.build_commit_date), prepr(bpy.app.build_commit_time), prepr(bpy.app.build_hash), prepr(bpy.app.build_type), )) output.write("build date: %s, %s\n" % (prepr(bpy.app.build_date), prepr(bpy.app.build_time))) output.write("platform: %s\n" % prepr(bpy.app.build_platform)) output.write("binary path: %s\n" % prepr(bpy.app.binary_path)) output.write("build cflags: %s\n" % prepr(bpy.app.build_cflags)) output.write("build cxxflags: %s\n" % prepr(bpy.app.build_cxxflags)) output.write("build linkflags: %s\n" % prepr(bpy.app.build_linkflags)) output.write("build system: %s\n" % prepr(bpy.app.build_system)) # python info output.write(title("Python")) output.write("version: %s\n" % (sys.version)) output.write("paths:\n") for p in sys.path: output.write("\t%r\n" % p) output.write(title("Python (External Binary)")) output.write("binary path: %s\n" % prepr(bpy.app.binary_path_python)) try: py_ver = prepr( subprocess.check_output([ bpy.app.binary_path_python, "--version", ]).strip()) except Exception as e: py_ver = str(e) output.write("version: %s\n" % py_ver) del py_ver output.write(title("Directories")) output.write("scripts:\n") for p in bpy.utils.script_paths(): output.write("\t%r\n" % p) output.write("user scripts: %r\n" % (bpy.utils.script_path_user())) output.write("pref scripts: %r\n" % (bpy.utils.script_path_pref())) output.write("datafiles: %r\n" % (bpy.utils.user_resource('DATAFILES'))) output.write("config: %r\n" % (bpy.utils.user_resource('CONFIG'))) output.write("scripts : %r\n" % (bpy.utils.user_resource('SCRIPTS'))) output.write("autosave: %r\n" % (bpy.utils.user_resource('AUTOSAVE'))) output.write("tempdir: %r\n" % (bpy.app.tempdir)) output.write(title("FFmpeg")) ffmpeg = bpy.app.ffmpeg if ffmpeg.supported: for lib in ("avcodec", "avdevice", "avformat", "avutil", "swscale"): output.write( "%s:%s%r\n" % (lib, " " * (10 - len(lib)), getattr(ffmpeg, lib + "_version_string"))) else: output.write("Blender was built without FFmpeg support\n") if bpy.app.build_options.sdl: output.write(title("SDL")) output.write("Version: %s\n" % bpy.app.sdl.version_string) output.write("Loading method: ") if bpy.app.build_options.sdl_dynload: output.write( "dynamically loaded by Blender (WITH_SDL_DYNLOAD=ON)\n") else: output.write("linked (WITH_SDL_DYNLOAD=OFF)\n") if not bpy.app.sdl.available: output.write("WARNING: Blender could not load SDL library\n") output.write(title("Other Libraries")) ocio = bpy.app.ocio output.write("OpenColorIO: ") if ocio.supported: if ocio.version_string == "fallback": output.write("Blender was built with OpenColorIO, " + "but it currently uses fallback color management.\n") else: output.write("%s\n" % (ocio.version_string)) else: output.write("Blender was built without OpenColorIO support\n") oiio = bpy.app.oiio output.write("OpenImageIO: ") if ocio.supported: output.write("%s\n" % (oiio.version_string)) else: output.write("Blender was built without OpenImageIO support\n") output.write("OpenShadingLanguage: ") if bpy.app.build_options.cycles: if bpy.app.build_options.cycles_osl: from _cycles import osl_version_string output.write("%s\n" % (osl_version_string)) else: output.write( "Blender was built without OpenShadingLanguage support in Cycles\n" ) else: output.write("Blender was built without Cycles support\n") openvdb = bpy.app.openvdb output.write("OpenVDB: ") if openvdb.supported: output.write("%s\n" % openvdb.version_string) else: output.write("Blender was built without OpenVDB support\n") if not bpy.app.build_options.sdl: output.write("SDL: Blender was built without SDL support\n") if bpy.app.background: output.write("\nOpenGL: missing, background mode\n") else: output.write(title("OpenGL")) version = bgl.glGetString(bgl.GL_RENDERER) output.write("renderer:\t%r\n" % version) output.write("vendor:\t\t%r\n" % (bgl.glGetString(bgl.GL_VENDOR))) output.write("version:\t%r\n" % (bgl.glGetString(bgl.GL_VERSION))) output.write("extensions:\n") glext = sorted(bgl.glGetString(bgl.GL_EXTENSIONS).split()) for l in glext: output.write("\t%s\n" % l) output.write(title("Implementation Dependent OpenGL Limits")) limit = bgl.Buffer(bgl.GL_INT, 1) bgl.glGetIntegerv(bgl.GL_MAX_TEXTURE_UNITS, limit) output.write("Maximum Fixed Function Texture Units:\t%d\n" % limit[0]) bgl.glGetIntegerv(bgl.GL_MAX_ELEMENTS_VERTICES, limit) output.write("Maximum DrawElements Vertices:\t%d\n" % limit[0]) bgl.glGetIntegerv(bgl.GL_MAX_ELEMENTS_INDICES, limit) output.write("Maximum DrawElements Indices:\t%d\n" % limit[0]) output.write("\nGLSL:\n") bgl.glGetIntegerv(bgl.GL_MAX_VARYING_FLOATS, limit) output.write("Maximum Varying Floats:\t%d\n" % limit[0]) bgl.glGetIntegerv(bgl.GL_MAX_VERTEX_ATTRIBS, limit) output.write("Maximum Vertex Attributes:\t%d\n" % limit[0]) bgl.glGetIntegerv(bgl.GL_MAX_VERTEX_UNIFORM_COMPONENTS, limit) output.write("Maximum Vertex Uniform Components:\t%d\n" % limit[0]) bgl.glGetIntegerv(bgl.GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, limit) output.write("Maximum Fragment Uniform Components:\t%d\n" % limit[0]) bgl.glGetIntegerv(bgl.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, limit) output.write("Maximum Vertex Image Units:\t%d\n" % limit[0]) bgl.glGetIntegerv(bgl.GL_MAX_TEXTURE_IMAGE_UNITS, limit) output.write("Maximum Fragment Image Units:\t%d\n" % limit[0]) bgl.glGetIntegerv(bgl.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, limit) output.write("Maximum Pipeline Image Units:\t%d\n" % limit[0]) if bpy.app.build_options.cycles: import cycles output.write(title("Cycles")) output.write(cycles.engine.system_info()) output.close()
def to_bglMatrix(mat): # return bgl.Buffer( # bgl.GL_FLOAT, len(mat)**2, [v for r in mat for v in r] # ) return bgl.Buffer(bgl.GL_FLOAT, [len(mat), len(mat)], mat)
def __new__(self, type, dimensions=0, template=None): """ :param type: GL_BYTE('bool','byte'), GL_SHORT('short'), GL_INT('int'), GL_FLOAT('float') or GL_DOUBLE('double') :type type: int | str :param dimensions: array size. e.g. 3: [0, 0, 0] [4, 2]: [(0, 0), (0, 0), (0, 0), (0, 0)] :type dimensions: int | list | tuple :param template: Used to initialize the Buffer e.g. list: [1, 2, 3], int: bgl.GL_BLEND :type template: None | sequence | int :return: :rtype: """ if isinstance(type, str): type = type.lower() if type in ('bool', 'byte'): type = bgl.GL_BYTE elif type == 'short': type = bgl.GL_SHORT elif type == 'int': type = bgl.GL_INT elif type == 'float': type = bgl.GL_FLOAT elif type == 'double': type = bgl.GL_DOUBLE else: type = None return_int = isinstance(dimensions, int) and dimensions < 1 if return_int: dim = 1 else: dim = dimensions if template is None: buf = bgl.Buffer(type, dim) elif isinstance(template, int): if type == bgl.GL_BYTE: glGet = bgl.glGetBooleanv elif type == bgl.GL_SHORT: glGet = bgl.glGetIntegerv elif type == bgl.GL_INT: glGet = bgl.glGetIntegerv elif type == bgl.GL_FLOAT: glGet = bgl.glGetFloatv elif type == bgl.GL_DOUBLE: glGet = bgl.glGetDoublev else: msg = "invalid first argument type, should be one of " \ "GL_BYTE('bool','byte'), GL_SHORT('short'), " \ "GL_INT('int'), GL_FLOAT('float') or GL_DOUBLE('double')" raise AttributeError(msg) buf = bgl.Buffer(type, dim) glGet(template, buf) else: buf = bgl.Buffer(type, dim, template) if return_int: return buf[0] else: return buf
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
def render(image, check_size): vertex_shader = ''' in vec2 pos; in vec2 texCoord; out vec2 uvInterp; void main() { uvInterp = texCoord; gl_Position = vec4(pos, 0.0, 1.0); } ''' fragment_shader = ''' uniform sampler2D image; uniform vec4 pattern_color; uniform float check_size; in vec2 uvInterp; float dist(vec2 p0, vec2 pf) { return sqrt((pf.x-p0.x)*(pf.x-p0.x)+(pf.y-p0.y)*(pf.y-p0.y)); } vec4 checker(vec2 uv, float check_size) { uv -= 0.5; float result = mod(floor(check_size * uv.x) + floor(check_size * uv.y), 2.0); float fin = sign(result); return vec4(fin, fin, fin, 1.0); } void main() { vec4 texture_color = texture(image, uvInterp); if(texture_color.w == 0.0){ discard; } if(texture_color.xyz == vec3(1.0, 1.0, 1.0)) { discard; } vec2 res = vec2(512, 512); vec4 final_color = pattern_color; float d = dist(res.xy*0.5, gl_FragCoord.xy)*0.001; final_color = mix(pattern_color, vec4(pattern_color.xyz*0.3, 1.0), d); texture_color = mix(checker(uvInterp, check_size), final_color, 0.9); gl_FragColor = texture_color; } ''' shader = gpu.types.GPUShader(vertex_shader, fragment_shader) batch = batch_for_shader( shader, 'TRI_FAN', { "pos": ((-1, -1), (1, -1), (1, 1), (-1, 1)), "texCoord": ((0, 0), (1, 0), (1, 1), (0, 1)), }, ) if image.gl_load(): return offscreen = gpu.types.GPUOffScreen(PREVIEW_WIDTH, PREVIEW_HEIGHT) with offscreen.bind(): bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode) shader.bind() shader.uniform_int("image", 0) shader.uniform_float("pattern_color", get_active_color()) shader.uniform_float("check_size", check_size) batch.draw(shader) buffer = bgl.Buffer(bgl.GL_FLOAT, PREVIEW_WIDTH * PREVIEW_HEIGHT * 4) bgl.glReadBuffer(bgl.GL_BACK) bgl.glReadPixels(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) offscreen.free() image.gl_free() return buffer
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 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) 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_LESS) 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.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 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 '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) # ----------------------------- # 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() # ----------------------------- # 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): settings = bpy.context.scene.render.image_settings myformat = settings.file_format 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
def draw_offscreen(context): """Draw the GUI into the offscreen texture""" offscreen = SprytileGui.offscreen target_img = SprytileGui.texture_grid tex_size = SprytileGui.tex_size offscreen.bind() glClear(GL_COLOR_BUFFER_BIT) glDisable(GL_DEPTH_TEST) glEnable(GL_BLEND) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluOrtho2D(0, tex_size[0], 0, tex_size[1]) def draw_full_quad(): texco = [(0, 0), (0, 1), (1, 1), (1, 0)] verco = [(0, 0), (0, tex_size[1]), (tex_size[0], tex_size[1]), (tex_size[0], 0)] glBegin(bgl.GL_QUADS) for i in range(4): glTexCoord2f(texco[i][0], texco[i][1]) glVertex2f(verco[i][0], verco[i][1]) glEnd() glColor4f(0.0, 0.0, 0.0, 0.5) draw_full_quad() if target_img is not None: glColor4f(1.0, 1.0, 1.0, 1.0) target_img.gl_load(0, GL_NEAREST, GL_NEAREST) glBindTexture(GL_TEXTURE_2D, target_img.bindcode[0]) # We need to backup and restore the MAG_FILTER to avoid messing up the Blender viewport old_mag_filter = Buffer(GL_INT, 1) glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, old_mag_filter) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glEnable(GL_TEXTURE_2D) draw_full_quad() glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, old_mag_filter) # Translate the gl context by grid matrix grid_matrix = sprytile_utils.get_grid_matrix(SprytileGui.loaded_grid) matrix_vals = [grid_matrix[j][i] for i in range(4) for j in range(4)] grid_buff = bgl.Buffer(bgl.GL_FLOAT, 16, matrix_vals) glMatrixMode(GL_MODELVIEW) glPushMatrix() glLoadIdentity() glLoadMatrixf(grid_buff) glDisable(GL_TEXTURE_2D) # Get data for drawing additional overlays grid_size = SprytileGui.loaded_grid.grid padding = SprytileGui.loaded_grid.padding margin = SprytileGui.loaded_grid.margin curr_sel = SprytileGui.loaded_grid.tile_selection is_pixel_grid = sprytile_utils.grid_is_single_pixel( SprytileGui.loaded_grid) is_use_mouse = context.scene.sprytile_ui.use_mouse is_selecting = SprytileGui.is_selecting glLineWidth(1) # Draw box for currently selected tile(s) # Pixel grid selection is drawn in draw_tile_select_ui if is_selecting is False and not (is_pixel_grid and curr_sel[2] == 1 or curr_sel[3] == 1): glColor4f(1.0, 1.0, 1.0, 1.0) curr_sel_min, curr_sel_max = SprytileGui.get_sel_bounds( grid_size, padding, margin, curr_sel[0], curr_sel[1], curr_sel[2], curr_sel[3]) SprytileGui.draw_selection(curr_sel_min, curr_sel_max) # Inside gui, draw appropriate selection for under mouse if is_use_mouse and is_selecting is False and SprytileGui.cursor_grid_pos is not None: cursor_pos = SprytileGui.cursor_grid_pos # In pixel grid, draw cross hair if is_pixel_grid: glColor4f(1.0, 1.0, 1.0, 0.5) glBegin(GL_LINE_STRIP) glVertex2i(0, int(cursor_pos.y + 1)) glVertex2i(tex_size[0], int(cursor_pos.y + 1)) glEnd() glBegin(GL_LINE_STRIP) glVertex2i(int(cursor_pos.x + 1), 0) glVertex2i(int(cursor_pos.x + 1), tex_size[1]) glEnd() # Draw box around selection else: glColor4f(1.0, 0.0, 0.0, 1.0) cursor_min, cursor_max = SprytileGui.get_sel_bounds( grid_size, padding, margin, int(cursor_pos.x), int(cursor_pos.y), ) SprytileGui.draw_selection(cursor_min, cursor_max) glPopMatrix() offscreen.unbind()
def status_image(): """ Show the corrensponding Image for the status """ imageHeight = windowHeight * 0.075 imageWidth = imageHeight x = windowWidth * 0.35 - imageWidth / 2 y = windowHeight * 0.45 - imageHeight / 2 gl_position = [[x, y], [x + imageWidth, y], [x + imageWidth, y + imageHeight], [x, y + imageHeight]] cam = blenderapi.scene().active_camera # get the suffix of the human to reference the right objects suffix = cam.name[-4:] if cam.name[-4] == "." else "" hand = objects['Hand_Grab.R' + suffix] # select the right Image if hand["selected"]: tex_id = closed_id else: tex_id = open_id view_buf = bgl.Buffer(bgl.GL_INT, 4) bgl.glGetIntegerv(bgl.GL_VIEWPORT, view_buf) view = view_buf.to_list() if hasattr(view_buf, "to_list") else view_buf.list # Save the state bgl.glPushAttrib(bgl.GL_ALL_ATTRIB_BITS) # Disable depth test so we always draw over things bgl.glDisable(bgl.GL_DEPTH_TEST) # Disable lighting so everything is shadless bgl.glDisable(bgl.GL_LIGHTING) # Unbinding the texture prevents BGUI frames from somehow picking up on # color of the last used texture bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0) # Make sure we're using smooth shading instead of flat bgl.glShadeModel(bgl.GL_SMOOTH) # Setup the matrices bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glPushMatrix() bgl.glLoadIdentity() bgl.gluOrtho2D(0, view[2], 0, view[3]) bgl.glMatrixMode(bgl.GL_MODELVIEW) bgl.glPushMatrix() bgl.glLoadIdentity() bgl.glEnable(bgl.GL_TEXTURE_2D) # Enable alpha blending bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) # Bind the texture bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex_id) # Draw the textured quad bgl.glColor4f(1, 1, 1, 1) bgl.glEnable(bgl.GL_POLYGON_OFFSET_FILL) bgl.glPolygonOffset(1.0, 1.0) bgl.glBegin(bgl.GL_QUADS) for i in range(4): bgl.glTexCoord2f(texco[i][0], texco[i][1]) bgl.glVertex2f(gl_position[i][0], gl_position[i][1]) bgl.glEnd() bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0) bgl.glPopMatrix() bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glPopMatrix() bgl.glPopAttrib()
def draw_tile_select_ui(view_min, view_max, view_size, tex_size, grid_size, tile_selection, padding, margin, show_extra, is_pixel): # Draw the texture quad bgl.glColor4f(1.0, 1.0, 1.0, 1.0) bgl.glBegin(bgl.GL_QUADS) uv = [(0, 0), (0, 1), (1, 1), (1, 0)] vtx = [(view_min.x, view_min.y), (view_min.x, view_max.y), (view_max.x, view_max.y), (view_max.x, view_min.y)] for i in range(4): glTexCoord2f(uv[i][0], uv[i][1]) glVertex2f(vtx[i][0], vtx[i][1]) bgl.glEnd() # Not drawing tile grid overlay if show_extra is False: return # Translate the gl context by grid matrix scale_factor = (view_size[0] / tex_size[0], view_size[1] / tex_size[1]) # Setup to draw grid into viewport offset_matrix = Matrix.Translation((view_min.x, view_min.y, 0)) grid_matrix = sprytile_utils.get_grid_matrix(SprytileGui.loaded_grid) grid_matrix = Matrix.Scale(scale_factor[0], 4, Vector( (1, 0, 0))) * Matrix.Scale(scale_factor[1], 4, Vector( (0, 1, 0))) * grid_matrix calc_matrix = offset_matrix * grid_matrix matrix_vals = [calc_matrix[j][i] for i in range(4) for j in range(4)] grid_buff = bgl.Buffer(bgl.GL_FLOAT, 16, matrix_vals) glPushMatrix() glLoadIdentity() glLoadMatrixf(grid_buff) glDisable(GL_TEXTURE_2D) glLineWidth(1) if is_pixel is False: glColor4f(0.0, 0.0, 0.0, 0.5) # Draw the grid cell_size = (grid_size[0] + padding[0] * 2 + margin[1] + margin[3], grid_size[1] + padding[1] * 2 + margin[0] + margin[2]) x_divs = ceil(tex_size[0] / cell_size[0]) y_divs = ceil(tex_size[1] / cell_size[1]) x_end = x_divs * cell_size[0] y_end = y_divs * cell_size[1] for x in range(x_divs + 1): x_pos = (x * cell_size[0]) glBegin(GL_LINES) glVertex2f(x_pos, 0) glVertex2f(x_pos, y_end) glEnd() for y in range(y_divs + 1): y_pos = (y * cell_size[1]) glBegin(GL_LINES) glVertex2f(0, y_pos) glVertex2f(x_end, y_pos) glEnd() if SprytileGui.is_selecting or (is_pixel and tile_selection[2] == 1 or tile_selection[3] == 1): sel_min, sel_max = SprytileGui.get_sel_bounds( grid_size, padding, margin, tile_selection[0], tile_selection[1], tile_selection[2], tile_selection[3]) glColor4f(1.0, 1.0, 1.0, 1.0) SprytileGui.draw_selection(sel_min, sel_max, 0) glPopMatrix()
def get_buffer(self): data = self.inputs['Float'].sv_get(deepcopy=False) self.total_size = self.calculate_total_size() # self.make_data_correct_length(data) texture = bgl.Buffer(bgl.GL_FLOAT, self.total_size, np.resize(data, self.total_size).tolist()) return texture
def draw_to_viewport(view_min, view_max, show_extra, label_counter, tilegrid, sprytile_data, cursor_loc, region, rv3d, middle_btn, context): """Draw the offscreen texture into the viewport""" # Prepare some data that will be used for drawing grid_size = SprytileGui.loaded_grid.grid tile_sel = SprytileGui.loaded_grid.tile_selection padding = SprytileGui.loaded_grid.padding margin = SprytileGui.loaded_grid.margin is_pixel = sprytile_utils.grid_is_single_pixel(SprytileGui.loaded_grid) # Draw work plane SprytileGui.draw_work_plane(grid_size, sprytile_data, cursor_loc, region, rv3d, middle_btn) # Setup GL for drawing the offscreen texture bgl.glColor4f(1.0, 1.0, 1.0, 1.0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, SprytileGui.texture) # Backup texture filter old_mag_filter = Buffer(bgl.GL_INT, [1]) bgl.glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, old_mag_filter) # Set texture filter bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_NEAREST) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glEnable(bgl.GL_BLEND) # Draw the preview tile if middle_btn is False: SprytileGui.draw_preview_tile(context, region, rv3d) # Calculate actual view size view_size = int(view_max.x - view_min.x), int(view_max.y - view_min.y) # Save the original scissor box, and then set new scissor setting scissor_box = bgl.Buffer(bgl.GL_INT, [4]) bgl.glGetIntegerv(bgl.GL_SCISSOR_BOX, scissor_box) bgl.glScissor( int(view_min.x) + scissor_box[0], int(view_min.y) + scissor_box[1], view_size[0], view_size[1]) # Draw the tile select UI SprytileGui.draw_tile_select_ui(view_min, view_max, view_size, SprytileGui.tex_size, grid_size, tile_sel, padding, margin, show_extra, is_pixel) # restore opengl defaults bgl.glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]) bgl.glLineWidth(1) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, old_mag_filter[0]) # Draw label if label_counter > 0: import math def ease_out_circ(t, b, c, d): t /= d t -= 1 return c * math.sqrt(1 - t * t) + b font_id = 0 font_size = 16 pad = 5 box_pad = font_size + (pad * 2) fade = label_counter fade = ease_out_circ(fade, 0, SprytileGui.label_frames, SprytileGui.label_frames) fade /= SprytileGui.label_frames bgl.glColor4f(0.0, 0.0, 0.0, 0.75 * fade) bgl.glBegin(bgl.GL_QUADS) uv = [(0, 0), (0, 1), (1, 1), (1, 0)] vtx = [(view_min.x, view_max.y), (view_min.x, view_max.y + box_pad), (view_max.x, view_max.y + +box_pad), (view_max.x, view_max.y)] for i in range(4): glTexCoord2f(uv[i][0], uv[i][1]) glVertex2f(vtx[i][0], vtx[i][1]) bgl.glEnd() bgl.glColor4f(1.0, 1.0, 1.0, 1.0 * fade) blf.size(font_id, font_size, 72) x_pos = view_min.x + pad y_pos = view_max.y + pad label_string = "%dx%d" % (tilegrid.grid[0], tilegrid.grid[1]) if tilegrid.name != "": label_string = "%s - %s" % (label_string, tilegrid.name) blf.position(font_id, x_pos, y_pos, 0) blf.draw(font_id, label_string) bgl.glDisable(bgl.GL_BLEND) bgl.glDisable(bgl.GL_TEXTURE_2D) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def set_pixel_dist(self, dist_px): self._dist_px = int(dist_px) self._dist_px_sq = self._dist_px**2 self.threshold = 2 * self._dist_px + 1 self._snap_buffer = bgl.Buffer(bgl.GL_FLOAT, (self.threshold, self.threshold))
def h_gen_texture(): id = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenTextures(1, id) return id.to_list()[0]
def assign_buffer(self, varName, varValue): return self.assign(varName, bgl.Buffer(bgl.GL_FLOAT, [4,4], varValue))
def h_del_texture(tex): id = bgl.Buffer(bgl.GL_INT, 1, [tex]) bgl.glDeleteTextures(1, id)
class FontManager: _cache = {0:0} _last_fontid = 0 _prefs = get_preferences() @staticmethod @property def last_fontid(): return FontManager._last_fontid @staticmethod def get_dpi(): ui_scale = FontManager._prefs.view.ui_scale pixel_size = FontManager._prefs.system.pixel_size dpi = 72 # FontManager._prefs.system.dpi return int(dpi * ui_scale * pixel_size) @staticmethod def load(val, load_callback=None): if val is None: fontid = FontManager._last_fontid else: if val not in FontManager._cache: # note: loading the same file multiple times is not a problem. # blender is smart enough to cache fontid = blf.load(val) print(f'Addon Common: Loaded font "{val}" as id {fontid}') FontManager._cache[val] = fontid FontManager._cache[fontid] = fontid if load_callback: load_callback(fontid) fontid = FontManager._cache[val] FontManager._last_fontid = fontid return fontid @staticmethod def unload_fontids(): for name,fontid in FontManager._cache.items(): print('Unloading font "%s" as id %d' % (name, fontid)) blf.unload(name) FontManager._cache = {} FontManager._last_fontid = 0 @staticmethod def unload(filename): assert filename in FontManager._cache fontid = FontManager._cache[filename] dprint('Unloading font "%s" as id %d' % (filename, fontid)) blf.unload(filename) del FontManager._cache[filename] if fontid == FontManager._last_fontid: FontManager._last_fontid = 0 @staticmethod def aspect(aspect, fontid=None): return blf.aspect(FontManager.load(fontid), aspect) @staticmethod def blur(radius, fontid=None): return blf.blur(FontManager.load(fontid), radius) @staticmethod def clipping(xymin, xymax, fontid=None): return blf.clipping(FontManager.load(fontid), *xymin, *xymax) @staticmethod def color(color, fontid=None): blf.color(FontManager.load(fontid), *color) @staticmethod def dimensions(text, fontid=None): return blf.dimensions(FontManager.load(fontid), text) @staticmethod def disable(option, fontid=None): return blf.disable(FontManager.load(fontid), option) @staticmethod def disable_rotation(fontid=None): return blf.disable(FontManager.load(fontid), blf.ROTATION) @staticmethod def disable_clipping(fontid=None): return blf.disable(FontManager.load(fontid), blf.CLIPPING) @staticmethod def disable_shadow(fontid=None): return blf.disable(FontManager.load(fontid), blf.SHADOW) @staticmethod @blender_version_wrapper("<", "3.00") def disable_kerning_default(fontid=None): # note: not a listed option in docs for `blf.disable`, but see `blf.word_wrap` return blf.disable(FontManager.load(fontid), blf.KERNING_DEFAULT) @staticmethod @blender_version_wrapper(">=", "3.00") def disable_kerning_default(fontid=None): # blf.KERNING_DEFAULT was removed in 3.0 return @staticmethod def disable_word_wrap(fontid=None): return blf.disable(FontManager.load(fontid), blf.WORD_WRAP) @staticmethod def draw(text, xyz=None, fontsize=None, dpi=None, fontid=None): fontid = FontManager.load(fontid) if xyz: blf.position(fontid, *xyz) if fontsize: FontManager.size(fontsize, dpi=dpi, fontid=fontid) return blf.draw(fontid, text) _pre_blend = bgl.Buffer(bgl.GL_BYTE, 1) _pre_src_rgb = bgl.Buffer(bgl.GL_INT, 1) _pre_dst_rgb = bgl.Buffer(bgl.GL_INT, 1) _pre_src_a = bgl.Buffer(bgl.GL_INT, 1) _pre_dst_a = bgl.Buffer(bgl.GL_INT, 1) @staticmethod def draw_simple(text, xyz): fontid = FontManager._last_fontid blf.position(fontid, *xyz) # blf.draw overwrites blend settings! store so we can restore bgl.glGetBooleanv(bgl.GL_BLEND_SRC_RGB, FontManager._pre_src_rgb) bgl.glGetIntegerv(bgl.GL_BLEND_DST_RGB, FontManager._pre_dst_rgb) bgl.glGetBooleanv(bgl.GL_BLEND_SRC_ALPHA, FontManager._pre_src_a) bgl.glGetIntegerv(bgl.GL_BLEND_DST_ALPHA, FontManager._pre_dst_a) bgl.glGetIntegerv(bgl.GL_BLEND, FontManager._pre_blend) ret = blf.draw(fontid, text) # restore blend settings! if FontManager._pre_blend[0]: bgl.glEnable(bgl.GL_BLEND) else: bgl.glDisable(bgl.GL_BLEND) bgl.glBlendFunc(FontManager._pre_src_rgb[0], FontManager._pre_dst_rgb[0]) #bgl.glBlendEquationSeparate(FontManager._pre_src_rgb[0], FontManager._pre_dst_rgb[0], FontManager._pre_src_a[0], FontManager._pre_dst_a[0]) return ret @staticmethod def enable(option, fontid=None): return blf.enable(FontManager.load(fontid), option) @staticmethod def enable_rotation(fontid=None): return blf.enable(FontManager.load(fontid), blf.ROTATION) @staticmethod def enable_clipping(fontid=None): return blf.enable(FontManager.load(fontid), blf.CLIPPING) @staticmethod def enable_shadow(fontid=None): return blf.enable(FontManager.load(fontid), blf.SHADOW) @staticmethod @blender_version_wrapper("<", "3.00") def enable_kerning_default(fontid=None): return blf.enable(FontManager.load(fontid), blf.KERNING_DEFAULT) @staticmethod @blender_version_wrapper(">=", "3.00") def enable_kerning_default(fontid=None): # blf.KERNING_DEFAULT was removed in 3.0 return @staticmethod def enable_word_wrap(fontid=None): # note: not a listed option in docs for `blf.enable`, but see `blf.word_wrap` return blf.enable(FontManager.load(fontid), blf.WORD_WRAP) @staticmethod def position(xyz, fontid=None): return blf.position(FontManager.load(fontid), *xyz) @staticmethod def rotation(angle, fontid=None): return blf.rotation(FontManager.load(fontid), angle) @staticmethod def shadow(level, rgba, fontid=None): return blf.shadow(FontManager.load(fontid), level, *rgba) @staticmethod def shadow_offset(xy, fontid=None): return blf.shadow_offset(FontManager.load(fontid), *xy) @staticmethod def size(size, dpi=None, fontid=None): if not dpi: dpi = FontManager.get_dpi() return blf.size(FontManager.load(fontid), size, dpi) @staticmethod def word_wrap(wrap_width, fontid=None): return blf.word_wrap(FontManager.load(fontid), wrap_width)
def draw_callback(cls, context): prefs = compat.get_user_preferences(context).addons[__package__].preferences if context.window.as_pointer() != cls.origin["window"]: return # Not match target window. rect = cls.calc_draw_area_rect(context) if not rect: return # No draw target. draw_area_min_x, draw_area_min_y, draw_area_max_x, draw_area_max_y = rect _, _, _, origin_x, origin_y = cls.get_origin(context) width = draw_area_max_x - origin_x height = draw_area_max_y - origin_y if width == height == 0: return region = context.region area = context.area if region.type == 'WINDOW': region_min_x, region_min_y, region_max_x, region_max_y = get_window_region_rect(area) else: region_min_x = region.x region_min_y = region.y region_max_x = region.x + region.width - 1 region_max_y = region.y + region.height - 1 if not intersect_aabb( [region_min_x, region_min_y], [region_max_x, region_max_y], [draw_area_min_x + 1, draw_area_min_y + 1], [draw_area_max_x - 1, draw_area_max_x - 1]): # We don't need to draw if draw area is not overlapped with region. return current_time = time.time() region_drawn = False font_size = prefs.font_size font_id = 0 dpi = compat.get_user_preferences(context).system.dpi blf.size(font_id, font_size, dpi) scissor_box = bgl.Buffer(bgl.GL_INT, 4) bgl.glGetIntegerv(bgl.GL_SCISSOR_BOX, scissor_box) # Clip 'TOOLS' and 'UI' region from 'WINDOW' region if need. # This prevents from drawing multiple time when # user_preferences.system.use_region_overlap is True. if context.area.type == 'VIEW_3D' and region.type == 'WINDOW': x_min, y_min, x_max, y_max = get_region_rect_on_v3d(context) bgl.glScissor(x_min, y_min, x_max - x_min + 1, y_max - y_min + 1) # Get string height in draw area. sh = blf.dimensions(0, string.printable)[1] x = origin_x - region.x y = origin_y - region.y # Draw last operator. operator_history = cls.removed_old_operator_history() if prefs.show_last_operator and operator_history: time_, bl_label, idname_py, _ = operator_history[-1] if current_time - time_ <= prefs.display_time: compat.set_blf_font_color(font_id, *prefs.color, 1.0) # Draw operator text. text = bpy.app.translations.pgettext_iface(bl_label, "Operator") text += " ('{}')".format(idname_py) offset_x = cls.get_text_offset_for_alignment(font_id, text, context) blf.position(font_id, x + offset_x, y, 0) if prefs.background: draw_text_background(text, font_id, x + offset_x, y, prefs.color_background) draw_text(text, font_id, prefs.color, prefs.shadow, prefs.color_shadow) y += sh + sh * cls.HEIGHT_RATIO_FOR_SEPARATOR * 0.2 # Draw separator. sw = blf.dimensions(font_id, "Left Mouse")[0] offset_x = cls.get_offset_for_alignment(sw, context) draw_line([x + offset_x, y], [x + sw + offset_x, y], prefs.color, prefs.shadow, prefs.color_shadow) y += sh * cls.HEIGHT_RATIO_FOR_SEPARATOR * 0.8 region_drawn = True else: y += sh + sh * cls.HEIGHT_RATIO_FOR_SEPARATOR # Draw hold modifier keys. drawing = False # TODO: Need to check if drawing is now on progress. compat.set_blf_font_color(font_id, *prefs.color, 1.0) margin = sh * 0.2 if cls.hold_modifier_keys or drawing: mod_keys = cls.sorted_modifier_keys(cls.hold_modifier_keys) if drawing: text = "" else: text = " + ".join(mod_keys) offset_x = cls.get_text_offset_for_alignment(font_id, text, context) # Draw rounded box. box_height = sh + margin * 2 box_width = blf.dimensions(font_id, text)[0] + margin * 2 draw_rounded_box(x - margin + offset_x, y - margin, box_width, box_height, box_height * 0.2, prefs.background, prefs.color_background) # Draw key text. blf.position(font_id, x + offset_x, y + margin, 0) draw_text(text, font_id, prefs.color, prefs.shadow, prefs.color_shadow) bgl.glColor4f(*prefs.color, 1.0) region_drawn = True y += sh + margin * 2 # Draw event history. event_history = cls.removed_old_event_history() y += sh * cls.HEIGHT_RATIO_FOR_SEPARATOR for _, event_type, modifiers, repeat_count in event_history[::-1]: color = prefs.color compat.set_blf_font_color(font_id, *color, 1.0) text = get_display_event_text(event_type.name) if modifiers: mod_keys = cls.sorted_modifier_keys(modifiers) text = "{} + {}".format(" + ".join(mod_keys), text) if repeat_count > 1: text += " x{}".format(repeat_count) offset_x = cls.get_text_offset_for_alignment(font_id, text, context) blf.position(font_id, x + offset_x, y, 0) if prefs.background: draw_text_background(text, font_id, x + offset_x, y, prefs.color_background) draw_text(text, font_id, prefs.color, prefs.shadow, prefs.color_shadow) y += sh region_drawn = True bgl.glDisable(bgl.GL_BLEND) bgl.glScissor(*scissor_box) bgl.glLineWidth(1.0) if region_drawn: cls.draw_regions_prev.add(region.as_pointer())
def __init__(self, obj): self._NULL = VoidBufValue(0) self.MVP = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) # self.obj = obj self.first_index = 0 self.vbo_segs = None self.vbo_segs_co = None self.vbo_origin = None self.vbo_origin_co = None self.num_segs = 0 self.num_origins = 0 self._draw_segs = False self._draw_origins = False self.is_mesh = False self.snap_mode = 0 self.vao = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenVertexArrays(1, self.vao) bgl.glBindVertexArray(self.vao[0]) _arrays = _Object_Arrays(obj) if _arrays.segs_co: self.vbo_segs_co = bgl.Buffer(bgl.GL_INT, 1) self.num_segs = len(_arrays.segs_co) bgl.glGenBuffers(1, self.vbo_segs_co) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs_co[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_segs * 24, _arrays.segs_co, bgl.GL_STATIC_DRAW) segs_indices = np.repeat(np.arange(self.num_segs, dtype='f4'), 2) self.vbo_segs = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_segs) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs[0]) bgl.glBufferData( bgl.GL_ARRAY_BUFFER, self.num_segs * 8, np_array_as_bgl_Buffer(segs_indices), bgl.GL_STATIC_DRAW ) del segs_indices self._draw_segs = True # objects origin if _arrays.origin_co: self.vbo_origin_co = bgl.Buffer(bgl.GL_INT, 1) self.num_origins = len(_arrays.origin_co) bgl.glGenBuffers(1, self.vbo_origin_co) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin_co[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_origins * 12, _arrays.origin_co, bgl.GL_STATIC_DRAW) orig_indices = np.arange(self.num_origins, dtype='f4') self.vbo_origin = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_origin) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin[0]) bgl.glBufferData( bgl.GL_ARRAY_BUFFER, self.num_origins * 4, np_array_as_bgl_Buffer(orig_indices), bgl.GL_STATIC_DRAW ) del orig_indices self.is_mesh = _arrays.is_mesh self._draw_origins = True del _arrays bgl.glBindVertexArray(0)
def draw_measurements_callback(self, context): sce = context.scene draw = 0 if hasattr(sce, "measure_panel_draw"): draw = sce.measure_panel_draw # 2D drawing code example #bgl.glBegin(bgl.GL_LINE_STRIP) #bgl.glVertex2i(0, 0) #bgl.glVertex2i(80, 100) #bgl.glEnd() # Get measured 3D points and colors. line = getMeasurePoints(context) if (line and draw): p1, p2, color = line # Get and convert the Perspective Matrix of the current view/region. view3d = bpy.context region = view3d.region_data perspMatrix = region.perspective_matrix tempMat = [perspMatrix[i][j] for i in range(4) for j in range(4)] perspBuff = bgl.Buffer(bgl.GL_FLOAT, 16, tempMat) # --- # Store previous OpenGL settings. # Store MatrixMode MatrixMode_prev = bgl.Buffer(bgl.GL_INT, [1]) bgl.glGetIntegerv(bgl.GL_MATRIX_MODE, MatrixMode_prev) MatrixMode_prev = MatrixMode_prev[0] # Store projection matrix ProjMatrix_prev = bgl.Buffer(bgl.GL_DOUBLE, [16]) bgl.glGetFloatv(bgl.GL_PROJECTION_MATRIX, ProjMatrix_prev) # Store Line width lineWidth_prev = bgl.Buffer(bgl.GL_FLOAT, [1]) bgl.glGetFloatv(bgl.GL_LINE_WIDTH, lineWidth_prev) lineWidth_prev = lineWidth_prev[0] # Store GL_BLEND blend_prev = bgl.Buffer(bgl.GL_BYTE, [1]) bgl.glGetFloatv(bgl.GL_BLEND, blend_prev) blend_prev = blend_prev[0] line_stipple_prev = bgl.Buffer(bgl.GL_BYTE, [1]) bgl.glGetFloatv(bgl.GL_LINE_STIPPLE, line_stipple_prev) line_stipple_prev = line_stipple_prev[0] # Store glColor4f color_prev = bgl.Buffer(bgl.GL_FLOAT, [4]) bgl.glGetFloatv(bgl.GL_COLOR, color_prev) # --- # Prepare for 3D drawing bgl.glLoadIdentity() bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glLoadMatrixf(perspBuff) bgl.glEnable(bgl.GL_BLEND) bgl.glEnable(bgl.GL_LINE_STIPPLE) # --- # Draw 3D stuff. width = 1 bgl.glLineWidth(width) # X bgl.glColor4f(1, 0, 0, 0.8) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex3f(p1[0], p1[1], p1[2]) bgl.glVertex3f(p2[0], p1[1], p1[2]) bgl.glEnd() # Y bgl.glColor4f(0, 1, 0, 0.8) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex3f(p1[0], p1[1], p1[2]) bgl.glVertex3f(p1[0], p2[1], p1[2]) bgl.glEnd() # Z bgl.glColor4f(0, 0, 1, 0.8) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex3f(p1[0], p1[1], p1[2]) bgl.glVertex3f(p1[0], p1[1], p2[2]) bgl.glEnd() # Dist width = 2 bgl.glLineWidth(width) bgl.glColor4f(color[0], color[1], color[2], color[3]) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex3f(p1[0], p1[1], p1[2]) bgl.glVertex3f(p2[0], p2[1], p2[2]) bgl.glEnd() # --- # Restore previous OpenGL settings bgl.glLoadIdentity() bgl.glMatrixMode(MatrixMode_prev) bgl.glLoadMatrixf(ProjMatrix_prev) bgl.glLineWidth(lineWidth_prev) if not blend_prev: bgl.glDisable(bgl.GL_BLEND) if not line_stipple_prev: bgl.glDisable(bgl.GL_LINE_STIPPLE) bgl.glColor4f(color_prev[0], color_prev[1], color_prev[2], color_prev[3]) # --- # Draw (2D) text # We do this after drawing the lines so # we can draw it OVER the line. coord_2d = region3d_get_2d_coordinates(context, p2 + (p1 - p2) * 0.5) OFFSET_LINE = 10 # Offset the text a bit to the right. OFFSET_Y = 15 # Offset of the lines. OFFSET_VALUE = 30 # Offset of value(s) from the text. dist = (p1 - p2).length # Write distance value into the scene property, # so we can display it in the panel & refresh the panel. if hasattr(sce, "measure_panel_dist"): sce.measure_panel_dist = dist context.area.tag_redraw() texts = [("Dist:", round(dist, PRECISION)), ("X:", round(abs(p1[0] - p2[0]), PRECISION)), ("Y:", round(abs(p1[1] - p2[1]), PRECISION)), ("Z:", round(abs(p1[2] - p2[2]), PRECISION))] # Draw all texts # @todo Get user pref for text color in 3D View bgl.glColor4f(1.0, 1.0, 1.0, 1.0) blf.size(0, 12, 72) # Prevent font size to randomly change. loc_x = coord_2d[0] + OFFSET_LINE loc_y = coord_2d[1] for t in texts: text = t[0] value = str(t[1]) + " BU" blf.position(0, loc_x, loc_y, 0) blf.draw(0, text) blf.position(0, loc_x + OFFSET_VALUE, loc_y, 0) blf.draw(0, value) loc_y -= OFFSET_Y # Handle mesh surface area calulations if (sce.measure_panel_calc_area): # Get a single selected object (or nothing). obj = getSingleObject(context) if (context.mode == 'EDIT_MESH'): obj = context.active_object if (obj and obj.type == 'MESH' and obj.data): # "Note: a Mesh will return the selection state of the mesh # when EditMode was last exited. A Python script operating # in EditMode must exit EditMode before getting the current # selection state of the mesh." # http://www.blender.org/documentation/249PythonDoc/ # /Mesh.MVert-class.html#sel # We can only provide this by existing & re-entering EditMode. # @todo: Better way to do this? # Get mesh data from Object. mesh = obj.data # Get transformation matrix from object. ob_mat = obj.matrix_world # Also make an inversed copy! of the matrix. ob_mat_inv = ob_mat.copy() Matrix.invert(ob_mat_inv) # Get the selected vertices. # @todo: Better (more efficient) way to do this? verts_selected = [v for v in mesh.vertices if v.select == 1] if len(verts_selected) >= 3: # Get selected faces # @todo: Better (more efficient) way to do this? faces_selected = [f for f in mesh.faces if f.select == 1] if len(faces_selected) > 0: area = objectSurfaceArea(obj, True, measureGlobal(sce)) if (area >= 0): sce.measure_panel_area1 = area elif (context.mode == 'OBJECT'): # We are working in object mode. if len(context.selected_objects) > 2: return # @todo Make this work again. # # We have more that 2 objects selected... # # mesh_objects = [o for o in context.selected_objects # if (o.type == 'MESH')] # if (len(mesh_objects) > 0): # # ... and at least one of them is a mesh. # # for o in mesh_objects: # area = objectSurfaceArea(o, False, # measureGlobal(sce)) # if (area >= 0): # #row.label(text=o.name, icon='OBJECT_DATA') # #row.label(text=str(round(area, PRECISION)) # # + " BU^2") elif len(context.selected_objects) == 2: # 2 objects selected. obj1, obj2 = context.selected_objects # Calculate surface area of the objects. area1 = objectSurfaceArea(obj1, False, measureGlobal(sce)) area2 = objectSurfaceArea(obj2, False, measureGlobal(sce)) sce.measure_panel_area1 = area1 sce.measure_panel_area2 = area2 elif (obj): # One object selected. # Calculate surface area of the object. area = objectSurfaceArea(obj, False, measureGlobal(sce)) if (area >= 0): sce.measure_panel_area1 = area
def get_bmesh_loose_verts(bm): pos = [v.co for v in bm.verts if not v.link_edges] if len(pos) < 1: return None return bgl.Buffer(bgl.GL_FLOAT, (len(pos), 3), pos)
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 = biggest_w * 4 equi_h = 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 return image