Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #3
0
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()
Beispiel #4
0
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()
Beispiel #5
0
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.")

    bgl.glEnable(bgl.GL_LINE_SMOOTH)
    bgl.glEnable(bgl.GL_BLEND)
    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()

        bgl.glDisable(bgl.GL_BLEND)
Beispiel #6
0
    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)