File: _ipynb_util.py

package info (click to toggle)
python-vispy 0.6.6-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 21,344 kB
  • sloc: python: 57,412; javascript: 6,810; makefile: 63; sh: 5
file content (112 lines) | stat: -rw-r--r-- 4,239 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# -*- coding: utf-8 -*-
# Copyright (c) Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.

"""Tools used by the IPython notebook backends."""

import re

import numpy as np

from ...ext.six import string_types, iteritems
from ...util.logs import _serialize_buffer


# -----------------------------------------------------------------------------
# GLIR commands serialization
# -----------------------------------------------------------------------------

def _extract_buffers(commands):
    """Extract all data buffers from the list of GLIR commands, and replace
    them by buffer pointers {buffer: <buffer_index>}. Return the modified list
    # of GILR commands and the list of buffers as well."""
    # First, filter all DATA commands.
    # Shader DATA commands are 3 elements, others are 4
    data_commands = [command for command in commands if command[0] == 'DATA']
    # Extract the arrays.
    buffers = [data_command[3] for data_command in data_commands]
    # Modify the commands by replacing the array buffers with pointers.
    commands_modified = list(commands)
    buffer_index = 0
    for i, command in enumerate(commands_modified):
        if command[0] == 'DATA':
            buffer = buffers[buffer_index]
            # shader code is type str; textures and everything else are numpy
            if isinstance(buffer, str):
                buffer = np.array(buffer, np.bytes_)
                buffers[buffer_index] = buffer
            commands_modified[i] = command[:3] + \
                ({'buffer_index': buffer_index,
                  'buffer_shape': buffer.shape,
                  'buffer_dtype': buffer.dtype.name},)
            buffer_index += 1
    return commands_modified, buffers


def _serialize_item(item):
    """Internal function: serialize native types."""
    # Recursively serialize lists, tuples, and dicts.
    if isinstance(item, (list, tuple)):
        return [_serialize_item(subitem) for subitem in item]
    elif isinstance(item, dict):
        return dict([(key, _serialize_item(value)) for (key, value) in iteritems(item)])

    # Serialize strings.
    elif isinstance(item, string_types):
        # Replace glSomething by something (needed for WebGL commands).
        if item.startswith('gl'):
            return re.sub(r'^gl([A-Z])', lambda m: m.group(1).lower(), item)
        else:
            return item

    # Process NumPy arrays that are not buffers (typically, uniform values).
    elif isinstance(item, np.ndarray):
        return _serialize_item(item.ravel().tolist())

    # Serialize numbers.
    else:
        try:
            # convert to scalar
            return item.item()
        except (AttributeError, ValueError):
            return item


def _serialize_command(command_modified):
    """Serialize a single GLIR (modified) command. The modification relates
    to the fact that buffers are replaced by pointers."""
    return _serialize_item(command_modified)


def create_glir_message(commands, array_serialization=None):
    """Create a JSON-serializable message of GLIR commands. NumPy arrays
    are serialized according to the specified method.

    Arguments
    ---------

    commands : list
        List of GLIR commands.
    array_serialization : string or None
        Serialization method for NumPy arrays. Possible values are:
            'binary' (default) : use a binary string
            'base64' : base64 encoded string of the array

    """
    # Default serialization method for NumPy arrays.
    if array_serialization is None:
        array_serialization = 'binary'
    # Extract the buffers.
    commands_modified, buffers = _extract_buffers(commands)
    # Serialize the modified commands (with buffer pointers) and the buffers.
    commands_serialized = [_serialize_command(command_modified)
                           for command_modified in commands_modified]
    buffers_serialized = [_serialize_buffer(buffer, array_serialization)
                          for buffer in buffers]
    # Create the final message.
    msg = {
        'msg_type': 'glir_commands',
        'commands': commands_serialized,
        'buffers': buffers_serialized,
    }
    return msg