Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

draw dotted/dashes line demo #2491

Open
baoshuang opened this issue May 25, 2023 · 1 comment
Open

draw dotted/dashes line demo #2491

baoshuang opened this issue May 25, 2023 · 1 comment

Comments

@baoshuang
Copy link

import numpy as np
from vispy import app, scene


def patch_vispy_gl():
    """    add glLineStipple to vispy
    """
    # step 1: add glLineStipple to _gl2
    from vispy.gloo import gl 
    import ctypes
    if hasattr(gl, "glLineStipple"):
        return

    def glLineStipple(factor, pattern):
        """
        void glLineStipple(	GLint	factor,  GLushort	pattern);

        factor: Specifies a multiplier for each bit in the line stipple pattern. If factor is 3, for example, each bit in the pattern is used three times before the next bit in the pattern is used. factor is clamped to the range [1, 256] and defaults to 1.
        pattern: Specifies a 16-bit integer whose bit pattern determines which fragments of a line will be drawn when the line is rasterized. Bit zero is used first; the default pattern is all 1's.
        """
        try:
            nativefunc = glLineStipple._native
        except AttributeError:
            nativefunc = glLineStipple._native = gl.gl2._get_gl_func("glLineStipple", None, (ctypes.c_int, ctypes.c_ushort,))
        nativefunc(factor, pattern)

    setattr(gl._gl2, "glLineStipple", glLineStipple)

    gl._copy_gl_functions(gl._gl2, gl)
    gl._copy_gl_functions(gl._gl2, globals())

    # step 2: add set_line_stipple supported
    from vispy.gloo import wrappers
    def set_line_stipple(self, factor, pattern):
        """
        factor:
            0: glDisable(GL_LINE_STIPPL)  **
            [1,256]: call glEnable(GL_LINE_STIPPL);glLineStipple(factor,pattern)
        """
        if factor == 0:
            self.glir.command("FUNC", 'glDisable', 0x0B24)  # GL_LINE_STIPPL = 0x0B24
        else:
            self.glir.command("FUNC", 'glEnable', 0x0B24)  # GL_LINE_STIPPL = 0x0B24
            self.glir.command("FUNC", 'glLineStipple', int(factor), pattern)

    setattr(wrappers.BaseGlooFunctions, "set_line_stipple", set_line_stipple)
    wrappers._setters.append("line_stipple")

    # step3:
    from vispy.visuals.visual import Visual
    def Visual__configure_gl_state(self):
        if "line_stipple" not in self._vshare.gl_state:
            self._vshare.gl_state["line_stipple"] = (0, 0)
        return Visual__configure_gl_state._raw(self)

    if Visual._configure_gl_state is not Visual__configure_gl_state:
        Visual__configure_gl_state._raw, Visual._configure_gl_state = Visual._configure_gl_state, Visual__configure_gl_state


patch_vispy_gl()

canvas = scene.SceneCanvas(keys='interactive', size=(600, 600), show=True)
canvas.measure_fps()

grid = canvas.central_widget.add_grid()
view = grid.add_view(0, 1)
view.camera = scene.PanZoomCamera()

# Add axes
yax = scene.AxisWidget(orientation='left')
yax.stretch = (0.1, 1)
grid.add_widget(yax, 0, 0)
yax.link_view(view)

xax = scene.AxisWidget(orientation='bottom')
xax.stretch = (1, 0.1)
grid.add_widget(xax, 1, 1)
xax.link_view(view)

x = np.linspace(0, 10, 50)
y = np.cos(x) * 10

pos = np.array([x, y]).T

DOTTED = (2, 0b0001000100010001)
DASHED = (1, 0b0001111100011111)
DASHDOT = (2, 0b0000111111000011)

line1 = scene.LinePlot(data=None, color="#ff0000", parent=view.scene, width=1, marker_size=6, symbol="o")
line1.update_gl_state(line_stipple=DOTTED)
line1.set_data(pos)

line2 = scene.Line(color="#00ff00", parent=view.scene, width=2, antialias=True)
line2.update_gl_state(line_stipple=DASHED)
line2.set_data(pos + (1, 0))

line3 = scene.Line(color="#0000ff", parent=view.scene, width=3, antialias=True)
line3.update_gl_state(line_stipple=DASHDOT)
line3.set_data(pos + (2, 0))

line4 = scene.InfiniteLine(pos=0, color=(1., 1., 1., 1.), parent=view.scene, width=1, vertical=False)
line4.update_gl_state(line_stipple=DASHDOT)

line5 = scene.InfiniteLine(pos=0, color=(0., 0., 1., 1.), parent=view.scene, width=1, vertical=True)
line5.update_gl_state(line_stipple=(4, 0b0001111100011111))

view.camera.set_range()

if __name__ == '__main__':
    app.run()

vispy_dash_line

Env: vispy 0.13.0 + python 3.9 + windows10(opengl32.dll)

@djhoese
Copy link
Member

djhoese commented May 26, 2023

This looks interesting, but it is kind of hard to parse out the full meaning from just your code. Could you please update your issue with an english description of what this does, why it is needed, and any other context I should know? Would you be willing to make a pull request adding this as an example? Or could/should this functionality be added to the existing LineVisual?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants