diff --git a/python/requirements.txt b/python/requirements.txt index 2bd116ae0..389a507f6 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -3,3 +3,4 @@ protobuf numpy websockets pytest +pillow diff --git a/python/test/test_builder.py b/python/test/test_builder.py index cc5a84492..616f6fdbc 100644 --- a/python/test/test_builder.py +++ b/python/test/test_builder.py @@ -1,8 +1,11 @@ import json -from easydict import EasyDict as edict - -from xviz_avs.builder import XVIZBuilder, XVIZUIPrimitiveBuilder, XVIZTimeSeriesBuilder, XVIZVariableBuilder import unittest +import numpy as np + +from easydict import EasyDict as edict +from PIL import Image +from xviz_avs.builder import (XVIZBuilder, XVIZTimeSeriesBuilder, + XVIZUIPrimitiveBuilder, XVIZVariableBuilder) PRIMARY_POSE_STREAM = '/vehicle_pose' @@ -69,7 +72,8 @@ def setUp(self): setup_pose(self.builder) def test_image(self): - data = bytes(b'12345') + data = np.array([[1,2],[3,4]]) + data = Image.fromarray(data.astype('u1')).convert('RGB') self.builder.primitive('/camera/1')\ .image(data) @@ -82,7 +86,12 @@ def test_image(self): '/camera/1': { 'images': [ { - 'data': 'MTIzNDU=' + 'width_px': 2, + 'height_px': 2, + 'data': b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x02\x00'\ + b'\x00\x00\x02\x08\x02\x00\x00\x00\xfd\xd4\x9as\x00\x00' \ + b'\x00\x16IDATx\x9ccdddddddabbbdd\x04\x00\x00\x9b\x00\x15'\ + b'\x86\xe2,\xcc\x00\x00\x00\x00IEND\xaeB`\x82' } ] } @@ -132,10 +141,10 @@ def setUp(self): setup_pose(self.builder) def test_null(self): - builder = XVIZUIPrimitiveBuilder(None, None) + builder = XVIZUIPrimitiveBuilder(None) data = builder.stream('/test').get_data() - assert data is None + assert not data def test_treetable_no_rows(self): TEST_COLUMNS = [{'display_text': 'Name', 'type': 'STRING'}] @@ -269,10 +278,10 @@ def setUp(self): setup_pose(self.builder) def test_null(self): - builder = XVIZTimeSeriesBuilder(None, None) + builder = XVIZTimeSeriesBuilder(None) data = builder.stream('/test').get_data() - assert data is None + assert not data def test_single_entry(self): self.builder = XVIZBuilder() @@ -530,10 +539,10 @@ def setUp(self): setup_pose(self.builder) def test_null(self): - builder = XVIZVariableBuilder(None, None) + builder = XVIZVariableBuilder(None) data = builder.stream('/test').get_data() - assert data is None + assert not data def test_int32s_variable(self): self.builder.variable('/test_var').values([1, 2, 3]) @@ -666,3 +675,8 @@ def test_bools_variable(self): } assert data == expected + +if __name__ == "__main__": + t = TestFutureInstanceBuilder() + t.setUp() + t.test_primitives() diff --git a/python/test/test_io.py b/python/test/test_io.py index b0543f28d..b944bd396 100644 --- a/python/test/test_io.py +++ b/python/test/test_io.py @@ -227,17 +227,17 @@ def test_glb_point_cloud_writer(self): expected = b'glTF\x02\x00\x00\x00D\x03\x00\x00\xf8\x02\x00\x00JSON{"asset":{"version":"2"'\ b'},"buffers":[{"byteLength":48}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLeng'\ - b'th":36},{"buffer":0,"byteOffset":36,"byteLength":12}],"accessors":[{"bufferView":0,'\ - b'"type":"VEC3","componentType":5126,"count":3},{"bufferView":1,"type":"VEC4","compon'\ - b'entType":5121,"count":3}],"images":[],"meshes":[],"extensions":{"AVS_xviz":{"type":'\ + b'th":12},{"buffer":0,"byteOffset":12,"byteLength":36}],"accessors":[{"bufferView":0,'\ + b'"type":"VEC4","componentType":5121,"count":3},{"bufferView":1,"type":"VEC3","compon'\ + b'entType":5126,"count":3}],"images":[],"meshes":[],"extensions":{"AVS_xviz":{"type":'\ b'"xviz/state_update","data":{"update_type":"INCREMENTAL","updates":[{"timestamp":2.0'\ b'00000000001,"poses":{"/vehicle_pose":{"timestamp":2.000000000001,"map_origin":{"lon'\ b'gitude":4.4,"latitude":5.5,"altitude":6.6},"position":[44.0,55.0,66.0],"orientation'\ - b'":[0.44,0.55,0.66]}},"primitives":{"/test_primitive":{"points":[{"points":"#/access'\ - b'ors/0","colors":"#/accessors/1"}]}}}]}}},"extensionsUsed":["AVS_xviz"]} 0\x00\x00'\ - b'\x00BIN\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80?\x00\x00'\ - b'\x80?\x00\x00\x80?\x00\x00\x00@\x00\x00\x00@\x00\x00\x00@\xff\x00\x00\x80\x00\xff'\ - b'\x00\x80\x00\x00\xff\x80' + b'":[0.44,0.55,0.66]}},"primitives":{"/test_primitive":{"points":[{"colors":"#/access'\ + b'ors/0","points":"#/accessors/1"}]}}}]}}},"extensionsUsed":["AVS_xviz"]} 0\x00\x00' \ + b'\x00BIN\x00\xff\x00\x00\x80\x00\xff\x00\x80\x00\x00\xff\x80\x00\x00\x00\x00\x00\x00'\ + b'\x00\x00\x00\x00\x00\x00\x00\x00\x80?\x00\x00\x80?\x00\x00\x80?\x00\x00\x00@\x00' \ + b'\x00\x00@\x00\x00\x00@' assert data == expected @@ -257,7 +257,7 @@ def test_glb_polyline_writer(self): b'ehicle_pose":{"timestamp":2.000000000001,"map_origin":{"longitude":4.4,"latitude":5'\ b'.5,"altitude":6.6},"position":[44.0,55.0,66.0],"orientation":[0.44,0.55,0.66]}},"pr'\ b'imitives":{"/test_primitive":{"polylines":[{"vertices":"#/accessors/0"}]}}}]}}},"ex'\ - b'tensionsUsed":["AVS_xviz"]} \x18\x00\x00\x00BIN\x00\x00\x00\x80?\x00\x00\x80?\x00'\ + b'tensionsUsed":["AVS_xviz"]} \x18\x00\x00\x00BIN\x00\x00\x00\x80?\x00\x00\x80?\x00' \ b'\x00\x80?\x00\x00\x00@\x00\x00\x00@\x00\x00\x00@' assert data == expected @@ -279,8 +279,8 @@ def test_glb_polygon_writer(self): b'":5.5,"altitude":6.6},"position":[44.0,55.0,66.0],"orientation":[0.44,0.55,0.66]}},'\ b'"primitives":{"/test_primitive":{"polygons":[{"base":{"style":{"height":2.0}},"vert'\ b'ices":"#/accessors/0"}]}}}]}}},"extensionsUsed":["AVS_xviz"]} <\x00\x00\x00BIN\x00'\ - b'\x00\x00\x80?\x00\x00\x80?\x00\x00\x80?\x00\x00\x00@\x00\x00\x00@\x00\x00\x00@\x00'\ - b'\x00@@\x00\x00@@\x00\x00@@\x00\x00\x80@\x00\x00\x80@\x00\x00\x80@\x00\x00\x80?\x00'\ + b'\x00\x00\x80?\x00\x00\x80?\x00\x00\x80?\x00\x00\x00@\x00\x00\x00@\x00\x00\x00@\x00' \ + b'\x00@@\x00\x00@@\x00\x00@@\x00\x00\x80@\x00\x00\x80@\x00\x00\x80@\x00\x00\x80?\x00' \ b'\x00\x80?\x00\x00\x80?' assert data == expected @@ -293,13 +293,12 @@ def test_protobuf_normal_writer(self): writer.write_message(builder.get_message()) data = source.read() - expected = b'glTF\x02\x00\x00\x004\x02\x00\x00\x18\x02\x00\x00JSON{"asset":{"version":"2"'\ - b'},"buffers":[{"byteLength":0}],"bufferViews":[],"accessors":[],"image":[],"meshes":'\ - b'[],"extensions":{"AVS_xviz":{"type":"#xviz/state_update","data":{"update_type":"#IN'\ - b'CREMENTAL","updates":[{"timestamp":2.000000000001,"poses":{"/vehicle_pose":{"timest'\ - b'amp":2.000000000001,"map_origin":{"longitude":4.4,"latitude":5.5,"altitude":6.6},"p'\ - b'osition":[44.0,55.0,66.0],"orientation":[0.44,0.55,0.66]}},"primitives":{"/test_pri'\ - b'mitive":{"circles":[{"center":[0.0,0.0,0.0],"radius":2.0}]}}}]}}},"extensionsUsed":'\ - b'["AVS_xviz"]}\x00\x00\x00\x00\x00\x00BIN\x00' - - # XXX: assert data == expected + expected = b'PBE1\n\x11xviz/state_update\x12\xd1\x01\n\'type.googleapis.com/xviz.v2.State'\ + b'Update\x12\xa5\x01\x08\x02\x12\xa0\x01\t\xcc\x08\x00\x00\x00\x00\x00@\x12k\n\r/vehi'\ + b'cle_pose\x12Z\t\xcc\x08\x00\x00\x00\x00\x00@\x12\x1b\t\x9a\x99\x99\x99\x99\x99\x11@'\ + b'\x11\x00\x00\x00\x00\x00\x00\x16@\x19ffffff\x1a@\x1a\x18\x00\x00\x00\x00\x00\x00F@' \ + b'\x00\x00\x00\x00\x00\x80K@\x00\x00\x00\x00\x00\x80P@"\x18)\\\x8f\xc2\xf5(\xdc?\x9a' \ + b'\x99\x99\x99\x99\x99\xe1?\x1f\x85\xebQ\xb8\x1e\xe5?\x1a(\n\x0f/test_primitive\x12' \ + b'\x15"\x13\x12\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00@' + + assert data == expected diff --git a/python/xviz_avs/builder/__init__.py b/python/xviz_avs/builder/__init__.py index 9462b81b1..47b8f6e35 100644 --- a/python/xviz_avs/builder/__init__.py +++ b/python/xviz_avs/builder/__init__.py @@ -13,7 +13,7 @@ PRIMITIVE_TYPES,\ UIPRIMITIVE_TYPES from .xviz_builder import XVIZBuilder -from .xviz_ui_builder import XVIZUIBuilder +from .ui_builder import XVIZUIBuilder from .metadata import XVIZMetadataBuilder from .pose import XVIZPoseBuilder diff --git a/python/xviz_avs/builder/base_builder.py b/python/xviz_avs/builder/base_builder.py index 68e429ca6..6a649cb95 100644 --- a/python/xviz_avs/builder/base_builder.py +++ b/python/xviz_avs/builder/base_builder.py @@ -1,11 +1,12 @@ import logging -from typing import Union +from typing import Union, NewType from easydict import EasyDict as edict from xviz_avs.message import XVIZMessage from xviz_avs.v2.session_pb2 import Metadata, StreamMetadata from xviz_avs.v2.style_pb2 import StyleStreamValue +# expose the constants ANNOTATION_TYPES = StreamMetadata.AnnotationType CATEGORY = StreamMetadata.Category COORDINATE_TYPES = StreamMetadata.CoordinateType @@ -13,6 +14,14 @@ PRIMITIVE_TYPES = StreamMetadata.PrimitiveType UIPRIMITIVE_TYPES = StreamMetadata.UIPrimitiveType +# for type hints +ANNOTATION_TYPES_T = NewType("ANNOTATION_TYPES", int) +CATEGORY_T = NewType("CATEGORY", int) +COORDINATE_TYPES_T = NewType("COORDINATE_TYPES", int) +SCALAR_TYPE_T = NewType("SCALAR_TYPE", int) +PRIMITIVE_TYPES_T = NewType("PRIMITIVE_TYPES", int) +UIPRIMITIVE_TYPES_T = NewType("UIPRIMITIVE_TYPES", int) + PRIMITIVE_STYLE_MAP = dict([ (PRIMITIVE_TYPES.CIRCLE, [ 'opacity', @@ -82,26 +91,26 @@ class XVIZBaseBuilder: # Reference [@xviz/builder/xviz-base-builder]/(https://github.com/uber/xviz/blob/master/modules/builder/src/builders/xviz-base-builder.js) """ - def __init__(self, category, metadata: Union[Metadata, XVIZMessage], logger=None): + def __init__(self, category, metadata: Union[Metadata, XVIZMessage]): self._stream_id = None self._category = category - self._metadata = metadata.data if isinstance(metadata, XVIZMessage) else metadata - self._logger = logger or logging.getLogger("xviz") + self._metadata = metadata._data if isinstance(metadata, XVIZMessage) else metadata + self._logger = logging.getLogger("xviz") - def stream(self, stream_id): + def stream(self, stream_id: str): if self._stream_id: self._flush() self._stream_id = stream_id return self @property - def stream_id(self): + def stream_id(self) -> str: return self._stream_id @property - def category(self): + def category(self) -> CATEGORY: return self._category @property - def metadata(self): + def metadata(self) -> XVIZMessage: return self._metadata def _flush(self): @@ -149,22 +158,39 @@ def _validate(self): import array from xviz_avs.v2.style_pb2 import StyleObjectValue, StyleStreamValue -def build_object_style(style): +def build_color(color: Union[list, tuple, bytes, str]) -> bytes: + ''' + Convert css style color string to bytes + ''' + if isinstance(color, (list, tuple, bytes)): + return bytes(color) + elif isinstance(color, str): + color = color.lstrip('#') + if len(color) in [3, 4]: # '#rgb' or '#rgba' style + return bytes([16 * int(c, 16) for c in color]) + elif len(color) in [6, 8]: # '#rrggbb' or '#rrggbbaa' style + return bytes([int(color[i*2:i*2+2], 16) + for i in range(len(color) // 2)]) + else: + raise ValueError("Unrecognized color string!") + raise ValueError("Unrecognized color object!") + +def build_object_style(style: dict) -> StyleObjectValue: ''' Create StyleObjectValue from dictionary. It basically deal with list of bytes. ''' if 'fill_color' in style.keys(): - style['fill_color'] = bytes(style['fill_color']) + style['fill_color'] = build_color(style['fill_color']) if 'stroke_color' in style.keys(): - style['stroke_color'] = bytes(style['stroke_color']) + style['stroke_color'] = build_color(style['stroke_color']) return StyleObjectValue(**style) -def build_stream_style(style): +def build_stream_style(style: dict) -> StyleStreamValue: ''' Create StyleStreamValue from dictionary. It basically deal with list of bytes. ''' if 'fill_color' in style.keys(): - style['fill_color'] = bytes(style['fill_color']) + style['fill_color'] = build_color(style['fill_color']) if 'stroke_color' in style.keys(): - style['stroke_color'] = bytes(style['stroke_color']) + style['stroke_color'] = build_color(style['stroke_color']) return StyleStreamValue(**style) diff --git a/python/xviz_avs/builder/future_instance.py b/python/xviz_avs/builder/future_instance.py index b919612a7..b7bb9b039 100644 --- a/python/xviz_avs/builder/future_instance.py +++ b/python/xviz_avs/builder/future_instance.py @@ -1,25 +1,29 @@ +from typing import Tuple +from collections import defaultdict + from xviz_avs.builder.base_builder import CATEGORY, PRIMITIVE_TYPES from xviz_avs.builder.primitive import XVIZPrimitiveBuilder from xviz_avs.v2.core_pb2 import FutureInstances, PrimitiveState class XVIZFutureInstanceBuilder(XVIZPrimitiveBuilder): - def __init__(self, metadata, logger=None): - super().__init__(metadata, logger) + def __init__(self, metadata): + super().__init__(metadata) self._category = CATEGORY.FUTURE_INSTANCE # Override category self.reset() self._futures = {} + self._futures_buffer = defaultdict(list) # Store entries in this list as (timestamp, type, primitive) # which we convert to Protobuf messages upon get_data() - self._futures_list = {} + self._futures_list = defaultdict(list) def reset(self): super().reset() self._ts = None - def timestamp(self, timestamp): + def timestamp(self, timestamp: float) -> 'XVIZFutureInstanceBuilder': self._ts = timestamp return self @@ -39,7 +43,8 @@ def _get_primitives_type(self, primitives, primitive_type): elif primitive_type == PRIMITIVE_TYPES.TEXT: return primitives.texts else: - raise ValueError("FutureInstance type '{0}' is not recognized".format(primitive_type)) + self._logger.error("FutureInstance type '%s' is not recognized", str(primitive_type)) + return [] def _flush_futures_list(self): # Since you cannot insert into a repeated message field @@ -54,36 +59,35 @@ def _flush_futures_list(self): entries.sort(key=lambda e: e[0]) last_ts = None - for entry in entries: - if last_ts is None or entry[0] != last_ts: + for ets, etype, eprimitive, ebuffer in entries: + if last_ts is None or ets != last_ts: # Adding a new timestamp entry to the arrays - last_ts = entry[0] - futures.timestamps.append(entry[0]) + last_ts = ets + futures.timestamps.append(ets) future_prim = futures.primitives.add() - future_prim_type = self._get_primitives_type(future_prim, entry[1]) - future_prim_type.append(entry[2]) + else: index = len(futures.timestamps)-1 future_prim = futures.primitives[index] - future_prim_type = self._get_primitives_type(future_prim, entry[1]) - future_prim_type.append(entry[2]) + + future_prim_type = self._get_primitives_type(future_prim, etype) + future_prim_type.append(eprimitive) + + if ebuffer is not None: + self._futures_buffer[(stream, ets)].append(ebuffer) + def _flush(self): - if self._stream_id not in self._futures_list: - self._futures_list[self._stream_id] = [] + primitive = self._format_primitive(len(self._futures_list[self._stream_id])) - primitive = self._format_primitive() - self._futures_list[self._stream_id].append((self._ts, self._type, primitive)) + self._futures_list[self._stream_id].append((self._ts, self._type, primitive, self._vertices_buffer)) self.reset() - def get_data(self): + def get_data(self) -> Tuple[FutureInstances, dict]: if self._type: self._flush() self._flush_futures_list() - if not self._futures: - return None - - return self._futures + return self._futures, self._futures_buffer diff --git a/python/xviz_avs/builder/link.py b/python/xviz_avs/builder/link.py index 3edd5f00c..9d2dfdfb6 100644 --- a/python/xviz_avs/builder/link.py +++ b/python/xviz_avs/builder/link.py @@ -2,12 +2,12 @@ from xviz_avs.v2.core_pb2 import Link class XVIZLinkBuilder(XVIZBaseBuilder): - def __init__(self, metadata, logger=None): - super().__init__(None, metadata, logger) + def __init__(self, metadata): + super().__init__(None, metadata) self._links = None self._target_stream = None - def parent(self, target_stream): + def parent(self, target_stream: str): self._target_stream = target_stream def _flush(self): diff --git a/python/xviz_avs/builder/metadata.py b/python/xviz_avs/builder/metadata.py index 6325be8ac..ababe990f 100644 --- a/python/xviz_avs/builder/metadata.py +++ b/python/xviz_avs/builder/metadata.py @@ -1,21 +1,30 @@ import logging -from easydict import EasyDict as edict -import numpy as np +from typing import Union +import numpy as np +from easydict import EasyDict as edict +from xviz_avs.builder.base_builder import (CATEGORY, CATEGORY_T, + COORDINATE_TYPES, + COORDINATE_TYPES_T, SCALAR_TYPE, + SCALAR_TYPE_T, build_object_style, + build_stream_style) +from xviz_avs.builder.ui_builder import XVIZUIBuilder from xviz_avs.message import XVIZMessage -from xviz_avs.builder.base_builder import build_object_style, build_stream_style -from xviz_avs.v2.session_pb2 import Metadata, StreamMetadata, LogInfo +from xviz_avs.v2.session_pb2 import LogInfo, Metadata, StreamMetadata class XVIZMetadataBuilder: - def __init__(self, logger=logging.getLogger("xviz")): - self._logger = logger - + """ + # Reference + [@xviz/builder/xviz-metadata-builder]/(https://github.com/uber/xviz/blob/master/modules/builder/src/builders/xviz-metadata-builder.js) + """ + def __init__(self): + self._logger = logging.getLogger("xviz") self._data = Metadata(version="2.0.0") self._temp_ui_builder = None self._reset() - def get_data(self): + def get_data(self) -> Metadata: self._flush() metadata = self._data @@ -29,65 +38,65 @@ def get_data(self): return metadata - def get_message(self): + def get_message(self) -> XVIZMessage: return XVIZMessage(metadata=self.get_data()) - def start_time(self, time): + def start_time(self, time: float) -> 'XVIZMetadataBuilder': self._data.log_info.start_time = time return self - def end_time(self, time): + def end_time(self, time: float) -> 'XVIZMetadataBuilder': self._data.log_info.end_time = time return self - def ui(self, ui_builder): + def ui(self, ui_builder: XVIZUIBuilder) -> 'XVIZMetadataBuilder': self._temp_ui_builder = ui_builder return self - def stream(self, stream_id): + def stream(self, stream_id: str) -> 'XVIZMetadataBuilder': if self._stream_id: self._flush() self._stream_id = stream_id return self - def category(self, category): + def category(self, category: Union[CATEGORY_T, str]): ''' Assign category for the stream. Used for validation in XVIZBuilder and not required for data. ''' if isinstance(category, int): self._temp_stream.category = category elif isinstance(category, str): - self._temp_stream.category = StreamMetadata.Category.Value(category.upper()) + self._temp_stream.category = CATEGORY.Value(category.upper()) else: self._logger.error("Invalid value type for category!") return self - def type(self, t): + def type(self, t: Union[SCALAR_TYPE_T, str]): ''' Assign primitive type for the stream. Used for validation in XVIZBuilder and not required for data. ''' if isinstance(t, int): self._temp_type = t elif isinstance(t, str): - self._temp_type = t.upper() + self._temp_type = SCALAR_TYPE.Value(t.upper()) else: self._logger.error("Invalid value type for category!") return self - def source(self, source): + def source(self, source: str): self._temp_stream.source = source return self - def unit(self, u): + def unit(self, u: str): self._temp_stream.units = u return self - def coordinate(self, coordinate): + def coordinate(self, coordinate: COORDINATE_TYPES_T): self._temp_stream.coordinate = coordinate return self - def transform_matrix(self, matrix): + def transform_matrix(self, matrix: Union[list, np.ndarray]): matrix = np.array(matrix).ravel() self._temp_stream.transform.extend(matrix.tolist()) return self @@ -95,11 +104,11 @@ def transform_matrix(self, matrix): def pose(self, position={}, orientation={}): raise NotImplementedError() # TODO: implement transformation - def stream_style(self, style): + def stream_style(self, style: dict): self._temp_stream.stream_style.MergeFrom(build_stream_style(style)) return self - def style_class(self, name, style): + def style_class(self, name: str, style: dict): if not self._stream_id: self._logger.error('A stream must set before adding a style rule.') return self @@ -108,7 +117,7 @@ def style_class(self, name, style): style_class.style.MergeFrom(build_object_style(style)) return self - def log_info(self, data): + def log_info(self, data: dict): self._data.log_info.MergeFrom(LogInfo(**data)) return self diff --git a/python/xviz_avs/builder/pose.py b/python/xviz_avs/builder/pose.py index cb23ba7d8..4e2613fb9 100644 --- a/python/xviz_avs/builder/pose.py +++ b/python/xviz_avs/builder/pose.py @@ -1,3 +1,5 @@ +from typing import Dict + from xviz_avs.builder.base_builder import XVIZBaseBuilder, CATEGORY from xviz_avs.v2.core_pb2 import Pose, MapOrigin @@ -6,10 +8,10 @@ class XVIZPoseBuilder(XVIZBaseBuilder): # Reference [@xviz/builder/xviz-pose-builder]/(https://github.com/uber/xviz/blob/master/modules/builder/src/builders/xviz-pose-builder.js) """ - def __init__(self, metadata, logger=None): - super().__init__(CATEGORY.POSE, metadata, logger) + def __init__(self, metadata): + super().__init__(CATEGORY.POSE, metadata) - self._poses = None + self._poses = {} self.reset() def reset(self): @@ -18,32 +20,29 @@ def reset(self): self._category = CATEGORY.POSE self._temp_pose = Pose() - def map_origin(self, longitude, latitude, altitude): + def map_origin(self, longitude: float, latitude: float, altitude: float) -> 'XVIZPoseBuilder': self._temp_pose.map_origin.longitude = longitude self._temp_pose.map_origin.latitude = latitude self._temp_pose.map_origin.altitude = altitude return self - def position(self, x, y, z): + def position(self, x: float, y: float, z: float) -> 'XVIZPoseBuilder': self._temp_pose.position.extend([x, y, z]) return self - def orientation(self, roll, pitch, yaw): + def orientation(self, roll: float, pitch: float, yaw: float) -> 'XVIZPoseBuilder': self._temp_pose.orientation.extend([roll, pitch, yaw]) return self - def timestamp(self, timestamp): + def timestamp(self, timestamp: float) -> 'XVIZPoseBuilder': self._temp_pose.timestamp = timestamp return self def _flush(self): - if not self._poses: - self._poses = {} - self._poses[self._stream_id] = self._temp_pose self._temp_pose = Pose() - def get_data(self): + def get_data(self) -> Dict[str, Pose]: if self._stream_id: self._flush() diff --git a/python/xviz_avs/builder/primitive.py b/python/xviz_avs/builder/primitive.py index ce84ab0e0..ce022feba 100644 --- a/python/xviz_avs/builder/primitive.py +++ b/python/xviz_avs/builder/primitive.py @@ -1,8 +1,15 @@ +from collections import defaultdict +from typing import List, Tuple, Union + import numpy as np +from PIL import Image as pImage -from xviz_avs.builder.base_builder import XVIZBaseBuilder, build_object_style, CATEGORY, PRIMITIVE_TYPES, PRIMITIVE_STYLE_MAP +from xviz_avs.builder.base_builder import (CATEGORY, PRIMITIVE_STYLE_MAP, + PRIMITIVE_TYPES, XVIZBaseBuilder, + build_object_style) from xviz_avs.v2.core_pb2 import PrimitiveState -from xviz_avs.v2.primitives_pb2 import PrimitiveBase, Circle, Image, Point, Polygon, Polyline, Stadium, Text +from xviz_avs.v2.primitives_pb2 import (Circle, Image, Point, Polygon, + Polyline, PrimitiveBase, Stadium, Text) class XVIZPrimitiveBuilder(XVIZBaseBuilder): @@ -12,72 +19,62 @@ class XVIZPrimitiveBuilder(XVIZBaseBuilder): # Reference [@xviz/builder/xviz-primitive-builder]/(https://github.com/uber/xviz/blob/master/modules/builder/src/builders/xviz-primitive-builder.js) """ - def __init__(self, metadata, logger=None): - super().__init__(CATEGORY.PRIMITIVE, metadata, logger) + def __init__(self, metadata): + super().__init__(CATEGORY.PRIMITIVE, metadata) - self._primitives = {} + self._primitives = defaultdict(PrimitiveState) + self._buffers = defaultdict(list) # direct storage of large float array, stream_id -> list of buffers in numpy self.reset() - def image(self, data): + def image(self, data: pImage.Image) -> 'XVIZPrimitiveBuilder': ''' - Add image data + Add image data. Internal representation is handled by pillow image ''' if self._type: self._flush() - if not isinstance(data, (bytes, np.ndarray, str)): - # TODO: support PILLOW and other image types - # should save raw data and preserve mimetype? - self._logger.error("An image data must be a string or numpy array") self._validate_prop_set_once("_image") self._type = PRIMITIVE_TYPES.IMAGE - self._image = Image(data=data) - - return self - - def dimensions(self, width_pixel=None, height_pixel=None): - ''' - Add dimension specs for image data - ''' - if not self._image: - self._logger.error("An image needs to be set first") - self._image.width_px = width_pixel - self._image.height_px = height_pixel + if isinstance(data, pImage.Image): + self._image = Image(width_px=data.width, height_px=data.height) + self._image_buffer = data + else: + self._logger.error("An image data must be a pillow Image") return self - def polygon(self, vertices): + def polygon(self, vertices: Union[np.ndarray, list]) -> 'XVIZPrimitiveBuilder': if self._type: self._flush() self._validate_prop_set_once("_vertices") - self._vertices = vertices + self._vertices = np.asarray(vertices, dtype='f4').flatten().tolist() self._type = PRIMITIVE_TYPES.POLYGON return self - def polyline(self, vertices): + def polyline(self, vertices: Union[np.ndarray, list]) -> 'XVIZPrimitiveBuilder': if self._type: self._flush() self._validate_prop_set_once("_vertices") - self._vertices = vertices + self._vertices = np.asarray(vertices, dtype='f4').flatten().tolist() self._type = PRIMITIVE_TYPES.POLYLINE return self - def points(self, vertices): + def points(self, vertices: Union[np.ndarray, list]) -> 'XVIZPrimitiveBuilder': if self._type: self._flush() - self._validate_prop_set_once("_vertices") - self._vertices = vertices + self._validate_prop_set_once("_vertices_buffer") + self._vertices_buffer = np.asarray(vertices, dtype='f4').flatten() self._type = PRIMITIVE_TYPES.POINT return self - def circle(self, position, radius): + def circle(self, position: Union[np.ndarray, list], radius: float) -> 'XVIZPrimitiveBuilder': if self._type: self._flush() @@ -89,16 +86,18 @@ def circle(self, position, radius): return self - def stadium(self, start, end, radius): + def stadium(self, start: Union[np.ndarray, list], end: Union[np.ndarray, list], radius: float) -> 'XVIZPrimitiveBuilder': if self._type: self._flush() self._validate_prop_set_once("_radius") + start = np.asarray(start, dtype="f4").tolist() if len(start) != 3: - self._logger.error("The start position must be of the form [x, y, z] where {} was provided".format(start)) + self._logger.error("The start position must be of the form [x, y, z] where %s was provided", str(start)) + end = np.asarray(end, dtype="f4").tolist() if len(end) != 3: - self._logger.error("The end position must be of the form [x, y, z] where {} was provided".format(end)) + self._logger.error("The end position must be of the form [x, y, z] where %s was provided", str(end)) self._vertices = [start, end] self._radius = radius @@ -106,8 +105,7 @@ def stadium(self, start, end, radius): return self - def text(self, message): - # XXX: is not actually defined yet + def text(self, message: str) -> 'XVIZPrimitiveBuilder': if self._type: self._flush() @@ -118,36 +116,37 @@ def text(self, message): return self - def position(self, point): + def position(self, point: Union[np.ndarray, list]) -> 'XVIZPrimitiveBuilder': self._validate_prop_set_once("_vertices") + point = np.asarray(point, dtype="f4").tolist() if len(point) != 3: self._logger.error("A position must be of the form [x, y, z] where {} was provided".format(point)) self._vertices = [point] return self - def colors(self, color_array): + def colors(self, color_array: Union[np.ndarray, list]) -> 'XVIZPrimitiveBuilder': self._validate_prop_set_once('_colors') - self._colors = color_array + self._colors = np.asarray(color_array, dtype='u1').flatten() # convert to bytes here return self - def style(self, style): + def style(self, style: dict) -> 'XVIZPrimitiveBuilder': self._validate_prerequisite() self._validate_prop_set_once('_style') self._style = style return self - def id(self, identifier): + def id(self, identifier: str) -> 'XVIZPrimitiveBuilder': self._validate_prerequisite() self._validate_prop_set_once('_id') self._id = identifier return self - def classes(self, class_list): + def classes(self, class_list: List[str]) -> 'XVIZPrimitiveBuilder': self._validate_prerequisite() self._validate_prop_set_once('_classes') @@ -158,55 +157,49 @@ def _validate(self): super()._validate() if self._type == PRIMITIVE_TYPES.IMAGE: - if self._image is None or self._image.data is None: - self._logger.warning("Stream {} image data are not provided.".format(self._stream_id)) + if self._image is None or self._image_buffer is None: + self._logger.warning("Stream %s image data are not provided.", self._stream_id) else: - if self._vertices is None: - self._logger.warning("Stream {} primitives vertices are not provided.".format(self._stream_id)) + if self._vertices is None and self._vertices_buffer is None: + self._logger.warning("Stream %s primitives vertices are not provided.", self._stream_id) def _flush(self): self._validate() self._flush_primitives() - def get_data(self): + def get_data(self) -> Tuple[dict, dict]: if self._type: self._flush() - if len(self._primitives) == 0: - return None - - return self._primitives + return self._primitives, self._buffers def _validate_prerequisite(self): if not self._type: self._logger.error("Start from a primitive first, e.g polygon(), image(), etc.") def _flush_primitives(self): - if self._stream_id not in self._primitives.keys(): - self._primitives[self._stream_id] = PrimitiveState() stream = self._primitives[self._stream_id] array_field_name = PRIMITIVE_TYPES.Name(self._type).lower() + 's' array = getattr(stream, array_field_name) - obj = self._format_primitive() + obj = self._format_primitive(len(array)) array.append(obj) self.reset() - def _format_primitive(self): - # XXX: Need to flatten arrays, TODO: need more elegant way - # flatten_vertices = [item for sublist in self._vertices for item in sublist] - + def _format_primitive(self, stream_pos: int): # Embed primitive data if self._type == PRIMITIVE_TYPES.POLYGON: obj = Polygon(vertices=self._vertices) elif self._type == PRIMITIVE_TYPES.POLYLINE: obj = Polyline(vertices=self._vertices) elif self._type == PRIMITIVE_TYPES.POINT: - obj = Point(points=self._vertices) - if self._colors: - obj.colors = bytes(self._colors) + obj = Point() + assert len(self._buffers[self._stream_id]) == stream_pos + self._buffers[self._stream_id].append(self._vertices_buffer) + if self._colors is not None: + obj.colors = self._colors.tobytes() elif self._type == PRIMITIVE_TYPES.TEXT: obj = Text(position=self._vertices[0], text=self._text) elif self._type == PRIMITIVE_TYPES.CIRCLE: @@ -217,6 +210,7 @@ def _format_primitive(self): if self._vertices: self._image.position = self._vertices[0] obj = self._image + self._buffers[self._stream_id].append(self._image_buffer) # Embed base data have_base = False @@ -259,3 +253,6 @@ def reset(self): self._id = None self._style = None self._classes = None + + self._vertices_buffer = None + self._image_buffer = None diff --git a/python/xviz_avs/builder/time_series.py b/python/xviz_avs/builder/time_series.py index c6f061638..8af084b85 100644 --- a/python/xviz_avs/builder/time_series.py +++ b/python/xviz_avs/builder/time_series.py @@ -1,21 +1,23 @@ +from typing import Union + from xviz_avs.builder.base_builder import XVIZBaseBuilder, CATEGORY from xviz_avs.v2.core_pb2 import TimeSeriesState class XVIZTimeSeriesBuilder(XVIZBaseBuilder): - def __init__(self, metadata, logger=None): - super().__init__(CATEGORY.TIME_SERIES, metadata, logger) + def __init__(self, metadata): + super().__init__(CATEGORY.TIME_SERIES, metadata) # Stores time_series data by timestamp then id # They will then be group when constructing final object self._data = {} self.reset() - def id(self, identifier): + def id(self, identifier: str) -> 'XVIZTimeSeriesBuilder': self._validate_prop_set_once('_id') self._id = identifier return self - def value(self, value): + def value(self, value: Union[int, float, str, bool]) -> 'XVIZTimeSeriesBuilder': self._validate_prop_set_once('_value') if isinstance(value, list): @@ -24,7 +26,7 @@ def value(self, value): self._value = value return self - def timestamp(self, timestamp): + def timestamp(self, timestamp: float) -> 'XVIZTimeSeriesBuilder': self._validate_prop_set_once('_timestamp') if isinstance(timestamp, list): @@ -33,7 +35,7 @@ def timestamp(self, timestamp): self._timestamp = timestamp return self - def get_data(self): + def get_data(self) -> []: self._flush() if not self._data: return None @@ -93,10 +95,10 @@ def _add_timestamp_entry(self): ts_entry = {self._id: self._get_id_entry(field_name)} self._data[self._timestamp] = ts_entry - def _get_id_entry(self, field_name): + def _get_id_entry(self, field_name: str): return {field_name: self._get_field_entry(field_name)} - def _get_field_entry(self, field_name): + def _get_field_entry(self, field_name: str): return dict(streams=[self._stream_id], values={field_name: [self._value]}) def _data_pending(self): diff --git a/python/xviz_avs/builder/xviz_ui_builder.py b/python/xviz_avs/builder/ui_builder.py similarity index 65% rename from python/xviz_avs/builder/xviz_ui_builder.py rename to python/xviz_avs/builder/ui_builder.py index 84f5207cc..77c7e3f76 100644 --- a/python/xviz_avs/builder/xviz_ui_builder.py +++ b/python/xviz_avs/builder/ui_builder.py @@ -1,17 +1,30 @@ -from xviz_avs.builder.declarative_ui import * - from functools import partial +from typing import Dict, Type + +from xviz_avs.builder.declarative_ui import * class XVIZUIBuilder: """ # Reference - [@xviz/builder/xviz-base-builder]/(https://github.com/uber/xviz/blob/master/modules/builder/src/builders/xviz-base-builder.js) - kwargs + [@xviz/builder/declarative-ui/xviz-ui-builder](https://github.com/uber/xviz/blob/master/modules/builder/src/builders/declarative-ui/xviz-ui-builder.js) + + kwargs: - validateError - validateWarn - logger """ + + # type hints + panel: Type[XVIZPanelBuilder] + container: Type[XVIZContainerBuilder] + metric: Type[XVIZMetricBuilder] + plot: Type[XVIZPlotBuilder] + select: Type[XVIZSelectBuilder] + table: Type[XVIZTableBuilder] + treetable: Type[XVIZTreeTableBuilder] + video: Type[XVIZVideoBuilder] + def __init__(self, **kwargs): self._kwargs = kwargs self._panels = [] @@ -27,12 +40,12 @@ def __init__(self, **kwargs): "video": XVIZVideoBuilder } - def child(self, panel): + def child(self, panel: XVIZPanelBuilder): if not isinstance(panel, XVIZPanelBuilder): raise TypeError("Argument panel must be an XVIZPanelBuilder instance") self._panels.append(panel) - def get_ui(self): + def get_ui(self) -> Dict[str, Dict]: ui = {item.name: item.get_ui() for item in self._panels} return ui diff --git a/python/xviz_avs/builder/ui_primitive.py b/python/xviz_avs/builder/ui_primitive.py index 0d9404289..60b57e355 100644 --- a/python/xviz_avs/builder/ui_primitive.py +++ b/python/xviz_avs/builder/ui_primitive.py @@ -1,28 +1,30 @@ +from typing import Union, Iterable, Dict + from xviz_avs.builder.base_builder import XVIZBaseBuilder, CATEGORY, UIPRIMITIVE_TYPES from xviz_avs.v2.core_pb2 import UIPrimitiveState from xviz_avs.v2.uiprimitives_pb2 import TreeTableNode, TreeTableColumn class XVIZTreeTableRowBuilder: - def __init__(self, id_, values, parent=None): + def __init__(self, id_: int, values: Union[int, float, str, bool], parent: int = None): self._node = TreeTableNode(id=id_) if parent: self._node.parent = parent self._node.column_values.extend([str(v) for v in values]) self._children = [] - def child(self, id_, values): + def child(self, id_: str, values: Union[int, float, str, bool]) -> 'XVIZTreeTableRowBuilder': row = XVIZTreeTableRowBuilder(id_, values, self._node.id) self._children.append(row) return row - def get_data(self): + def get_data(self) -> list: return [self._node] + [node for child in self._children for node in child.get_data()] class XVIZUIPrimitiveBuilder(XVIZBaseBuilder): - def __init__(self, metadata, logger=None): - super().__init__(CATEGORY.PRIMITIVE, metadata, logger) + def __init__(self, metadata): + super().__init__(CATEGORY.PRIMITIVE, metadata) self.reset() self._primitives = {} @@ -33,7 +35,7 @@ def reset(self): self._columns = None self._rows = [] - def treetable(self, columns): + def treetable(self, columns: Iterable[dict]): if self._type: self._flush() @@ -44,7 +46,7 @@ def treetable(self, columns): return self - def row(self, id_, values): + def row(self, id_: int, values: Union[int, float, str, bool]) -> XVIZTreeTableRowBuilder: self._validate_prop_set_once('_id') row = XVIZTreeTableRowBuilder(id_, values) @@ -57,14 +59,10 @@ def _flush(self): self._validate() self._flush_primitive() - def get_data(self): + def get_data(self) -> Dict[str, UIPrimitiveState]: if self._type: self._flush() - - if self._primitives: - return self._primitives - - return None + return self._primitives def _flush_primitive(self): if self._type == UIPRIMITIVE_TYPES.TREETABLE: diff --git a/python/xviz_avs/builder/variable.py b/python/xviz_avs/builder/variable.py index db251a664..71a2c9c79 100644 --- a/python/xviz_avs/builder/variable.py +++ b/python/xviz_avs/builder/variable.py @@ -1,10 +1,12 @@ +from typing import Union, Dict + from xviz_avs.builder.base_builder import XVIZBaseBuilder, CATEGORY from xviz_avs.v2.core_pb2 import VariableState class XVIZVariableBuilder(XVIZBaseBuilder): - def __init__(self, metadata, logger=None): - super().__init__(CATEGORY.VARIABLE, metadata, logger) + def __init__(self, metadata): + super().__init__(CATEGORY.VARIABLE, metadata) # Stores variable data by stream then id # They will then be group when constructing final object @@ -14,12 +16,12 @@ def __init__(self, metadata, logger=None): self._id = None self._values = None - def id(self, identifier): + def id(self, identifier: str) -> 'XVIZVariableBuilder': self._validate_prop_set_once('_id') self._id = identifier return self - def values(self, values): + def values(self, values: Union[int, float, str, bool]) -> 'XVIZVariableBuilder': self._validate_prop_set_once('_values') if not isinstance(values, (list, tuple)): self._logger.error("Input `values` must be array") @@ -27,7 +29,7 @@ def values(self, values): self._values = values return self - def get_data(self): + def get_data(self) -> Dict[str, VariableState]: self._flush() if not self._data: return None @@ -48,9 +50,7 @@ def _add_variable_entry(self): if self._id: for entry in stream_entry.variables: if entry.base.object_id == self._id: - # TODO validate error, which should throw self._logger.error("Input `values` already set for id %s" % self._id) - raise Exception('id values already set') var_entry = stream_entry.variables.add() value = self._values[0] diff --git a/python/xviz_avs/builder/xviz_builder.py b/python/xviz_avs/builder/xviz_builder.py index 676cb6754..660eea24e 100644 --- a/python/xviz_avs/builder/xviz_builder.py +++ b/python/xviz_avs/builder/xviz_builder.py @@ -1,4 +1,5 @@ import logging +from typing import List from easydict import EasyDict as edict from xviz_avs.message import XVIZFrame, XVIZMessage @@ -18,75 +19,87 @@ PRIMARY_POSE_STREAM = '/vehicle_pose' class XVIZBuilder: - def __init__(self, metadata=None, disable_streams=None, - logger=logging.getLogger("xviz")): + """ + # Reference + [@xviz/builder/xviz-builder]/(https://github.com/uber/xviz/blob/master/modules/builder/src/builders/xviz-builder.js) + """ + def __init__(self, metadata: XVIZMessage = None, disable_streams: List[str] = None, + logger: logging.Logger = logging.getLogger("xviz"), + update_type: StateUpdate.UpdateType = StateUpdate.UpdateType.INCREMENTAL): self._logger = logger self._metadata = metadata self._disable_streams = disable_streams or [] self._stream_builder = None - self._update_type = StateUpdate.UpdateType.INCREMENTAL - - self._links_builder = XVIZLinkBuilder(self._metadata, self._logger) - self._pose_builder = XVIZPoseBuilder(self._metadata, self._logger) - self._variables_builder = XVIZVariableBuilder(self._metadata, self._logger) - self._primitives_builder = XVIZPrimitiveBuilder(self._metadata, self._logger) - self._future_instance_builder = XVIZFutureInstanceBuilder(self._metadata, self._logger) - self._ui_primitives_builder = XVIZUIPrimitiveBuilder(self._metadata, self._logger) - self._time_series_builder = XVIZTimeSeriesBuilder(self._metadata, self._logger) - - def pose(self, stream_id=PRIMARY_POSE_STREAM): + self._stream_buffers = {} + self._update_type = update_type + + self._links_builder = XVIZLinkBuilder(self._metadata) + self._pose_builder = XVIZPoseBuilder(self._metadata) + self._variables_builder = XVIZVariableBuilder(self._metadata) + self._primitives_builder = XVIZPrimitiveBuilder(self._metadata) + self._future_instance_builder = XVIZFutureInstanceBuilder(self._metadata) + self._ui_primitives_builder = XVIZUIPrimitiveBuilder(self._metadata) + self._time_series_builder = XVIZTimeSeriesBuilder(self._metadata) + + def pose(self, stream_id: str = PRIMARY_POSE_STREAM) -> XVIZPoseBuilder: self._stream_builder = self._pose_builder.stream(stream_id) return self._stream_builder - def variable(self, stream_id): + def variable(self, stream_id: str) -> XVIZVariableBuilder: self._stream_builder = self._variables_builder.stream(stream_id) return self._stream_builder - def primitive(self, stream_id): + def primitive(self, stream_id: str) -> XVIZPrimitiveBuilder: self._stream_builder = self._primitives_builder.stream(stream_id) return self._stream_builder - def future_instance(self, stream_id, timestamp): + def future_instance(self, stream_id: str, timestamp: float) -> XVIZFutureInstanceBuilder: self._stream_builder = self._future_instance_builder.stream(stream_id) self._stream_builder.timestamp(timestamp) return self._stream_builder - def ui_primitives(self, stream_id): + def ui_primitives(self, stream_id: str) -> XVIZUIPrimitiveBuilder: self._stream_builder = self._ui_primitives_builder.stream(stream_id) return self._stream_builder - def time_series(self, stream_id): + def time_series(self, stream_id: str) -> XVIZTimeSeriesBuilder: self._stream_builder = self._time_series_builder.stream(stream_id) return self._stream_builder - def link(self, parent, child): + def link(self, parent: str, child: str) -> XVIZLinkBuilder: self._stream_builder = self._links_builder.stream(child).parent(parent) return self._stream_builder def _reset(self): self._stream_builder = None - def get_data(self): + def _get_streamset(self): poses = self._pose_builder.get_data() if (not poses) or (PRIMARY_POSE_STREAM not in poses): self._logger.error('Every message requires a %s stream', PRIMARY_POSE_STREAM) - data = XVIZFrame(StreamSet( - timestamp=poses[PRIMARY_POSE_STREAM].timestamp, # FIXME: does timestamp have to be the same with pose? + primitive_data, primitive_buffer = self._primitives_builder.get_data() + futures_data, futures_buffer = self._future_instance_builder.get_data() + sset = StreamSet( + timestamp=poses[PRIMARY_POSE_STREAM].timestamp, # XXX: does timestamp have to be the same with pose? poses=poses, - primitives=self._primitives_builder.get_data(), - future_instances=self._future_instance_builder.get_data(), + primitives=primitive_data, + future_instances=futures_data, variables=self._variables_builder.get_data(), time_series=self._time_series_builder.get_data(), ui_primitives=self._ui_primitives_builder.get_data(), links=self._links_builder.get_data() - )) + ) + self._stream_buffers.update(primitive_buffer) + self._stream_buffers.update(futures_buffer) + return sset - return data + def get_data(self) -> XVIZFrame: + return XVIZFrame(self._get_streamset(), self._stream_buffers) - def get_message(self): + def get_message(self) -> XVIZMessage: message = XVIZMessage(StateUpdate( update_type=self._update_type, - updates=[self.get_data().data] - )) + updates=[self._get_streamset()], + ), buffers=[self._stream_buffers]) return message diff --git a/python/xviz_avs/io/base.py b/python/xviz_avs/io/base.py index 5aeee3ad8..d9c19f6bd 100644 --- a/python/xviz_avs/io/base.py +++ b/python/xviz_avs/io/base.py @@ -17,7 +17,7 @@ def __init__(self, source: BaseSource): self._counter = 2 def _get_sequential_name(self, message: XVIZMessage, index=None): - raw_data = message.data + raw_data = message._data if isinstance(raw_data, Metadata): self._save_timestamp(raw_data) fname = "1-frame" diff --git a/python/xviz_avs/io/gltf.py b/python/xviz_avs/io/gltf.py index 7a24c26b3..4c54e0089 100644 --- a/python/xviz_avs/io/gltf.py +++ b/python/xviz_avs/io/gltf.py @@ -2,14 +2,20 @@ This module provides basic io under GLTF format """ +import array +import base64 +import json import logging -import json, array, struct, base64 -from typing import Union +import mimetypes +import struct +from io import BytesIO from collections import namedtuple -from easydict import EasyDict as edict +from typing import Union +import numpy as np +from easydict import EasyDict as edict from xviz_avs.io.base import XVIZBaseWriter -from xviz_avs.message import XVIZMessage, XVIZEnvelope, StateUpdate +from xviz_avs.message import StateUpdate, XVIZEnvelope, XVIZMessage # Constants @@ -32,12 +38,12 @@ def pad_to_4bytes(length): return (length + 3) & ~3 # Wrappers -class ImageWrapper: - def __init__(self, image: bytes, width: int = None, height: int = None, mime_type: str = None): - self.data = image - self.mime_type = mime_type - self.width = width - self.height = height +ImageWrapper = namedtuple("TypedArray", ( + "data", # bytes + "width", + "height", + "mime_type" +)) TypedArrayWrapper = namedtuple("TypedArray", ( "array", # flattened array @@ -116,7 +122,7 @@ def add_buffer_view(self, buffer: bytes): return len(self._json.bufferViews) - 1 - def add_buffer(self, buffer: Union[array.array, bytes], size: int = 3): + def add_buffer(self, buffer: Union[np.ndarray, array.array, bytes], size: int = 3): ''' Add a binary buffer. Builds glTF "JSON metadata" and saves buffer reference. Buffer will be copied into BIN chunk during "pack". @@ -128,6 +134,12 @@ def add_buffer(self, buffer: Union[array.array, bytes], size: int = 3): :param count: XXX :return: accessor_index: Index of added buffer in "accessors" list ''' + if isinstance(buffer, np.ndarray): + buffer_view_index = self.add_buffer_view(buffer.tobytes()) + return self.add_accessor( + buffer_view_index, size=size, + component_type=component_type_d[buffer.dtype.char], count=len(buffer.reshape(-1, size))) + if isinstance(buffer, array.array): buffer_view_index = self.add_buffer_view(buffer.tobytes()) return self.add_accessor( @@ -263,26 +275,27 @@ def add_compressed_point_cloud(self, attributes): raise NotImplementedError() class XVIZGLBWriter(XVIZBaseWriter): - def __init__(self, sink, wrap_envelope=True, use_xviz_extension=True): + def __init__(self, sink, wrap_envelope=True, use_xviz_extension=True, image_encoding='PNG'): # TODO: also support precision limit in GLTF Json super().__init__(sink) self._use_xviz_extension = use_xviz_extension self._wrap_envelop = wrap_envelope self._counter = 2 + self._image_encoding = image_encoding def write_message(self, message: XVIZMessage, index: int = None): self._check_valid() if self._wrap_envelop: - obj = XVIZEnvelope(message).to_object() + obj = XVIZEnvelope(message).to_object(unravel='partial') else: - obj = message.to_object() + obj = message.to_object(unravel='partial') builder = GLTFBuilder() fname = self._get_sequential_name(message, index) + '.glb' - if isinstance(message.data, StateUpdate): + if isinstance(message._data, StateUpdate): # Wrap image data and point cloud if self._wrap_envelop: dataobjs = obj['data']['updates'] @@ -298,13 +311,10 @@ def write_message(self, message: XVIZMessage, index: int = None): num_points = None if 'points' in pldata: num_points = len(pldata['points']) // 3 - pldata['points'] = TypedArrayWrapper( - array=array.array('f', pldata['points']), - size=3, - ) + pldata['points'] = TypedArrayWrapper(array=pldata['points'], size=3) if 'colors' in pldata: # infer size from num_points - assert num_points is not None + assert num_points is not None, "No points are provided in the stream" color_bytes = bytes(pldata['colors']) size = len(color_bytes) // num_points assert size in (3, 4), 'expecting size to be 3 or 4, got %s' % size @@ -330,11 +340,16 @@ def write_message(self, message: XVIZMessage, index: int = None): # process images if 'images' in pdata: for imdata in pdata['images']: + image = imdata['data'] + data = BytesIO() + image.save(data, format=self._image_encoding) + mime = mimetypes.types_map['.' + self._image_encoding.lower()] + imdata['data'] = ImageWrapper( - image=base64.b64decode(imdata['data']), - width=imdata['width_px'], - height=imdata['height_px'], - mime_type='image/png', # FIXME: use Pillow to detect type + data=data.getvalue(), + width=image.width, + height=image.height, + mime_type=mime ) # Encode GLB into file diff --git a/python/xviz_avs/io/protobuf.py b/python/xviz_avs/io/protobuf.py index 25d044891..19893ebb6 100644 --- a/python/xviz_avs/io/protobuf.py +++ b/python/xviz_avs/io/protobuf.py @@ -12,9 +12,9 @@ def __init__(self, sink, wrap_envelope=True): def write_message(self, message: XVIZMessage, index: int = None): self._check_valid() if self._wrap_envelop: - obj = XVIZEnvelope(message).data + obj = XVIZEnvelope(message).to_proto() else: - obj = message.data + obj = message.to_proto() data = BytesIO() # write PBE1 header diff --git a/python/xviz_avs/io/sources.py b/python/xviz_avs/io/sources.py index 160dc6d8d..babdbe703 100644 --- a/python/xviz_avs/io/sources.py +++ b/python/xviz_avs/io/sources.py @@ -2,9 +2,11 @@ This module contains `sources` that can read and write data from certain source by key-value strategy. Here the source is the combine definition of `source` and `sink` as from xviz JS library. ''' -import os import io +import os from collections import defaultdict +from pathlib import Path + class BaseSource: def __init__(self): @@ -21,23 +23,24 @@ def write(self, data, name): class DirectorySource: def __init__(self, directory): - self._dir = directory - assert os.path.isdir(self._dir) + self._dir = Path(directory) + if self._dir.exists(): + assert self._dir.is_dir() + else: + self._dir.mkdir(parents=True) def open(self, name, mode='r'): - fpath = os.path.join(self._dir, name) + fpath = self._dir / name if mode == 'r': - return open(fpath, 'rb') + return fpath.open('rb') elif mode == 'w': - return open(fpath, 'wb') + return fpath.open('wb') def read(self, name): - with open(os.path.join(self._dir, name), 'rb') as fin: - return fin.read() + return (self._dir / name).read_bytes() def write(self, data, name): - with open(os.path.join(self._dir, name), 'wb') as fout: - fout.write(data) + (self._dir / name).write_bytes(data) def close(self): pass diff --git a/python/xviz_avs/message.py b/python/xviz_avs/message.py index 860fca4ba..09ae41239 100644 --- a/python/xviz_avs/message.py +++ b/python/xviz_avs/message.py @@ -1,20 +1,15 @@ import base64 -from typing import Union, Dict, List +from PIL import Image as pImage +from io import BytesIO +from typing import Dict, List, Union -from xviz_avs.v2.core_pb2 import StreamSet -from xviz_avs.v2.session_pb2 import StateUpdate, Metadata -from xviz_avs.v2.options_pb2 import xviz_json_schema -from xviz_avs.v2.envelope_pb2 import Envelope from google.protobuf.json_format import MessageToDict -def _unravel_list(list_: list, width: int) -> List[list]: # XXX: This is actually not used - if len(list_) % width != 0: - raise ValueError("The shape of the list is incorrect!") +from xviz_avs.v2.core_pb2 import StreamSet +from xviz_avs.v2.envelope_pb2 import Envelope +from xviz_avs.v2.options_pb2 import xviz_json_schema +from xviz_avs.v2.session_pb2 import Metadata, StateUpdate - new_list = [] - for i in range(len(list_) // width): - new_list.append(list_[i*width:(i+1)*width]) - return new_list def _unravel_style_object(style: dict): # TODO: support `#FFFFFFFF` style packing @@ -27,48 +22,115 @@ class XVIZFrame: ''' This class is basically a wrapper around protobuf message `StreamSet`. It represent a frame of update. ''' - def __init__(self, data: StreamSet = None): + def __init__(self, data: StreamSet = None, buffers: dict = {}): if data and not isinstance(data, StreamSet): raise ValueError("The data input must be structured (using StreamSet class)") - self._data = data + self._data = data or StreamSet() + self._buffers = buffers + + def _pack_image(self, image: pImage.Image): + ''' + Pack image data into bytes + ''' + data = BytesIO() + image.save(data, format="PNG") # compress to PNG format by default + return data.getvalue() - def to_object(self, unravel: bool = True) -> Dict: + def to_object(self, unravel: str = 'full') -> Dict: ''' Serialize this data to primitive objects (with dict and list). Flattened arrays will be restored in this process. + + :param unravel: convert packed binary data to readable objects + none: do not unravel + partial: only unravel small binary data + full: unravel all binary data ''' + assert unravel in ['none', 'partial', 'full'] dataobj = MessageToDict(self._data, preserving_proto_field_name=True) - if not unravel: + + if unravel is 'none': return dataobj if 'primitives' in dataobj: - for pdata in dataobj['primitives'].values(): - # process colors + for stream_id, pdata in dataobj['primitives'].items(): + # process point array and colors if 'points' in pdata: - for pldata in pdata['points']: + for pldata, buffer in zip(pdata['points'], self._buffers[stream_id]): + pldata['points'] = buffer.tolist() if unravel is 'full' else buffer if 'colors' in pldata: pldata['colors'] = list(base64.b64decode(pldata['colors'])) + # process images + if 'images' in pdata: + for pldata, buffer in zip(pdata['images'], self._buffers[stream_id]): + pldata['data'] = self._pack_image(buffer) if unravel is 'full' else buffer + # process styles for pcats in pdata.values(): for pldata in pcats: - if 'base' in pldata and 'style' in pldata['base']: + if isinstance(pldata, dict) and 'base' in pldata and 'style' in pldata['base']: _unravel_style_object(pldata['base']['style']) - + + if 'future_instances' in dataobj: + for stream_id, pdata in dataobj['future_instances'].items(): + for fts, fdata in zip(pdata['timestamps'], pdata['primitives']): + # process point array and colors + if 'points' in fdata: + for pldata, buffer in zip(fdata['points'], self._buffers[(stream_id, fts)]): + pldata['points'] = buffer.tolist() if unravel is 'full' else buffer + if 'colors' in pldata: + pldata['colors'] = list(base64.b64decode(pldata['colors'])) + + # process images + if 'images' in pdata: + for pldata, buffer in zip(pdata['images'], self._buffers[(stream_id, fts)]): + pldata['data'] = self._pack_image(buffer) if unravel is 'full' else buffer + + # process styles + for pcats in fdata.values(): + for pldata in pcats: + if isinstance(pldata, dict) and 'base' in pldata and 'style' in pldata['base']: + _unravel_style_object(pldata['base']['style']) + return dataobj - @property - def data(self) -> StreamSet: - return self._data + def to_proto(self) -> StreamSet: + # apply buffer to proper location, this could take some time + data = StreamSet() + data.CopyFrom(self._data) + + # flush primitives data + for stream_id, pdata in data.primitives.items(): + if len(pdata.points) > 0: + for ptdata, ptbuffer in zip(pdata.points, self._buffers[stream_id]): + ptdata.points = ptbuffer.tolist() + if len(pdata.images) > 0: + for ptdata, ptbuffer in zip(pdata.images, self._buffers[stream_id]): + ptdata.data = self._pack_image(ptbuffer) + + # flush future primitives data + for stream_id, pdata in data.future_instances.items(): + for fts, fdata in zip(pdata.timestamps, pdata.primitives): + if len(fdata.points) > 0: + for ptdata, ptbuffer in zip(fdata.points, self._buffers[(stream_id, fts)]): + ptdata.points = ptbuffer.tolist() + if len(fdata.images) > 0: + for ptdata, ptbuffer in zip(fdata.images, self._buffers[(stream_id, fts)]): + ptdata.data = self._pack_image(ptbuffer) + + return data AllDataType = Union[StateUpdate, Metadata] class XVIZMessage: def __init__(self, update: StateUpdate = None, - metadata: Metadata = None + metadata: Metadata = None, + buffers: dict = {} ): self._data = None + self._buffers = buffers if update: if not isinstance(update, StateUpdate): @@ -87,18 +149,28 @@ def __init__(self, def get_schema(self) -> str: return type(self._data).DESCRIPTOR.GetOptions().Extensions[xviz_json_schema] - @property - def data(self) -> AllDataType: - return self._data + def to_proto(self) -> AllDataType: + # apply buffer to state update message + if isinstance(self._data, StateUpdate): + data = StateUpdate() + data.update_type = self._data.update_type + for frame, buffer in zip(self._data.updates, self._buffers): + data.updates.append(XVIZFrame(frame, buffer).to_proto()) + return data + else: + return self._data - def to_object(self, unravel: bool = True) -> Dict: - if not unravel: + def to_object(self, unravel: str = 'full') -> Dict: + assert unravel in ['none', 'partial', 'full'] + + if unravel is 'none': return MessageToDict(self._data, preserving_proto_field_name=True) if isinstance(self._data, StateUpdate): return { 'update_type': StateUpdate.UpdateType.Name(self._data.update_type), - 'updates': [XVIZFrame(frame).to_object() for frame in self._data.updates] + 'updates': [XVIZFrame(frame, buffer).to_object(unravel=unravel) + for frame, buffer in zip(self._data.updates, self._buffers)] } elif isinstance(self._data, Metadata): dataobj = MessageToDict(self._data, preserving_proto_field_name=True) @@ -118,21 +190,26 @@ class XVIZEnvelope: def __init__(self, data: Union[XVIZMessage, AllDataType]): if isinstance(data, XVIZMessage): type_str = data.get_schema() - data = data.data + buffers = data._buffers + data = data._data else: type_str = XVIZMessage(data).get_schema() + buffers = {} self._type = type(data) self._data = Envelope(type=type_str.replace("session", "xviz")) - self._data.data.Pack(data) + self._raw = data # lazy packing of data to avoid performance issue + self._raw_buffers = buffers - @property - def data(self) -> Envelope: - return self._data + def to_proto(self) -> Envelope: + data = Envelope() + data.CopyFrom(self._data) + data.data.Pack(self.to_message().to_proto()) + return data - def to_object(self, unravel: bool = True) -> Dict: - if not unravel: - return MessageToDict(self._data, preserving_proto_field_name=True) + def to_object(self, unravel: str = 'full') -> Dict: + if unravel is 'none': + return MessageToDict(self.to_proto(), preserving_proto_field_name=True) return { "type": self._data.type, @@ -141,12 +218,8 @@ def to_object(self, unravel: bool = True) -> Dict: def to_message(self) -> XVIZMessage: if self._data.type == "xviz/metadata": - udata = Metadata() - self._data.data.Unpack(udata) - return XVIZMessage(metadata=udata) + return XVIZMessage(metadata=self._raw, buffers=self._raw_buffers) elif self._data.type == "xviz/state_update": - udata = StateUpdate() - self._data.data.Unpack(udata) - return XVIZMessage(update=udata) + return XVIZMessage(update=self._raw, buffers=self._raw_buffers) else: raise ValueError("Unrecognized envelope data") diff --git a/python/xviz_avs/v2/README.md b/python/xviz_avs/v2/README.md index 296c0722e..e8a75634d 100644 --- a/python/xviz_avs/v2/README.md +++ b/python/xviz_avs/v2/README.md @@ -1,4 +1,3 @@ This folder is generated from protobuf definitions obtained from [xviz@9cb3c30](https://github.com/uber/xviz/tree/v1.0.1/xviz/v2). -TODO: Wait protobuf to be fixed -To build the definitions you need to download `protoc` compiler with version greater than `v3.3.0`. Then execute `protoc -I= --python_out= /xviz/v2/*.proto` to generated python bindings +To build the definitions you need to download `protoc` compiler with version greater than `v3.3.0` and (pip) install `mypy-protobuf` to generate type hints for protocols. Then execute `protoc -I= --python_out= --mypy_out= /xviz/v2/*.proto` to generated python bindings diff --git a/python/xviz_avs/v2/annotation_pb2.pyi b/python/xviz_avs/v2/annotation_pb2.pyi new file mode 100644 index 000000000..c2da8f30f --- /dev/null +++ b/python/xviz_avs/v2/annotation_pb2.pyi @@ -0,0 +1,68 @@ +# @generated by generate_proto_mypy_stubs.py. Do not edit! +import sys +from google.protobuf.descriptor import ( + Descriptor as google___protobuf___descriptor___Descriptor, + FileDescriptor as google___protobuf___descriptor___FileDescriptor, +) + +from google.protobuf.internal.containers import ( + RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, +) + +from google.protobuf.message import ( + Message as google___protobuf___message___Message, +) + +from typing import ( + Iterable as typing___Iterable, + Optional as typing___Optional, + Text as typing___Text, +) + +from typing_extensions import ( + Literal as typing_extensions___Literal, +) + +from xviz.v2.style_pb2 import ( + StyleObjectValue as xviz___v2___style_pb2___StyleObjectValue, +) + + +builtin___bool = bool +builtin___bytes = bytes +builtin___float = float +builtin___int = int + + +DESCRIPTOR: google___protobuf___descriptor___FileDescriptor = ... + +class VisualBase(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + object_id: typing___Text = ... + + def __init__(self, + *, + object_id : typing___Optional[typing___Text] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"object_id",b"object_id"]) -> None: ... +type___VisualBase = VisualBase + +class Visual(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + style_classes: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... + + @property + def base(self) -> type___VisualBase: ... + + @property + def inline_style(self) -> xviz___v2___style_pb2___StyleObjectValue: ... + + def __init__(self, + *, + base : typing___Optional[type___VisualBase] = None, + style_classes : typing___Optional[typing___Iterable[typing___Text]] = None, + inline_style : typing___Optional[xviz___v2___style_pb2___StyleObjectValue] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"base",b"base",u"inline_style",b"inline_style"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"base",b"base",u"inline_style",b"inline_style",u"style_classes",b"style_classes"]) -> None: ... +type___Visual = Visual diff --git a/python/xviz_avs/v2/core_pb2.pyi b/python/xviz_avs/v2/core_pb2.pyi new file mode 100644 index 000000000..0e496eda6 --- /dev/null +++ b/python/xviz_avs/v2/core_pb2.pyi @@ -0,0 +1,415 @@ +# @generated by generate_proto_mypy_stubs.py. Do not edit! +import sys +from google.protobuf.descriptor import ( + Descriptor as google___protobuf___descriptor___Descriptor, + FileDescriptor as google___protobuf___descriptor___FileDescriptor, +) + +from google.protobuf.internal.containers import ( + RepeatedCompositeFieldContainer as google___protobuf___internal___containers___RepeatedCompositeFieldContainer, + RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, +) + +from google.protobuf.message import ( + Message as google___protobuf___message___Message, +) + +from typing import ( + Iterable as typing___Iterable, + Mapping as typing___Mapping, + MutableMapping as typing___MutableMapping, + Optional as typing___Optional, + Text as typing___Text, +) + +from typing_extensions import ( + Literal as typing_extensions___Literal, +) + +from xviz.v2.annotation_pb2 import ( + Visual as xviz___v2___annotation_pb2___Visual, +) + +from xviz.v2.primitives_pb2 import ( + Circle as xviz___v2___primitives_pb2___Circle, + Image as xviz___v2___primitives_pb2___Image, + Point as xviz___v2___primitives_pb2___Point, + Polygon as xviz___v2___primitives_pb2___Polygon, + Polyline as xviz___v2___primitives_pb2___Polyline, + Stadium as xviz___v2___primitives_pb2___Stadium, + Text as xviz___v2___primitives_pb2___Text, +) + +from xviz.v2.uiprimitives_pb2 import ( + TreeTable as xviz___v2___uiprimitives_pb2___TreeTable, +) + + +builtin___bool = bool +builtin___bytes = bytes +builtin___float = float +builtin___int = int + + +DESCRIPTOR: google___protobuf___descriptor___FileDescriptor = ... + +class StreamSet(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + class PosesEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + + @property + def value(self) -> type___Pose: ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[type___Pose] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___PosesEntry = PosesEntry + + class PrimitivesEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + + @property + def value(self) -> type___PrimitiveState: ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[type___PrimitiveState] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___PrimitivesEntry = PrimitivesEntry + + class FutureInstancesEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + + @property + def value(self) -> type___FutureInstances: ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[type___FutureInstances] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___FutureInstancesEntry = FutureInstancesEntry + + class VariablesEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + + @property + def value(self) -> type___VariableState: ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[type___VariableState] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___VariablesEntry = VariablesEntry + + class AnnotationsEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + + @property + def value(self) -> type___AnnotationState: ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[type___AnnotationState] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___AnnotationsEntry = AnnotationsEntry + + class UiPrimitivesEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + + @property + def value(self) -> type___UIPrimitiveState: ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[type___UIPrimitiveState] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___UiPrimitivesEntry = UiPrimitivesEntry + + class LinksEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + + @property + def value(self) -> type___Link: ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[type___Link] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___LinksEntry = LinksEntry + + timestamp: builtin___float = ... + no_data_streams: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... + + @property + def poses(self) -> typing___MutableMapping[typing___Text, type___Pose]: ... + + @property + def primitives(self) -> typing___MutableMapping[typing___Text, type___PrimitiveState]: ... + + @property + def time_series(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___TimeSeriesState]: ... + + @property + def future_instances(self) -> typing___MutableMapping[typing___Text, type___FutureInstances]: ... + + @property + def variables(self) -> typing___MutableMapping[typing___Text, type___VariableState]: ... + + @property + def annotations(self) -> typing___MutableMapping[typing___Text, type___AnnotationState]: ... + + @property + def ui_primitives(self) -> typing___MutableMapping[typing___Text, type___UIPrimitiveState]: ... + + @property + def links(self) -> typing___MutableMapping[typing___Text, type___Link]: ... + + def __init__(self, + *, + timestamp : typing___Optional[builtin___float] = None, + poses : typing___Optional[typing___Mapping[typing___Text, type___Pose]] = None, + primitives : typing___Optional[typing___Mapping[typing___Text, type___PrimitiveState]] = None, + time_series : typing___Optional[typing___Iterable[type___TimeSeriesState]] = None, + future_instances : typing___Optional[typing___Mapping[typing___Text, type___FutureInstances]] = None, + variables : typing___Optional[typing___Mapping[typing___Text, type___VariableState]] = None, + annotations : typing___Optional[typing___Mapping[typing___Text, type___AnnotationState]] = None, + ui_primitives : typing___Optional[typing___Mapping[typing___Text, type___UIPrimitiveState]] = None, + no_data_streams : typing___Optional[typing___Iterable[typing___Text]] = None, + links : typing___Optional[typing___Mapping[typing___Text, type___Link]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"annotations",b"annotations",u"future_instances",b"future_instances",u"links",b"links",u"no_data_streams",b"no_data_streams",u"poses",b"poses",u"primitives",b"primitives",u"time_series",b"time_series",u"timestamp",b"timestamp",u"ui_primitives",b"ui_primitives",u"variables",b"variables"]) -> None: ... +type___StreamSet = StreamSet + +class Pose(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + timestamp: builtin___float = ... + position: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + orientation: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + + @property + def map_origin(self) -> type___MapOrigin: ... + + def __init__(self, + *, + timestamp : typing___Optional[builtin___float] = None, + map_origin : typing___Optional[type___MapOrigin] = None, + position : typing___Optional[typing___Iterable[builtin___float]] = None, + orientation : typing___Optional[typing___Iterable[builtin___float]] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"map_origin",b"map_origin"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"map_origin",b"map_origin",u"orientation",b"orientation",u"position",b"position",u"timestamp",b"timestamp"]) -> None: ... +type___Pose = Pose + +class MapOrigin(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + longitude: builtin___float = ... + latitude: builtin___float = ... + altitude: builtin___float = ... + + def __init__(self, + *, + longitude : typing___Optional[builtin___float] = None, + latitude : typing___Optional[builtin___float] = None, + altitude : typing___Optional[builtin___float] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"altitude",b"altitude",u"latitude",b"latitude",u"longitude",b"longitude"]) -> None: ... +type___MapOrigin = MapOrigin + +class PrimitiveState(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + + @property + def polygons(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[xviz___v2___primitives_pb2___Polygon]: ... + + @property + def polylines(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[xviz___v2___primitives_pb2___Polyline]: ... + + @property + def texts(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[xviz___v2___primitives_pb2___Text]: ... + + @property + def circles(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[xviz___v2___primitives_pb2___Circle]: ... + + @property + def points(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[xviz___v2___primitives_pb2___Point]: ... + + @property + def stadiums(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[xviz___v2___primitives_pb2___Stadium]: ... + + @property + def images(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[xviz___v2___primitives_pb2___Image]: ... + + def __init__(self, + *, + polygons : typing___Optional[typing___Iterable[xviz___v2___primitives_pb2___Polygon]] = None, + polylines : typing___Optional[typing___Iterable[xviz___v2___primitives_pb2___Polyline]] = None, + texts : typing___Optional[typing___Iterable[xviz___v2___primitives_pb2___Text]] = None, + circles : typing___Optional[typing___Iterable[xviz___v2___primitives_pb2___Circle]] = None, + points : typing___Optional[typing___Iterable[xviz___v2___primitives_pb2___Point]] = None, + stadiums : typing___Optional[typing___Iterable[xviz___v2___primitives_pb2___Stadium]] = None, + images : typing___Optional[typing___Iterable[xviz___v2___primitives_pb2___Image]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"circles",b"circles",u"images",b"images",u"points",b"points",u"polygons",b"polygons",u"polylines",b"polylines",u"stadiums",b"stadiums",u"texts",b"texts"]) -> None: ... +type___PrimitiveState = PrimitiveState + +class UIPrimitiveState(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + + @property + def treetable(self) -> xviz___v2___uiprimitives_pb2___TreeTable: ... + + def __init__(self, + *, + treetable : typing___Optional[xviz___v2___uiprimitives_pb2___TreeTable] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"treetable",b"treetable"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"treetable",b"treetable"]) -> None: ... +type___UIPrimitiveState = UIPrimitiveState + +class TimeSeriesState(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + timestamp: builtin___float = ... + object_id: typing___Text = ... + streams: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... + + @property + def values(self) -> type___Values: ... + + def __init__(self, + *, + timestamp : typing___Optional[builtin___float] = None, + object_id : typing___Optional[typing___Text] = None, + streams : typing___Optional[typing___Iterable[typing___Text]] = None, + values : typing___Optional[type___Values] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"values",b"values"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"object_id",b"object_id",u"streams",b"streams",u"timestamp",b"timestamp",u"values",b"values"]) -> None: ... +type___TimeSeriesState = TimeSeriesState + +class FutureInstances(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + timestamps: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + + @property + def primitives(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___PrimitiveState]: ... + + def __init__(self, + *, + timestamps : typing___Optional[typing___Iterable[builtin___float]] = None, + primitives : typing___Optional[typing___Iterable[type___PrimitiveState]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"primitives",b"primitives",u"timestamps",b"timestamps"]) -> None: ... +type___FutureInstances = FutureInstances + +class VariableState(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + + @property + def variables(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___Variable]: ... + + def __init__(self, + *, + variables : typing___Optional[typing___Iterable[type___Variable]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"variables",b"variables"]) -> None: ... +type___VariableState = VariableState + +class AnnotationState(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + + @property + def visuals(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[xviz___v2___annotation_pb2___Visual]: ... + + def __init__(self, + *, + visuals : typing___Optional[typing___Iterable[xviz___v2___annotation_pb2___Visual]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"visuals",b"visuals"]) -> None: ... +type___AnnotationState = AnnotationState + +class Variable(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + + @property + def base(self) -> type___VariableBase: ... + + @property + def values(self) -> type___Values: ... + + def __init__(self, + *, + base : typing___Optional[type___VariableBase] = None, + values : typing___Optional[type___Values] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"base",b"base",u"values",b"values"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"base",b"base",u"values",b"values"]) -> None: ... +type___Variable = Variable + +class VariableBase(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + object_id: typing___Text = ... + + def __init__(self, + *, + object_id : typing___Optional[typing___Text] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"object_id",b"object_id"]) -> None: ... +type___VariableBase = VariableBase + +class Values(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + doubles: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + int32s: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___int] = ... + bools: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___bool] = ... + strings: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... + + def __init__(self, + *, + doubles : typing___Optional[typing___Iterable[builtin___float]] = None, + int32s : typing___Optional[typing___Iterable[builtin___int]] = None, + bools : typing___Optional[typing___Iterable[builtin___bool]] = None, + strings : typing___Optional[typing___Iterable[typing___Text]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"bools",b"bools",u"doubles",b"doubles",u"int32s",b"int32s",u"strings",b"strings"]) -> None: ... +type___Values = Values + +class Link(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + target_pose: typing___Text = ... + + def __init__(self, + *, + target_pose : typing___Optional[typing___Text] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"target_pose",b"target_pose"]) -> None: ... +type___Link = Link diff --git a/python/xviz_avs/v2/envelope_pb2.pyi b/python/xviz_avs/v2/envelope_pb2.pyi new file mode 100644 index 000000000..46b9c4202 --- /dev/null +++ b/python/xviz_avs/v2/envelope_pb2.pyi @@ -0,0 +1,48 @@ +# @generated by generate_proto_mypy_stubs.py. Do not edit! +import sys +from google.protobuf.any_pb2 import ( + Any as google___protobuf___any_pb2___Any, +) + +from google.protobuf.descriptor import ( + Descriptor as google___protobuf___descriptor___Descriptor, + FileDescriptor as google___protobuf___descriptor___FileDescriptor, +) + +from google.protobuf.message import ( + Message as google___protobuf___message___Message, +) + +from typing import ( + Optional as typing___Optional, + Text as typing___Text, +) + +from typing_extensions import ( + Literal as typing_extensions___Literal, +) + + +builtin___bool = bool +builtin___bytes = bytes +builtin___float = float +builtin___int = int + + +DESCRIPTOR: google___protobuf___descriptor___FileDescriptor = ... + +class Envelope(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + type: typing___Text = ... + + @property + def data(self) -> google___protobuf___any_pb2___Any: ... + + def __init__(self, + *, + type : typing___Optional[typing___Text] = None, + data : typing___Optional[google___protobuf___any_pb2___Any] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"data",b"data"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"data",b"data",u"type",b"type"]) -> None: ... +type___Envelope = Envelope diff --git a/python/xviz_avs/v2/options_pb2.pyi b/python/xviz_avs/v2/options_pb2.pyi new file mode 100644 index 000000000..fe2da1ded --- /dev/null +++ b/python/xviz_avs/v2/options_pb2.pyi @@ -0,0 +1,15 @@ +# @generated by generate_proto_mypy_stubs.py. Do not edit! +import sys +from google.protobuf.descriptor import ( + FieldDescriptor as google___protobuf___descriptor___FieldDescriptor, + FileDescriptor as google___protobuf___descriptor___FileDescriptor, +) + +from google.protobuf.message import ( + Message as google___protobuf___message___Message, +) + + +DESCRIPTOR: google___protobuf___descriptor___FileDescriptor = ... + +xviz_json_schema: google___protobuf___descriptor___FieldDescriptor = ... diff --git a/python/xviz_avs/v2/primitives_pb2.pyi b/python/xviz_avs/v2/primitives_pb2.pyi new file mode 100644 index 000000000..469dbddd6 --- /dev/null +++ b/python/xviz_avs/v2/primitives_pb2.pyi @@ -0,0 +1,185 @@ +# @generated by generate_proto_mypy_stubs.py. Do not edit! +import sys +from google.protobuf.descriptor import ( + Descriptor as google___protobuf___descriptor___Descriptor, + FileDescriptor as google___protobuf___descriptor___FileDescriptor, +) + +from google.protobuf.internal.containers import ( + RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, +) + +from google.protobuf.message import ( + Message as google___protobuf___message___Message, +) + +from typing import ( + Iterable as typing___Iterable, + Optional as typing___Optional, + Text as typing___Text, +) + +from typing_extensions import ( + Literal as typing_extensions___Literal, +) + +from xviz.v2.style_pb2 import ( + StyleObjectValue as xviz___v2___style_pb2___StyleObjectValue, +) + + +builtin___bool = bool +builtin___bytes = bytes +builtin___float = float +builtin___int = int + + +DESCRIPTOR: google___protobuf___descriptor___FileDescriptor = ... + +class PrimitiveBase(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + object_id: typing___Text = ... + classes: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... + + @property + def style(self) -> xviz___v2___style_pb2___StyleObjectValue: ... + + def __init__(self, + *, + object_id : typing___Optional[typing___Text] = None, + classes : typing___Optional[typing___Iterable[typing___Text]] = None, + style : typing___Optional[xviz___v2___style_pb2___StyleObjectValue] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"style",b"style"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"classes",b"classes",u"object_id",b"object_id",u"style",b"style"]) -> None: ... +type___PrimitiveBase = PrimitiveBase + +class Circle(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + center: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + radius: builtin___float = ... + + @property + def base(self) -> type___PrimitiveBase: ... + + def __init__(self, + *, + base : typing___Optional[type___PrimitiveBase] = None, + center : typing___Optional[typing___Iterable[builtin___float]] = None, + radius : typing___Optional[builtin___float] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"base",b"base"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"base",b"base",u"center",b"center",u"radius",b"radius"]) -> None: ... +type___Circle = Circle + +class Image(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + position: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + data: builtin___bytes = ... + width_px: builtin___int = ... + height_px: builtin___int = ... + + @property + def base(self) -> type___PrimitiveBase: ... + + def __init__(self, + *, + base : typing___Optional[type___PrimitiveBase] = None, + position : typing___Optional[typing___Iterable[builtin___float]] = None, + data : typing___Optional[builtin___bytes] = None, + width_px : typing___Optional[builtin___int] = None, + height_px : typing___Optional[builtin___int] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"base",b"base"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"base",b"base",u"data",b"data",u"height_px",b"height_px",u"position",b"position",u"width_px",b"width_px"]) -> None: ... +type___Image = Image + +class Point(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + points: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + colors: builtin___bytes = ... + + @property + def base(self) -> type___PrimitiveBase: ... + + def __init__(self, + *, + base : typing___Optional[type___PrimitiveBase] = None, + points : typing___Optional[typing___Iterable[builtin___float]] = None, + colors : typing___Optional[builtin___bytes] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"base",b"base"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"base",b"base",u"colors",b"colors",u"points",b"points"]) -> None: ... +type___Point = Point + +class Polygon(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + vertices: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + + @property + def base(self) -> type___PrimitiveBase: ... + + def __init__(self, + *, + base : typing___Optional[type___PrimitiveBase] = None, + vertices : typing___Optional[typing___Iterable[builtin___float]] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"base",b"base"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"base",b"base",u"vertices",b"vertices"]) -> None: ... +type___Polygon = Polygon + +class Polyline(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + vertices: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + colors: builtin___bytes = ... + + @property + def base(self) -> type___PrimitiveBase: ... + + def __init__(self, + *, + base : typing___Optional[type___PrimitiveBase] = None, + vertices : typing___Optional[typing___Iterable[builtin___float]] = None, + colors : typing___Optional[builtin___bytes] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"base",b"base"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"base",b"base",u"colors",b"colors",u"vertices",b"vertices"]) -> None: ... +type___Polyline = Polyline + +class Stadium(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + start: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + end: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + radius: builtin___float = ... + + @property + def base(self) -> type___PrimitiveBase: ... + + def __init__(self, + *, + base : typing___Optional[type___PrimitiveBase] = None, + start : typing___Optional[typing___Iterable[builtin___float]] = None, + end : typing___Optional[typing___Iterable[builtin___float]] = None, + radius : typing___Optional[builtin___float] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"base",b"base"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"base",b"base",u"end",b"end",u"radius",b"radius",u"start",b"start"]) -> None: ... +type___Stadium = Stadium + +class Text(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + position: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + text: typing___Text = ... + + @property + def base(self) -> type___PrimitiveBase: ... + + def __init__(self, + *, + base : typing___Optional[type___PrimitiveBase] = None, + position : typing___Optional[typing___Iterable[builtin___float]] = None, + text : typing___Optional[typing___Text] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"base",b"base"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"base",b"base",u"position",b"position",u"text",b"text"]) -> None: ... +type___Text = Text diff --git a/python/xviz_avs/v2/session_pb2.pyi b/python/xviz_avs/v2/session_pb2.pyi new file mode 100644 index 000000000..e9faf81a8 --- /dev/null +++ b/python/xviz_avs/v2/session_pb2.pyi @@ -0,0 +1,507 @@ +# @generated by generate_proto_mypy_stubs.py. Do not edit! +import sys +from google.protobuf.descriptor import ( + Descriptor as google___protobuf___descriptor___Descriptor, + EnumDescriptor as google___protobuf___descriptor___EnumDescriptor, + FileDescriptor as google___protobuf___descriptor___FileDescriptor, +) + +from google.protobuf.internal.containers import ( + RepeatedCompositeFieldContainer as google___protobuf___internal___containers___RepeatedCompositeFieldContainer, + RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, +) + +from google.protobuf.internal.enum_type_wrapper import ( + _EnumTypeWrapper as google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper, +) + +from google.protobuf.message import ( + Message as google___protobuf___message___Message, +) + +from google.protobuf.struct_pb2 import ( + Struct as google___protobuf___struct_pb2___Struct, +) + +from typing import ( + Iterable as typing___Iterable, + Mapping as typing___Mapping, + MutableMapping as typing___MutableMapping, + NewType as typing___NewType, + Optional as typing___Optional, + Text as typing___Text, + cast as typing___cast, +) + +from typing_extensions import ( + Literal as typing_extensions___Literal, +) + +from xviz.v2.core_pb2 import ( + StreamSet as xviz___v2___core_pb2___StreamSet, +) + +from xviz.v2.style_pb2 import ( + StyleClass as xviz___v2___style_pb2___StyleClass, + StyleStreamValue as xviz___v2___style_pb2___StyleStreamValue, +) + + +builtin___bool = bool +builtin___bytes = bytes +builtin___float = float +builtin___int = int + + +DESCRIPTOR: google___protobuf___descriptor___FileDescriptor = ... + +SessionTypeValue = typing___NewType('SessionTypeValue', builtin___int) +type___SessionTypeValue = SessionTypeValue +SessionType: _SessionType +class _SessionType(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[SessionTypeValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + SESSION_TYPE_INVALID = typing___cast(SessionTypeValue, 0) + LIVE = typing___cast(SessionTypeValue, 1) + LOG = typing___cast(SessionTypeValue, 2) + UNBUFFERED_LOG = typing___cast(SessionTypeValue, 3) +SESSION_TYPE_INVALID = typing___cast(SessionTypeValue, 0) +LIVE = typing___cast(SessionTypeValue, 1) +LOG = typing___cast(SessionTypeValue, 2) +UNBUFFERED_LOG = typing___cast(SessionTypeValue, 3) +type___SessionType = SessionType + +class Start(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + MessageFormatValue = typing___NewType('MessageFormatValue', builtin___int) + type___MessageFormatValue = MessageFormatValue + MessageFormat: _MessageFormat + class _MessageFormat(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[Start.MessageFormatValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + START_MESSAGE_FORMAT_INVALID = typing___cast(Start.MessageFormatValue, 0) + JSON = typing___cast(Start.MessageFormatValue, 1) + BINARY = typing___cast(Start.MessageFormatValue, 2) + START_MESSAGE_FORMAT_INVALID = typing___cast(Start.MessageFormatValue, 0) + JSON = typing___cast(Start.MessageFormatValue, 1) + BINARY = typing___cast(Start.MessageFormatValue, 2) + type___MessageFormat = MessageFormat + + version: typing___Text = ... + profile: typing___Text = ... + session_type: type___SessionTypeValue = ... + message_format: type___Start.MessageFormatValue = ... + log: typing___Text = ... + + def __init__(self, + *, + version : typing___Optional[typing___Text] = None, + profile : typing___Optional[typing___Text] = None, + session_type : typing___Optional[type___SessionTypeValue] = None, + message_format : typing___Optional[type___Start.MessageFormatValue] = None, + log : typing___Optional[typing___Text] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"log",b"log",u"message_format",b"message_format",u"profile",b"profile",u"session_type",b"session_type",u"version",b"version"]) -> None: ... +type___Start = Start + +class TransformLog(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + id: typing___Text = ... + start_timestamp: builtin___float = ... + end_timestamp: builtin___float = ... + desired_streams: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... + + def __init__(self, + *, + id : typing___Optional[typing___Text] = None, + start_timestamp : typing___Optional[builtin___float] = None, + end_timestamp : typing___Optional[builtin___float] = None, + desired_streams : typing___Optional[typing___Iterable[typing___Text]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"desired_streams",b"desired_streams",u"end_timestamp",b"end_timestamp",u"id",b"id",u"start_timestamp",b"start_timestamp"]) -> None: ... +type___TransformLog = TransformLog + +class StateUpdate(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + UpdateTypeValue = typing___NewType('UpdateTypeValue', builtin___int) + type___UpdateTypeValue = UpdateTypeValue + UpdateType: _UpdateType + class _UpdateType(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[StateUpdate.UpdateTypeValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + STATE_UPDATE_UPDATE_TYPE_INVALID = typing___cast(StateUpdate.UpdateTypeValue, 0) + SNAPSHOT = typing___cast(StateUpdate.UpdateTypeValue, 1) + INCREMENTAL = typing___cast(StateUpdate.UpdateTypeValue, 2) + COMPLETE_STATE = typing___cast(StateUpdate.UpdateTypeValue, 3) + PERSISTENT = typing___cast(StateUpdate.UpdateTypeValue, 4) + STATE_UPDATE_UPDATE_TYPE_INVALID = typing___cast(StateUpdate.UpdateTypeValue, 0) + SNAPSHOT = typing___cast(StateUpdate.UpdateTypeValue, 1) + INCREMENTAL = typing___cast(StateUpdate.UpdateTypeValue, 2) + COMPLETE_STATE = typing___cast(StateUpdate.UpdateTypeValue, 3) + PERSISTENT = typing___cast(StateUpdate.UpdateTypeValue, 4) + type___UpdateType = UpdateType + + update_type: type___StateUpdate.UpdateTypeValue = ... + + @property + def updates(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[xviz___v2___core_pb2___StreamSet]: ... + + def __init__(self, + *, + update_type : typing___Optional[type___StateUpdate.UpdateTypeValue] = None, + updates : typing___Optional[typing___Iterable[xviz___v2___core_pb2___StreamSet]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"update_type",b"update_type",u"updates",b"updates"]) -> None: ... +type___StateUpdate = StateUpdate + +class TransformLogDone(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + id: typing___Text = ... + + def __init__(self, + *, + id : typing___Optional[typing___Text] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"id",b"id"]) -> None: ... +type___TransformLogDone = TransformLogDone + +class TransformPointInTime(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + id: typing___Text = ... + query_timestamp: builtin___float = ... + desired_streams: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... + + def __init__(self, + *, + id : typing___Optional[typing___Text] = None, + query_timestamp : typing___Optional[builtin___float] = None, + desired_streams : typing___Optional[typing___Iterable[typing___Text]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"desired_streams",b"desired_streams",u"id",b"id",u"query_timestamp",b"query_timestamp"]) -> None: ... +type___TransformPointInTime = TransformPointInTime + +class Reconfigure(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + UpdateTypeValue = typing___NewType('UpdateTypeValue', builtin___int) + type___UpdateTypeValue = UpdateTypeValue + UpdateType: _UpdateType + class _UpdateType(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[Reconfigure.UpdateTypeValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + RECONFIGURE_UPDATE_TYPE_INVALID = typing___cast(Reconfigure.UpdateTypeValue, 0) + DELTA = typing___cast(Reconfigure.UpdateTypeValue, 1) + FULL = typing___cast(Reconfigure.UpdateTypeValue, 2) + RECONFIGURE_UPDATE_TYPE_INVALID = typing___cast(Reconfigure.UpdateTypeValue, 0) + DELTA = typing___cast(Reconfigure.UpdateTypeValue, 1) + FULL = typing___cast(Reconfigure.UpdateTypeValue, 2) + type___UpdateType = UpdateType + + update_type: type___Reconfigure.UpdateTypeValue = ... + + @property + def config_update(self) -> google___protobuf___struct_pb2___Struct: ... + + def __init__(self, + *, + update_type : typing___Optional[type___Reconfigure.UpdateTypeValue] = None, + config_update : typing___Optional[google___protobuf___struct_pb2___Struct] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"config_update",b"config_update"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"config_update",b"config_update",u"update_type",b"update_type"]) -> None: ... +type___Reconfigure = Reconfigure + +class Metadata(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + class StreamsEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + + @property + def value(self) -> type___StreamMetadata: ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[type___StreamMetadata] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___StreamsEntry = StreamsEntry + + class CamerasEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + + @property + def value(self) -> type___CameraInfo: ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[type___CameraInfo] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___CamerasEntry = CamerasEntry + + class StreamAliasesEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + value: typing___Text = ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[typing___Text] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___StreamAliasesEntry = StreamAliasesEntry + + class UiConfigEntry(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + key: typing___Text = ... + + @property + def value(self) -> type___UIPanelInfo: ... + + def __init__(self, + *, + key : typing___Optional[typing___Text] = None, + value : typing___Optional[type___UIPanelInfo] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... + type___UiConfigEntry = UiConfigEntry + + version: typing___Text = ... + + @property + def streams(self) -> typing___MutableMapping[typing___Text, type___StreamMetadata]: ... + + @property + def cameras(self) -> typing___MutableMapping[typing___Text, type___CameraInfo]: ... + + @property + def stream_aliases(self) -> typing___MutableMapping[typing___Text, typing___Text]: ... + + @property + def ui_config(self) -> typing___MutableMapping[typing___Text, type___UIPanelInfo]: ... + + @property + def log_info(self) -> type___LogInfo: ... + + def __init__(self, + *, + version : typing___Optional[typing___Text] = None, + streams : typing___Optional[typing___Mapping[typing___Text, type___StreamMetadata]] = None, + cameras : typing___Optional[typing___Mapping[typing___Text, type___CameraInfo]] = None, + stream_aliases : typing___Optional[typing___Mapping[typing___Text, typing___Text]] = None, + ui_config : typing___Optional[typing___Mapping[typing___Text, type___UIPanelInfo]] = None, + log_info : typing___Optional[type___LogInfo] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"log_info",b"log_info"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"cameras",b"cameras",u"log_info",b"log_info",u"stream_aliases",b"stream_aliases",u"streams",b"streams",u"ui_config",b"ui_config",u"version",b"version"]) -> None: ... +type___Metadata = Metadata + +class Error(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + message: typing___Text = ... + + def __init__(self, + *, + message : typing___Optional[typing___Text] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"message",b"message"]) -> None: ... +type___Error = Error + +class StreamMetadata(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + CategoryValue = typing___NewType('CategoryValue', builtin___int) + type___CategoryValue = CategoryValue + Category: _Category + class _Category(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[StreamMetadata.CategoryValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + STREAM_METADATA_CATEGORY_INVALID = typing___cast(StreamMetadata.CategoryValue, 0) + PRIMITIVE = typing___cast(StreamMetadata.CategoryValue, 1) + TIME_SERIES = typing___cast(StreamMetadata.CategoryValue, 2) + VARIABLE = typing___cast(StreamMetadata.CategoryValue, 3) + ANNOTATION = typing___cast(StreamMetadata.CategoryValue, 4) + FUTURE_INSTANCE = typing___cast(StreamMetadata.CategoryValue, 5) + POSE = typing___cast(StreamMetadata.CategoryValue, 6) + UI_PRIMITIVE = typing___cast(StreamMetadata.CategoryValue, 7) + STREAM_METADATA_CATEGORY_INVALID = typing___cast(StreamMetadata.CategoryValue, 0) + PRIMITIVE = typing___cast(StreamMetadata.CategoryValue, 1) + TIME_SERIES = typing___cast(StreamMetadata.CategoryValue, 2) + VARIABLE = typing___cast(StreamMetadata.CategoryValue, 3) + ANNOTATION = typing___cast(StreamMetadata.CategoryValue, 4) + FUTURE_INSTANCE = typing___cast(StreamMetadata.CategoryValue, 5) + POSE = typing___cast(StreamMetadata.CategoryValue, 6) + UI_PRIMITIVE = typing___cast(StreamMetadata.CategoryValue, 7) + type___Category = Category + + ScalarTypeValue = typing___NewType('ScalarTypeValue', builtin___int) + type___ScalarTypeValue = ScalarTypeValue + ScalarType: _ScalarType + class _ScalarType(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[StreamMetadata.ScalarTypeValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + STREAM_METADATA_SCALAR_TYPE_INVALID = typing___cast(StreamMetadata.ScalarTypeValue, 0) + FLOAT = typing___cast(StreamMetadata.ScalarTypeValue, 1) + INT32 = typing___cast(StreamMetadata.ScalarTypeValue, 2) + STRING = typing___cast(StreamMetadata.ScalarTypeValue, 3) + BOOL = typing___cast(StreamMetadata.ScalarTypeValue, 4) + STREAM_METADATA_SCALAR_TYPE_INVALID = typing___cast(StreamMetadata.ScalarTypeValue, 0) + FLOAT = typing___cast(StreamMetadata.ScalarTypeValue, 1) + INT32 = typing___cast(StreamMetadata.ScalarTypeValue, 2) + STRING = typing___cast(StreamMetadata.ScalarTypeValue, 3) + BOOL = typing___cast(StreamMetadata.ScalarTypeValue, 4) + type___ScalarType = ScalarType + + PrimitiveTypeValue = typing___NewType('PrimitiveTypeValue', builtin___int) + type___PrimitiveTypeValue = PrimitiveTypeValue + PrimitiveType: _PrimitiveType + class _PrimitiveType(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[StreamMetadata.PrimitiveTypeValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + STREAM_METADATA_PRIMITIVE_TYPE_INVALID = typing___cast(StreamMetadata.PrimitiveTypeValue, 0) + CIRCLE = typing___cast(StreamMetadata.PrimitiveTypeValue, 1) + IMAGE = typing___cast(StreamMetadata.PrimitiveTypeValue, 2) + POINT = typing___cast(StreamMetadata.PrimitiveTypeValue, 3) + POLYGON = typing___cast(StreamMetadata.PrimitiveTypeValue, 4) + POLYLINE = typing___cast(StreamMetadata.PrimitiveTypeValue, 5) + STADIUM = typing___cast(StreamMetadata.PrimitiveTypeValue, 6) + TEXT = typing___cast(StreamMetadata.PrimitiveTypeValue, 7) + STREAM_METADATA_PRIMITIVE_TYPE_INVALID = typing___cast(StreamMetadata.PrimitiveTypeValue, 0) + CIRCLE = typing___cast(StreamMetadata.PrimitiveTypeValue, 1) + IMAGE = typing___cast(StreamMetadata.PrimitiveTypeValue, 2) + POINT = typing___cast(StreamMetadata.PrimitiveTypeValue, 3) + POLYGON = typing___cast(StreamMetadata.PrimitiveTypeValue, 4) + POLYLINE = typing___cast(StreamMetadata.PrimitiveTypeValue, 5) + STADIUM = typing___cast(StreamMetadata.PrimitiveTypeValue, 6) + TEXT = typing___cast(StreamMetadata.PrimitiveTypeValue, 7) + type___PrimitiveType = PrimitiveType + + UIPrimitiveTypeValue = typing___NewType('UIPrimitiveTypeValue', builtin___int) + type___UIPrimitiveTypeValue = UIPrimitiveTypeValue + UIPrimitiveType: _UIPrimitiveType + class _UIPrimitiveType(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[StreamMetadata.UIPrimitiveTypeValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + STREAM_METADATA_UI_PRIMITIVE_TYPE_INVALID = typing___cast(StreamMetadata.UIPrimitiveTypeValue, 0) + TREETABLE = typing___cast(StreamMetadata.UIPrimitiveTypeValue, 1) + STREAM_METADATA_UI_PRIMITIVE_TYPE_INVALID = typing___cast(StreamMetadata.UIPrimitiveTypeValue, 0) + TREETABLE = typing___cast(StreamMetadata.UIPrimitiveTypeValue, 1) + type___UIPrimitiveType = UIPrimitiveType + + AnnotationTypeValue = typing___NewType('AnnotationTypeValue', builtin___int) + type___AnnotationTypeValue = AnnotationTypeValue + AnnotationType: _AnnotationType + class _AnnotationType(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[StreamMetadata.AnnotationTypeValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + STREAM_METADATA_ANNOTATION_TYPE_INVALID = typing___cast(StreamMetadata.AnnotationTypeValue, 0) + VISUAL = typing___cast(StreamMetadata.AnnotationTypeValue, 1) + STREAM_METADATA_ANNOTATION_TYPE_INVALID = typing___cast(StreamMetadata.AnnotationTypeValue, 0) + VISUAL = typing___cast(StreamMetadata.AnnotationTypeValue, 1) + type___AnnotationType = AnnotationType + + CoordinateTypeValue = typing___NewType('CoordinateTypeValue', builtin___int) + type___CoordinateTypeValue = CoordinateTypeValue + CoordinateType: _CoordinateType + class _CoordinateType(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[StreamMetadata.CoordinateTypeValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + STREAM_METADATA_COORDINATE_TYPE_INVALID = typing___cast(StreamMetadata.CoordinateTypeValue, 0) + GEOGRAPHIC = typing___cast(StreamMetadata.CoordinateTypeValue, 1) + IDENTITY = typing___cast(StreamMetadata.CoordinateTypeValue, 2) + DYNAMIC = typing___cast(StreamMetadata.CoordinateTypeValue, 3) + VEHICLE_RELATIVE = typing___cast(StreamMetadata.CoordinateTypeValue, 4) + STREAM_METADATA_COORDINATE_TYPE_INVALID = typing___cast(StreamMetadata.CoordinateTypeValue, 0) + GEOGRAPHIC = typing___cast(StreamMetadata.CoordinateTypeValue, 1) + IDENTITY = typing___cast(StreamMetadata.CoordinateTypeValue, 2) + DYNAMIC = typing___cast(StreamMetadata.CoordinateTypeValue, 3) + VEHICLE_RELATIVE = typing___cast(StreamMetadata.CoordinateTypeValue, 4) + type___CoordinateType = CoordinateType + + source: typing___Text = ... + units: typing___Text = ... + category: type___StreamMetadata.CategoryValue = ... + scalar_type: type___StreamMetadata.ScalarTypeValue = ... + primitive_type: type___StreamMetadata.PrimitiveTypeValue = ... + ui_primitive_type: type___StreamMetadata.UIPrimitiveTypeValue = ... + annotation_type: type___StreamMetadata.AnnotationTypeValue = ... + coordinate: type___StreamMetadata.CoordinateTypeValue = ... + transform: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + transform_callback: typing___Text = ... + + @property + def stream_style(self) -> xviz___v2___style_pb2___StyleStreamValue: ... + + @property + def style_classes(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[xviz___v2___style_pb2___StyleClass]: ... + + def __init__(self, + *, + source : typing___Optional[typing___Text] = None, + units : typing___Optional[typing___Text] = None, + category : typing___Optional[type___StreamMetadata.CategoryValue] = None, + scalar_type : typing___Optional[type___StreamMetadata.ScalarTypeValue] = None, + primitive_type : typing___Optional[type___StreamMetadata.PrimitiveTypeValue] = None, + ui_primitive_type : typing___Optional[type___StreamMetadata.UIPrimitiveTypeValue] = None, + annotation_type : typing___Optional[type___StreamMetadata.AnnotationTypeValue] = None, + stream_style : typing___Optional[xviz___v2___style_pb2___StyleStreamValue] = None, + style_classes : typing___Optional[typing___Iterable[xviz___v2___style_pb2___StyleClass]] = None, + coordinate : typing___Optional[type___StreamMetadata.CoordinateTypeValue] = None, + transform : typing___Optional[typing___Iterable[builtin___float]] = None, + transform_callback : typing___Optional[typing___Text] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"stream_style",b"stream_style"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"annotation_type",b"annotation_type",u"category",b"category",u"coordinate",b"coordinate",u"primitive_type",b"primitive_type",u"scalar_type",b"scalar_type",u"source",b"source",u"stream_style",b"stream_style",u"style_classes",b"style_classes",u"transform",b"transform",u"transform_callback",b"transform_callback",u"ui_primitive_type",b"ui_primitive_type",u"units",b"units"]) -> None: ... +type___StreamMetadata = StreamMetadata + +class CameraInfo(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + human_name: typing___Text = ... + source: typing___Text = ... + vehicle_position: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + vehicle_orientation: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + pixel_width: builtin___float = ... + pixel_height: builtin___float = ... + rectification_projection: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + gl_projection: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + + def __init__(self, + *, + human_name : typing___Optional[typing___Text] = None, + source : typing___Optional[typing___Text] = None, + vehicle_position : typing___Optional[typing___Iterable[builtin___float]] = None, + vehicle_orientation : typing___Optional[typing___Iterable[builtin___float]] = None, + pixel_width : typing___Optional[builtin___float] = None, + pixel_height : typing___Optional[builtin___float] = None, + rectification_projection : typing___Optional[typing___Iterable[builtin___float]] = None, + gl_projection : typing___Optional[typing___Iterable[builtin___float]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"gl_projection",b"gl_projection",u"human_name",b"human_name",u"pixel_height",b"pixel_height",u"pixel_width",b"pixel_width",u"rectification_projection",b"rectification_projection",u"source",b"source",u"vehicle_orientation",b"vehicle_orientation",u"vehicle_position",b"vehicle_position"]) -> None: ... +type___CameraInfo = CameraInfo + +class UIPanelInfo(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + name: typing___Text = ... + needed_streams: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... + + @property + def config(self) -> google___protobuf___struct_pb2___Struct: ... + + def __init__(self, + *, + name : typing___Optional[typing___Text] = None, + needed_streams : typing___Optional[typing___Iterable[typing___Text]] = None, + config : typing___Optional[google___protobuf___struct_pb2___Struct] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"config",b"config"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"config",b"config",u"name",b"name",u"needed_streams",b"needed_streams"]) -> None: ... +type___UIPanelInfo = UIPanelInfo + +class LogInfo(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + start_time: builtin___float = ... + end_time: builtin___float = ... + + def __init__(self, + *, + start_time : typing___Optional[builtin___float] = None, + end_time : typing___Optional[builtin___float] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"end_time",b"end_time",u"start_time",b"start_time"]) -> None: ... +type___LogInfo = LogInfo diff --git a/python/xviz_avs/v2/style_pb2.pyi b/python/xviz_avs/v2/style_pb2.pyi new file mode 100644 index 000000000..002481f5b --- /dev/null +++ b/python/xviz_avs/v2/style_pb2.pyi @@ -0,0 +1,190 @@ +# @generated by generate_proto_mypy_stubs.py. Do not edit! +import sys +from google.protobuf.descriptor import ( + Descriptor as google___protobuf___descriptor___Descriptor, + EnumDescriptor as google___protobuf___descriptor___EnumDescriptor, + FileDescriptor as google___protobuf___descriptor___FileDescriptor, +) + +from google.protobuf.internal.containers import ( + RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, +) + +from google.protobuf.internal.enum_type_wrapper import ( + _EnumTypeWrapper as google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper, +) + +from google.protobuf.message import ( + Message as google___protobuf___message___Message, +) + +from typing import ( + Iterable as typing___Iterable, + NewType as typing___NewType, + Optional as typing___Optional, + Text as typing___Text, + cast as typing___cast, +) + +from typing_extensions import ( + Literal as typing_extensions___Literal, +) + + +builtin___bool = bool +builtin___bytes = bytes +builtin___float = float +builtin___int = int + + +DESCRIPTOR: google___protobuf___descriptor___FileDescriptor = ... + +TextAnchorValue = typing___NewType('TextAnchorValue', builtin___int) +type___TextAnchorValue = TextAnchorValue +TextAnchor: _TextAnchor +class _TextAnchor(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[TextAnchorValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + TEXT_ANCHOR_INVALID = typing___cast(TextAnchorValue, 0) + START = typing___cast(TextAnchorValue, 1) + MIDDLE = typing___cast(TextAnchorValue, 2) + END = typing___cast(TextAnchorValue, 3) +TEXT_ANCHOR_INVALID = typing___cast(TextAnchorValue, 0) +START = typing___cast(TextAnchorValue, 1) +MIDDLE = typing___cast(TextAnchorValue, 2) +END = typing___cast(TextAnchorValue, 3) +type___TextAnchor = TextAnchor + +TextAlignmentBaselineValue = typing___NewType('TextAlignmentBaselineValue', builtin___int) +type___TextAlignmentBaselineValue = TextAlignmentBaselineValue +TextAlignmentBaseline: _TextAlignmentBaseline +class _TextAlignmentBaseline(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[TextAlignmentBaselineValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + TEXT_ALIGNMENT_BASELINE_INVALID = typing___cast(TextAlignmentBaselineValue, 0) + TOP = typing___cast(TextAlignmentBaselineValue, 1) + CENTER = typing___cast(TextAlignmentBaselineValue, 2) + BOTTOM = typing___cast(TextAlignmentBaselineValue, 3) +TEXT_ALIGNMENT_BASELINE_INVALID = typing___cast(TextAlignmentBaselineValue, 0) +TOP = typing___cast(TextAlignmentBaselineValue, 1) +CENTER = typing___cast(TextAlignmentBaselineValue, 2) +BOTTOM = typing___cast(TextAlignmentBaselineValue, 3) +type___TextAlignmentBaseline = TextAlignmentBaseline + +PointColorModeValue = typing___NewType('PointColorModeValue', builtin___int) +type___PointColorModeValue = PointColorModeValue +PointColorMode: _PointColorMode +class _PointColorMode(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[PointColorModeValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + POINT_COLOR_MODE_INVALID = typing___cast(PointColorModeValue, 0) + ELEVATION = typing___cast(PointColorModeValue, 1) + DISTANCE_TO_VEHICLE = typing___cast(PointColorModeValue, 2) +POINT_COLOR_MODE_INVALID = typing___cast(PointColorModeValue, 0) +ELEVATION = typing___cast(PointColorModeValue, 1) +DISTANCE_TO_VEHICLE = typing___cast(PointColorModeValue, 2) +type___PointColorMode = PointColorMode + +class StyleClass(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + name: typing___Text = ... + + @property + def style(self) -> type___StyleObjectValue: ... + + def __init__(self, + *, + name : typing___Optional[typing___Text] = None, + style : typing___Optional[type___StyleObjectValue] = None, + ) -> None: ... + def HasField(self, field_name: typing_extensions___Literal[u"style",b"style"]) -> builtin___bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"name",b"name",u"style",b"style"]) -> None: ... +type___StyleClass = StyleClass + +class StyleObjectValue(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + fill_color: builtin___bytes = ... + stroke_color: builtin___bytes = ... + stroke_width: builtin___float = ... + radius: builtin___float = ... + text_size: builtin___float = ... + text_rotation: builtin___float = ... + text_anchor: type___TextAnchorValue = ... + text_baseline: type___TextAlignmentBaselineValue = ... + height: builtin___float = ... + + def __init__(self, + *, + fill_color : typing___Optional[builtin___bytes] = None, + stroke_color : typing___Optional[builtin___bytes] = None, + stroke_width : typing___Optional[builtin___float] = None, + radius : typing___Optional[builtin___float] = None, + text_size : typing___Optional[builtin___float] = None, + text_rotation : typing___Optional[builtin___float] = None, + text_anchor : typing___Optional[type___TextAnchorValue] = None, + text_baseline : typing___Optional[type___TextAlignmentBaselineValue] = None, + height : typing___Optional[builtin___float] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"fill_color",b"fill_color",u"height",b"height",u"radius",b"radius",u"stroke_color",b"stroke_color",u"stroke_width",b"stroke_width",u"text_anchor",b"text_anchor",u"text_baseline",b"text_baseline",u"text_rotation",b"text_rotation",u"text_size",b"text_size"]) -> None: ... +type___StyleObjectValue = StyleObjectValue + +class StyleStreamValue(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + fill_color: builtin___bytes = ... + stroke_color: builtin___bytes = ... + stroke_width: builtin___float = ... + radius: builtin___float = ... + text_size: builtin___float = ... + text_rotation: builtin___float = ... + text_anchor: type___TextAnchorValue = ... + text_baseline: type___TextAlignmentBaselineValue = ... + height: builtin___float = ... + radius_min_pixels: builtin___int = ... + radius_max_pixels: builtin___int = ... + stroke_width_min_pixels: builtin___int = ... + stroke_width_max_pixels: builtin___int = ... + opacity: builtin___float = ... + stroked: builtin___bool = ... + filled: builtin___bool = ... + extruded: builtin___bool = ... + radius_pixels: builtin___int = ... + font_weight: builtin___int = ... + font_family: typing___Text = ... + point_color_mode: type___PointColorModeValue = ... + point_color_domain: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + + def __init__(self, + *, + fill_color : typing___Optional[builtin___bytes] = None, + stroke_color : typing___Optional[builtin___bytes] = None, + stroke_width : typing___Optional[builtin___float] = None, + radius : typing___Optional[builtin___float] = None, + text_size : typing___Optional[builtin___float] = None, + text_rotation : typing___Optional[builtin___float] = None, + text_anchor : typing___Optional[type___TextAnchorValue] = None, + text_baseline : typing___Optional[type___TextAlignmentBaselineValue] = None, + height : typing___Optional[builtin___float] = None, + radius_min_pixels : typing___Optional[builtin___int] = None, + radius_max_pixels : typing___Optional[builtin___int] = None, + stroke_width_min_pixels : typing___Optional[builtin___int] = None, + stroke_width_max_pixels : typing___Optional[builtin___int] = None, + opacity : typing___Optional[builtin___float] = None, + stroked : typing___Optional[builtin___bool] = None, + filled : typing___Optional[builtin___bool] = None, + extruded : typing___Optional[builtin___bool] = None, + radius_pixels : typing___Optional[builtin___int] = None, + font_weight : typing___Optional[builtin___int] = None, + font_family : typing___Optional[typing___Text] = None, + point_color_mode : typing___Optional[type___PointColorModeValue] = None, + point_color_domain : typing___Optional[typing___Iterable[builtin___float]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"extruded",b"extruded",u"fill_color",b"fill_color",u"filled",b"filled",u"font_family",b"font_family",u"font_weight",b"font_weight",u"height",b"height",u"opacity",b"opacity",u"point_color_domain",b"point_color_domain",u"point_color_mode",b"point_color_mode",u"radius",b"radius",u"radius_max_pixels",b"radius_max_pixels",u"radius_min_pixels",b"radius_min_pixels",u"radius_pixels",b"radius_pixels",u"stroke_color",b"stroke_color",u"stroke_width",b"stroke_width",u"stroke_width_max_pixels",b"stroke_width_max_pixels",u"stroke_width_min_pixels",b"stroke_width_min_pixels",u"stroked",b"stroked",u"text_anchor",b"text_anchor",u"text_baseline",b"text_baseline",u"text_rotation",b"text_rotation",u"text_size",b"text_size"]) -> None: ... +type___StyleStreamValue = StyleStreamValue + +class Color(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + values: builtin___bytes = ... + + def __init__(self, + *, + values : typing___Optional[builtin___bytes] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"values",b"values"]) -> None: ... +type___Color = Color diff --git a/python/xviz_avs/v2/uiprimitives_pb2.pyi b/python/xviz_avs/v2/uiprimitives_pb2.pyi new file mode 100644 index 000000000..69cd97614 --- /dev/null +++ b/python/xviz_avs/v2/uiprimitives_pb2.pyi @@ -0,0 +1,105 @@ +# @generated by generate_proto_mypy_stubs.py. Do not edit! +import sys +from google.protobuf.descriptor import ( + Descriptor as google___protobuf___descriptor___Descriptor, + EnumDescriptor as google___protobuf___descriptor___EnumDescriptor, + FileDescriptor as google___protobuf___descriptor___FileDescriptor, +) + +from google.protobuf.internal.containers import ( + RepeatedCompositeFieldContainer as google___protobuf___internal___containers___RepeatedCompositeFieldContainer, + RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, +) + +from google.protobuf.internal.enum_type_wrapper import ( + _EnumTypeWrapper as google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper, +) + +from google.protobuf.message import ( + Message as google___protobuf___message___Message, +) + +from typing import ( + Iterable as typing___Iterable, + NewType as typing___NewType, + Optional as typing___Optional, + Text as typing___Text, + cast as typing___cast, +) + +from typing_extensions import ( + Literal as typing_extensions___Literal, +) + + +builtin___bool = bool +builtin___bytes = bytes +builtin___float = float +builtin___int = int + + +DESCRIPTOR: google___protobuf___descriptor___FileDescriptor = ... + +class TreeTable(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + + @property + def columns(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___TreeTableColumn]: ... + + @property + def nodes(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___TreeTableNode]: ... + + def __init__(self, + *, + columns : typing___Optional[typing___Iterable[type___TreeTableColumn]] = None, + nodes : typing___Optional[typing___Iterable[type___TreeTableNode]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"columns",b"columns",u"nodes",b"nodes"]) -> None: ... +type___TreeTable = TreeTable + +class TreeTableColumn(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + ColumnTypeValue = typing___NewType('ColumnTypeValue', builtin___int) + type___ColumnTypeValue = ColumnTypeValue + ColumnType: _ColumnType + class _ColumnType(google___protobuf___internal___enum_type_wrapper____EnumTypeWrapper[TreeTableColumn.ColumnTypeValue]): + DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... + TREE_TABLE_COLUMN_COLUMN_TYPE_INVALID = typing___cast(TreeTableColumn.ColumnTypeValue, 0) + INT32 = typing___cast(TreeTableColumn.ColumnTypeValue, 1) + DOUBLE = typing___cast(TreeTableColumn.ColumnTypeValue, 2) + STRING = typing___cast(TreeTableColumn.ColumnTypeValue, 3) + BOOLEAN = typing___cast(TreeTableColumn.ColumnTypeValue, 4) + TREE_TABLE_COLUMN_COLUMN_TYPE_INVALID = typing___cast(TreeTableColumn.ColumnTypeValue, 0) + INT32 = typing___cast(TreeTableColumn.ColumnTypeValue, 1) + DOUBLE = typing___cast(TreeTableColumn.ColumnTypeValue, 2) + STRING = typing___cast(TreeTableColumn.ColumnTypeValue, 3) + BOOLEAN = typing___cast(TreeTableColumn.ColumnTypeValue, 4) + type___ColumnType = ColumnType + + display_text: typing___Text = ... + type: type___TreeTableColumn.ColumnTypeValue = ... + unit: typing___Text = ... + + def __init__(self, + *, + display_text : typing___Optional[typing___Text] = None, + type : typing___Optional[type___TreeTableColumn.ColumnTypeValue] = None, + unit : typing___Optional[typing___Text] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"display_text",b"display_text",u"type",b"type",u"unit",b"unit"]) -> None: ... +type___TreeTableColumn = TreeTableColumn + +class TreeTableNode(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + id: builtin___int = ... + parent: builtin___int = ... + column_values: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... + + def __init__(self, + *, + id : typing___Optional[builtin___int] = None, + parent : typing___Optional[builtin___int] = None, + column_values : typing___Optional[typing___Iterable[typing___Text]] = None, + ) -> None: ... + def ClearField(self, field_name: typing_extensions___Literal[u"column_values",b"column_values",u"id",b"id",u"parent",b"parent"]) -> None: ... +type___TreeTableNode = TreeTableNode