def new_custom_shape(type, verts): """ Create a new shape that can be passed to :class:`bpy.types.Gizmo.draw_custom_shape`. :arg type: The type of shape to create in (POINTS, LINES, TRIS, LINE_STRIP). :type type: string :arg verts: Coordinates. :type verts: sequence of of 2D or 3D coordinates. :arg display_name: Optional callback that takes the full path, returns the name to display. :type display_name: Callable that takes a string and returns a string. :return: The newly created shape. :rtype: Undefined (it may change). """ import gpu from gpu.types import ( GPUBatch, GPUVertBuf, GPUVertFormat, ) dims = len(verts[0]) if dims not in {2, 3}: raise ValueError("Expected 2D or 3D vertex") fmt = GPUVertFormat() pos_id = fmt.attr_add(id="pos", comp_type='F32', len=dims, fetch_mode='FLOAT') vbo = GPUVertBuf(len=len(verts), format=fmt) vbo.attr_fill(id=pos_id, data=verts) batch = GPUBatch(type=type, buf=vbo) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR' if dims == 3 else '2D_UNIFORM_COLOR') batch.program_set(shader) return (batch, shader)
def custom_batch(shader, type, content, indices=None): """ shader type: 'POINTS', 'LINES', 'TRIS' or 'LINES_ADJ' """ from gpu.types import ( GPUBatch, GPUIndexBuf, GPUVertBuf, ) for data in content.values(): vbo_len = len(data) break else: raise ValueError("Empty 'content'") vbo_format = shader.format_calc() vbo = GPUVertBuf(vbo_format, vbo_len) for id, data in content.items(): if len(data) != vbo_len: raise ValueError("Length mismatch for 'content' values") vbo.attr_fill(id, data) if indices is None: return GPUBatch(type=type, buf=vbo) else: ibo = GPUIndexBuf(type=type, seq=indices) return GPUBatch(type=type, buf=vbo, elem=ibo)
def ΔΔ画n点(ξ): # print("ξ==",ξ); if (0 < LG.CL条序艹点画G[ξ]): i一 = LG.CL条序艹点画G[ξ] - LG.L条序艹pre点[ξ] #print("==",i一,[*LG.CL条序艹点画G],LG.L条序艹pre点,LG.L条序L点序f2); if (0 < i一): LG.L条序L点序f2[ξ].extend([[]] * i一) LG.L条序艹pre点[ξ] = LG.CL条序艹点画G[ξ] #print("++",[*LG.CL条序艹点画G],LG.L条序艹pre点,LG.L条序L点序f2); elif (i一 < 0): #现在比之前少了,就缩小 LG.L条序L点序f2[ξ] = LG.L条序L点序f2[ξ][:LG.CL条序艹点画G[ξ]] LG.L条序艹pre点[ξ] = LG.CL条序艹点画G[ξ] #print("--",LG.L条序艹pre点,LG.L条序L点序f2); # print("==",[*LG.CL条序艹点画G],LG.L条序L点序f2,LG.CL条序L点序f2画G); for i in range(LG.CL条序艹点画G[ξ]): # print("==",i,LG.CL条序L点序f2画G[ξ][i]); LG.L条序L点序f2[ξ][i] = LG.CL条序L点序f2画G[ξ][i] # print("LG.CL条序L点序f2画G==",LG.L条序L点序f2[ξ]);#,*LG.CL条序L点序f2画G #------------------------------ vbo_format = shader.format_calc() len = LG.L条序L点序f2[ξ].__len__() V点 = GPUVertBuf(vbo_format, len) V点.attr_fill(id="pos", data=LG.L条序L点序f2[ξ]) #------------------------------ shader.bind() shader.uniform_float("color", LG.CL条序col点G[ξ]) GPUBatch(type='POINTS', buf=V点).draw(shader)
def ΔΔ画n乛(ξ): # print("LG.CL条序艹乛画G[ξ]==",ξ,[*LG.CL条序艹乛画G],LG.L条序艹pre乛,LG.CL条序L段序L4f2乛画G[ξ]); if (0 < LG.CL条序艹乛画G[ξ]): i一 = LG.CL条序艹乛画G[ξ] - LG.L条序艹pre乛[ξ] #print("LG.CL条序艹乛画G[ξ]==",LG.L条序艹pre乛,LG.CL条序艹乛画G[ξ],i一,LG.L条序LL6f2[ξ].__len__(),id(LG.L条序LL6f2[ξ])); if (0 < i一): LG.L条序LL6f2[ξ].extend([[]] * 6 * i一) LG.L条序艹pre乛[ξ] = LG.CL条序艹乛画G[ξ] #print("++id(L条序LL6f2[ξ])==",LG.L条序LL6f2[ξ].__len__(),id(LG.L条序LL6f2[ξ])); elif (i一 < 0): LG.L条序LL6f2[ξ] = LG.L条序LL6f2[ξ][:6 * LG.CL条序艹乛画G[ξ]] LG.L条序艹pre乛[ξ] = LG.CL条序艹乛画G[ξ] #LG.L条序LL6f2[ξ]=LG.L条序LL6f2[ξ]; #print("--id(L条序LL6f2[ξ])==",LG.L条序LL6f2[ξ].__len__(),id(LG.L条序LL6f2[ξ])); for i in range(LG.CL条序艹乛画G[ξ]): LG.CL4f2 = LG.CL条序L段序L4f2乛画G[ξ][i] #print("CL4f2==",*LG.CL4f2[0],*LG.CL4f2[1],*LG.CL4f2[2],*LG.CL4f2[3]); j = i * 6 #[0,1,2,3,4,5 , 6,7,8,9,10,11] LG.L条序LL6f2[ξ][j] = LG.CL4f2[0] LG.L条序LL6f2[ξ][j + 1] = LG.CL4f2[1] LG.L条序LL6f2[ξ][j + 2] = LG.CL4f2[1] LG.L条序LL6f2[ξ][j + 3] = LG.CL4f2[2] LG.L条序LL6f2[ξ][j + 4] = LG.CL4f2[1] LG.L条序LL6f2[ξ][j + 5] = LG.CL4f2[3] #------------------------------ vbo_format = shader.format_calc() len = LG.L条序LL6f2[ξ].__len__() #print("LG.L条序LL6f2[ξ]==",LG.L条序LL6f2[ξ],LG.L条序LL6f2[ξ].__len__(),id(LG.L条序LL6f2[ξ])); V点 = GPUVertBuf(vbo_format, len) V点.attr_fill(id="pos", data=LG.L条序LL6f2[ξ]) #------------------------------ shader.bind() shader.uniform_float("color", LG.CL条序col乛G[ξ]) GPUBatch(type='LINES', buf=V点).draw(shader)
def ΔΔ画n一一(ξ): if (0 < LG.CL条序艹一一画G[ξ]): i一 = LG.CL条序艹一一画G[ξ] - LG.L条序艹pre一一[ξ] if (0 < i一): LG.L条序LL2f2一一[ξ].extend([[]] * 2 * i一) LG.L条序艹pre一一[ξ] = LG.CL条序艹一一画G[ξ] #增加容量 # print("++id(L条序LL2f2一一)==",LG.L条序LL2f2一一.__len__(),id(LG.L条序LL2f2一一)); elif (i一 < 0): LG.L条序LL2f2一一[ξ] = LG.L条序LL2f2一一[ξ][:2 * LG.CL条序艹一一画G[ξ]] LG.L条序艹pre一一[ξ] = LG.CL条序艹一一画G[ξ] #减少容量 # print("--id(L条序LL2f2一一)==",LG.L条序LL2f2一一.__len__(),id(LG.L条序LL2f2一一)); for i in range(LG.CL条序艹一一画G[ξ]): LG.CL2f2 = LG.CL条序L段序L2f2一一画G[ξ][i] j = i * 2 LG.L条序LL2f2一一[ξ][j] = LG.CL2f2[0] LG.L条序LL2f2一一[ξ][j + 1] = LG.CL2f2[1] #------------------------------ vbo_format = shader.format_calc() len = LG.L条序LL2f2一一[ξ].__len__() #print("L条序LL2f2一一==",LG.name,LG.L条序LL2f2一一,LG.L条序LL2f2一一.__len__(),id(LG.L条序LL2f2一一)); V点 = GPUVertBuf(vbo_format, len) V点.attr_fill(id="pos", data=LG.L条序LL2f2一一[ξ]) #------------------------------ shader.bind() shader.uniform_float("color", LG.CL条序col一一G[ξ]) GPUBatch(type='LINES', buf=V点).draw(shader)
def batch_point_get(self): if self._batch_point is None: from gpu.types import ( GPUVertBuf, GPUBatch, ) vbo = GPUVertBuf(self._format_pos, len=1) vbo.attr_fill(0, ((0.0, 0.0, 0.0), )) self._batch_point = GPUBatch(type="POINTS", buf=vbo) return self._batch_point
def batch_line_strip_create(self, coords): from gpu.types import ( GPUVertBuf, GPUBatch, ) vbo = GPUVertBuf(self._format_pos, len=len(coords)) vbo.attr_fill(0, data=coords) batch_lines = GPUBatch(type="LINE_STRIP", buf=vbo) return batch_lines
def batch_triangles_create(self, coords): from gpu.types import ( GPUVertBuf, GPUBatch, ) vbo = GPUVertBuf(self._format_pos, len=len(coords)) vbo.attr_fill(0, data=coords) batch_tris = GPUBatch(type="TRIS", buf=vbo) return batch_tris
def draw_lines(self, context, obj, vertices, indices, topology=None): region = context.region region3d = context.region_data color = context.scene.DocProperties.decorations_colour fmt = GPUVertFormat() fmt.attr_add(id="pos", comp_type="F32", len=3, fetch_mode="FLOAT") if topology: fmt.attr_add(id="topo", comp_type="U8", len=1, fetch_mode="INT") vbo = GPUVertBuf(len=len(vertices), format=fmt) vbo.attr_fill(id="pos", data=vertices) if topology: vbo.attr_fill(id="topo", data=topology) ibo = GPUIndexBuf(type="LINES", seq=indices) batch = GPUBatch(type="LINES", buf=vbo, elem=ibo) bgl.glEnable(bgl.GL_LINE_SMOOTH) bgl.glHint(bgl.GL_LINE_SMOOTH_HINT, bgl.GL_NICEST) bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) self.shader.bind() self.shader.uniform_float self.shader.uniform_float("viewMatrix", region3d.perspective_matrix) self.shader.uniform_float("winsize", (region.width, region.height)) self.shader.uniform_float("color", color) # Horrific prototype code factor = self.camera_zoom_to_factor( context.space_data.region_3d.view_camera_zoom) camera_width_px = factor * context.region.width mm_to_px = camera_width_px / self.camera_width_mm # 0.00025 is a magic constant number I visually discovered to get the right number. # It probably should be dynamically calculated using system.dpi or something. viewport_drawing_scale = 0.00025 * mm_to_px self.shader.uniform_float("viewportDrawingScale", viewport_drawing_scale) batch.draw(self.shader)
def batch(*args, **attr_data): """ Positional arguments: vbo format | shader | built-in shader name, primitive type, [indices] Keyword arguments: data for the corresponding shader attributes """ arg_count = len(args) if (arg_count < 2) or (arg_count > 3): raise TypeError( f"batch() takes from 2 to 3 positional arguments but {arg_count} were given" ) vbo_len = 0 for data in attr_data.values(): if not data: continue data_len = len(data) if data_len == vbo_len: continue if vbo_len == 0: vbo_len = data_len else: raise ValueError( "Length mismatch for vertex attribute data") vbo_format = args[0] if isinstance(vbo_format, str): vbo_format = shader_from_builtin(vbo_format) if isinstance(vbo_format, GPUShader): vbo_format = vbo_format.format_calc() primitive_type = args[1] indices = (args[2] if arg_count > 2 else None) vbo = GPUVertBuf(vbo_format, vbo_len) for id, data in attr_data.items(): vbo.attr_fill(id, data) if indices is None: return GPUBatch(type=primitive_type, buf=vbo) else: ibo = GPUIndexBuf(type=primitive_type, seq=indices) return GPUBatch(type=primitive_type, buf=vbo, elem=ibo)
def batch_lines_smooth_color_create(self, coords, colors): from gpu.types import ( GPUVertBuf, GPUBatch, ) vbo = GPUVertBuf(self._format_pos_and_color, len=len(coords)) vbo.attr_fill(0, data=coords) vbo.attr_fill(1, data=colors) batch_lines = GPUBatch(type="LINES", buf=vbo) return batch_lines
def Δ画囗(CL5f4): # return; vbo_format = shader.format_calc() V点 = GPUVertBuf(vbo_format, 4) #print("CL5f4==",CL5f4); V点.attr_fill(id="pos", data=[(CL5f4[0][0], CL5f4[0][1]), (CL5f4[1][0], CL5f4[1][1]), (CL5f4[2][0], CL5f4[2][1]), (CL5f4[3][0], CL5f4[3][1])]) #------------------------------ shader.bind() shader.uniform_float("color", CL5f4[4]) GPUBatch(type='TRI_FAN', buf=V点).draw(shader)
def draw_circle_2d(position, color, radius, segments=32, batch_type='TRI_FAN'): from math import sin, cos, pi import gpu from gpu.types import ( GPUBatch, GPUVertBuf, GPUVertFormat, ) if segments <= 0: raise ValueError("Amount of segments must be greater than 0.") set_line_smooth() bgl.glDepthMask(False) with gpu.matrix.push_pop(): gpu.matrix.translate(position) gpu.matrix.scale_uniform(radius) mul = (1.0 / (segments - 1)) * (pi * 2) verts = [(sin(i * mul), cos(i * mul)) for i in range(segments)] fmt = GPUVertFormat() pos_id = fmt.attr_add(id="pos", comp_type='F32', len=2, fetch_mode='FLOAT') vbo = GPUVertBuf(len=len(verts), format=fmt) vbo.attr_fill(id=pos_id, data=verts) batch = GPUBatch(type=batch_type, buf=vbo) shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') batch.program_set(shader) shader.uniform_float("color", color) batch.draw() set_line_smooth(False)
def batch_for_shader(shader, type, content, indices=None): """ Return a batch already configured and compatible with the shader. :arg shader: shader for which a compatible format will be computed. :type shader: :class:`gpu.types.GPUShader` :arg type: "'POINTS', 'LINES', 'TRIS' or 'LINES_ADJ'". :type type: str :arg content: Maps the name of the shader attribute with the data to fill the vertex buffer. :type content: dict :return: compatible batch :rtype: :class:`gpu.types.Batch` """ import gpu from gpu.types import ( GPUBatch, GPUIndexBuf, GPUVertBuf, ) for data in content.values(): vbo_len = len(data) break else: raise ValueError("Empty 'content'") vbo_format = shader.format_calc() vbo = GPUVertBuf(vbo_format, vbo_len) for id, data in content.items(): if len(data) != vbo_len: raise ValueError("Length mismatch for 'content' values") vbo.attr_fill(id, data) if indices is None: return GPUBatch(type=type, buf=vbo) else: ibo = GPUIndexBuf(type=type, seq=indices) return GPUBatch(type=type, buf=vbo, elem=ibo)
def draw_circle_2d(position, color, radius, segments=32): """ Draw a circle. :arg position: Position where the circle will be drawn. :type position: 2D Vector :arg color: Color of the circle. To use transparency GL_BLEND has to be enabled. :type color: tuple containing RGBA values :arg radius: Radius of the circle. :type radius: float :arg segments: How many segments will be used to draw the circle. Higher values give besser results but the drawing will take longer. :type segments: int """ from math import sin, cos, pi import gpu from gpu.types import ( GPUBatch, GPUVertBuf, GPUVertFormat, ) if segments <= 0: raise ValueError("Amount of segments must be greater than 0.") with gpu.matrix.push_pop(): gpu.matrix.translate(position) gpu.matrix.scale_uniform(radius) mul = (1.0 / (segments - 1)) * (pi * 2) verts = [(sin(i * mul), cos(i * mul)) for i in range(segments)] fmt = GPUVertFormat() pos_id = fmt.attr_add(id="pos", comp_type='F32', len=2, fetch_mode='FLOAT') vbo = GPUVertBuf(len=len(verts), format=fmt) vbo.attr_fill(id=pos_id, data=verts) batch = GPUBatch(type='LINE_STRIP', buf=vbo) shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') batch.program_set(shader) shader.uniform_float("color", color) batch.draw()
def draw_circle_2d(position, color, radius, *, segments=32): """ Draw a circle. :arg position: Position where the circle will be drawn. :type position: 2D Vector :arg color: Color of the circle. To use transparency GL_BLEND has to be enabled. :type color: tuple containing RGBA values :arg radius: Radius of the circle. :type radius: float :arg segments: How many segments will be used to draw the circle. Higher values give besser results but the drawing will take longer. :type segments: int """ from math import sin, cos, pi import gpu from gpu.types import ( GPUBatch, GPUVertBuf, GPUVertFormat, ) if segments <= 0: raise ValueError("Amount of segments must be greater than 0.") with gpu.matrix.push_pop(): gpu.matrix.translate(position) gpu.matrix.scale_uniform(radius) mul = (1.0 / (segments - 1)) * (pi * 2) verts = [(sin(i * mul), cos(i * mul)) for i in range(segments)] fmt = GPUVertFormat() pos_id = fmt.attr_add(id="pos", comp_type='F32', len=2, fetch_mode='FLOAT') vbo = GPUVertBuf(len=len(verts), format=fmt) vbo.attr_fill(id=pos_id, data=verts) batch = GPUBatch(type='LINE_STRIP', buf=vbo) shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') batch.program_set(shader) shader.uniform_float("color", color) batch.draw()
def to_batch(type, coords): vbo = GPUVertBuf(sh_fmt, len(coords)) vbo.attr_fill("pos", coords) batch = GPUBatch(type=type, buf=vbo) batch.program_set(shader) return batch