diff --git a/anylabeling/utils.py b/anylabeling/utils.py index ca14ba0..1e34db7 100644 --- a/anylabeling/utils.py +++ b/anylabeling/utils.py @@ -1,5 +1,16 @@ +import os + from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot +MESH_EXTENSIONS = [".obj", ".stl", ".ply"] + + +def is_mesh_file(filename): + """Check if the filename is a mesh file""" + if not filename: + return False + return os.path.splitext(filename)[1].lower() in MESH_EXTENSIONS + class GenericWorker(QObject): finished = pyqtSignal() diff --git a/anylabeling/views/labeling/label_file.py b/anylabeling/views/labeling/label_file.py index ec82c4d..a66c9e5 100644 --- a/anylabeling/views/labeling/label_file.py +++ b/anylabeling/views/labeling/label_file.py @@ -6,6 +6,8 @@ import PIL.Image +from anylabeling.utils import is_mesh_file + from ...app_info import __version__ from . import utils from .logger import logger @@ -31,12 +33,17 @@ def __init__(self, filename=None): self.shapes = [] self.image_path = None self.image_data = None + self.flags = {} + self.other_data = {} if filename is not None: self.load(filename) self.filename = filename @staticmethod def load_image_file(filename): + if is_mesh_file(filename): + return None + try: image_pil = PIL.Image.open(filename) except OSError: @@ -74,6 +81,7 @@ def load(self, filename): "group_id", "shape_type", "flags", + "vertex_indices", ] try: with io_open(filename, "r") as f: @@ -82,30 +90,36 @@ def load(self, filename): if version is None: logger.warning("Loading JSON file (%s) of unknown version", filename) - if data["imageData"] is not None: + image_path = data.get("imagePath", "") + if is_mesh_file(image_path): + image_data = None + elif data.get("imageData") is not None: image_data = base64.b64decode(data["imageData"]) - else: + elif image_path: # relative path from label file to relative path from cwd - image_path = osp.join(osp.dirname(filename), data["imagePath"]) - image_data = self.load_image_file(image_path) + abs_image_path = osp.join(osp.dirname(filename), image_path) + image_data = self.load_image_file(abs_image_path) + else: + image_data = None flags = data.get("flags") or {} - image_path = data["imagePath"] - self._check_image_height_and_width( - base64.b64encode(image_data).decode("utf-8"), - data.get("imageHeight"), - data.get("imageWidth"), - ) + if image_data: + self._check_image_height_and_width( + base64.b64encode(image_data).decode("utf-8"), + data.get("imageHeight"), + data.get("imageWidth"), + ) shapes = [ { - "label": s["label"], + "label": s.get("label", ""), "text": s.get("text", ""), - "points": s["points"], + "points": s.get("points", []), "shape_type": s.get("shape_type", "polygon"), + "vertex_indices": s.get("vertex_indices", []), "flags": s.get("flags", {}), "group_id": s.get("group_id"), "other_data": {k: v for k, v in s.items() if k not in shape_keys}, } - for s in data["shapes"] + for s in data.get("shapes", []) ] except Exception as e: # noqa raise LabelFileError(e) from e diff --git a/anylabeling/views/labeling/label_widget.py b/anylabeling/views/labeling/label_widget.py index 6816dcf..64d09ea 100644 --- a/anylabeling/views/labeling/label_widget.py +++ b/anylabeling/views/labeling/label_widget.py @@ -1,5 +1,6 @@ import functools import html +import json import math import os import os.path as osp @@ -23,6 +24,7 @@ from anylabeling.config import get_config, save_config from anylabeling.services.auto_labeling.types import AutoLabelingMode from anylabeling.styles import AppTheme +from anylabeling.utils import MESH_EXTENSIONS, is_mesh_file from anylabeling.views.labeling import utils from anylabeling.views.labeling.label_file import LabelFile, LabelFileError from anylabeling.views.labeling.logger import logger @@ -31,12 +33,14 @@ AutoLabelingWidget, BrightnessContrastDialog, Canvas, + Canvas3D, FileDialogPreview, LabelDialog, LabelListWidget, LabelListWidgetItem, ToolBar, UniqueLabelQListWidget, + ViewControls3D, ZoomWidget, ) @@ -233,10 +237,23 @@ def __init__( self.unique_label_list.addItem(item) rgb = self._get_rgb_by_label(label) self.unique_label_list.set_item_label(item, label, rgb) + self.unique_label_list.itemSelectionChanged.connect( + self._update_3d_active_label + ) + # Container with Add Label button + label list + label_dock_widget = QtWidgets.QWidget() + label_dock_layout = QVBoxLayout() + label_dock_layout.setContentsMargins(0, 0, 0, 0) + label_dock_layout.setSpacing(2) + self.add_label_button = QtWidgets.QPushButton(self.tr("+ Add Label")) + self.add_label_button.clicked.connect(self._add_label_manually) + label_dock_layout.addWidget(self.add_label_button) + label_dock_layout.addWidget(self.unique_label_list) + label_dock_widget.setLayout(label_dock_layout) self.label_dock = QtWidgets.QDockWidget(self.tr("Labels"), self.main_window) self.label_dock.setObjectName("Labels") self.label_dock.setFeatures(features) - self.label_dock.setWidget(self.unique_label_list) + self.label_dock.setWidget(label_dock_widget) self.label_dock.setStyleSheet(dock_title_style) self.main_window.addDockWidget( Qt.DockWidgetArea.RightDockWidgetArea, self.label_dock @@ -274,6 +291,26 @@ def __init__( ) self.canvas.zoom_request.connect(self.zoom_request) + # 3D Canvas + self.canvas_3d = Canvas3D(parent=self) + self.canvas_3d.new_shape.connect(self._on_new_shape_3d) + self.canvas_3d.shapes_updated.connect(self.set_dirty) + # self.canvas_3d.selection_changed.connect(self.shape_selection_changed) + + # 3D View Controls dock + self.view_controls_3d = ViewControls3D(self.canvas_3d) + self.view_controls_3d_dock = QtWidgets.QDockWidget( + self.tr("3D View Controls"), self.main_window + ) + self.view_controls_3d_dock.setObjectName("3DViewControls") + self.view_controls_3d_dock.setFeatures(features) + self.view_controls_3d_dock.setWidget(self.view_controls_3d) + self.view_controls_3d_dock.setStyleSheet(dock_title_style) + self.main_window.addDockWidget( + Qt.DockWidgetArea.RightDockWidgetArea, self.view_controls_3d_dock + ) + self.view_controls_3d_dock.hide() # Hidden until a mesh is loaded + scroll_area = QtWidgets.QScrollArea() scroll_area.setWidget(self.canvas) scroll_area.setWidgetResizable(True) @@ -288,7 +325,11 @@ def __init__( self.canvas.selection_changed.connect(self.shape_selection_changed) self.canvas.drawing_polygon.connect(self.toggle_drawing_sensitive) - self._central_widget = scroll_area + self.central_stack = QtWidgets.QStackedWidget() + self.central_stack.addWidget(scroll_area) # Index 0: 2D + self.central_stack.addWidget(self.canvas_3d) # Index 1: 3D + + self._central_widget = self.central_stack # Actions create_action = functools.partial(utils.new_action, self) @@ -452,6 +493,38 @@ def __init__( self.tr("Start drawing linestrip. Ctrl+LeftClick ends creation."), enabled=False, ) + create_brush_3d = create_action( + self.tr("Brush 3D"), + lambda: self.toggle_draw_mode_3d(Canvas3D.BRUSH), + "Ctrl+B", + "brush", + self.tr("Paint on 3D mesh"), + enabled=False, + ) + view_mode_3d = create_action( + self.tr("View 3D"), + lambda: self.toggle_draw_mode_3d(Canvas3D.VIEW), + "Escape", + "edit", + self.tr("Switch the 3D canvas back to view (orbit) mode"), + enabled=False, + ) + decrease_brush_size_3d = create_action( + self.tr("Decrease 3D brush size"), + lambda: self._adjust_3d_brush_size(-1), + "[", + None, + self.tr("Make the 3D brush radius smaller"), + enabled=False, + ) + increase_brush_size_3d = create_action( + self.tr("Increase 3D brush size"), + lambda: self._adjust_3d_brush_size(+1), + "]", + None, + self.tr("Make the 3D brush radius larger"), + enabled=False, + ) edit_mode = create_action( self.tr("Edit Object"), self.set_edit_mode, @@ -827,6 +900,10 @@ def __init__( create_line_mode=create_line_mode, create_point_mode=create_point_mode, create_line_strip_mode=create_line_strip_mode, + create_brush_3d=create_brush_3d, + view_mode_3d=view_mode_3d, + decrease_brush_size_3d=decrease_brush_size_3d, + increase_brush_size_3d=increase_brush_size_3d, zoom=zoom, zoom_in=zoom_in, zoom_out=zoom_out, @@ -1039,6 +1116,7 @@ def __init__( self.actions.create_line_mode, self.actions.create_point_mode, self.actions.create_line_strip_mode, + create_brush_3d, edit_mode, delete, undo, @@ -1155,7 +1233,7 @@ def __init__( central_layout.addWidget(self.label_instruction) central_layout.addWidget(self.auto_labeling_widget) - central_layout.addWidget(scroll_area) + central_layout.addWidget(self.central_stack) # Set the central widget content center_widget = QtWidgets.QWidget() @@ -1347,7 +1425,11 @@ def set_dirty(self): self.actions.undo.setEnabled(self.canvas.is_shape_restorable) if self._config["auto_save"] or self.actions.save_auto.isChecked(): - label_file = osp.splitext(self.image_path)[0] + ".json" + if is_mesh_file(self.image_path): + label_file = osp.splitext(self.image_path)[0] + ".anylabeling.json" + else: + label_file = osp.splitext(self.image_path)[0] + ".json" + if self.output_dir: label_file_without_path = osp.basename(label_file) label_file = osp.join(self.output_dir, label_file_without_path) @@ -1510,6 +1592,121 @@ def toggle_draw_mode( self.actions.edit_mode.setEnabled(not edit) self.label_instruction.setText(self.get_labeling_instruction()) + def toggle_draw_mode_3d(self, mode): + """Toggle 3D draw mode""" + self.canvas_3d.set_mode(mode) + self.view_controls_3d.set_mode(mode) + self.actions.create_brush_3d.setEnabled(mode != Canvas3D.BRUSH) + self.actions.view_mode_3d.setEnabled(mode != Canvas3D.VIEW) + + def _adjust_3d_brush_size(self, direction): + """Step the 3D brush radius via shortcut. Direction: -1 smaller, +1 larger.""" + slider = getattr(self.view_controls_3d, "brush_size_slider", None) + if slider is None: + return + step = 1 + new_value = max(slider.minimum(), min(slider.maximum(), slider.value() + direction * step)) + slider.setValue(new_value) + + def _add_label_manually(self): + """Add a new label to the unique label list via input dialog""" + text, ok = QtWidgets.QInputDialog.getText( + self, self.tr("Add Label"), self.tr("Label name:") + ) + if ok and text: + text = text.strip() + if not text: + return + if self.unique_label_list.find_items_by_label(text): + return # Already exists + item = self.unique_label_list.create_item_from_label(text) + self.unique_label_list.addItem(item) + rgb = self._get_rgb_by_label(text) + self.unique_label_list.set_item_label(item, text, rgb) + # Select the newly added label + self.unique_label_list.clearSelection() + item.setSelected(True) + self._save_folder_labels() + + def _get_folder_settings_path(self): + """Get path to .anylabeling_settings.json in the current data folder""" + folder = self.output_dir or self.last_open_dir + if folder: + return osp.join(folder, ".anylabeling_settings.json") + return None + + def _save_folder_labels(self): + """Save the current label list to the data folder settings file""" + settings_path = self._get_folder_settings_path() + if not settings_path: + return + # Read existing settings + data = {} + if osp.exists(settings_path): + try: + with open(settings_path, encoding="utf-8") as f: + data = json.load(f) + except Exception: + pass + # Collect labels + labels = [] + for i in range(self.unique_label_list.count()): + label = self.unique_label_list.item(i).data(Qt.ItemDataRole.UserRole) + if label: + labels.append(label) + data["labels"] = labels + try: + with open(settings_path, "w", encoding="utf-8") as f: + json.dump(data, f, ensure_ascii=False, indent=2) + except Exception as e: + logger.warning("Failed to save folder labels: %s", e) + + def _load_folder_labels(self): + """Load labels from the data folder settings file""" + settings_path = self._get_folder_settings_path() + if not settings_path or not osp.exists(settings_path): + return + try: + with open(settings_path, encoding="utf-8") as f: + data = json.load(f) + for label in data.get("labels", []): + if not self.unique_label_list.find_items_by_label(label): + item = self.unique_label_list.create_item_from_label(label) + self.unique_label_list.addItem(item) + rgb = self._get_rgb_by_label(label) + self.unique_label_list.set_item_label(item, label, rgb) + except Exception as e: + logger.warning("Failed to load folder labels: %s", e) + + def _update_3d_active_label(self): + """Sync selected label from unique_label_list to canvas_3d""" + items = self.unique_label_list.selectedItems() + if items: + label = items[0].data(Qt.ItemDataRole.UserRole) + self.canvas_3d.active_label = label + # Sync label color to canvas_3d + rgb = self._get_rgb_by_label(label) + self.canvas_3d.set_label_color(label, rgb) + else: + self.canvas_3d.active_label = "" + + def _sync_all_label_colors_3d(self): + """Push all known label colors to canvas_3d""" + for i in range(self.unique_label_list.count()): + label = self.unique_label_list.item(i).data(Qt.ItemDataRole.UserRole) + if label: + rgb = self._get_rgb_by_label(label) + self.canvas_3d.set_label_color(label, rgb) + + def _on_new_shape_3d(self): + """Handle new shape from 3D canvas (label already set via active_label)""" + shape = self.canvas_3d.shapes[-1] + # Ensure color is synced for this label + rgb = self._get_rgb_by_label(shape.label) + self.canvas_3d.set_label_color(shape.label, rgb) + self.add_label(shape) + self.set_dirty() + def set_edit_mode(self): # Disable auto labeling self.clear_auto_labeling_marks() @@ -1752,31 +1949,37 @@ def load_shapes(self, shapes, replace=True): self.label_list.clearSelection() self._no_selection_slot = False self.canvas.load_shapes(shapes, replace=replace) + self.canvas_3d.load_shapes(shapes, replace=replace) def load_labels(self, shapes): s = [] for shape in shapes: label = shape["label"] text = shape.get("text", "") - points = shape["points"] - shape_type = shape["shape_type"] - flags = shape["flags"] - group_id = shape["group_id"] - other_data = shape["other_data"] - - if not points: - # skip point-empty shape + points = shape.get("points", []) + shape_type = shape.get("shape_type", "polygon") + flags = shape.get("flags", {}) + group_id = shape.get("group_id") + other_data = shape.get("other_data", {}) + vertex_indices = shape.get("vertex_indices", []) + + if not points and not vertex_indices: + # skip empty shape continue - shape = Shape( + shape_obj = Shape( label=label, text=text, shape_type=shape_type, group_id=group_id, + vertex_indices=vertex_indices, ) - for x, y in points: - shape.add_point(QtCore.QPointF(x, y)) - shape.close() + for point in points: + if isinstance(point, (list, tuple)): + shape_obj.add_point(QtCore.QPointF(*point)) + else: + shape_obj.add_point(point) + shape_obj.close() default_flags = {} if self._config["label_flags"]: @@ -1784,12 +1987,12 @@ def load_labels(self, shapes): if re.match(pattern, label): for key in keys: default_flags[key] = False - shape.flags = default_flags + shape_obj.flags = default_flags if flags: - shape.flags.update(flags) - shape.other_data = other_data + shape_obj.flags.update(flags) + shape_obj.other_data = other_data - s.append(shape) + s.append(shape_obj) self.load_shapes(s) def load_flags(self, flags): @@ -1839,7 +2042,19 @@ def format_shape(s): flags[key] = flag try: image_path = osp.relpath(self.image_path, osp.dirname(filename)) - image_data = self.image_data if self._config["store_data"] else None + if is_mesh_file(self.image_path): + image_data = None + image_height = None + image_width = None + # Include RLE-encoded vertex label ids for mesh files + self.other_data["vertex_label_ids"] = utils.encode_rle( + self.canvas_3d.vertex_label_ids.tolist() + ) + else: + image_data = self.image_data if self._config["store_data"] else None + image_height = self.image.height() + image_width = self.image.width() + if osp.dirname(filename) and not osp.exists(osp.dirname(filename)): os.makedirs(osp.dirname(filename)) label_file.save( @@ -1847,8 +2062,8 @@ def format_shape(s): shapes=shapes, image_path=image_path, image_data=image_data, - image_height=self.image.height(), - image_width=self.image.width(), + image_height=image_height, + image_width=image_width, other_data=self.other_data, flags=flags, ) @@ -2136,6 +2351,67 @@ def load_file(self, filename=None): # noqa: C901 if self.output_dir: label_file_without_path = osp.basename(label_file) label_file = osp.join(self.output_dir, label_file_without_path) + + # Handle mesh files + if is_mesh_file(filename): + self.central_stack.setCurrentIndex(1) + self.view_controls_3d_dock.show() + self.canvas_3d.load_mesh(filename) + self.actions.create_brush_3d.setEnabled(True) + self.actions.view_mode_3d.setEnabled(True) + self.actions.decrease_brush_size_3d.setEnabled(True) + self.actions.increase_brush_size_3d.setEnabled(True) + self.filename = filename + self.image_path = filename + self.image_data = None + self.image = QtGui.QImage() # Dummy image + + # Prefer .anylabeling.json, fallback to .json + label_file_v2 = osp.splitext(filename)[0] + ".anylabeling.json" + if self.output_dir: + label_file_v2 = osp.join(self.output_dir, osp.basename(label_file_v2)) + + if QtCore.QFile.exists(label_file_v2) and LabelFile.is_label_file( + label_file_v2 + ): + label_file = label_file_v2 + + # Load labels if exists + if QtCore.QFile.exists(label_file) and LabelFile.is_label_file(label_file): + try: + self.label_file = LabelFile(label_file) + self.other_data = self.label_file.other_data + self.shape_text_edit.textChanged.disconnect() + self.shape_text_edit.setPlainText( + self.other_data.get("image_text", "") + ) + self.shape_text_edit.textChanged.connect(self.shape_text_changed) + self._sync_all_label_colors_3d() + if "vertex_label_ids" in self.other_data: + self.canvas_3d.load_vertex_label_ids( + self.other_data["vertex_label_ids"] + ) + self.load_labels(self.label_file.shapes) + if self.label_file.flags is not None: + flags = dict.fromkeys(self._config["flags"] or [], False) + flags.update(self.label_file.flags) + self.load_flags(flags) + except Exception as e: + self.error_message(self.tr("Error opening label file"), str(e)) + else: + self.label_file = None + self.canvas_3d.clear_shapes() + self.set_clean() + self._sync_all_label_colors_3d() + + self.canvas.setEnabled(False) + self.actions.save.setEnabled(True) + self.actions.save_as.setEnabled(True) + return True + else: + self.central_stack.setCurrentIndex(0) + self.view_controls_3d_dock.hide() + if QtCore.QFile.exists(label_file) and LabelFile.is_label_file(label_file): try: self.label_file = LabelFile(label_file) @@ -2408,8 +2684,9 @@ def open_file(self, _value=False): f"*.{fmt.data().decode()}" for fmt in QtGui.QImageReader.supportedImageFormats() ] + mesh_formats = [f"*{ext}" for ext in MESH_EXTENSIONS] filters = self.tr("Image & Label files (%s)") % " ".join( - formats + [f"*{LabelFile.suffix}"] + formats + mesh_formats + [f"*{LabelFile.suffix}"] ) file_dialog = FileDialogPreview(self) file_dialog.setFileMode(FileDialogPreview.ExistingFile) @@ -2524,7 +2801,10 @@ def get_label_file(self): if self.filename.lower().endswith(".json"): label_file = self.filename else: - label_file = osp.splitext(self.filename)[0] + ".json" + if is_mesh_file(self.filename): + label_file = osp.splitext(self.filename)[0] + ".anylabeling.json" + else: + label_file = osp.splitext(self.filename)[0] + ".json" return label_file @@ -2680,6 +2960,7 @@ def import_dropped_image_files(self, image_files): f".{fmt.data().decode().lower()}" for fmt in QtGui.QImageReader.supportedImageFormats() ] + extensions.extend(MESH_EXTENSIONS) self.filename = None for file in image_files: @@ -2711,6 +2992,7 @@ def import_image_folder(self, dirpath, pattern=None, load=True): return self.last_open_dir = dirpath + self._load_folder_labels() self.filename = None self.file_list_widget.clear() for filename in self.scan_all_images(dirpath): @@ -2735,6 +3017,7 @@ def scan_all_images(self, folder_path): for fmt in QtGui.QImageReader.supportedImageFormats() if fmt.data().decode().lower() != "svg" ] + extensions.extend(MESH_EXTENSIONS) images = [] for root, _, files in os.walk(folder_path): diff --git a/anylabeling/views/labeling/shape.py b/anylabeling/views/labeling/shape.py index 9ee8ae6..fe235ed 100644 --- a/anylabeling/views/labeling/shape.py +++ b/anylabeling/views/labeling/shape.py @@ -51,11 +51,13 @@ def __init__( shape_type=None, flags=None, group_id=None, + vertex_indices=None, ): self.label = label self.text = text self.group_id = group_id self.points = [] + self.vertex_indices = vertex_indices or [] self.fill = False self.selected = False self.shape_type = shape_type @@ -73,6 +75,10 @@ def __init__( self._closed = False + self._path = None # Cache for QPainterPath + self._vrtx_path = None # Cache for vertex QPainterPath + self._last_scale = None # Track scale for vertex path invalidation + if line_color is not None: # Override the class line_color attribute # with an object attribute. Currently this @@ -98,6 +104,8 @@ def shape_type(self, value): "line", "circle", "linestrip", + "brush_3d", + "keypoint_3d", ]: raise ValueError(f"Unexpected shape_type: {value}") self._shape_type = value @@ -112,6 +120,8 @@ def add_point(self, point): self.close() else: self.points.append(point) + self._path = None + self._vrtx_path = None def can_add_point(self): """Check if shape supports more points""" @@ -120,16 +130,22 @@ def can_add_point(self): def pop_point(self): """Remove and return the last point of the shape""" if self.points: + self._path = None + self._vrtx_path = None return self.points.pop() return None def insert_point(self, i, point): """Insert a point to a specific index""" self.points.insert(i, point) + self._path = None + self._vrtx_path = None def remove_point(self, i): """Remove point from a specific index""" self.points.pop(i) + self._path = None + self._vrtx_path = None def is_closed(self): """Check if the shape is closed""" @@ -154,63 +170,65 @@ def paint(self, painter: QtGui.QPainter): # noqa: C901 pen.setWidth(max(1, int(round(2.0 / self.scale)))) painter.setPen(pen) - line_path = QtGui.QPainterPath() - vrtx_path = QtGui.QPainterPath() - - if self.shape_type == "rectangle": - assert len(self.points) in [1, 2] - if len(self.points) == 2: - rectangle = self.get_rect_from_line(*self.points) - line_path.addRect(rectangle) - if self.selected: - for i in range(len(self.points)): - self.draw_vertex(vrtx_path, i) - elif self.shape_type == "circle": - assert len(self.points) in [1, 2] - if len(self.points) == 2: - rectangle = self.get_circle_rect_from_line(self.points) - line_path.addEllipse(rectangle) - if self.selected: - for i in range(len(self.points)): - self.draw_vertex(vrtx_path, i) - elif self.shape_type == "linestrip": - line_path.moveTo(self.points[0]) - if self.selected: - self.draw_vertex(vrtx_path, 0) - - # Small improvement to start at the 2nd point and technically correct - for i, p in enumerate(self.points[1:], start=1): - line_path.lineTo(p) - if self.selected: - self.draw_vertex(vrtx_path, i) - - elif self.shape_type == "point": - assert len(self.points) == 1 - self.draw_vertex(vrtx_path, 0) - else: - line_path.moveTo(self.points[0]) - # Uncommenting the following line will draw 2 paths - # for the 1st vertex, and make it non-filled, which - # may be desirable. - self.draw_vertex(vrtx_path, 0) - - # Small improvement to start at the 2nd point and technically correct - for i, p in enumerate(self.points[1:], start=1): - line_path.lineTo(p) - if self.selected: - self.draw_vertex(vrtx_path, i) + # Invalidate vertex path if scale changed (since vertex size depends on scale) + if self.scale != self._last_scale: + self._vrtx_path = None + self._last_scale = self.scale - if self.is_closed(): - # Properly close the path - line_path.closeSubpath() + if self._path is None or (self.selected and self._vrtx_path is None): + self._path = QtGui.QPainterPath() + self._vrtx_path = QtGui.QPainterPath() - painter.drawPath(line_path) - painter.drawPath(vrtx_path) + if self.shape_type == "rectangle": + assert len(self.points) in [1, 2] + if len(self.points) == 2: + rectangle = self.get_rect_from_line(*self.points) + self._path.addRect(rectangle) + if self.selected: + for i in range(len(self.points)): + self.draw_vertex(self._vrtx_path, i) + elif self.shape_type == "circle": + assert len(self.points) in [1, 2] + if len(self.points) == 2: + rectangle = self.get_circle_rect_from_line(self.points) + self._path.addEllipse(rectangle) + if self.selected: + for i in range(len(self.points)): + self.draw_vertex(self._vrtx_path, i) + elif self.shape_type == "linestrip": + self._path.moveTo(self.points[0]) + if self.selected: + self.draw_vertex(self._vrtx_path, 0) + + # Small improvement to start at the 2nd point and technically correct + for i, p in enumerate(self.points[1:], start=1): + self._path.lineTo(p) + if self.selected: + self.draw_vertex(self._vrtx_path, i) + + elif self.shape_type == "point": + assert len(self.points) == 1 + self.draw_vertex(self._vrtx_path, 0) + else: + self._path.moveTo(self.points[0]) + # Always draw first vertex for non-special shapes + self.draw_vertex(self._vrtx_path, 0) + + for i, p in enumerate(self.points[1:], start=1): + self._path.lineTo(p) + if self.selected: + self.draw_vertex(self._vrtx_path, i) + + if self.is_closed(): + self._path.closeSubpath() + + painter.drawPath(self._path) + painter.drawPath(self._vrtx_path) if self._vertex_fill_color is not None: - painter.fillPath(vrtx_path, self._vertex_fill_color) + painter.fillPath(self._vrtx_path, self._vertex_fill_color) if self.fill: color = self.select_fill_color if self.selected else self.fill_color - painter.fillPath(line_path, color) + painter.fillPath(self._path, color) def draw_vertex(self, path, i): """Draw a vertex""" @@ -262,7 +280,9 @@ def nearest_edge(self, point, epsilon): def contains_point(self, point): """Check if shape contains a point""" - return self.make_path().contains(point) + if self._path is None: + self._path = self.make_path() + return self._path.contains(point) def get_circle_rect_from_line(self, line): """Computes parameters to draw with `QPainterPath::addEllipse`""" @@ -299,10 +319,14 @@ def bounding_rect(self): def move_by(self, offset): """Move all points by an offset""" self.points = [p + offset for p in self.points] + self._path = None + self._vrtx_path = None def move_vertex_by(self, i, offset): """Move a specific vertex by an offset""" self.points[i] = self.points[i] + offset + self._path = None + self._vrtx_path = None def highlight_vertex(self, i, action): """Highlight a vertex appropriately based on the current action @@ -314,10 +338,12 @@ def highlight_vertex(self, i, action): """ self._highlight_index = i self._highlight_mode = action + self._vrtx_path = None def highlight_clear(self): """Clear the highlighted point""" self._highlight_index = None + self._vrtx_path = None def copy(self): """Copy shape""" diff --git a/anylabeling/views/labeling/utils/__init__.py b/anylabeling/views/labeling/utils/__init__.py index 45309dc..dcd4cf2 100644 --- a/anylabeling/views/labeling/utils/__init__.py +++ b/anylabeling/views/labeling/utils/__init__.py @@ -22,6 +22,36 @@ new_button, new_icon, ) + + +def encode_rle(data): + """Encode data using Run-Length Encoding""" + if len(data) == 0: + return [] + res = [] + current_val = data[0] + current_count = 0 + for val in data: + if val == current_val: + current_count += 1 + else: + res.extend([int(current_val), int(current_count)]) + current_val = val + current_count = 1 + res.extend([int(current_val), int(current_count)]) + return res + + +def decode_rle(rle): + """Decode data using Run-Length Encoding""" + res = [] + for i in range(0, len(rle), 2): + val = rle[i] + count = rle[i + 1] + res.extend([val] * count) + return res + + from .shape import ( masks_to_bboxes, polygons_to_mask, diff --git a/anylabeling/views/labeling/widgets/__init__.py b/anylabeling/views/labeling/widgets/__init__.py index f94ead3..506214c 100644 --- a/anylabeling/views/labeling/widgets/__init__.py +++ b/anylabeling/views/labeling/widgets/__init__.py @@ -3,6 +3,7 @@ from .auto_labeling import AutoLabelingWidget from .brightness_contrast_dialog import BrightnessContrastDialog from .canvas import Canvas +from .canvas3d import Canvas3D, ViewControls3D from .color_dialog import ColorDialog from .file_dialog_preview import FileDialogPreview from .label_dialog import LabelDialog, LabelQLineEdit diff --git a/anylabeling/views/labeling/widgets/canvas.py b/anylabeling/views/labeling/widgets/canvas.py index 8578de8..80d00f7 100644 --- a/anylabeling/views/labeling/widgets/canvas.py +++ b/anylabeling/views/labeling/widgets/canvas.py @@ -315,7 +315,7 @@ def mouseMoveEvent(self, ev): # noqa: C901 elif self.create_mode == "point": self.line.points = [self.current[0]] self.line.close() - self.repaint() + self.update() self.current.highlight_clear() return @@ -324,22 +324,22 @@ def mouseMoveEvent(self, ev): # noqa: C901 if self.selected_shapes_copy and self.prev_point: self.override_cursor(CURSOR_MOVE) self.bounded_move_shapes(self.selected_shapes_copy, pos) - self.repaint() + self.update() elif self.selected_shapes: self.selected_shapes_copy = [s.copy() for s in self.selected_shapes] - self.repaint() + self.update() return # Polygon/Vertex moving. if QtCore.Qt.MouseButton.LeftButton & ev.buttons(): if self.selected_vertex(): self.bounded_move_vertex(pos) - self.repaint() + self.update() self.moving_shape = True elif self.selected_shapes and self.prev_point: self.override_cursor(CURSOR_MOVE) self.bounded_move_shapes(self.selected_shapes, pos) - self.repaint() + self.update() self.moving_shape = True return diff --git a/anylabeling/views/labeling/widgets/canvas3d.py b/anylabeling/views/labeling/widgets/canvas3d.py new file mode 100644 index 0000000..9213810 --- /dev/null +++ b/anylabeling/views/labeling/widgets/canvas3d.py @@ -0,0 +1,1112 @@ +import numpy as np +import pyvista as pv +import vtk +from PyQt6 import QtCore +from PyQt6.QtWidgets import ( + QButtonGroup, + QCheckBox, + QComboBox, + QGroupBox, + QHBoxLayout, + QLabel, + QPushButton, + QSlider, + QVBoxLayout, + QWidget, +) +from pyvistaqt import QtInteractor + +from .. import utils +from ..shape import Shape + + +class ViewControls3D(QWidget): + """Collapsible controls panel for 3D mesh viewing options""" + + def __init__(self, canvas, parent=None): + super().__init__(parent) + self.canvas = canvas + self._build_ui() + + def _build_ui(self): + layout = QVBoxLayout() + layout.setContentsMargins(6, 6, 6, 6) + layout.setSpacing(6) + + # --- Mode toggle group --- + mode_group = QGroupBox("Mode") + mode_layout = QHBoxLayout() + mode_layout.setSpacing(2) + + self.mode_btn_group = QButtonGroup(self) + self.mode_btn_group.setExclusive(True) + + self.view_btn = QPushButton("View") + self.view_btn.setCheckable(True) + self.view_btn.setChecked(True) + self.view_btn.setFixedHeight(28) + + self.brush_btn = QPushButton("Brush") + self.brush_btn.setCheckable(True) + self.brush_btn.setFixedHeight(28) + + self.mode_btn_group.addButton(self.view_btn, 0) + self.mode_btn_group.addButton(self.brush_btn, 1) + + mode_layout.addWidget(self.view_btn) + mode_layout.addWidget(self.brush_btn) + + mode_group.setLayout(mode_layout) + layout.addWidget(mode_group) + + self.mode_btn_group.idClicked.connect(self._on_mode_clicked) + + # --- Brush settings group --- + brush_group = QGroupBox("Brush") + brush_layout = QVBoxLayout() + brush_layout.setSpacing(4) + + size_row = QHBoxLayout() + size_row.addWidget(QLabel("Size:")) + self.brush_size_slider = QSlider(QtCore.Qt.Orientation.Horizontal) + self.brush_size_slider.setRange(1, 100) + self.brush_size_slider.setValue(20) + self.brush_size_slider.valueChanged.connect(self._on_brush_size) + size_row.addWidget(self.brush_size_slider) + self.brush_size_label = QLabel("2.0%") + self.brush_size_label.setFixedWidth(42) + size_row.addWidget(self.brush_size_label) + brush_layout.addLayout(size_row) + + brush_group.setLayout(brush_layout) + layout.addWidget(brush_group) + + # --- Display group --- + display_group = QGroupBox("Display") + display_layout = QVBoxLayout() + display_layout.setSpacing(4) + + # Representation mode + rep_row = QHBoxLayout() + rep_row.addWidget(QLabel("Style:")) + self.rep_combo = QComboBox() + self.rep_combo.addItems(["Surface", "Wireframe", "Points", "Surface + Edges"]) + self.rep_combo.currentTextChanged.connect(self._on_representation) + rep_row.addWidget(self.rep_combo) + display_layout.addLayout(rep_row) + + # Show edges + self.edges_cb = QCheckBox("Show edges") + self.edges_cb.toggled.connect(self._on_edges_toggled) + display_layout.addWidget(self.edges_cb) + + # Double-sided rendering + self.doublesided_cb = QCheckBox("Double-sided") + self.doublesided_cb.setChecked(True) + self.doublesided_cb.toggled.connect(self._on_doublesided) + display_layout.addWidget(self.doublesided_cb) + + # Smooth shading + self.smooth_cb = QCheckBox("Smooth shading") + self.smooth_cb.setChecked(True) + self.smooth_cb.toggled.connect(self._on_smooth_shading) + display_layout.addWidget(self.smooth_cb) + + display_group.setLayout(display_layout) + layout.addWidget(display_group) + + # --- Material group --- + material_group = QGroupBox("Material") + material_layout = QVBoxLayout() + material_layout.setSpacing(4) + + # Opacity slider + opacity_row = QHBoxLayout() + opacity_row.addWidget(QLabel("Opacity:")) + self.opacity_slider = QSlider(QtCore.Qt.Orientation.Horizontal) + self.opacity_slider.setRange(10, 100) + self.opacity_slider.setValue(100) + self.opacity_slider.valueChanged.connect(self._on_opacity) + opacity_row.addWidget(self.opacity_slider) + self.opacity_label = QLabel("100%") + self.opacity_label.setFixedWidth(36) + opacity_row.addWidget(self.opacity_label) + material_layout.addLayout(opacity_row) + + # Metallic slider + metallic_row = QHBoxLayout() + metallic_row.addWidget(QLabel("Metallic:")) + self.metallic_slider = QSlider(QtCore.Qt.Orientation.Horizontal) + self.metallic_slider.setRange(0, 100) + self.metallic_slider.setValue(10) + self.metallic_slider.valueChanged.connect(self._on_metallic) + metallic_row.addWidget(self.metallic_slider) + self.metallic_label = QLabel("0.10") + self.metallic_label.setFixedWidth(36) + metallic_row.addWidget(self.metallic_label) + material_layout.addLayout(metallic_row) + + # Roughness slider + roughness_row = QHBoxLayout() + roughness_row.addWidget(QLabel("Roughness:")) + self.roughness_slider = QSlider(QtCore.Qt.Orientation.Horizontal) + self.roughness_slider.setRange(0, 100) + self.roughness_slider.setValue(50) + self.roughness_slider.valueChanged.connect(self._on_roughness) + roughness_row.addWidget(self.roughness_slider) + self.roughness_label = QLabel("0.50") + self.roughness_label.setFixedWidth(36) + roughness_row.addWidget(self.roughness_label) + material_layout.addLayout(roughness_row) + + # Color preset + color_row = QHBoxLayout() + color_row.addWidget(QLabel("Color:")) + self.color_combo = QComboBox() + self.color_combo.addItems( + ["White", "Light Gray", "Beige", "Light Blue", "Cyan", "Gold"] + ) + self.color_combo.currentTextChanged.connect(self._on_color) + color_row.addWidget(self.color_combo) + material_layout.addLayout(color_row) + + material_group.setLayout(material_layout) + layout.addWidget(material_group) + + # --- Camera group --- + camera_group = QGroupBox("Camera") + camera_layout = QVBoxLayout() + camera_layout.setSpacing(4) + + # View preset buttons + view_row1 = QHBoxLayout() + for label, view in [ + ("+X", (1, 0, 0)), + ("-X", (-1, 0, 0)), + ("+Y", (0, 1, 0)), + ("-Y", (0, -1, 0)), + ]: + btn = QPushButton(label) + btn.setFixedHeight(24) + btn.clicked.connect( + lambda _, v=view: self.canvas.set_viewup_and_position(v) + ) + view_row1.addWidget(btn) + camera_layout.addLayout(view_row1) + + view_row2 = QHBoxLayout() + for label, view in [ + ("+Z", (0, 0, 1)), + ("-Z", (0, 0, -1)), + ("Iso", "iso"), + ]: + btn = QPushButton(label) + btn.setFixedHeight(24) + btn.clicked.connect( + lambda _, v=view: self.canvas.set_viewup_and_position(v) + ) + view_row2.addWidget(btn) + + reset_btn = QPushButton("Reset") + reset_btn.setFixedHeight(24) + reset_btn.clicked.connect(self.canvas.reset_camera) + view_row2.addWidget(reset_btn) + camera_layout.addLayout(view_row2) + + # Projection + self.parallel_cb = QCheckBox("Parallel projection") + self.parallel_cb.toggled.connect(self._on_parallel_projection) + camera_layout.addWidget(self.parallel_cb) + + camera_group.setLayout(camera_layout) + layout.addWidget(camera_group) + + layout.addStretch() + self.setLayout(layout) + + # --- Callbacks --- + + def _on_representation(self, text): + self.canvas.set_representation(text) + + def _on_edges_toggled(self, checked): + # Sync combo when toggling edges independently + if checked and self.rep_combo.currentText() == "Surface": + self.rep_combo.blockSignals(True) + self.rep_combo.setCurrentText("Surface + Edges") + self.rep_combo.blockSignals(False) + elif not checked and self.rep_combo.currentText() == "Surface + Edges": + self.rep_combo.blockSignals(True) + self.rep_combo.setCurrentText("Surface") + self.rep_combo.blockSignals(False) + self.canvas.set_show_edges(checked) + + def _on_doublesided(self, checked): + self.canvas.set_doublesided(checked) + + def _on_smooth_shading(self, checked): + self.canvas.set_smooth_shading(checked) + + def _on_opacity(self, value): + self.opacity_label.setText(f"{value}%") + self.canvas.set_opacity(value / 100.0) + + def _on_metallic(self, value): + v = value / 100.0 + self.metallic_label.setText(f"{v:.2f}") + self.canvas.set_metallic(v) + + def _on_roughness(self, value): + v = value / 100.0 + self.roughness_label.setText(f"{v:.2f}") + self.canvas.set_roughness(v) + + def _on_color(self, text): + color_map = { + "White": "white", + "Light Gray": "lightgray", + "Beige": "wheat", + "Light Blue": "lightblue", + "Cyan": "lightcyan", + "Gold": "gold", + } + self.canvas.set_mesh_color(color_map.get(text, "white")) + + def _on_parallel_projection(self, checked): + self.canvas.set_parallel_projection(checked) + + def _on_brush_size(self, value): + pct = value / 10.0 + self.brush_size_label.setText(f"{pct:.1f}%") + # Compute actual radius from mesh bounding box diagonal + if self.canvas._main_mesh is not None: + bounds = self.canvas._main_mesh.bounds + diag = np.linalg.norm( + np.array([bounds[1], bounds[3], bounds[5]]) + - np.array([bounds[0], bounds[2], bounds[4]]) + ) + self.canvas.set_brush_radius(diag * pct / 100.0) + + def _on_mode_clicked(self, btn_id): + mode_map = {0: Canvas3D.VIEW, 1: Canvas3D.BRUSH} + mode = mode_map.get(btn_id, Canvas3D.VIEW) + self.canvas.set_mode(mode) + + def set_mode(self, mode): + """Sync toggle buttons to reflect externally set mode""" + mode_to_id = {Canvas3D.VIEW: 0, Canvas3D.BRUSH: 1} + btn_id = mode_to_id.get(mode, 0) + self.mode_btn_group.button(btn_id).setChecked(True) + + +class Canvas3D(QtInteractor): + """3D Canvas for mesh visualization and annotation""" + + # Emitted once when a new label is first painted (not per stroke) + new_shape = QtCore.pyqtSignal() + # Emitted when existing shape data changes (for dirty tracking) + shapes_updated = QtCore.pyqtSignal() + selection_changed = QtCore.pyqtSignal(list) + zoom_request = QtCore.pyqtSignal(int, QtCore.QPoint) + scroll_request = QtCore.pyqtSignal(int, QtCore.Qt.Orientation) + + VIEW = "view" + BRUSH = "brush" + + # Default rendering properties + _DEFAULT_COLOR = "white" + _DEFAULT_METALLIC = 0.1 + _DEFAULT_ROUGHNESS = 0.5 + _DEFAULT_OPACITY = 1.0 + + # Unlabeled sentinel + _NO_LABEL = -1 + + def __init__(self, parent=None): + # Suppress VTK warnings + vtk.vtkObject.GlobalWarningDisplayOff() + + super().__init__(parent) + self.parent = parent + self._main_mesh = None + self.mode = self.VIEW + self.brush_radius = 0.05 + self.active_label = "" + self.selected_shapes = [] + + # --- Efficient data structures --- + # Per-vertex label id: numpy int array, _NO_LABEL = unlabeled + self._vertex_label_ids = np.array([], dtype=np.int32) + # Bidirectional label <-> id mapping + self._label_to_id = {} # label_str -> int id + self._id_to_label = [] # id -> label_str + # Label colors: id -> (r, g, b) uint8 + self._label_colors = {} # label_str -> (r, g, b) + # One consolidated Shape per label for saving + self._shapes_by_label = {} # label_str -> Shape + + # Interaction state + self._painting = False + self._stroke_dirty = False # vertices changed during current drag + self._last_paint_pos = ( + None # position of the last paint event for interpolation + ) + self._last_screen_pos = ( + None # position of the last screen paint event for interpolation + ) + self._observer_tags = [] + self._cursor_actor_name = "__brush_cursor__" + + # Per-vertex RGB colors on the main mesh + self._vertex_colors = None # np.uint8 (n, 3) — current vertex colors + self._base_color_rgb = np.array([255, 255, 255], dtype=np.uint8) + # True once the main mesh actor is rendering with per-vertex scalar + # colors (i.e. after the first paint stroke). While this is True the + # paint hot path mutates self._main_mesh.point_data in place rather + # than re-running self.add_mesh — the latter is O(actor rebuild) and + # makes painting feel laggy on dense meshes. + self._scalar_mode_active = False + # Reused cursor sphere actor — created once per load_mesh and just + # repositioned on mouse-move. + self._cursor_actor = None + self._cursor_radius_baseline = 1.0 + + # Reusable picker (avoid re-creating per event) + self._picker = vtk.vtkCellPicker() + self._picker.SetTolerance(0.005) + + # VTK point locator for fast radius queries + self._point_locator = None + self._locator_dataset = None # prevent GC + self._mesh_points = None # stable copy of mesh points + + # Current rendering state + self._show_edges = False + self._smooth_shading = True + self._doublesided = True + self._color = self._DEFAULT_COLOR + self._metallic = self._DEFAULT_METALLIC + self._roughness = self._DEFAULT_ROUGHNESS + self._opacity = self._DEFAULT_OPACITY + + # Setup plotter. enable_trackball_style requires an interactive + # render-window iren, which isn't present in headless test envs + # (vtk-osmesa, no display) — guard so the widget can still be + # constructed for unit tests of the data-model layer. + try: + self.enable_trackball_style() + except RuntimeError: + pass + self.add_axes() + self.set_background("slategray", top="white") + self._setup_lighting() + + # --- Lighting --- + + def _setup_lighting(self): + """Configure three-point lighting for better surface perception""" + self.remove_all_lights() + key_light = pv.Light(position=(1, 1, 1), focal_point=(0, 0, 0), intensity=0.8) + key_light.positional = False + fill_light = pv.Light( + position=(-1, 0.5, 0.5), focal_point=(0, 0, 0), intensity=0.4 + ) + fill_light.positional = False + rim_light = pv.Light( + position=(0, -1, 0.5), focal_point=(0, 0, 0), intensity=0.3 + ) + rim_light.positional = False + self.add_light(key_light) + self.add_light(fill_light) + self.add_light(rim_light) + + # --- Mesh rendering --- + + def _get_main_actor(self): + if "main_mesh" in self.renderer.actors: + return self.renderer.actors["main_mesh"] + return None + + def _redraw_mesh(self): + if self._main_mesh is None: + return + + # Ensure _vertex_colors size matches mesh size to avoid ValueError + if ( + self._vertex_colors is not None + and len(self._vertex_colors) != self._main_mesh.n_points + ): + return + + # add_mesh below replaces every actor that lives under our names — + # including the cursor sphere if it shared the renderer. Drop the + # cached cursor reference so _ensure_cursor_actor recreates it lazily. + self._cursor_actor = None + # add_mesh re-creates the actor, so the in-place scalar fast path + # has to re-bootstrap on the next paint. + self._scalar_mode_active = False + + has_paint = self._vertex_colors is not None and np.any( + self._vertex_label_ids != self._NO_LABEL + ) + + if has_paint: + # Explicitly set scalars on the mesh object and ensure they are active + self._main_mesh.point_data["label_colors"] = self._vertex_colors + self._main_mesh.set_active_scalars("label_colors") + self.add_mesh( + self._main_mesh, + name="main_mesh", + pickable=True, + scalars="label_colors", + rgb=True, + opacity=self._opacity, + smooth_shading=self._smooth_shading, + split_sharp_edges=self._smooth_shading, + show_edges=self._show_edges, + reset_camera=False, + ) + else: + # Clean mesh, no paint — use PBR material + if "label_colors" in self._main_mesh.point_data: + del self._main_mesh.point_data["label_colors"] + self.add_mesh( + self._main_mesh, + name="main_mesh", + pickable=True, + pbr=True, + metallic=self._metallic, + roughness=self._roughness, + color=self._color, + opacity=self._opacity, + smooth_shading=self._smooth_shading, + split_sharp_edges=self._smooth_shading, + show_edges=self._show_edges, + reset_camera=False, + ) + + actor = self._get_main_actor() + if actor: + actor.GetProperty().SetBackfaceCulling(not self._doublesided) + self.render() + + def load_mesh(self, filename): + """Load and display a mesh file""" + self.clear() + self._shapes_by_label.clear() + self._label_to_id.clear() + self._id_to_label.clear() + # self.clear() removed all actors including any previous cursor sphere. + self._cursor_actor = None + self._scalar_mode_active = False + self._setup_lighting() + try: + self._main_mesh = pv.read(filename) + if not self._main_mesh.n_points: + raise ValueError("Mesh has no points") + + self._main_mesh.compute_normals(inplace=True) + n = self._main_mesh.n_points + + # Stable copy of vertex positions (survives add_mesh transforms) + self._mesh_points = np.array(self._main_mesh.points, copy=True) + + # Init vertex labels array + self._vertex_label_ids = np.full(n, self._NO_LABEL, dtype=np.int32) + + # Init per-vertex colors (all base color) + self._vertex_colors = np.tile(self._base_color_rgb, (n, 1)).astype(np.uint8) + + # Build VTK point locator for fast radius queries + self._build_point_locator() + + self._redraw_mesh() + self.reset_camera() + + # Brush radius = 2% of bounding box diagonal + bounds = self._main_mesh.bounds + diag = np.linalg.norm( + np.array([bounds[1], bounds[3], bounds[5]]) + - np.array([bounds[0], bounds[2], bounds[4]]) + ) + self.brush_radius = diag * 0.02 + + except Exception as e: + print(f"Error loading mesh: {e}") + + def _build_point_locator(self): + """Build a VTK static point locator for O(log n) radius queries""" + # Keep reference to dataset to prevent garbage collection + self._locator_dataset = pv.PolyData(self._mesh_points) + self._point_locator = vtk.vtkStaticPointLocator() + self._point_locator.SetDataSet(self._locator_dataset) + self._point_locator.BuildLocator() + + # --- Label id management --- + + @property + def vertex_label_ids(self): + """Return array of vertex label ids""" + return self._vertex_label_ids + + @vertex_label_ids.setter + def vertex_label_ids(self, value): + """Set vertex label ids""" + n_verts = len(self._vertex_label_ids) + ids = np.array(value, dtype=np.int32) + if len(ids) == n_verts: + self._vertex_label_ids = ids + self._refresh_vertex_colors() + + def load_vertex_label_ids(self, ids): + """Load vertex label ids from array of class ids (int) or RLE""" + if self._main_mesh is None: + return + n_verts = len(self._vertex_label_ids) + + # Check if it's RLE-encoded (heuristically or by checking decoded length) + if len(ids) != n_verts: + try: + decoded_ids = utils.decode_rle(ids) + if len(decoded_ids) == n_verts: + ids = decoded_ids + except Exception: + pass + + ids_arr = np.array(ids, dtype=np.int32) + if len(ids_arr) != n_verts: + return + + self._vertex_label_ids = ids_arr + + # Build shapes from label ids + self._shapes_by_label.clear() + unique_lids = np.unique(self._vertex_label_ids) + new_labels = [] + for lid in unique_lids: + if lid == self._NO_LABEL: + continue + + label = self._get_lid_to_label(lid) + if not label: + continue + + indices = np.where(self._vertex_label_ids == lid)[0] + if len(indices) > 0: + self._shapes_by_label[label] = Shape( + shape_type="brush_3d", + vertex_indices=sorted(indices.tolist()), + label=label, + ) + new_labels.append(label) + + self._refresh_vertex_colors() + for _ in new_labels: + self.new_shape.emit() + + def _get_or_create_label_id(self, label): + """Get numeric id for a label string, creating if needed""" + if label not in self._label_to_id: + lid = len(self._id_to_label) + self._label_to_id[label] = lid + self._id_to_label.append(label) + return self._label_to_id[label] + + def _get_lid_to_label(self, lid): + """Get label string for a numeric id""" + if 0 <= lid < len(self._id_to_label): + return self._id_to_label[lid] + return None + + # --- View control methods --- + + def set_representation(self, mode): + actor = self._get_main_actor() + if not actor: + return + prop = actor.GetProperty() + if mode == "Wireframe": + prop.SetRepresentationToWireframe() + self._show_edges = False + elif mode == "Points": + prop.SetRepresentationToPoints() + prop.SetPointSize(3) + self._show_edges = False + elif mode == "Surface + Edges": + prop.SetRepresentationToSurface() + prop.SetEdgeVisibility(True) + self._show_edges = True + else: + prop.SetRepresentationToSurface() + prop.SetEdgeVisibility(False) + self._show_edges = False + self.render() + + def set_show_edges(self, show): + self._show_edges = show + actor = self._get_main_actor() + if actor: + actor.GetProperty().SetEdgeVisibility(show) + self.render() + + def set_doublesided(self, enabled): + self._doublesided = enabled + actor = self._get_main_actor() + if actor: + actor.GetProperty().SetBackfaceCulling(not enabled) + self.render() + + def set_smooth_shading(self, enabled): + self._smooth_shading = enabled + self._redraw_mesh() + + def set_opacity(self, opacity): + self._opacity = opacity + actor = self._get_main_actor() + if actor: + actor.GetProperty().SetOpacity(opacity) + self.render() + + def set_metallic(self, value): + self._metallic = value + self._redraw_mesh() + + def set_roughness(self, value): + self._roughness = value + self._redraw_mesh() + + def set_mesh_color(self, color): + self._color = color + self._redraw_mesh() + + def set_parallel_projection(self, enabled): + if enabled: + self.enable_parallel_projection() + else: + self.disable_parallel_projection() + + def set_viewup_and_position(self, direction): + if self._main_mesh is None: + return + if direction == "iso": + self.view_isometric() + else: + dx, dy, dz = direction + view_up = (0, 1, 0) if abs(dz) == 1 else (0, 0, 1) + self.view_vector((-dx, -dy, -dz), viewup=view_up) + self.reset_camera() + + def set_brush_radius(self, radius): + self.brush_radius = radius + + # --- Mode and interaction --- + + def _iren_interactor(self): + """Return the live VTK interactor, or None in headless contexts.""" + try: + iren = self.iren.interactor if self.iren is not None else None + except RuntimeError: + iren = None + return iren + + def set_mode(self, mode): + self.mode = mode + self.disable_picking() + self._remove_paint_observers() + self._hide_cursor() + self._painting = False + if mode == self.VIEW: + try: + self.enable_trackball_style() + except RuntimeError: + pass + else: + iren = self._iren_interactor() + if iren is not None: + style = vtk.vtkInteractorStyleUser() + iren.SetInteractorStyle(style) + self._install_paint_observers() + + def _install_paint_observers(self): + self._remove_paint_observers() + iren = self._iren_interactor() + if iren is None: + return + self._observer_tags = [ + iren.AddObserver("MouseMoveEvent", self._on_mouse_move), + iren.AddObserver("LeftButtonPressEvent", self._on_left_press), + iren.AddObserver("LeftButtonReleaseEvent", self._on_left_release), + ] + + def _remove_paint_observers(self): + iren = self._iren_interactor() + if iren is None: + self._observer_tags = [] + return + for tag in self._observer_tags: + iren.RemoveObserver(tag) + self._observer_tags = [] + + def _on_mouse_move(self, obj, event): + if self._main_mesh is None: + return + pos = self.iren.interactor.GetEventPosition() + hit = self._raycast(pos) + if hit is not None: + self._show_cursor(hit) + if self._painting and self.mode == self.BRUSH: + self._paint_at(hit, pos) + else: + self._hide_cursor() + + def _on_left_press(self, obj, event): + if self._main_mesh is None: + return + self._painting = True + self._stroke_dirty = False + pos = self.iren.interactor.GetEventPosition() + hit = self._raycast(pos) + if hit is not None: + self._paint_at(hit, pos) + + def _on_left_release(self, obj, event): + if self._painting and self._stroke_dirty: + self.shapes_updated.emit() + self._painting = False + self._stroke_dirty = False + self._last_paint_pos = None + self._last_screen_pos = None + + # --- Raycasting (reuses picker) --- + + def _raycast(self, screen_pos): + hit = self._picker.Pick(screen_pos[0], screen_pos[1], 0, self.renderer) + if hit: + return np.array(self._picker.GetPickPosition()) + return None + + # --- Fast radius query via VTK locator --- + + def _find_vertices_in_radius(self, center): + """O(log n) radius query using VTK static point locator""" + if self._point_locator is None: + return np.array([], dtype=np.int64) + result = vtk.vtkIdList() + self._point_locator.FindPointsWithinRadius(self.brush_radius, center, result) + n = result.GetNumberOfIds() + if n == 0: + return np.array([], dtype=np.int64) + + # Optimized conversion from vtkIdList to numpy array + indices = np.empty(n, dtype=np.int64) + for i in range(n): + indices[i] = result.GetId(i) + return indices + + def _find_vertices_in_screen_radius(self, hit_point, screen_pos): + """Find vertices whose projection is within the brush radius on screen.""" + if self._point_locator is None or self._main_mesh is None: + return np.array([], dtype=np.int64) + + # 1. Estimate a loose 3D search radius to get candidates. + # We use a large enough radius to cover the projected area. + # This radius is approximated based on the brush radius and camera distance. + # Brush radius is a percentage of diagonal, let's use it directly for 3D search first + # to narrow down candidates. + search_radius = self.brush_radius * 2.0 + + candidates_ids = vtk.vtkIdList() + self._point_locator.FindPointsWithinRadius( + search_radius, hit_point, candidates_ids + ) + n = candidates_ids.GetNumberOfIds() + if n == 0: + return np.array([], dtype=np.int64) + + # 2. Project candidate vertices to screen space and check distance to mouse. + # Using vtkCoordinate for projection + coord = vtk.vtkCoordinate() + coord.SetCoordinateSystemToWorld() + + # Determine the 2D brush radius in pixels + # Currently brush_radius is in world units. + # We need to find the screen-space radius. + # Let's project two points separated by brush_radius in world space. + p1_world = hit_point + p2_world = hit_point + np.array([self.brush_radius, 0, 0]) + + def world_to_screen(world_pt): + coord.SetValue(*world_pt) + return np.array(coord.GetComputedDoubleDisplayValue(self.renderer)) + + p1_screen = world_to_screen(p1_world) + p2_screen = world_to_screen(p2_world) + pixel_radius = np.linalg.norm(p1_screen - p2_screen) + + target_screen = np.array(screen_pos) + + indices = [] + for i in range(n): + idx = candidates_ids.GetId(i) + pt_world = self._mesh_points[idx] + pt_screen = world_to_screen(pt_world) + if np.linalg.norm(pt_screen - target_screen) <= pixel_radius: + indices.append(idx) + + return np.array(indices, dtype=np.int64) + + # --- Mesh overlay for painting & cursor --- + + def _apply_colors_and_render(self): + """Push current vertex colours to VTK and re-render in place. + + Hot path during a brush stroke. The first invocation switches the + main mesh from PBR shading to per-vertex scalar colouring (one + full add_mesh, unavoidable). Every subsequent invocation just + mutates ``self._main_mesh.point_data`` and triggers a re-render — + roughly O(n_painted_verts) for the numpy assign and O(1) extra + VTK overhead instead of rebuilding the actor. + """ + if self._main_mesh is None or self._vertex_colors is None: + return + if not self._scalar_mode_active: + self._redraw_mesh() + self._scalar_mode_active = True + return + # Reassign — pyvista's wrapper marks the underlying VTK array + # modified, which is what the renderer needs to see new colours. + self._main_mesh.point_data["label_colors"] = self._vertex_colors + self._main_mesh.set_active_scalars("label_colors") + self.render() + + def _ensure_cursor_actor(self): + """Create the brush-cursor sphere once and reuse it across moves.""" + if self._cursor_actor is not None: + return + unit_sphere = pv.Sphere( + radius=1.0, + theta_resolution=16, + phi_resolution=16, + ) + self._cursor_actor = self.add_mesh( + unit_sphere, + color="cyan", + opacity=0.2, + name=self._cursor_actor_name, + pickable=False, + reset_camera=False, + ) + # Hide until the first _show_cursor call positions it. + self._cursor_actor.SetVisibility(False) + + def _show_cursor(self, center): + """Position and show the brush cursor sphere.""" + self._ensure_cursor_actor() + if self._cursor_actor is None: + return + r = float(self.brush_radius) + self._cursor_actor.SetScale(r, r, r) + self._cursor_actor.SetPosition(float(center[0]), float(center[1]), float(center[2])) + self._cursor_actor.SetVisibility(True) + + def _hide_cursor(self): + if self._cursor_actor is not None: + self._cursor_actor.SetVisibility(False) + + # --- Vertex painting --- + + def set_label_color(self, label, rgb): + self._label_colors[label] = tuple(rgb) + # Update existing painted vertices with new color + if label in self._label_to_id and self._vertex_colors is not None: + lid = self._label_to_id[label] + mask = self._vertex_label_ids == lid + if np.any(mask): + self._vertex_colors[mask] = [rgb[0], rgb[1], rgb[2]] + + def _paint_at(self, point, screen_pos=None): + """Paint vertices at a world-space point with immediate visual feedback.""" + label = self.active_label or "mask" + lid = self._get_or_create_label_id(label) + rgb = self._label_colors.get(label, (0, 255, 0)) + + if self.mode == self.BRUSH: + # Interpolate between last position and current position for smooth strokes + points_to_paint = [point] + screens_to_paint = [screen_pos] if screen_pos is not None else [None] + + if self._last_paint_pos is not None: + diff = point - self._last_paint_pos + dist = np.linalg.norm(diff) + # If distance is more than half a radius, interpolate + if dist > self.brush_radius * 0.5: + num_steps = int(dist / (self.brush_radius * 0.5)) + for i in range(1, num_steps): + interp_point = self._last_paint_pos + diff * (i / num_steps) + points_to_paint.append(interp_point) + # Also interpolate screen position if available + if ( + screen_pos is not None + and getattr(self, "_last_screen_pos", None) is not None + ): + s_diff = np.array(screen_pos) - np.array( + self._last_screen_pos + ) + interp_screen = np.array(self._last_screen_pos) + s_diff * ( + i / num_steps + ) + screens_to_paint.append(interp_screen) + else: + screens_to_paint.append(None) + + new_indices_set = set() + for p, s in zip(points_to_paint, screens_to_paint): + if s is not None: + indices = self._find_vertices_in_screen_radius(p, s) + else: + indices = self._find_vertices_in_radius(p) + + if len(indices) > 0: + self._vertex_label_ids[indices] = lid + self._vertex_colors[indices] = [rgb[0], rgb[1], rgb[2]] + new_indices_set.update(indices.tolist()) + + if new_indices_set: + self._merge_into_shape(label, new_indices_set, "brush_3d") + + self._last_paint_pos = point + if screen_pos is not None: + self._last_screen_pos = screen_pos + + self._stroke_dirty = True + self._apply_colors_and_render() + + def _merge_into_shape(self, label, new_indices, shape_type): + """Merge vertices into the consolidated shape for this label""" + if label in self._shapes_by_label: + shape = self._shapes_by_label[label] + # Use a set for much faster merging, then convert back to sorted list + existing = set(shape.vertex_indices) + existing.update(new_indices) + shape.vertex_indices = sorted(list(existing)) + else: + shape = Shape( + shape_type=shape_type, + vertex_indices=sorted(list(set(new_indices))), + label=label, + ) + self._shapes_by_label[label] = shape + self.new_shape.emit() + + def _refresh_vertex_colors(self): + """Rebuild vertex colors from vertex label ids""" + if self._vertex_colors is None: + return + + # Reset all to base color + self._vertex_colors[:] = self._base_color_rgb + + # Apply labels colors + n_labels = len(self._id_to_label) + for lid in range(n_labels): + mask = self._vertex_label_ids == lid + if not np.any(mask): + continue + label_str = self._id_to_label[lid] + rgb = self._label_colors.get(label_str, (0, 255, 0)) + self._vertex_colors[mask] = [rgb[0], rgb[1], rgb[2]] + + self._apply_colors_and_render() + + # --- Shape management --- + + @property + def shapes(self): + """Return consolidated list of shapes (one per label)""" + return list(self._shapes_by_label.values()) + + @shapes.setter + def shapes(self, value): + """Allow assignment for compatibility (e.g. shapes = [])""" + self._shapes_by_label.clear() + for s in value: + if s.label: + self._shapes_by_label[s.label] = s + + def add_shape(self, shape): + """Add a shape externally""" + lid = self._get_or_create_label_id(shape.label) + n_verts = len(self._vertex_label_ids) + indices = np.array(shape.vertex_indices, dtype=np.int64) + indices = indices[(indices >= 0) & (indices < n_verts)] + if len(indices) > 0: + self._vertex_label_ids[indices] = lid + self._shapes_by_label[shape.label] = shape + self._refresh_vertex_colors() + self.new_shape.emit() + + def load_shapes(self, shapes, replace=True): + if replace: + # If we already have vertex labels, we don't want to clear them here + # as they were likely loaded via load_vertex_label_ids already. + # We only clear if no vertex labels are present. + if np.all(self._vertex_label_ids == self._NO_LABEL): + self.clear_shapes() + else: + # Only clear non-brush shapes from our tracking + to_remove = [ + l + for l, s in self._shapes_by_label.items() + if s.shape_type not in ("brush_3d",) + ] + for l in to_remove: + del self._shapes_by_label[l] + + n_verts = len(self._vertex_label_ids) + for shape in shapes: + if shape.shape_type not in ("brush_3d",): + # Handle other potential shape types if necessary + continue + + # If it's a brush shape but we already have labels from vertex_label_ids, + # we skip it to avoid redundancy/overwriting with potentially older data. + if shape.shape_type == "brush_3d" and not np.all( + self._vertex_label_ids == self._NO_LABEL + ): + continue + + if not shape.vertex_indices: + continue + label = shape.label + lid = self._get_or_create_label_id(label) + indices = np.array(shape.vertex_indices, dtype=np.int64) + # Clamp to valid vertex range + indices = indices[(indices >= 0) & (indices < n_verts)] + if len(indices) == 0: + continue + self._vertex_label_ids[indices] = lid + # Merge into consolidated shape (no signal during bulk load) + if label in self._shapes_by_label: + existing = set(self._shapes_by_label[label].vertex_indices) + existing.update(indices.tolist()) + self._shapes_by_label[label].vertex_indices = sorted(existing) + else: + self._shapes_by_label[label] = Shape( + shape_type=shape.shape_type, + vertex_indices=sorted(indices.tolist()), + label=label, + ) + self._refresh_vertex_colors() + # Emit new_shape once per label for the label list + for label in self._shapes_by_label: + self.new_shape.emit() + + def clear_shapes(self): + if len(self._vertex_label_ids) > 0: + self._vertex_label_ids[:] = self._NO_LABEL + if self._vertex_colors is not None: + self._vertex_colors[:] = self._base_color_rgb + self._apply_colors_and_render() + self._shapes_by_label.clear() + self._label_to_id.clear() + self._id_to_label.clear() diff --git a/pyproject.toml b/pyproject.toml index f13922a..9e1b573 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,9 @@ dependencies = [ "darkdetect>=0.8.0", "huggingface_hub>=0.24.0", "osam>=0.4.0", # CLIP tokenizer for SAM3 language encoder + "pyvista>=0.43.0", + "pyvistaqt>=0.11.0", + "trimesh>=4.0.0", ] [project.optional-dependencies] diff --git a/sample_meshes/README.md b/sample_meshes/README.md new file mode 100644 index 0000000..0e2a689 --- /dev/null +++ b/sample_meshes/README.md @@ -0,0 +1,37 @@ +# Sample meshes + +Small synthetic meshes for trying out the 3D mesh-labeling feature +(`Canvas3D`). All four are generated by `pyvista` and saved with +`Plotter.export_obj()` — fully synthetic, no licensing constraints. + +| File | Vertices | Triangles | Notes | +| ------------ | -------- | --------- | --------------------------- | +| `cube.obj` | 8 | 12 | Smallest test case | +| `cone.obj` | 21 | 38 | Sharp apex, good for picker | +| `sphere.obj` | 530 | 1056 | Even subdivision | +| `torus.obj` | 529 | 1058 | Genus-1 topology | + +Total on disk: ~190 KB. + +## Regenerating + +```python +import pyvista as pv + +meshes = { + "cube.obj": pv.Cube().triangulate(), + "sphere.obj": pv.Sphere(theta_resolution=24, phi_resolution=24), + "torus.obj": pv.ParametricTorus(u_res=24, v_res=24).triangulate(), + "cone.obj": pv.Cone(resolution=20).triangulate(), +} +for name, mesh in meshes.items(): + pl = pv.Plotter(off_screen=True) + pl.add_mesh(mesh) + pl.export_obj(f"sample_meshes/{name}") + pl.close() +``` + +## Bring your own mesh + +Anything `pyvista.read()` understands works: `.obj`, `.ply`, `.stl`, +`.vtk`, `.vtu`, etc. diff --git a/sample_meshes/cone.obj b/sample_meshes/cone.obj new file mode 100644 index 0000000..084611e --- /dev/null +++ b/sample_meshes/cone.obj @@ -0,0 +1,66 @@ +# wavefront obj file written by the visualization toolkit + +mtllib cone.mtl + +v 0.5 0 0 +v -0.5 0.5 0 +v -0.5 0.4755282700061798 0.15450850129127502 +v -0.5 0.404508501291275 0.29389262199401855 +v -0.5 0.29389262199401855 0.404508501291275 +v -0.5 0.15450850129127502 0.4755282700061798 +v -0.5 3.0616171314629196e-17 0.5 +v -0.5 -0.15450850129127502 0.4755282700061798 +v -0.5 -0.29389262199401855 0.404508501291275 +v -0.5 -0.404508501291275 0.29389262199401855 +v -0.5 -0.4755282700061798 0.15450850129127502 +v -0.5 -0.5 6.123234262925839e-17 +v -0.5 -0.4755282700061798 -0.15450850129127502 +v -0.5 -0.404508501291275 -0.29389262199401855 +v -0.5 -0.29389262199401855 -0.404508501291275 +v -0.5 -0.15450850129127502 -0.4755282700061798 +v -0.5 -9.184850732644269e-17 -0.5 +v -0.5 0.15450850129127502 -0.4755282700061798 +v -0.5 0.29389262199401855 -0.404508501291275 +v -0.5 0.404508501291275 -0.29389262199401855 +v -0.5 0.4755282700061798 -0.15450850129127502 + +g grp1 +usemtl mtl1 +f 18 17 19 +f 19 17 20 +f 17 16 20 +f 16 15 20 +f 15 14 20 +f 20 14 21 +f 21 14 2 +f 2 14 3 +f 3 14 4 +f 4 14 5 +f 5 14 6 +f 14 13 6 +f 13 12 6 +f 12 11 6 +f 6 11 7 +f 7 11 8 +f 8 11 9 +f 11 10 9 +f 1 2 3 +f 1 3 4 +f 1 4 5 +f 1 5 6 +f 1 6 7 +f 1 7 8 +f 1 8 9 +f 1 9 10 +f 1 10 11 +f 1 11 12 +f 1 12 13 +f 1 13 14 +f 1 14 15 +f 1 15 16 +f 1 16 17 +f 1 17 18 +f 1 18 19 +f 1 19 20 +f 1 20 21 +f 1 21 2 diff --git a/sample_meshes/cube.obj b/sample_meshes/cube.obj new file mode 100644 index 0000000..17d3651 --- /dev/null +++ b/sample_meshes/cube.obj @@ -0,0 +1,43 @@ +# wavefront obj file written by the visualization toolkit + +mtllib cube.mtl + +v -0.5 -0.5 -0.5 +v -0.5 -0.5 0.5 +v -0.5 0.5 0.5 +v -0.5 0.5 -0.5 +v 0.5 -0.5 -0.5 +v 0.5 0.5 -0.5 +v 0.5 0.5 0.5 +v 0.5 -0.5 0.5 +vn -0.5773503184318542 -0.5773503184318542 -0.5773503184318542 +vn -0.5773503184318542 -0.5773503184318542 0.5773503184318542 +vn -0.5773503184318542 0.5773503184318542 0.5773503184318542 +vn -0.5773503184318542 0.5773503184318542 -0.5773503184318542 +vn 0.5773503184318542 -0.5773503184318542 -0.5773503184318542 +vn 0.5773503184318542 0.5773503184318542 -0.5773503184318542 +vn 0.5773503184318542 0.5773503184318542 0.5773503184318542 +vn 0.5773503184318542 -0.5773503184318542 0.5773503184318542 +vt 0 0 0 +vt 1 0 0 +vt 1 1 0 +vt 0 1 0 +vt 0 0 0 +vt 0 1 0 +vt -1 1 0 +vt -1 0 0 + +g grp1 +usemtl mtl1 +f 1/1/1 2/2/2 4/4/4 +f 3/3/3 4/4/4 2/2/2 +f 5/5/5 6/6/6 8/8/8 +f 7/7/7 8/8/8 6/6/6 +f 1/1/1 5/5/5 2/2/2 +f 8/8/8 2/2/2 5/5/5 +f 4/4/4 3/3/3 6/6/6 +f 7/7/7 6/6/6 3/3/3 +f 1/1/1 4/4/4 5/5/5 +f 6/6/6 5/5/5 4/4/4 +f 2/2/2 8/8/8 3/3/3 +f 7/7/7 3/3/3 8/8/8 diff --git a/sample_meshes/sphere.obj b/sample_meshes/sphere.obj new file mode 100644 index 0000000..e3e3192 --- /dev/null +++ b/sample_meshes/sphere.obj @@ -0,0 +1,2123 @@ +# wavefront obj file written by the visualization toolkit + +mtllib sphere.mtl + +v 0 0 0.5 +v 0 0 -0.5 +v 0.06808332353830338 0 0.4953429698944092 +v 0.134898379445076 0 0.4814586341381073 +v 0.19920054078102112 0 0.45860564708709717 +v 0.2597919702529907 0 0.4272097051143646 +v 0.3155439794063568 0 0.3878556489944458 +v 0.3654179871082306 0 0.3412765860557556 +v 0.40848493576049805 0 0.28834015130996704 +v 0.4439426064491272 0 0.2300325185060501 +v 0.47113046050071716 0 0.167439803481102 +v 0.48954203724861145 0 0.10172800719738007 +v 0.49883437156677246 0 0.034121207892894745 +v 0.49883437156677246 0 -0.034121207892894745 +v 0.48954203724861145 0 -0.10172800719738007 +v 0.47113046050071716 0 -0.167439803481102 +v 0.4439426064491272 0 -0.2300325185060501 +v 0.40848493576049805 0 -0.28834015130996704 +v 0.3654179871082306 0 -0.3412765860557556 +v 0.3155439794063568 0 -0.3878556489944458 +v 0.2597919702529907 0 -0.4272097051143646 +v 0.19920054078102112 0 -0.45860564708709717 +v 0.134898379445076 0 -0.4814586341381073 +v 0.06808332353830338 0 -0.4953429698944092 +v 0.0657634437084198 0.01762126013636589 0.4953429698944092 +v 0.130301833152771 0.03491427004337311 0.4814586341381073 +v 0.19241295754909515 0.051556896418333054 0.45860564708709717 +v 0.2509397864341736 0.06723911315202713 0.4272097051143646 +v 0.3047920763492584 0.08166878670454025 0.3878556489944458 +v 0.35296666622161865 0.0945771336555481 0.3412765860557556 +v 0.394566148519516 0.10572368651628494 0.28834015130996704 +v 0.428815633058548 0.11490080505609512 0.2300325185060501 +v 0.45507708191871643 0.12193753570318222 0.167439803481102 +v 0.47286128997802734 0.12670280039310455 0.10172800719738007 +v 0.4818370044231415 0.12910783290863037 0.034121207892894745 +v 0.4818370044231415 0.12910783290863037 -0.034121207892894745 +v 0.47286128997802734 0.12670280039310455 -0.10172800719738007 +v 0.45507708191871643 0.12193753570318222 -0.167439803481102 +v 0.428815633058548 0.11490080505609512 -0.2300325185060501 +v 0.394566148519516 0.10572368651628494 -0.28834015130996704 +v 0.35296666622161865 0.0945771336555481 -0.3412765860557556 +v 0.3047920763492584 0.08166878670454025 -0.3878556489944458 +v 0.2509397864341736 0.06723911315202713 -0.4272097051143646 +v 0.19241295754909515 0.051556896418333054 -0.45860564708709717 +v 0.130301833152771 0.03491427004337311 -0.4814586341381073 +v 0.0657634437084198 0.01762126013636589 -0.4953429698944092 +v 0.058961886912584305 0.03404166176915169 0.4953429698944092 +v 0.11682543158531189 0.067449189722538 0.4814586341381073 +v 0.1725127249956131 0.09960027039051056 0.45860564708709717 +v 0.22498644888401031 0.12989598512649536 0.4272097051143646 +v 0.27326908707618713 0.1577719897031784 0.3878556489944458 +v 0.3164612650871277 0.1827089935541153 0.3412765860557556 +v 0.3537583351135254 0.20424246788024902 0.28834015130996704 +v 0.3844655752182007 0.2219713032245636 0.2300325185060501 +v 0.40801095962524414 0.23556523025035858 0.167439803481102 +v 0.42395585775375366 0.24477101862430573 0.10172800719738007 +v 0.4320032596588135 0.24941718578338623 0.034121207892894745 +v 0.4320032596588135 0.24941718578338623 -0.034121207892894745 +v 0.42395585775375366 0.24477101862430573 -0.10172800719738007 +v 0.40801095962524414 0.23556523025035858 -0.167439803481102 +v 0.3844655752182007 0.2219713032245636 -0.2300325185060501 +v 0.3537583351135254 0.20424246788024902 -0.28834015130996704 +v 0.3164612650871277 0.1827089935541153 -0.3412765860557556 +v 0.27326908707618713 0.1577719897031784 -0.3878556489944458 +v 0.22498644888401031 0.12989598512649536 -0.4272097051143646 +v 0.1725127249956131 0.09960027039051056 -0.45860564708709717 +v 0.11682543158531189 0.067449189722538 -0.4814586341381073 +v 0.058961886912584305 0.03404166176915169 -0.4953429698944092 +v 0.04814217984676361 0.04814217984676361 0.4953429698944092 +v 0.09538756310939789 0.09538756310939789 0.4814586341381073 +v 0.1408560574054718 0.1408560574054718 0.45860564708709717 +v 0.18370066583156586 0.18370066583156586 0.4272097051143646 +v 0.22312328219413757 0.22312328219413757 0.3878556489944458 +v 0.25838953256607056 0.25838953256607056 0.3412765860557556 +v 0.28884246945381165 0.28884246945381165 0.28834015130996704 +v 0.31391483545303345 0.31391483545303345 0.2300325185060501 +v 0.3331395387649536 0.3331395387649536 0.167439803481102 +v 0.346158504486084 0.346158504486084 0.10172800719738007 +v 0.3527291715145111 0.3527291715145111 0.034121207892894745 +v 0.3527291715145111 0.3527291715145111 -0.034121207892894745 +v 0.346158504486084 0.346158504486084 -0.10172800719738007 +v 0.3331395387649536 0.3331395387649536 -0.167439803481102 +v 0.31391483545303345 0.31391483545303345 -0.2300325185060501 +v 0.28884246945381165 0.28884246945381165 -0.28834015130996704 +v 0.25838953256607056 0.25838953256607056 -0.3412765860557556 +v 0.22312328219413757 0.22312328219413757 -0.3878556489944458 +v 0.18370066583156586 0.18370066583156586 -0.4272097051143646 +v 0.1408560574054718 0.1408560574054718 -0.45860564708709717 +v 0.09538756310939789 0.09538756310939789 -0.4814586341381073 +v 0.04814217984676361 0.04814217984676361 -0.4953429698944092 +v 0.03404166176915169 0.058961886912584305 0.4953429698944092 +v 0.067449189722538 0.11682543158531189 0.4814586341381073 +v 0.09960027039051056 0.1725127249956131 0.45860564708709717 +v 0.12989598512649536 0.22498644888401031 0.4272097051143646 +v 0.1577719897031784 0.27326908707618713 0.3878556489944458 +v 0.1827089935541153 0.3164612650871277 0.3412765860557556 +v 0.20424246788024902 0.3537583351135254 0.28834015130996704 +v 0.2219713032245636 0.3844655752182007 0.2300325185060501 +v 0.23556523025035858 0.40801095962524414 0.167439803481102 +v 0.24477101862430573 0.42395585775375366 0.10172800719738007 +v 0.24941718578338623 0.4320032596588135 0.034121207892894745 +v 0.24941718578338623 0.4320032596588135 -0.034121207892894745 +v 0.24477101862430573 0.42395585775375366 -0.10172800719738007 +v 0.23556523025035858 0.40801095962524414 -0.167439803481102 +v 0.2219713032245636 0.3844655752182007 -0.2300325185060501 +v 0.20424246788024902 0.3537583351135254 -0.28834015130996704 +v 0.1827089935541153 0.3164612650871277 -0.3412765860557556 +v 0.1577719897031784 0.27326908707618713 -0.3878556489944458 +v 0.12989598512649536 0.22498644888401031 -0.4272097051143646 +v 0.09960027039051056 0.1725127249956131 -0.45860564708709717 +v 0.067449189722538 0.11682543158531189 -0.4814586341381073 +v 0.03404166176915169 0.058961886912584305 -0.4953429698944092 +v 0.01762126013636589 0.0657634437084198 0.4953429698944092 +v 0.03491427004337311 0.130301833152771 0.4814586341381073 +v 0.051556896418333054 0.19241295754909515 0.45860564708709717 +v 0.06723911315202713 0.2509397864341736 0.4272097051143646 +v 0.08166878670454025 0.3047920763492584 0.3878556489944458 +v 0.0945771336555481 0.35296666622161865 0.3412765860557556 +v 0.10572368651628494 0.394566148519516 0.28834015130996704 +v 0.11490080505609512 0.428815633058548 0.2300325185060501 +v 0.12193753570318222 0.45507708191871643 0.167439803481102 +v 0.12670280039310455 0.47286128997802734 0.10172800719738007 +v 0.12910783290863037 0.4818370044231415 0.034121207892894745 +v 0.12910783290863037 0.4818370044231415 -0.034121207892894745 +v 0.12670280039310455 0.47286128997802734 -0.10172800719738007 +v 0.12193753570318222 0.45507708191871643 -0.167439803481102 +v 0.11490080505609512 0.428815633058548 -0.2300325185060501 +v 0.10572368651628494 0.394566148519516 -0.28834015130996704 +v 0.0945771336555481 0.35296666622161865 -0.3412765860557556 +v 0.08166878670454025 0.3047920763492584 -0.3878556489944458 +v 0.06723911315202713 0.2509397864341736 -0.4272097051143646 +v 0.051556896418333054 0.19241295754909515 -0.45860564708709717 +v 0.03491427004337311 0.130301833152771 -0.4814586341381073 +v 0.01762126013636589 0.0657634437084198 -0.4953429698944092 +v 4.16890136535141e-18 0.06808332353830338 0.4953429698944092 +v 8.260143706073892e-18 0.134898379445076 0.4814586341381073 +v 1.2197515150020178e-17 0.19920054078102112 0.45860564708709717 +v 1.590767083304611e-17 0.2597919702529907 0.4272097051143646 +v 1.9321496506250434e-17 0.3155439794063568 0.3878556489944458 +v 2.237539769695946e-17 0.3654179871082306 0.3412765860557556 +v 2.5012489194447914e-17 0.40848493576049805 0.28834015130996704 +v 2.7183644742136274e-17 0.4439426064491272 0.2300325185060501 +v 2.884842017115437e-17 0.47113046050071716 0.167439803481102 +v 2.9975804480337595e-17 0.48954203724861145 0.10172800719738007 +v 3.054479555393322e-17 0.49883437156677246 0.034121207892894745 +v 3.054479555393322e-17 0.49883437156677246 -0.034121207892894745 +v 2.9975804480337595e-17 0.48954203724861145 -0.10172800719738007 +v 2.884842017115437e-17 0.47113046050071716 -0.167439803481102 +v 2.7183644742136274e-17 0.4439426064491272 -0.2300325185060501 +v 2.5012489194447914e-17 0.40848493576049805 -0.28834015130996704 +v 2.237539769695946e-17 0.3654179871082306 -0.3412765860557556 +v 1.9321496506250434e-17 0.3155439794063568 -0.3878556489944458 +v 1.590767083304611e-17 0.2597919702529907 -0.4272097051143646 +v 1.2197515150020178e-17 0.19920054078102112 -0.45860564708709717 +v 8.260143706073892e-18 0.134898379445076 -0.4814586341381073 +v 4.16890136535141e-18 0.06808332353830338 -0.4953429698944092 +v -0.01762126013636589 0.0657634437084198 0.4953429698944092 +v -0.03491427004337311 0.130301833152771 0.4814586341381073 +v -0.051556896418333054 0.19241295754909515 0.45860564708709717 +v -0.06723911315202713 0.2509397864341736 0.4272097051143646 +v -0.08166878670454025 0.3047920763492584 0.3878556489944458 +v -0.0945771336555481 0.35296666622161865 0.3412765860557556 +v -0.10572368651628494 0.394566148519516 0.28834015130996704 +v -0.11490080505609512 0.428815633058548 0.2300325185060501 +v -0.12193753570318222 0.45507708191871643 0.167439803481102 +v -0.12670280039310455 0.47286128997802734 0.10172800719738007 +v -0.12910783290863037 0.4818370044231415 0.034121207892894745 +v -0.12910783290863037 0.4818370044231415 -0.034121207892894745 +v -0.12670280039310455 0.47286128997802734 -0.10172800719738007 +v -0.12193753570318222 0.45507708191871643 -0.167439803481102 +v -0.11490080505609512 0.428815633058548 -0.2300325185060501 +v -0.10572368651628494 0.394566148519516 -0.28834015130996704 +v -0.0945771336555481 0.35296666622161865 -0.3412765860557556 +v -0.08166878670454025 0.3047920763492584 -0.3878556489944458 +v -0.06723911315202713 0.2509397864341736 -0.4272097051143646 +v -0.051556896418333054 0.19241295754909515 -0.45860564708709717 +v -0.03491427004337311 0.130301833152771 -0.4814586341381073 +v -0.01762126013636589 0.0657634437084198 -0.4953429698944092 +v -0.03404166176915169 0.058961886912584305 0.4953429698944092 +v -0.067449189722538 0.11682543158531189 0.4814586341381073 +v -0.09960027039051056 0.1725127249956131 0.45860564708709717 +v -0.12989598512649536 0.22498644888401031 0.4272097051143646 +v -0.1577719897031784 0.27326908707618713 0.3878556489944458 +v -0.1827089935541153 0.3164612650871277 0.3412765860557556 +v -0.20424246788024902 0.3537583351135254 0.28834015130996704 +v -0.2219713032245636 0.3844655752182007 0.2300325185060501 +v -0.23556523025035858 0.40801095962524414 0.167439803481102 +v -0.24477101862430573 0.42395585775375366 0.10172800719738007 +v -0.24941718578338623 0.4320032596588135 0.034121207892894745 +v -0.24941718578338623 0.4320032596588135 -0.034121207892894745 +v -0.24477101862430573 0.42395585775375366 -0.10172800719738007 +v -0.23556523025035858 0.40801095962524414 -0.167439803481102 +v -0.2219713032245636 0.3844655752182007 -0.2300325185060501 +v -0.20424246788024902 0.3537583351135254 -0.28834015130996704 +v -0.1827089935541153 0.3164612650871277 -0.3412765860557556 +v -0.1577719897031784 0.27326908707618713 -0.3878556489944458 +v -0.12989598512649536 0.22498644888401031 -0.4272097051143646 +v -0.09960027039051056 0.1725127249956131 -0.45860564708709717 +v -0.067449189722538 0.11682543158531189 -0.4814586341381073 +v -0.03404166176915169 0.058961886912584305 -0.4953429698944092 +v -0.04814217984676361 0.04814217984676361 0.4953429698944092 +v -0.09538756310939789 0.09538756310939789 0.4814586341381073 +v -0.1408560574054718 0.1408560574054718 0.45860564708709717 +v -0.18370066583156586 0.18370066583156586 0.4272097051143646 +v -0.22312328219413757 0.22312328219413757 0.3878556489944458 +v -0.25838953256607056 0.25838953256607056 0.3412765860557556 +v -0.28884246945381165 0.28884246945381165 0.28834015130996704 +v -0.31391483545303345 0.31391483545303345 0.2300325185060501 +v -0.3331395387649536 0.3331395387649536 0.167439803481102 +v -0.346158504486084 0.346158504486084 0.10172800719738007 +v -0.3527291715145111 0.3527291715145111 0.034121207892894745 +v -0.3527291715145111 0.3527291715145111 -0.034121207892894745 +v -0.346158504486084 0.346158504486084 -0.10172800719738007 +v -0.3331395387649536 0.3331395387649536 -0.167439803481102 +v -0.31391483545303345 0.31391483545303345 -0.2300325185060501 +v -0.28884246945381165 0.28884246945381165 -0.28834015130996704 +v -0.25838953256607056 0.25838953256607056 -0.3412765860557556 +v -0.22312328219413757 0.22312328219413757 -0.3878556489944458 +v -0.18370066583156586 0.18370066583156586 -0.4272097051143646 +v -0.1408560574054718 0.1408560574054718 -0.45860564708709717 +v -0.09538756310939789 0.09538756310939789 -0.4814586341381073 +v -0.04814217984676361 0.04814217984676361 -0.4953429698944092 +v -0.058961886912584305 0.03404166176915169 0.4953429698944092 +v -0.11682543158531189 0.067449189722538 0.4814586341381073 +v -0.1725127249956131 0.09960027039051056 0.45860564708709717 +v -0.22498644888401031 0.12989598512649536 0.4272097051143646 +v -0.27326908707618713 0.1577719897031784 0.3878556489944458 +v -0.3164612650871277 0.1827089935541153 0.3412765860557556 +v -0.3537583351135254 0.20424246788024902 0.28834015130996704 +v -0.3844655752182007 0.2219713032245636 0.2300325185060501 +v -0.40801095962524414 0.23556523025035858 0.167439803481102 +v -0.42395585775375366 0.24477101862430573 0.10172800719738007 +v -0.4320032596588135 0.24941718578338623 0.034121207892894745 +v -0.4320032596588135 0.24941718578338623 -0.034121207892894745 +v -0.42395585775375366 0.24477101862430573 -0.10172800719738007 +v -0.40801095962524414 0.23556523025035858 -0.167439803481102 +v -0.3844655752182007 0.2219713032245636 -0.2300325185060501 +v -0.3537583351135254 0.20424246788024902 -0.28834015130996704 +v -0.3164612650871277 0.1827089935541153 -0.3412765860557556 +v -0.27326908707618713 0.1577719897031784 -0.3878556489944458 +v -0.22498644888401031 0.12989598512649536 -0.4272097051143646 +v -0.1725127249956131 0.09960027039051056 -0.45860564708709717 +v -0.11682543158531189 0.067449189722538 -0.4814586341381073 +v -0.058961886912584305 0.03404166176915169 -0.4953429698944092 +v -0.0657634437084198 0.01762126013636589 0.4953429698944092 +v -0.130301833152771 0.03491427004337311 0.4814586341381073 +v -0.19241295754909515 0.051556896418333054 0.45860564708709717 +v -0.2509397864341736 0.06723911315202713 0.4272097051143646 +v -0.3047920763492584 0.08166878670454025 0.3878556489944458 +v -0.35296666622161865 0.0945771336555481 0.3412765860557556 +v -0.394566148519516 0.10572368651628494 0.28834015130996704 +v -0.428815633058548 0.11490080505609512 0.2300325185060501 +v -0.45507708191871643 0.12193753570318222 0.167439803481102 +v -0.47286128997802734 0.12670280039310455 0.10172800719738007 +v -0.4818370044231415 0.12910783290863037 0.034121207892894745 +v -0.4818370044231415 0.12910783290863037 -0.034121207892894745 +v -0.47286128997802734 0.12670280039310455 -0.10172800719738007 +v -0.45507708191871643 0.12193753570318222 -0.167439803481102 +v -0.428815633058548 0.11490080505609512 -0.2300325185060501 +v -0.394566148519516 0.10572368651628494 -0.28834015130996704 +v -0.35296666622161865 0.0945771336555481 -0.3412765860557556 +v -0.3047920763492584 0.08166878670454025 -0.3878556489944458 +v -0.2509397864341736 0.06723911315202713 -0.4272097051143646 +v -0.19241295754909515 0.051556896418333054 -0.45860564708709717 +v -0.130301833152771 0.03491427004337311 -0.4814586341381073 +v -0.0657634437084198 0.01762126013636589 -0.4953429698944092 +v -0.06808332353830338 8.33780273070282e-18 0.4953429698944092 +v -0.134898379445076 1.6520287412147783e-17 0.4814586341381073 +v -0.19920054078102112 2.4395030300040356e-17 0.45860564708709717 +v -0.2597919702529907 3.181534166609222e-17 0.4272097051143646 +v -0.3155439794063568 3.864299301250087e-17 0.3878556489944458 +v -0.3654179871082306 4.475079539391892e-17 0.3412765860557556 +v -0.40848493576049805 5.002497838889583e-17 0.28834015130996704 +v -0.4439426064491272 5.436728948427255e-17 0.2300325185060501 +v -0.47113046050071716 5.769684034230874e-17 0.167439803481102 +v -0.48954203724861145 5.995160896067519e-17 0.10172800719738007 +v -0.49883437156677246 6.108959110786644e-17 0.034121207892894745 +v -0.49883437156677246 6.108959110786644e-17 -0.034121207892894745 +v -0.48954203724861145 5.995160896067519e-17 -0.10172800719738007 +v -0.47113046050071716 5.769684034230874e-17 -0.167439803481102 +v -0.4439426064491272 5.436728948427255e-17 -0.2300325185060501 +v -0.40848493576049805 5.002497838889583e-17 -0.28834015130996704 +v -0.3654179871082306 4.475079539391892e-17 -0.3412765860557556 +v -0.3155439794063568 3.864299301250087e-17 -0.3878556489944458 +v -0.2597919702529907 3.181534166609222e-17 -0.4272097051143646 +v -0.19920054078102112 2.4395030300040356e-17 -0.45860564708709717 +v -0.134898379445076 1.6520287412147783e-17 -0.4814586341381073 +v -0.06808332353830338 8.33780273070282e-18 -0.4953429698944092 +v -0.0657634437084198 -0.01762126013636589 0.4953429698944092 +v -0.130301833152771 -0.03491427004337311 0.4814586341381073 +v -0.19241295754909515 -0.051556896418333054 0.45860564708709717 +v -0.2509397864341736 -0.06723911315202713 0.4272097051143646 +v -0.3047920763492584 -0.08166878670454025 0.3878556489944458 +v -0.35296666622161865 -0.0945771336555481 0.3412765860557556 +v -0.394566148519516 -0.10572368651628494 0.28834015130996704 +v -0.428815633058548 -0.11490080505609512 0.2300325185060501 +v -0.45507708191871643 -0.12193753570318222 0.167439803481102 +v -0.47286128997802734 -0.12670280039310455 0.10172800719738007 +v -0.4818370044231415 -0.12910783290863037 0.034121207892894745 +v -0.4818370044231415 -0.12910783290863037 -0.034121207892894745 +v -0.47286128997802734 -0.12670280039310455 -0.10172800719738007 +v -0.45507708191871643 -0.12193753570318222 -0.167439803481102 +v -0.428815633058548 -0.11490080505609512 -0.2300325185060501 +v -0.394566148519516 -0.10572368651628494 -0.28834015130996704 +v -0.35296666622161865 -0.0945771336555481 -0.3412765860557556 +v -0.3047920763492584 -0.08166878670454025 -0.3878556489944458 +v -0.2509397864341736 -0.06723911315202713 -0.4272097051143646 +v -0.19241295754909515 -0.051556896418333054 -0.45860564708709717 +v -0.130301833152771 -0.03491427004337311 -0.4814586341381073 +v -0.0657634437084198 -0.01762126013636589 -0.4953429698944092 +v -0.058961886912584305 -0.03404166176915169 0.4953429698944092 +v -0.11682543158531189 -0.067449189722538 0.4814586341381073 +v -0.1725127249956131 -0.09960027039051056 0.45860564708709717 +v -0.22498644888401031 -0.12989598512649536 0.4272097051143646 +v -0.27326908707618713 -0.1577719897031784 0.3878556489944458 +v -0.3164612650871277 -0.1827089935541153 0.3412765860557556 +v -0.3537583351135254 -0.20424246788024902 0.28834015130996704 +v -0.3844655752182007 -0.2219713032245636 0.2300325185060501 +v -0.40801095962524414 -0.23556523025035858 0.167439803481102 +v -0.42395585775375366 -0.24477101862430573 0.10172800719738007 +v -0.4320032596588135 -0.24941718578338623 0.034121207892894745 +v -0.4320032596588135 -0.24941718578338623 -0.034121207892894745 +v -0.42395585775375366 -0.24477101862430573 -0.10172800719738007 +v -0.40801095962524414 -0.23556523025035858 -0.167439803481102 +v -0.3844655752182007 -0.2219713032245636 -0.2300325185060501 +v -0.3537583351135254 -0.20424246788024902 -0.28834015130996704 +v -0.3164612650871277 -0.1827089935541153 -0.3412765860557556 +v -0.27326908707618713 -0.1577719897031784 -0.3878556489944458 +v -0.22498644888401031 -0.12989598512649536 -0.4272097051143646 +v -0.1725127249956131 -0.09960027039051056 -0.45860564708709717 +v -0.11682543158531189 -0.067449189722538 -0.4814586341381073 +v -0.058961886912584305 -0.03404166176915169 -0.4953429698944092 +v -0.04814217984676361 -0.04814217984676361 0.4953429698944092 +v -0.09538756310939789 -0.09538756310939789 0.4814586341381073 +v -0.1408560574054718 -0.1408560574054718 0.45860564708709717 +v -0.18370066583156586 -0.18370066583156586 0.4272097051143646 +v -0.22312328219413757 -0.22312328219413757 0.3878556489944458 +v -0.25838953256607056 -0.25838953256607056 0.3412765860557556 +v -0.28884246945381165 -0.28884246945381165 0.28834015130996704 +v -0.31391483545303345 -0.31391483545303345 0.2300325185060501 +v -0.3331395387649536 -0.3331395387649536 0.167439803481102 +v -0.346158504486084 -0.346158504486084 0.10172800719738007 +v -0.3527291715145111 -0.3527291715145111 0.034121207892894745 +v -0.3527291715145111 -0.3527291715145111 -0.034121207892894745 +v -0.346158504486084 -0.346158504486084 -0.10172800719738007 +v -0.3331395387649536 -0.3331395387649536 -0.167439803481102 +v -0.31391483545303345 -0.31391483545303345 -0.2300325185060501 +v -0.28884246945381165 -0.28884246945381165 -0.28834015130996704 +v -0.25838953256607056 -0.25838953256607056 -0.3412765860557556 +v -0.22312328219413757 -0.22312328219413757 -0.3878556489944458 +v -0.18370066583156586 -0.18370066583156586 -0.4272097051143646 +v -0.1408560574054718 -0.1408560574054718 -0.45860564708709717 +v -0.09538756310939789 -0.09538756310939789 -0.4814586341381073 +v -0.04814217984676361 -0.04814217984676361 -0.4953429698944092 +v -0.03404166176915169 -0.058961886912584305 0.4953429698944092 +v -0.067449189722538 -0.11682543158531189 0.4814586341381073 +v -0.09960027039051056 -0.1725127249956131 0.45860564708709717 +v -0.12989598512649536 -0.22498644888401031 0.4272097051143646 +v -0.1577719897031784 -0.27326908707618713 0.3878556489944458 +v -0.1827089935541153 -0.3164612650871277 0.3412765860557556 +v -0.20424246788024902 -0.3537583351135254 0.28834015130996704 +v -0.2219713032245636 -0.3844655752182007 0.2300325185060501 +v -0.23556523025035858 -0.40801095962524414 0.167439803481102 +v -0.24477101862430573 -0.42395585775375366 0.10172800719738007 +v -0.24941718578338623 -0.4320032596588135 0.034121207892894745 +v -0.24941718578338623 -0.4320032596588135 -0.034121207892894745 +v -0.24477101862430573 -0.42395585775375366 -0.10172800719738007 +v -0.23556523025035858 -0.40801095962524414 -0.167439803481102 +v -0.2219713032245636 -0.3844655752182007 -0.2300325185060501 +v -0.20424246788024902 -0.3537583351135254 -0.28834015130996704 +v -0.1827089935541153 -0.3164612650871277 -0.3412765860557556 +v -0.1577719897031784 -0.27326908707618713 -0.3878556489944458 +v -0.12989598512649536 -0.22498644888401031 -0.4272097051143646 +v -0.09960027039051056 -0.1725127249956131 -0.45860564708709717 +v -0.067449189722538 -0.11682543158531189 -0.4814586341381073 +v -0.03404166176915169 -0.058961886912584305 -0.4953429698944092 +v -0.01762126013636589 -0.0657634437084198 0.4953429698944092 +v -0.03491427004337311 -0.130301833152771 0.4814586341381073 +v -0.051556896418333054 -0.19241295754909515 0.45860564708709717 +v -0.06723911315202713 -0.2509397864341736 0.4272097051143646 +v -0.08166878670454025 -0.3047920763492584 0.3878556489944458 +v -0.0945771336555481 -0.35296666622161865 0.3412765860557556 +v -0.10572368651628494 -0.394566148519516 0.28834015130996704 +v -0.11490080505609512 -0.428815633058548 0.2300325185060501 +v -0.12193753570318222 -0.45507708191871643 0.167439803481102 +v -0.12670280039310455 -0.47286128997802734 0.10172800719738007 +v -0.12910783290863037 -0.4818370044231415 0.034121207892894745 +v -0.12910783290863037 -0.4818370044231415 -0.034121207892894745 +v -0.12670280039310455 -0.47286128997802734 -0.10172800719738007 +v -0.12193753570318222 -0.45507708191871643 -0.167439803481102 +v -0.11490080505609512 -0.428815633058548 -0.2300325185060501 +v -0.10572368651628494 -0.394566148519516 -0.28834015130996704 +v -0.0945771336555481 -0.35296666622161865 -0.3412765860557556 +v -0.08166878670454025 -0.3047920763492584 -0.3878556489944458 +v -0.06723911315202713 -0.2509397864341736 -0.4272097051143646 +v -0.051556896418333054 -0.19241295754909515 -0.45860564708709717 +v -0.03491427004337311 -0.130301833152771 -0.4814586341381073 +v -0.01762126013636589 -0.0657634437084198 -0.4953429698944092 +v -1.2506703682463924e-17 -0.06808332353830338 0.4953429698944092 +v -2.4780431945402287e-17 -0.134898379445076 0.4814586341381073 +v -3.659254793160237e-17 -0.19920054078102112 0.45860564708709717 +v -4.7723010844777106e-17 -0.2597919702529907 0.4272097051143646 +v -5.79644895187513e-17 -0.3155439794063568 0.3878556489944458 +v -6.712619639960083e-17 -0.3654179871082306 0.3412765860557556 +v -7.503746427462129e-17 -0.40848493576049805 0.28834015130996704 +v -8.155093588077005e-17 -0.4439426064491272 0.2300325185060501 +v -8.654526051346312e-17 -0.47113046050071716 0.167439803481102 +v -8.992741674973523e-17 -0.48954203724861145 0.10172800719738007 +v -9.163438666179966e-17 -0.49883437156677246 0.034121207892894745 +v -9.163438666179966e-17 -0.49883437156677246 -0.034121207892894745 +v -8.992741674973523e-17 -0.48954203724861145 -0.10172800719738007 +v -8.654526051346312e-17 -0.47113046050071716 -0.167439803481102 +v -8.155093588077005e-17 -0.4439426064491272 -0.2300325185060501 +v -7.503746427462129e-17 -0.40848493576049805 -0.28834015130996704 +v -6.712619639960083e-17 -0.3654179871082306 -0.3412765860557556 +v -5.79644895187513e-17 -0.3155439794063568 -0.3878556489944458 +v -4.7723010844777106e-17 -0.2597919702529907 -0.4272097051143646 +v -3.659254793160237e-17 -0.19920054078102112 -0.45860564708709717 +v -2.4780431945402287e-17 -0.134898379445076 -0.4814586341381073 +v -1.2506703682463924e-17 -0.06808332353830338 -0.4953429698944092 +v 0.01762126013636589 -0.0657634437084198 0.4953429698944092 +v 0.03491427004337311 -0.130301833152771 0.4814586341381073 +v 0.051556896418333054 -0.19241295754909515 0.45860564708709717 +v 0.06723911315202713 -0.2509397864341736 0.4272097051143646 +v 0.08166878670454025 -0.3047920763492584 0.3878556489944458 +v 0.0945771336555481 -0.35296666622161865 0.3412765860557556 +v 0.10572368651628494 -0.394566148519516 0.28834015130996704 +v 0.11490080505609512 -0.428815633058548 0.2300325185060501 +v 0.12193753570318222 -0.45507708191871643 0.167439803481102 +v 0.12670280039310455 -0.47286128997802734 0.10172800719738007 +v 0.12910783290863037 -0.4818370044231415 0.034121207892894745 +v 0.12910783290863037 -0.4818370044231415 -0.034121207892894745 +v 0.12670280039310455 -0.47286128997802734 -0.10172800719738007 +v 0.12193753570318222 -0.45507708191871643 -0.167439803481102 +v 0.11490080505609512 -0.428815633058548 -0.2300325185060501 +v 0.10572368651628494 -0.394566148519516 -0.28834015130996704 +v 0.0945771336555481 -0.35296666622161865 -0.3412765860557556 +v 0.08166878670454025 -0.3047920763492584 -0.3878556489944458 +v 0.06723911315202713 -0.2509397864341736 -0.4272097051143646 +v 0.051556896418333054 -0.19241295754909515 -0.45860564708709717 +v 0.03491427004337311 -0.130301833152771 -0.4814586341381073 +v 0.01762126013636589 -0.0657634437084198 -0.4953429698944092 +v 0.03404166176915169 -0.058961886912584305 0.4953429698944092 +v 0.067449189722538 -0.11682543158531189 0.4814586341381073 +v 0.09960027039051056 -0.1725127249956131 0.45860564708709717 +v 0.12989598512649536 -0.22498644888401031 0.4272097051143646 +v 0.1577719897031784 -0.27326908707618713 0.3878556489944458 +v 0.1827089935541153 -0.3164612650871277 0.3412765860557556 +v 0.20424246788024902 -0.3537583351135254 0.28834015130996704 +v 0.2219713032245636 -0.3844655752182007 0.2300325185060501 +v 0.23556523025035858 -0.40801095962524414 0.167439803481102 +v 0.24477101862430573 -0.42395585775375366 0.10172800719738007 +v 0.24941718578338623 -0.4320032596588135 0.034121207892894745 +v 0.24941718578338623 -0.4320032596588135 -0.034121207892894745 +v 0.24477101862430573 -0.42395585775375366 -0.10172800719738007 +v 0.23556523025035858 -0.40801095962524414 -0.167439803481102 +v 0.2219713032245636 -0.3844655752182007 -0.2300325185060501 +v 0.20424246788024902 -0.3537583351135254 -0.28834015130996704 +v 0.1827089935541153 -0.3164612650871277 -0.3412765860557556 +v 0.1577719897031784 -0.27326908707618713 -0.3878556489944458 +v 0.12989598512649536 -0.22498644888401031 -0.4272097051143646 +v 0.09960027039051056 -0.1725127249956131 -0.45860564708709717 +v 0.067449189722538 -0.11682543158531189 -0.4814586341381073 +v 0.03404166176915169 -0.058961886912584305 -0.4953429698944092 +v 0.04814217984676361 -0.04814217984676361 0.4953429698944092 +v 0.09538756310939789 -0.09538756310939789 0.4814586341381073 +v 0.1408560574054718 -0.1408560574054718 0.45860564708709717 +v 0.18370066583156586 -0.18370066583156586 0.4272097051143646 +v 0.22312328219413757 -0.22312328219413757 0.3878556489944458 +v 0.25838953256607056 -0.25838953256607056 0.3412765860557556 +v 0.28884246945381165 -0.28884246945381165 0.28834015130996704 +v 0.31391483545303345 -0.31391483545303345 0.2300325185060501 +v 0.3331395387649536 -0.3331395387649536 0.167439803481102 +v 0.346158504486084 -0.346158504486084 0.10172800719738007 +v 0.3527291715145111 -0.3527291715145111 0.034121207892894745 +v 0.3527291715145111 -0.3527291715145111 -0.034121207892894745 +v 0.346158504486084 -0.346158504486084 -0.10172800719738007 +v 0.3331395387649536 -0.3331395387649536 -0.167439803481102 +v 0.31391483545303345 -0.31391483545303345 -0.2300325185060501 +v 0.28884246945381165 -0.28884246945381165 -0.28834015130996704 +v 0.25838953256607056 -0.25838953256607056 -0.3412765860557556 +v 0.22312328219413757 -0.22312328219413757 -0.3878556489944458 +v 0.18370066583156586 -0.18370066583156586 -0.4272097051143646 +v 0.1408560574054718 -0.1408560574054718 -0.45860564708709717 +v 0.09538756310939789 -0.09538756310939789 -0.4814586341381073 +v 0.04814217984676361 -0.04814217984676361 -0.4953429698944092 +v 0.058961886912584305 -0.03404166176915169 0.4953429698944092 +v 0.11682543158531189 -0.067449189722538 0.4814586341381073 +v 0.1725127249956131 -0.09960027039051056 0.45860564708709717 +v 0.22498644888401031 -0.12989598512649536 0.4272097051143646 +v 0.27326908707618713 -0.1577719897031784 0.3878556489944458 +v 0.3164612650871277 -0.1827089935541153 0.3412765860557556 +v 0.3537583351135254 -0.20424246788024902 0.28834015130996704 +v 0.3844655752182007 -0.2219713032245636 0.2300325185060501 +v 0.40801095962524414 -0.23556523025035858 0.167439803481102 +v 0.42395585775375366 -0.24477101862430573 0.10172800719738007 +v 0.4320032596588135 -0.24941718578338623 0.034121207892894745 +v 0.4320032596588135 -0.24941718578338623 -0.034121207892894745 +v 0.42395585775375366 -0.24477101862430573 -0.10172800719738007 +v 0.40801095962524414 -0.23556523025035858 -0.167439803481102 +v 0.3844655752182007 -0.2219713032245636 -0.2300325185060501 +v 0.3537583351135254 -0.20424246788024902 -0.28834015130996704 +v 0.3164612650871277 -0.1827089935541153 -0.3412765860557556 +v 0.27326908707618713 -0.1577719897031784 -0.3878556489944458 +v 0.22498644888401031 -0.12989598512649536 -0.4272097051143646 +v 0.1725127249956131 -0.09960027039051056 -0.45860564708709717 +v 0.11682543158531189 -0.067449189722538 -0.4814586341381073 +v 0.058961886912584305 -0.03404166176915169 -0.4953429698944092 +v 0.0657634437084198 -0.01762126013636589 0.4953429698944092 +v 0.130301833152771 -0.03491427004337311 0.4814586341381073 +v 0.19241295754909515 -0.051556896418333054 0.45860564708709717 +v 0.2509397864341736 -0.06723911315202713 0.4272097051143646 +v 0.3047920763492584 -0.08166878670454025 0.3878556489944458 +v 0.35296666622161865 -0.0945771336555481 0.3412765860557556 +v 0.394566148519516 -0.10572368651628494 0.28834015130996704 +v 0.428815633058548 -0.11490080505609512 0.2300325185060501 +v 0.45507708191871643 -0.12193753570318222 0.167439803481102 +v 0.47286128997802734 -0.12670280039310455 0.10172800719738007 +v 0.4818370044231415 -0.12910783290863037 0.034121207892894745 +v 0.4818370044231415 -0.12910783290863037 -0.034121207892894745 +v 0.47286128997802734 -0.12670280039310455 -0.10172800719738007 +v 0.45507708191871643 -0.12193753570318222 -0.167439803481102 +v 0.428815633058548 -0.11490080505609512 -0.2300325185060501 +v 0.394566148519516 -0.10572368651628494 -0.28834015130996704 +v 0.35296666622161865 -0.0945771336555481 -0.3412765860557556 +v 0.3047920763492584 -0.08166878670454025 -0.3878556489944458 +v 0.2509397864341736 -0.06723911315202713 -0.4272097051143646 +v 0.19241295754909515 -0.051556896418333054 -0.45860564708709717 +v 0.130301833152771 -0.03491427004337311 -0.4814586341381073 +v 0.0657634437084198 -0.01762126013636589 -0.4953429698944092 +vn 0 0 1 +vn 0 0 -1 +vn 0.13616666197776794 0 0.9906859993934631 +vn 0.26979678869247437 0 0.9629173278808594 +vn 0.39840108156204224 0 0.9172112941741943 +vn 0.5195839405059814 0 0.8544194102287292 +vn 0.6310879588127136 0 0.7757112979888916 +vn 0.7308359742164612 0 0.6825531721115112 +vn 0.8169699311256409 0 0.5766803622245789 +vn 0.8878852128982544 0 0.4600650370121002 +vn 0.9422609210014343 0 0.334879606962204 +vn 0.9790840744972229 0 0.20345601439476013 +vn 0.9976688027381897 0 0.06824242323637009 +vn 0.9976688027381897 0 -0.06824242323637009 +vn 0.9790840744972229 0 -0.20345601439476013 +vn 0.9422609210014343 0 -0.334879606962204 +vn 0.8878852128982544 0 -0.4600650370121002 +vn 0.8169699311256409 0 -0.5766803622245789 +vn 0.7308359742164612 0 -0.6825531721115112 +vn 0.6310879588127136 0 -0.7757112979888916 +vn 0.5195839405059814 0 -0.8544194102287292 +vn 0.39840108156204224 0 -0.9172112941741943 +vn 0.26979678869247437 0 -0.9629173278808594 +vn 0.13616666197776794 0 -0.9906859993934631 +vn 0.1315269023180008 0.03524252399802208 0.9906859993934631 +vn 0.2606036961078644 0.06982854753732681 0.9629173278808594 +vn 0.3848259150981903 0.10311379283666611 0.9172112941741943 +vn 0.5018795728683472 0.13447822630405426 0.8544194102287292 +vn 0.6095841526985168 0.1633375734090805 0.7757112979888916 +vn 0.7059333324432373 0.1891542673110962 0.6825531721115112 +vn 0.7891323566436768 0.21144738793373108 0.5766803622245789 +vn 0.857631266117096 0.22980161011219025 0.4600650370121002 +vn 0.9101541638374329 0.24387507140636444 0.334879606962204 +vn 0.9457226395606995 0.2534056305885315 0.20345602929592133 +vn 0.9636740684509277 0.25821569561958313 0.06824242323637009 +vn 0.9636740684509277 0.25821569561958313 -0.06824242323637009 +vn 0.9457226395606995 0.2534056305885315 -0.20345602929592133 +vn 0.9101541638374329 0.24387507140636444 -0.334879606962204 +vn 0.857631266117096 0.22980161011219025 -0.4600650370121002 +vn 0.7891323566436768 0.21144738793373108 -0.5766803622245789 +vn 0.7059333324432373 0.1891542673110962 -0.6825531721115112 +vn 0.6095841526985168 0.1633375734090805 -0.7757112979888916 +vn 0.5018795728683472 0.13447822630405426 -0.8544194102287292 +vn 0.3848259150981903 0.10311379283666611 -0.9172112941741943 +vn 0.2606036961078644 0.06982854753732681 -0.9629173278808594 +vn 0.1315269023180008 0.03524252399802208 -0.9906859993934631 +vn 0.1179237812757492 0.06808333098888397 0.9906859993934631 +vn 0.23365086317062378 0.134898379445076 0.9629172682762146 +vn 0.3450254499912262 0.19920054078102112 0.9172112941741943 +vn 0.44997289776802063 0.2597919702529907 0.8544194102287292 +vn 0.5465381741523743 0.3155439794063568 0.7757112979888916 +vn 0.6329225301742554 0.3654179871082306 0.6825531721115112 +vn 0.7075167298316956 0.40848496556282043 0.5766803622245789 +vn 0.7689311504364014 0.4439426064491272 0.4600650370121002 +vn 0.8160219192504883 0.47113046050071716 0.334879606962204 +vn 0.8479117155075073 0.48954203724861145 0.20345601439476013 +vn 0.864006519317627 0.49883437156677246 0.06824241578578949 +vn 0.864006519317627 0.49883437156677246 -0.06824241578578949 +vn 0.8479117155075073 0.48954203724861145 -0.20345601439476013 +vn 0.8160219192504883 0.47113046050071716 -0.334879606962204 +vn 0.7689311504364014 0.4439426064491272 -0.4600650370121002 +vn 0.7075167298316956 0.40848496556282043 -0.5766803622245789 +vn 0.6329225301742554 0.3654179871082306 -0.6825531721115112 +vn 0.5465381741523743 0.3155439794063568 -0.7757112979888916 +vn 0.44997289776802063 0.2597919702529907 -0.8544194102287292 +vn 0.3450254499912262 0.19920054078102112 -0.9172112941741943 +vn 0.23365086317062378 0.134898379445076 -0.9629172682762146 +vn 0.1179237812757492 0.06808333098888397 -0.9906859993934631 +vn 0.09628436714410782 0.09628436714410782 0.9906859993934631 +vn 0.19077514111995697 0.19077514111995697 0.9629173278808594 +vn 0.2817121148109436 0.2817121148109436 0.9172112941741943 +vn 0.3674013614654541 0.3674013614654541 0.854419469833374 +vn 0.44624656438827515 0.44624656438827515 0.7757112979888916 +vn 0.5167790651321411 0.5167790651321411 0.6825531721115112 +vn 0.5776849985122681 0.5776849985122681 0.5766803622245789 +vn 0.6278296709060669 0.6278296709060669 0.4600650370121002 +vn 0.666279137134552 0.666279137134552 0.33487963676452637 +vn 0.692317008972168 0.692317008972168 0.20345601439476013 +vn 0.7054583430290222 0.7054583430290222 0.06824241578578949 +vn 0.7054583430290222 0.7054583430290222 -0.06824241578578949 +vn 0.692317008972168 0.692317008972168 -0.20345601439476013 +vn 0.666279137134552 0.666279137134552 -0.33487963676452637 +vn 0.6278296709060669 0.6278296709060669 -0.4600650370121002 +vn 0.5776849985122681 0.5776849985122681 -0.5766803622245789 +vn 0.5167790651321411 0.5167790651321411 -0.6825531721115112 +vn 0.44624656438827515 0.44624656438827515 -0.7757112979888916 +vn 0.3674013614654541 0.3674013614654541 -0.854419469833374 +vn 0.2817121148109436 0.2817121148109436 -0.9172112941741943 +vn 0.19077514111995697 0.19077514111995697 -0.9629173278808594 +vn 0.09628436714410782 0.09628436714410782 -0.9906859993934631 +vn 0.06808333098888397 0.1179237812757492 0.9906859993934631 +vn 0.134898379445076 0.23365086317062378 0.9629172682762146 +vn 0.19920054078102112 0.3450254499912262 0.9172112941741943 +vn 0.2597919702529907 0.44997289776802063 0.8544194102287292 +vn 0.3155439794063568 0.5465381741523743 0.7757112979888916 +vn 0.3654179871082306 0.6329225301742554 0.6825531721115112 +vn 0.40848496556282043 0.7075167298316956 0.5766803622245789 +vn 0.4439426064491272 0.7689311504364014 0.4600650370121002 +vn 0.47113046050071716 0.8160219192504883 0.334879606962204 +vn 0.48954203724861145 0.8479117155075073 0.20345601439476013 +vn 0.49883437156677246 0.864006519317627 0.06824241578578949 +vn 0.49883437156677246 0.864006519317627 -0.06824241578578949 +vn 0.48954203724861145 0.8479117155075073 -0.20345601439476013 +vn 0.47113046050071716 0.8160219192504883 -0.334879606962204 +vn 0.4439426064491272 0.7689311504364014 -0.4600650370121002 +vn 0.40848496556282043 0.7075167298316956 -0.5766803622245789 +vn 0.3654179871082306 0.6329225301742554 -0.6825531721115112 +vn 0.3155439794063568 0.5465381741523743 -0.7757112979888916 +vn 0.2597919702529907 0.44997289776802063 -0.8544194102287292 +vn 0.19920054078102112 0.3450254499912262 -0.9172112941741943 +vn 0.134898379445076 0.23365086317062378 -0.9629172682762146 +vn 0.06808333098888397 0.1179237812757492 -0.9906859993934631 +vn 0.03524252399802208 0.1315269023180008 0.9906859993934631 +vn 0.06982854753732681 0.2606036961078644 0.9629173278808594 +vn 0.10311379283666611 0.3848259150981903 0.9172112941741943 +vn 0.13447822630405426 0.5018795728683472 0.8544194102287292 +vn 0.1633375734090805 0.6095841526985168 0.7757112979888916 +vn 0.1891542673110962 0.7059333324432373 0.6825531721115112 +vn 0.21144738793373108 0.7891323566436768 0.5766803622245789 +vn 0.22980161011219025 0.857631266117096 0.4600650370121002 +vn 0.24387507140636444 0.9101541638374329 0.334879606962204 +vn 0.2534056305885315 0.9457226395606995 0.20345602929592133 +vn 0.25821569561958313 0.9636740684509277 0.06824242323637009 +vn 0.25821569561958313 0.9636740684509277 -0.06824242323637009 +vn 0.2534056305885315 0.9457226395606995 -0.20345602929592133 +vn 0.24387507140636444 0.9101541638374329 -0.334879606962204 +vn 0.22980161011219025 0.857631266117096 -0.4600650370121002 +vn 0.21144738793373108 0.7891323566436768 -0.5766803622245789 +vn 0.1891542673110962 0.7059333324432373 -0.6825531721115112 +vn 0.1633375734090805 0.6095841526985168 -0.7757112979888916 +vn 0.13447822630405426 0.5018795728683472 -0.8544194102287292 +vn 0.10311379283666611 0.3848259150981903 -0.9172112941741943 +vn 0.06982854753732681 0.2606036961078644 -0.9629173278808594 +vn 0.03524252399802208 0.1315269023180008 -0.9906859993934631 +vn 8.337803557883433e-18 0.13616666197776794 0.9906859993934631 +vn 1.6520289066509008e-17 0.26979678869247437 0.9629173278808594 +vn 2.4395030300040356e-17 0.39840108156204224 0.9172112941741943 +vn 3.181534166609222e-17 0.5195839405059814 0.8544194102287292 +vn 3.864299301250087e-17 0.6310879588127136 0.7757112979888916 +vn 4.475079539391892e-17 0.7308359742164612 0.6825531721115112 +vn 5.002498169761828e-17 0.8169699311256409 0.5766803622245789 +vn 5.436728948427255e-17 0.8878852128982544 0.4600650370121002 +vn 5.769684034230874e-17 0.9422609210014343 0.334879606962204 +vn 5.995160896067519e-17 0.9790840744972229 0.20345601439476013 +vn 6.108959772531134e-17 0.9976688027381897 0.06824242323637009 +vn 6.108959772531134e-17 0.9976688027381897 -0.06824242323637009 +vn 5.995160896067519e-17 0.9790840744972229 -0.20345601439476013 +vn 5.769684034230874e-17 0.9422609210014343 -0.334879606962204 +vn 5.436728948427255e-17 0.8878852128982544 -0.4600650370121002 +vn 5.002498169761828e-17 0.8169699311256409 -0.5766803622245789 +vn 4.475079539391892e-17 0.7308359742164612 -0.6825531721115112 +vn 3.864299301250087e-17 0.6310879588127136 -0.7757112979888916 +vn 3.181534166609222e-17 0.5195839405059814 -0.8544194102287292 +vn 2.4395030300040356e-17 0.39840108156204224 -0.9172112941741943 +vn 1.6520289066509008e-17 0.26979678869247437 -0.9629173278808594 +vn 8.337803557883433e-18 0.13616666197776794 -0.9906859993934631 +vn -0.03524252399802208 0.1315269023180008 0.9906859993934631 +vn -0.06982854753732681 0.2606036961078644 0.9629173278808594 +vn -0.10311379283666611 0.3848259150981903 0.9172112941741943 +vn -0.13447822630405426 0.5018795728683472 0.8544194102287292 +vn -0.1633375734090805 0.6095841526985168 0.7757112979888916 +vn -0.1891542673110962 0.7059333324432373 0.6825531721115112 +vn -0.21144738793373108 0.7891323566436768 0.5766803622245789 +vn -0.22980161011219025 0.857631266117096 0.4600650370121002 +vn -0.24387507140636444 0.9101541638374329 0.334879606962204 +vn -0.2534056305885315 0.9457226395606995 0.20345602929592133 +vn -0.25821569561958313 0.9636740684509277 0.06824242323637009 +vn -0.25821569561958313 0.9636740684509277 -0.06824242323637009 +vn -0.2534056305885315 0.9457226395606995 -0.20345602929592133 +vn -0.24387507140636444 0.9101541638374329 -0.334879606962204 +vn -0.22980161011219025 0.857631266117096 -0.4600650370121002 +vn -0.21144738793373108 0.7891323566436768 -0.5766803622245789 +vn -0.1891542673110962 0.7059333324432373 -0.6825531721115112 +vn -0.1633375734090805 0.6095841526985168 -0.7757112979888916 +vn -0.13447822630405426 0.5018795728683472 -0.8544194102287292 +vn -0.10311379283666611 0.3848259150981903 -0.9172112941741943 +vn -0.06982854753732681 0.2606036961078644 -0.9629173278808594 +vn -0.03524252399802208 0.1315269023180008 -0.9906859993934631 +vn -0.06808333098888397 0.1179237812757492 0.9906859993934631 +vn -0.134898379445076 0.23365086317062378 0.9629172682762146 +vn -0.19920054078102112 0.3450254499912262 0.9172112941741943 +vn -0.2597919702529907 0.44997289776802063 0.8544194102287292 +vn -0.3155439794063568 0.5465381741523743 0.7757112979888916 +vn -0.3654179871082306 0.6329225301742554 0.6825531721115112 +vn -0.40848496556282043 0.7075167298316956 0.5766803622245789 +vn -0.4439426064491272 0.7689311504364014 0.4600650370121002 +vn -0.47113046050071716 0.8160219192504883 0.334879606962204 +vn -0.48954203724861145 0.8479117155075073 0.20345601439476013 +vn -0.49883437156677246 0.864006519317627 0.06824241578578949 +vn -0.49883437156677246 0.864006519317627 -0.06824241578578949 +vn -0.48954203724861145 0.8479117155075073 -0.20345601439476013 +vn -0.47113046050071716 0.8160219192504883 -0.334879606962204 +vn -0.4439426064491272 0.7689311504364014 -0.4600650370121002 +vn -0.40848496556282043 0.7075167298316956 -0.5766803622245789 +vn -0.3654179871082306 0.6329225301742554 -0.6825531721115112 +vn -0.3155439794063568 0.5465381741523743 -0.7757112979888916 +vn -0.2597919702529907 0.44997289776802063 -0.8544194102287292 +vn -0.19920054078102112 0.3450254499912262 -0.9172112941741943 +vn -0.134898379445076 0.23365086317062378 -0.9629172682762146 +vn -0.06808333098888397 0.1179237812757492 -0.9906859993934631 +vn -0.09628436714410782 0.09628436714410782 0.9906859993934631 +vn -0.19077514111995697 0.19077514111995697 0.9629173278808594 +vn -0.2817121148109436 0.2817121148109436 0.9172112941741943 +vn -0.3674013614654541 0.3674013614654541 0.854419469833374 +vn -0.44624656438827515 0.44624656438827515 0.7757112979888916 +vn -0.5167790651321411 0.5167790651321411 0.6825531721115112 +vn -0.5776849985122681 0.5776849985122681 0.5766803622245789 +vn -0.6278296709060669 0.6278296709060669 0.4600650370121002 +vn -0.666279137134552 0.666279137134552 0.33487963676452637 +vn -0.692317008972168 0.692317008972168 0.20345601439476013 +vn -0.7054583430290222 0.7054583430290222 0.06824241578578949 +vn -0.7054583430290222 0.7054583430290222 -0.06824241578578949 +vn -0.692317008972168 0.692317008972168 -0.20345601439476013 +vn -0.666279137134552 0.666279137134552 -0.33487963676452637 +vn -0.6278296709060669 0.6278296709060669 -0.4600650370121002 +vn -0.5776849985122681 0.5776849985122681 -0.5766803622245789 +vn -0.5167790651321411 0.5167790651321411 -0.6825531721115112 +vn -0.44624656438827515 0.44624656438827515 -0.7757112979888916 +vn -0.3674013614654541 0.3674013614654541 -0.854419469833374 +vn -0.2817121148109436 0.2817121148109436 -0.9172112941741943 +vn -0.19077514111995697 0.19077514111995697 -0.9629173278808594 +vn -0.09628436714410782 0.09628436714410782 -0.9906859993934631 +vn -0.1179237812757492 0.06808333098888397 0.9906859993934631 +vn -0.23365086317062378 0.134898379445076 0.9629172682762146 +vn -0.3450254499912262 0.19920054078102112 0.9172112941741943 +vn -0.44997289776802063 0.2597919702529907 0.8544194102287292 +vn -0.5465381741523743 0.3155439794063568 0.7757112979888916 +vn -0.6329225301742554 0.3654179871082306 0.6825531721115112 +vn -0.7075167298316956 0.40848496556282043 0.5766803622245789 +vn -0.7689311504364014 0.4439426064491272 0.4600650370121002 +vn -0.8160219192504883 0.47113046050071716 0.334879606962204 +vn -0.8479117155075073 0.48954203724861145 0.20345601439476013 +vn -0.864006519317627 0.49883437156677246 0.06824241578578949 +vn -0.864006519317627 0.49883437156677246 -0.06824241578578949 +vn -0.8479117155075073 0.48954203724861145 -0.20345601439476013 +vn -0.8160219192504883 0.47113046050071716 -0.334879606962204 +vn -0.7689311504364014 0.4439426064491272 -0.4600650370121002 +vn -0.7075167298316956 0.40848496556282043 -0.5766803622245789 +vn -0.6329225301742554 0.3654179871082306 -0.6825531721115112 +vn -0.5465381741523743 0.3155439794063568 -0.7757112979888916 +vn -0.44997289776802063 0.2597919702529907 -0.8544194102287292 +vn -0.3450254499912262 0.19920054078102112 -0.9172112941741943 +vn -0.23365086317062378 0.134898379445076 -0.9629172682762146 +vn -0.1179237812757492 0.06808333098888397 -0.9906859993934631 +vn -0.1315269023180008 0.03524252399802208 0.9906859993934631 +vn -0.2606036961078644 0.06982854753732681 0.9629173278808594 +vn -0.3848259150981903 0.10311379283666611 0.9172112941741943 +vn -0.5018795728683472 0.13447822630405426 0.8544194102287292 +vn -0.6095841526985168 0.1633375734090805 0.7757112979888916 +vn -0.7059333324432373 0.1891542673110962 0.6825531721115112 +vn -0.7891323566436768 0.21144738793373108 0.5766803622245789 +vn -0.857631266117096 0.22980161011219025 0.4600650370121002 +vn -0.9101541638374329 0.24387507140636444 0.334879606962204 +vn -0.9457226395606995 0.2534056305885315 0.20345602929592133 +vn -0.9636740684509277 0.25821569561958313 0.06824242323637009 +vn -0.9636740684509277 0.25821569561958313 -0.06824242323637009 +vn -0.9457226395606995 0.2534056305885315 -0.20345602929592133 +vn -0.9101541638374329 0.24387507140636444 -0.334879606962204 +vn -0.857631266117096 0.22980161011219025 -0.4600650370121002 +vn -0.7891323566436768 0.21144738793373108 -0.5766803622245789 +vn -0.7059333324432373 0.1891542673110962 -0.6825531721115112 +vn -0.6095841526985168 0.1633375734090805 -0.7757112979888916 +vn -0.5018795728683472 0.13447822630405426 -0.8544194102287292 +vn -0.3848259150981903 0.10311379283666611 -0.9172112941741943 +vn -0.2606036961078644 0.06982854753732681 -0.9629173278808594 +vn -0.1315269023180008 0.03524252399802208 -0.9906859993934631 +vn -0.13616666197776794 1.6675607115766865e-17 0.9906859993934631 +vn -0.26979678869247437 3.3040578133018017e-17 0.9629173278808594 +vn -0.39840108156204224 4.879006060008071e-17 0.9172112941741943 +vn -0.5195839405059814 6.363068333218444e-17 0.8544194102287292 +vn -0.6310879588127136 7.728598602500174e-17 0.7757112979888916 +vn -0.7308359742164612 8.950159078783784e-17 0.6825531721115112 +vn -0.8169699311256409 1.0004996339523656e-16 0.5766803622245789 +vn -0.8878852128982544 1.087345789685451e-16 0.4600650370121002 +vn -0.9422609210014343 1.153936806846175e-16 0.334879606962204 +vn -0.9790840744972229 1.1990321792135038e-16 0.20345601439476013 +vn -0.9976688027381897 1.2217919545062268e-16 0.06824242323637009 +vn -0.9976688027381897 1.2217919545062268e-16 -0.06824242323637009 +vn -0.9790840744972229 1.1990321792135038e-16 -0.20345601439476013 +vn -0.9422609210014343 1.153936806846175e-16 -0.334879606962204 +vn -0.8878852128982544 1.087345789685451e-16 -0.4600650370121002 +vn -0.8169699311256409 1.0004996339523656e-16 -0.5766803622245789 +vn -0.7308359742164612 8.950159078783784e-17 -0.6825531721115112 +vn -0.6310879588127136 7.728598602500174e-17 -0.7757112979888916 +vn -0.5195839405059814 6.363068333218444e-17 -0.8544194102287292 +vn -0.39840108156204224 4.879006060008071e-17 -0.9172112941741943 +vn -0.26979678869247437 3.3040578133018017e-17 -0.9629173278808594 +vn -0.13616666197776794 1.6675607115766865e-17 -0.9906859993934631 +vn -0.1315269023180008 -0.03524252399802208 0.9906859993934631 +vn -0.2606036961078644 -0.06982854753732681 0.9629173278808594 +vn -0.3848259150981903 -0.10311379283666611 0.9172112941741943 +vn -0.5018795728683472 -0.13447822630405426 0.8544194102287292 +vn -0.6095841526985168 -0.1633375734090805 0.7757112979888916 +vn -0.7059333324432373 -0.1891542673110962 0.6825531721115112 +vn -0.7891323566436768 -0.21144738793373108 0.5766803622245789 +vn -0.857631266117096 -0.22980161011219025 0.4600650370121002 +vn -0.9101541638374329 -0.24387507140636444 0.334879606962204 +vn -0.9457226395606995 -0.2534056305885315 0.20345602929592133 +vn -0.9636740684509277 -0.25821569561958313 0.06824242323637009 +vn -0.9636740684509277 -0.25821569561958313 -0.06824242323637009 +vn -0.9457226395606995 -0.2534056305885315 -0.20345602929592133 +vn -0.9101541638374329 -0.24387507140636444 -0.334879606962204 +vn -0.857631266117096 -0.22980161011219025 -0.4600650370121002 +vn -0.7891323566436768 -0.21144738793373108 -0.5766803622245789 +vn -0.7059333324432373 -0.1891542673110962 -0.6825531721115112 +vn -0.6095841526985168 -0.1633375734090805 -0.7757112979888916 +vn -0.5018795728683472 -0.13447822630405426 -0.8544194102287292 +vn -0.3848259150981903 -0.10311379283666611 -0.9172112941741943 +vn -0.2606036961078644 -0.06982854753732681 -0.9629173278808594 +vn -0.1315269023180008 -0.03524252399802208 -0.9906859993934631 +vn -0.1179237812757492 -0.06808333098888397 0.9906859993934631 +vn -0.23365086317062378 -0.134898379445076 0.9629172682762146 +vn -0.3450254499912262 -0.19920054078102112 0.9172112941741943 +vn -0.44997289776802063 -0.2597919702529907 0.8544194102287292 +vn -0.5465381741523743 -0.3155439794063568 0.7757112979888916 +vn -0.6329225301742554 -0.3654179871082306 0.6825531721115112 +vn -0.7075167298316956 -0.40848496556282043 0.5766803622245789 +vn -0.7689311504364014 -0.4439426064491272 0.4600650370121002 +vn -0.8160219192504883 -0.47113046050071716 0.334879606962204 +vn -0.8479117155075073 -0.48954203724861145 0.20345601439476013 +vn -0.864006519317627 -0.49883437156677246 0.06824241578578949 +vn -0.864006519317627 -0.49883437156677246 -0.06824241578578949 +vn -0.8479117155075073 -0.48954203724861145 -0.20345601439476013 +vn -0.8160219192504883 -0.47113046050071716 -0.334879606962204 +vn -0.7689311504364014 -0.4439426064491272 -0.4600650370121002 +vn -0.7075167298316956 -0.40848496556282043 -0.5766803622245789 +vn -0.6329225301742554 -0.3654179871082306 -0.6825531721115112 +vn -0.5465381741523743 -0.3155439794063568 -0.7757112979888916 +vn -0.44997289776802063 -0.2597919702529907 -0.8544194102287292 +vn -0.3450254499912262 -0.19920054078102112 -0.9172112941741943 +vn -0.23365086317062378 -0.134898379445076 -0.9629172682762146 +vn -0.1179237812757492 -0.06808333098888397 -0.9906859993934631 +vn -0.09628436714410782 -0.09628436714410782 0.9906859993934631 +vn -0.19077514111995697 -0.19077514111995697 0.9629173278808594 +vn -0.2817121148109436 -0.2817121148109436 0.9172112941741943 +vn -0.3674013614654541 -0.3674013614654541 0.854419469833374 +vn -0.44624656438827515 -0.44624656438827515 0.7757112979888916 +vn -0.5167790651321411 -0.5167790651321411 0.6825531721115112 +vn -0.5776849985122681 -0.5776849985122681 0.5766803622245789 +vn -0.6278296709060669 -0.6278296709060669 0.4600650370121002 +vn -0.666279137134552 -0.666279137134552 0.33487963676452637 +vn -0.692317008972168 -0.692317008972168 0.20345601439476013 +vn -0.7054583430290222 -0.7054583430290222 0.06824241578578949 +vn -0.7054583430290222 -0.7054583430290222 -0.06824241578578949 +vn -0.692317008972168 -0.692317008972168 -0.20345601439476013 +vn -0.666279137134552 -0.666279137134552 -0.33487963676452637 +vn -0.6278296709060669 -0.6278296709060669 -0.4600650370121002 +vn -0.5776849985122681 -0.5776849985122681 -0.5766803622245789 +vn -0.5167790651321411 -0.5167790651321411 -0.6825531721115112 +vn -0.44624656438827515 -0.44624656438827515 -0.7757112979888916 +vn -0.3674013614654541 -0.3674013614654541 -0.854419469833374 +vn -0.2817121148109436 -0.2817121148109436 -0.9172112941741943 +vn -0.19077514111995697 -0.19077514111995697 -0.9629173278808594 +vn -0.09628436714410782 -0.09628436714410782 -0.9906859993934631 +vn -0.06808333098888397 -0.1179237812757492 0.9906859993934631 +vn -0.134898379445076 -0.23365086317062378 0.9629172682762146 +vn -0.19920054078102112 -0.3450254499912262 0.9172112941741943 +vn -0.2597919702529907 -0.44997289776802063 0.8544194102287292 +vn -0.3155439794063568 -0.5465381741523743 0.7757112979888916 +vn -0.3654179871082306 -0.6329225301742554 0.6825531721115112 +vn -0.40848496556282043 -0.7075167298316956 0.5766803622245789 +vn -0.4439426064491272 -0.7689311504364014 0.4600650370121002 +vn -0.47113046050071716 -0.8160219192504883 0.334879606962204 +vn -0.48954203724861145 -0.8479117155075073 0.20345601439476013 +vn -0.49883437156677246 -0.864006519317627 0.06824241578578949 +vn -0.49883437156677246 -0.864006519317627 -0.06824241578578949 +vn -0.48954203724861145 -0.8479117155075073 -0.20345601439476013 +vn -0.47113046050071716 -0.8160219192504883 -0.334879606962204 +vn -0.4439426064491272 -0.7689311504364014 -0.4600650370121002 +vn -0.40848496556282043 -0.7075167298316956 -0.5766803622245789 +vn -0.3654179871082306 -0.6329225301742554 -0.6825531721115112 +vn -0.3155439794063568 -0.5465381741523743 -0.7757112979888916 +vn -0.2597919702529907 -0.44997289776802063 -0.8544194102287292 +vn -0.19920054078102112 -0.3450254499912262 -0.9172112941741943 +vn -0.134898379445076 -0.23365086317062378 -0.9629172682762146 +vn -0.06808333098888397 -0.1179237812757492 -0.9906859993934631 +vn -0.03524252399802208 -0.1315269023180008 0.9906859993934631 +vn -0.06982854753732681 -0.2606036961078644 0.9629173278808594 +vn -0.10311379283666611 -0.3848259150981903 0.9172112941741943 +vn -0.13447822630405426 -0.5018795728683472 0.8544194102287292 +vn -0.1633375734090805 -0.6095841526985168 0.7757112979888916 +vn -0.1891542673110962 -0.7059333324432373 0.6825531721115112 +vn -0.21144738793373108 -0.7891323566436768 0.5766803622245789 +vn -0.22980161011219025 -0.857631266117096 0.4600650370121002 +vn -0.24387507140636444 -0.9101541638374329 0.334879606962204 +vn -0.2534056305885315 -0.9457226395606995 0.20345602929592133 +vn -0.25821569561958313 -0.9636740684509277 0.06824242323637009 +vn -0.25821569561958313 -0.9636740684509277 -0.06824242323637009 +vn -0.2534056305885315 -0.9457226395606995 -0.20345602929592133 +vn -0.24387507140636444 -0.9101541638374329 -0.334879606962204 +vn -0.22980161011219025 -0.857631266117096 -0.4600650370121002 +vn -0.21144738793373108 -0.7891323566436768 -0.5766803622245789 +vn -0.1891542673110962 -0.7059333324432373 -0.6825531721115112 +vn -0.1633375734090805 -0.6095841526985168 -0.7757112979888916 +vn -0.13447822630405426 -0.5018795728683472 -0.8544194102287292 +vn -0.10311379283666611 -0.3848259150981903 -0.9172112941741943 +vn -0.06982854753732681 -0.2606036961078644 -0.9629173278808594 +vn -0.03524252399802208 -0.1315269023180008 -0.9906859993934631 +vn -2.5013409019289073e-17 -0.13616666197776794 0.9906859993934631 +vn -4.9560867199527025e-17 -0.26979678869247437 0.9629173278808594 +vn -7.318509586320474e-17 -0.39840108156204224 0.9172112941741943 +vn -9.544602168955421e-17 -0.5195839405059814 0.8544194102287292 +vn -1.159289790375026e-16 -0.6310879588127136 0.7757112979888916 +vn -1.3425239279920165e-16 -0.7308359742164612 0.6825531721115112 +vn -1.5007494178413238e-16 -0.8169699311256409 0.5766803622245789 +vn -1.631018717615401e-16 -0.8878852128982544 0.4600650370121002 +vn -1.7309052102692623e-16 -0.9422609210014343 0.334879606962204 +vn -1.7985483349947047e-16 -0.9790840744972229 0.20345601439476013 +vn -1.8326878655848913e-16 -0.9976688027381897 0.06824242323637009 +vn -1.8326878655848913e-16 -0.9976688027381897 -0.06824242323637009 +vn -1.7985483349947047e-16 -0.9790840744972229 -0.20345601439476013 +vn -1.7309052102692623e-16 -0.9422609210014343 -0.334879606962204 +vn -1.631018717615401e-16 -0.8878852128982544 -0.4600650370121002 +vn -1.5007494178413238e-16 -0.8169699311256409 -0.5766803622245789 +vn -1.3425239279920165e-16 -0.7308359742164612 -0.6825531721115112 +vn -1.159289790375026e-16 -0.6310879588127136 -0.7757112979888916 +vn -9.544602168955421e-17 -0.5195839405059814 -0.8544194102287292 +vn -7.318509586320474e-17 -0.39840108156204224 -0.9172112941741943 +vn -4.9560867199527025e-17 -0.26979678869247437 -0.9629173278808594 +vn -2.5013409019289073e-17 -0.13616666197776794 -0.9906859993934631 +vn 0.03524252399802208 -0.1315269023180008 0.9906859993934631 +vn 0.06982854753732681 -0.2606036961078644 0.9629173278808594 +vn 0.10311379283666611 -0.3848259150981903 0.9172112941741943 +vn 0.13447822630405426 -0.5018795728683472 0.8544194102287292 +vn 0.1633375734090805 -0.6095841526985168 0.7757112979888916 +vn 0.1891542673110962 -0.7059333324432373 0.6825531721115112 +vn 0.21144738793373108 -0.7891323566436768 0.5766803622245789 +vn 0.22980161011219025 -0.857631266117096 0.4600650370121002 +vn 0.24387507140636444 -0.9101541638374329 0.334879606962204 +vn 0.2534056305885315 -0.9457226395606995 0.20345602929592133 +vn 0.25821569561958313 -0.9636740684509277 0.06824242323637009 +vn 0.25821569561958313 -0.9636740684509277 -0.06824242323637009 +vn 0.2534056305885315 -0.9457226395606995 -0.20345602929592133 +vn 0.24387507140636444 -0.9101541638374329 -0.334879606962204 +vn 0.22980161011219025 -0.857631266117096 -0.4600650370121002 +vn 0.21144738793373108 -0.7891323566436768 -0.5766803622245789 +vn 0.1891542673110962 -0.7059333324432373 -0.6825531721115112 +vn 0.1633375734090805 -0.6095841526985168 -0.7757112979888916 +vn 0.13447822630405426 -0.5018795728683472 -0.8544194102287292 +vn 0.10311379283666611 -0.3848259150981903 -0.9172112941741943 +vn 0.06982854753732681 -0.2606036961078644 -0.9629173278808594 +vn 0.03524252399802208 -0.1315269023180008 -0.9906859993934631 +vn 0.06808333098888397 -0.1179237812757492 0.9906859993934631 +vn 0.134898379445076 -0.23365086317062378 0.9629172682762146 +vn 0.19920054078102112 -0.3450254499912262 0.9172112941741943 +vn 0.2597919702529907 -0.44997289776802063 0.8544194102287292 +vn 0.3155439794063568 -0.5465381741523743 0.7757112979888916 +vn 0.3654179871082306 -0.6329225301742554 0.6825531721115112 +vn 0.40848496556282043 -0.7075167298316956 0.5766803622245789 +vn 0.4439426064491272 -0.7689311504364014 0.4600650370121002 +vn 0.47113046050071716 -0.8160219192504883 0.334879606962204 +vn 0.48954203724861145 -0.8479117155075073 0.20345601439476013 +vn 0.49883437156677246 -0.864006519317627 0.06824241578578949 +vn 0.49883437156677246 -0.864006519317627 -0.06824241578578949 +vn 0.48954203724861145 -0.8479117155075073 -0.20345601439476013 +vn 0.47113046050071716 -0.8160219192504883 -0.334879606962204 +vn 0.4439426064491272 -0.7689311504364014 -0.4600650370121002 +vn 0.40848496556282043 -0.7075167298316956 -0.5766803622245789 +vn 0.3654179871082306 -0.6329225301742554 -0.6825531721115112 +vn 0.3155439794063568 -0.5465381741523743 -0.7757112979888916 +vn 0.2597919702529907 -0.44997289776802063 -0.8544194102287292 +vn 0.19920054078102112 -0.3450254499912262 -0.9172112941741943 +vn 0.134898379445076 -0.23365086317062378 -0.9629172682762146 +vn 0.06808333098888397 -0.1179237812757492 -0.9906859993934631 +vn 0.09628436714410782 -0.09628436714410782 0.9906859993934631 +vn 0.19077514111995697 -0.19077514111995697 0.9629173278808594 +vn 0.2817121148109436 -0.2817121148109436 0.9172112941741943 +vn 0.3674013614654541 -0.3674013614654541 0.854419469833374 +vn 0.44624656438827515 -0.44624656438827515 0.7757112979888916 +vn 0.5167790651321411 -0.5167790651321411 0.6825531721115112 +vn 0.5776849985122681 -0.5776849985122681 0.5766803622245789 +vn 0.6278296709060669 -0.6278296709060669 0.4600650370121002 +vn 0.666279137134552 -0.666279137134552 0.33487963676452637 +vn 0.692317008972168 -0.692317008972168 0.20345601439476013 +vn 0.7054583430290222 -0.7054583430290222 0.06824241578578949 +vn 0.7054583430290222 -0.7054583430290222 -0.06824241578578949 +vn 0.692317008972168 -0.692317008972168 -0.20345601439476013 +vn 0.666279137134552 -0.666279137134552 -0.33487963676452637 +vn 0.6278296709060669 -0.6278296709060669 -0.4600650370121002 +vn 0.5776849985122681 -0.5776849985122681 -0.5766803622245789 +vn 0.5167790651321411 -0.5167790651321411 -0.6825531721115112 +vn 0.44624656438827515 -0.44624656438827515 -0.7757112979888916 +vn 0.3674013614654541 -0.3674013614654541 -0.854419469833374 +vn 0.2817121148109436 -0.2817121148109436 -0.9172112941741943 +vn 0.19077514111995697 -0.19077514111995697 -0.9629173278808594 +vn 0.09628436714410782 -0.09628436714410782 -0.9906859993934631 +vn 0.1179237812757492 -0.06808333098888397 0.9906859993934631 +vn 0.23365086317062378 -0.134898379445076 0.9629172682762146 +vn 0.3450254499912262 -0.19920054078102112 0.9172112941741943 +vn 0.44997289776802063 -0.2597919702529907 0.8544194102287292 +vn 0.5465381741523743 -0.3155439794063568 0.7757112979888916 +vn 0.6329225301742554 -0.3654179871082306 0.6825531721115112 +vn 0.7075167298316956 -0.40848496556282043 0.5766803622245789 +vn 0.7689311504364014 -0.4439426064491272 0.4600650370121002 +vn 0.8160219192504883 -0.47113046050071716 0.334879606962204 +vn 0.8479117155075073 -0.48954203724861145 0.20345601439476013 +vn 0.864006519317627 -0.49883437156677246 0.06824241578578949 +vn 0.864006519317627 -0.49883437156677246 -0.06824241578578949 +vn 0.8479117155075073 -0.48954203724861145 -0.20345601439476013 +vn 0.8160219192504883 -0.47113046050071716 -0.334879606962204 +vn 0.7689311504364014 -0.4439426064491272 -0.4600650370121002 +vn 0.7075167298316956 -0.40848496556282043 -0.5766803622245789 +vn 0.6329225301742554 -0.3654179871082306 -0.6825531721115112 +vn 0.5465381741523743 -0.3155439794063568 -0.7757112979888916 +vn 0.44997289776802063 -0.2597919702529907 -0.8544194102287292 +vn 0.3450254499912262 -0.19920054078102112 -0.9172112941741943 +vn 0.23365086317062378 -0.134898379445076 -0.9629172682762146 +vn 0.1179237812757492 -0.06808333098888397 -0.9906859993934631 +vn 0.1315269023180008 -0.03524252399802208 0.9906859993934631 +vn 0.2606036961078644 -0.06982854753732681 0.9629173278808594 +vn 0.3848259150981903 -0.10311379283666611 0.9172112941741943 +vn 0.5018795728683472 -0.13447822630405426 0.8544194102287292 +vn 0.6095841526985168 -0.1633375734090805 0.7757112979888916 +vn 0.7059333324432373 -0.1891542673110962 0.6825531721115112 +vn 0.7891323566436768 -0.21144738793373108 0.5766803622245789 +vn 0.857631266117096 -0.22980161011219025 0.4600650370121002 +vn 0.9101541638374329 -0.24387507140636444 0.334879606962204 +vn 0.9457226395606995 -0.2534056305885315 0.20345602929592133 +vn 0.9636740684509277 -0.25821569561958313 0.06824242323637009 +vn 0.9636740684509277 -0.25821569561958313 -0.06824242323637009 +vn 0.9457226395606995 -0.2534056305885315 -0.20345602929592133 +vn 0.9101541638374329 -0.24387507140636444 -0.334879606962204 +vn 0.857631266117096 -0.22980161011219025 -0.4600650370121002 +vn 0.7891323566436768 -0.21144738793373108 -0.5766803622245789 +vn 0.7059333324432373 -0.1891542673110962 -0.6825531721115112 +vn 0.6095841526985168 -0.1633375734090805 -0.7757112979888916 +vn 0.5018795728683472 -0.13447822630405426 -0.8544194102287292 +vn 0.3848259150981903 -0.10311379283666611 -0.9172112941741943 +vn 0.2606036961078644 -0.06982854753732681 -0.9629173278808594 +vn 0.1315269023180008 -0.03524252399802208 -0.9906859993934631 + +g grp1 +usemtl mtl1 +f 3//3 25//25 1//1 +f 25//25 47//47 1//1 +f 47//47 69//69 1//1 +f 69//69 91//91 1//1 +f 91//91 113//113 1//1 +f 113//113 135//135 1//1 +f 135//135 157//157 1//1 +f 157//157 179//179 1//1 +f 179//179 201//201 1//1 +f 201//201 223//223 1//1 +f 223//223 245//245 1//1 +f 245//245 267//267 1//1 +f 267//267 289//289 1//1 +f 289//289 311//311 1//1 +f 311//311 333//333 1//1 +f 333//333 355//355 1//1 +f 355//355 377//377 1//1 +f 377//377 399//399 1//1 +f 399//399 421//421 1//1 +f 421//421 443//443 1//1 +f 443//443 465//465 1//1 +f 465//465 487//487 1//1 +f 487//487 509//509 1//1 +f 509//509 3//3 1//1 +f 24//24 2//2 46//46 +f 46//46 2//2 68//68 +f 68//68 2//2 90//90 +f 90//90 2//2 112//112 +f 112//112 2//2 134//134 +f 134//134 2//2 156//156 +f 156//156 2//2 178//178 +f 178//178 2//2 200//200 +f 200//200 2//2 222//222 +f 222//222 2//2 244//244 +f 244//244 2//2 266//266 +f 266//266 2//2 288//288 +f 288//288 2//2 310//310 +f 310//310 2//2 332//332 +f 332//332 2//2 354//354 +f 354//354 2//2 376//376 +f 376//376 2//2 398//398 +f 398//398 2//2 420//420 +f 420//420 2//2 442//442 +f 442//442 2//2 464//464 +f 464//464 2//2 486//486 +f 486//486 2//2 508//508 +f 508//508 2//2 530//530 +f 530//530 2//2 24//24 +f 3//3 4//4 26//26 +f 3//3 26//26 25//25 +f 4//4 5//5 27//27 +f 4//4 27//27 26//26 +f 5//5 6//6 28//28 +f 5//5 28//28 27//27 +f 6//6 7//7 29//29 +f 6//6 29//29 28//28 +f 7//7 8//8 30//30 +f 7//7 30//30 29//29 +f 8//8 9//9 31//31 +f 8//8 31//31 30//30 +f 9//9 10//10 32//32 +f 9//9 32//32 31//31 +f 10//10 11//11 33//33 +f 10//10 33//33 32//32 +f 11//11 12//12 34//34 +f 11//11 34//34 33//33 +f 12//12 13//13 35//35 +f 12//12 35//35 34//34 +f 13//13 14//14 36//36 +f 13//13 36//36 35//35 +f 14//14 15//15 37//37 +f 14//14 37//37 36//36 +f 15//15 16//16 38//38 +f 15//15 38//38 37//37 +f 16//16 17//17 39//39 +f 16//16 39//39 38//38 +f 17//17 18//18 40//40 +f 17//17 40//40 39//39 +f 18//18 19//19 41//41 +f 18//18 41//41 40//40 +f 19//19 20//20 42//42 +f 19//19 42//42 41//41 +f 20//20 21//21 43//43 +f 20//20 43//43 42//42 +f 21//21 22//22 44//44 +f 21//21 44//44 43//43 +f 22//22 23//23 45//45 +f 22//22 45//45 44//44 +f 23//23 24//24 46//46 +f 23//23 46//46 45//45 +f 25//25 26//26 48//48 +f 25//25 48//48 47//47 +f 26//26 27//27 49//49 +f 26//26 49//49 48//48 +f 27//27 28//28 50//50 +f 27//27 50//50 49//49 +f 28//28 29//29 51//51 +f 28//28 51//51 50//50 +f 29//29 30//30 52//52 +f 29//29 52//52 51//51 +f 30//30 31//31 53//53 +f 30//30 53//53 52//52 +f 31//31 32//32 54//54 +f 31//31 54//54 53//53 +f 32//32 33//33 55//55 +f 32//32 55//55 54//54 +f 33//33 34//34 56//56 +f 33//33 56//56 55//55 +f 34//34 35//35 57//57 +f 34//34 57//57 56//56 +f 35//35 36//36 58//58 +f 35//35 58//58 57//57 +f 36//36 37//37 59//59 +f 36//36 59//59 58//58 +f 37//37 38//38 60//60 +f 37//37 60//60 59//59 +f 38//38 39//39 61//61 +f 38//38 61//61 60//60 +f 39//39 40//40 62//62 +f 39//39 62//62 61//61 +f 40//40 41//41 63//63 +f 40//40 63//63 62//62 +f 41//41 42//42 64//64 +f 41//41 64//64 63//63 +f 42//42 43//43 65//65 +f 42//42 65//65 64//64 +f 43//43 44//44 66//66 +f 43//43 66//66 65//65 +f 44//44 45//45 67//67 +f 44//44 67//67 66//66 +f 45//45 46//46 68//68 +f 45//45 68//68 67//67 +f 47//47 48//48 70//70 +f 47//47 70//70 69//69 +f 48//48 49//49 71//71 +f 48//48 71//71 70//70 +f 49//49 50//50 72//72 +f 49//49 72//72 71//71 +f 50//50 51//51 73//73 +f 50//50 73//73 72//72 +f 51//51 52//52 74//74 +f 51//51 74//74 73//73 +f 52//52 53//53 75//75 +f 52//52 75//75 74//74 +f 53//53 54//54 76//76 +f 53//53 76//76 75//75 +f 54//54 55//55 77//77 +f 54//54 77//77 76//76 +f 55//55 56//56 78//78 +f 55//55 78//78 77//77 +f 56//56 57//57 79//79 +f 56//56 79//79 78//78 +f 57//57 58//58 80//80 +f 57//57 80//80 79//79 +f 58//58 59//59 81//81 +f 58//58 81//81 80//80 +f 59//59 60//60 82//82 +f 59//59 82//82 81//81 +f 60//60 61//61 83//83 +f 60//60 83//83 82//82 +f 61//61 62//62 84//84 +f 61//61 84//84 83//83 +f 62//62 63//63 85//85 +f 62//62 85//85 84//84 +f 63//63 64//64 86//86 +f 63//63 86//86 85//85 +f 64//64 65//65 87//87 +f 64//64 87//87 86//86 +f 65//65 66//66 88//88 +f 65//65 88//88 87//87 +f 66//66 67//67 89//89 +f 66//66 89//89 88//88 +f 67//67 68//68 90//90 +f 67//67 90//90 89//89 +f 69//69 70//70 92//92 +f 69//69 92//92 91//91 +f 70//70 71//71 93//93 +f 70//70 93//93 92//92 +f 71//71 72//72 94//94 +f 71//71 94//94 93//93 +f 72//72 73//73 95//95 +f 72//72 95//95 94//94 +f 73//73 74//74 96//96 +f 73//73 96//96 95//95 +f 74//74 75//75 97//97 +f 74//74 97//97 96//96 +f 75//75 76//76 98//98 +f 75//75 98//98 97//97 +f 76//76 77//77 99//99 +f 76//76 99//99 98//98 +f 77//77 78//78 100//100 +f 77//77 100//100 99//99 +f 78//78 79//79 101//101 +f 78//78 101//101 100//100 +f 79//79 80//80 102//102 +f 79//79 102//102 101//101 +f 80//80 81//81 103//103 +f 80//80 103//103 102//102 +f 81//81 82//82 104//104 +f 81//81 104//104 103//103 +f 82//82 83//83 105//105 +f 82//82 105//105 104//104 +f 83//83 84//84 106//106 +f 83//83 106//106 105//105 +f 84//84 85//85 107//107 +f 84//84 107//107 106//106 +f 85//85 86//86 108//108 +f 85//85 108//108 107//107 +f 86//86 87//87 109//109 +f 86//86 109//109 108//108 +f 87//87 88//88 110//110 +f 87//87 110//110 109//109 +f 88//88 89//89 111//111 +f 88//88 111//111 110//110 +f 89//89 90//90 112//112 +f 89//89 112//112 111//111 +f 91//91 92//92 114//114 +f 91//91 114//114 113//113 +f 92//92 93//93 115//115 +f 92//92 115//115 114//114 +f 93//93 94//94 116//116 +f 93//93 116//116 115//115 +f 94//94 95//95 117//117 +f 94//94 117//117 116//116 +f 95//95 96//96 118//118 +f 95//95 118//118 117//117 +f 96//96 97//97 119//119 +f 96//96 119//119 118//118 +f 97//97 98//98 120//120 +f 97//97 120//120 119//119 +f 98//98 99//99 121//121 +f 98//98 121//121 120//120 +f 99//99 100//100 122//122 +f 99//99 122//122 121//121 +f 100//100 101//101 123//123 +f 100//100 123//123 122//122 +f 101//101 102//102 124//124 +f 101//101 124//124 123//123 +f 102//102 103//103 125//125 +f 102//102 125//125 124//124 +f 103//103 104//104 126//126 +f 103//103 126//126 125//125 +f 104//104 105//105 127//127 +f 104//104 127//127 126//126 +f 105//105 106//106 128//128 +f 105//105 128//128 127//127 +f 106//106 107//107 129//129 +f 106//106 129//129 128//128 +f 107//107 108//108 130//130 +f 107//107 130//130 129//129 +f 108//108 109//109 131//131 +f 108//108 131//131 130//130 +f 109//109 110//110 132//132 +f 109//109 132//132 131//131 +f 110//110 111//111 133//133 +f 110//110 133//133 132//132 +f 111//111 112//112 134//134 +f 111//111 134//134 133//133 +f 113//113 114//114 136//136 +f 113//113 136//136 135//135 +f 114//114 115//115 137//137 +f 114//114 137//137 136//136 +f 115//115 116//116 138//138 +f 115//115 138//138 137//137 +f 116//116 117//117 139//139 +f 116//116 139//139 138//138 +f 117//117 118//118 140//140 +f 117//117 140//140 139//139 +f 118//118 119//119 141//141 +f 118//118 141//141 140//140 +f 119//119 120//120 142//142 +f 119//119 142//142 141//141 +f 120//120 121//121 143//143 +f 120//120 143//143 142//142 +f 121//121 122//122 144//144 +f 121//121 144//144 143//143 +f 122//122 123//123 145//145 +f 122//122 145//145 144//144 +f 123//123 124//124 146//146 +f 123//123 146//146 145//145 +f 124//124 125//125 147//147 +f 124//124 147//147 146//146 +f 125//125 126//126 148//148 +f 125//125 148//148 147//147 +f 126//126 127//127 149//149 +f 126//126 149//149 148//148 +f 127//127 128//128 150//150 +f 127//127 150//150 149//149 +f 128//128 129//129 151//151 +f 128//128 151//151 150//150 +f 129//129 130//130 152//152 +f 129//129 152//152 151//151 +f 130//130 131//131 153//153 +f 130//130 153//153 152//152 +f 131//131 132//132 154//154 +f 131//131 154//154 153//153 +f 132//132 133//133 155//155 +f 132//132 155//155 154//154 +f 133//133 134//134 156//156 +f 133//133 156//156 155//155 +f 135//135 136//136 158//158 +f 135//135 158//158 157//157 +f 136//136 137//137 159//159 +f 136//136 159//159 158//158 +f 137//137 138//138 160//160 +f 137//137 160//160 159//159 +f 138//138 139//139 161//161 +f 138//138 161//161 160//160 +f 139//139 140//140 162//162 +f 139//139 162//162 161//161 +f 140//140 141//141 163//163 +f 140//140 163//163 162//162 +f 141//141 142//142 164//164 +f 141//141 164//164 163//163 +f 142//142 143//143 165//165 +f 142//142 165//165 164//164 +f 143//143 144//144 166//166 +f 143//143 166//166 165//165 +f 144//144 145//145 167//167 +f 144//144 167//167 166//166 +f 145//145 146//146 168//168 +f 145//145 168//168 167//167 +f 146//146 147//147 169//169 +f 146//146 169//169 168//168 +f 147//147 148//148 170//170 +f 147//147 170//170 169//169 +f 148//148 149//149 171//171 +f 148//148 171//171 170//170 +f 149//149 150//150 172//172 +f 149//149 172//172 171//171 +f 150//150 151//151 173//173 +f 150//150 173//173 172//172 +f 151//151 152//152 174//174 +f 151//151 174//174 173//173 +f 152//152 153//153 175//175 +f 152//152 175//175 174//174 +f 153//153 154//154 176//176 +f 153//153 176//176 175//175 +f 154//154 155//155 177//177 +f 154//154 177//177 176//176 +f 155//155 156//156 178//178 +f 155//155 178//178 177//177 +f 157//157 158//158 180//180 +f 157//157 180//180 179//179 +f 158//158 159//159 181//181 +f 158//158 181//181 180//180 +f 159//159 160//160 182//182 +f 159//159 182//182 181//181 +f 160//160 161//161 183//183 +f 160//160 183//183 182//182 +f 161//161 162//162 184//184 +f 161//161 184//184 183//183 +f 162//162 163//163 185//185 +f 162//162 185//185 184//184 +f 163//163 164//164 186//186 +f 163//163 186//186 185//185 +f 164//164 165//165 187//187 +f 164//164 187//187 186//186 +f 165//165 166//166 188//188 +f 165//165 188//188 187//187 +f 166//166 167//167 189//189 +f 166//166 189//189 188//188 +f 167//167 168//168 190//190 +f 167//167 190//190 189//189 +f 168//168 169//169 191//191 +f 168//168 191//191 190//190 +f 169//169 170//170 192//192 +f 169//169 192//192 191//191 +f 170//170 171//171 193//193 +f 170//170 193//193 192//192 +f 171//171 172//172 194//194 +f 171//171 194//194 193//193 +f 172//172 173//173 195//195 +f 172//172 195//195 194//194 +f 173//173 174//174 196//196 +f 173//173 196//196 195//195 +f 174//174 175//175 197//197 +f 174//174 197//197 196//196 +f 175//175 176//176 198//198 +f 175//175 198//198 197//197 +f 176//176 177//177 199//199 +f 176//176 199//199 198//198 +f 177//177 178//178 200//200 +f 177//177 200//200 199//199 +f 179//179 180//180 202//202 +f 179//179 202//202 201//201 +f 180//180 181//181 203//203 +f 180//180 203//203 202//202 +f 181//181 182//182 204//204 +f 181//181 204//204 203//203 +f 182//182 183//183 205//205 +f 182//182 205//205 204//204 +f 183//183 184//184 206//206 +f 183//183 206//206 205//205 +f 184//184 185//185 207//207 +f 184//184 207//207 206//206 +f 185//185 186//186 208//208 +f 185//185 208//208 207//207 +f 186//186 187//187 209//209 +f 186//186 209//209 208//208 +f 187//187 188//188 210//210 +f 187//187 210//210 209//209 +f 188//188 189//189 211//211 +f 188//188 211//211 210//210 +f 189//189 190//190 212//212 +f 189//189 212//212 211//211 +f 190//190 191//191 213//213 +f 190//190 213//213 212//212 +f 191//191 192//192 214//214 +f 191//191 214//214 213//213 +f 192//192 193//193 215//215 +f 192//192 215//215 214//214 +f 193//193 194//194 216//216 +f 193//193 216//216 215//215 +f 194//194 195//195 217//217 +f 194//194 217//217 216//216 +f 195//195 196//196 218//218 +f 195//195 218//218 217//217 +f 196//196 197//197 219//219 +f 196//196 219//219 218//218 +f 197//197 198//198 220//220 +f 197//197 220//220 219//219 +f 198//198 199//199 221//221 +f 198//198 221//221 220//220 +f 199//199 200//200 222//222 +f 199//199 222//222 221//221 +f 201//201 202//202 224//224 +f 201//201 224//224 223//223 +f 202//202 203//203 225//225 +f 202//202 225//225 224//224 +f 203//203 204//204 226//226 +f 203//203 226//226 225//225 +f 204//204 205//205 227//227 +f 204//204 227//227 226//226 +f 205//205 206//206 228//228 +f 205//205 228//228 227//227 +f 206//206 207//207 229//229 +f 206//206 229//229 228//228 +f 207//207 208//208 230//230 +f 207//207 230//230 229//229 +f 208//208 209//209 231//231 +f 208//208 231//231 230//230 +f 209//209 210//210 232//232 +f 209//209 232//232 231//231 +f 210//210 211//211 233//233 +f 210//210 233//233 232//232 +f 211//211 212//212 234//234 +f 211//211 234//234 233//233 +f 212//212 213//213 235//235 +f 212//212 235//235 234//234 +f 213//213 214//214 236//236 +f 213//213 236//236 235//235 +f 214//214 215//215 237//237 +f 214//214 237//237 236//236 +f 215//215 216//216 238//238 +f 215//215 238//238 237//237 +f 216//216 217//217 239//239 +f 216//216 239//239 238//238 +f 217//217 218//218 240//240 +f 217//217 240//240 239//239 +f 218//218 219//219 241//241 +f 218//218 241//241 240//240 +f 219//219 220//220 242//242 +f 219//219 242//242 241//241 +f 220//220 221//221 243//243 +f 220//220 243//243 242//242 +f 221//221 222//222 244//244 +f 221//221 244//244 243//243 +f 223//223 224//224 246//246 +f 223//223 246//246 245//245 +f 224//224 225//225 247//247 +f 224//224 247//247 246//246 +f 225//225 226//226 248//248 +f 225//225 248//248 247//247 +f 226//226 227//227 249//249 +f 226//226 249//249 248//248 +f 227//227 228//228 250//250 +f 227//227 250//250 249//249 +f 228//228 229//229 251//251 +f 228//228 251//251 250//250 +f 229//229 230//230 252//252 +f 229//229 252//252 251//251 +f 230//230 231//231 253//253 +f 230//230 253//253 252//252 +f 231//231 232//232 254//254 +f 231//231 254//254 253//253 +f 232//232 233//233 255//255 +f 232//232 255//255 254//254 +f 233//233 234//234 256//256 +f 233//233 256//256 255//255 +f 234//234 235//235 257//257 +f 234//234 257//257 256//256 +f 235//235 236//236 258//258 +f 235//235 258//258 257//257 +f 236//236 237//237 259//259 +f 236//236 259//259 258//258 +f 237//237 238//238 260//260 +f 237//237 260//260 259//259 +f 238//238 239//239 261//261 +f 238//238 261//261 260//260 +f 239//239 240//240 262//262 +f 239//239 262//262 261//261 +f 240//240 241//241 263//263 +f 240//240 263//263 262//262 +f 241//241 242//242 264//264 +f 241//241 264//264 263//263 +f 242//242 243//243 265//265 +f 242//242 265//265 264//264 +f 243//243 244//244 266//266 +f 243//243 266//266 265//265 +f 245//245 246//246 268//268 +f 245//245 268//268 267//267 +f 246//246 247//247 269//269 +f 246//246 269//269 268//268 +f 247//247 248//248 270//270 +f 247//247 270//270 269//269 +f 248//248 249//249 271//271 +f 248//248 271//271 270//270 +f 249//249 250//250 272//272 +f 249//249 272//272 271//271 +f 250//250 251//251 273//273 +f 250//250 273//273 272//272 +f 251//251 252//252 274//274 +f 251//251 274//274 273//273 +f 252//252 253//253 275//275 +f 252//252 275//275 274//274 +f 253//253 254//254 276//276 +f 253//253 276//276 275//275 +f 254//254 255//255 277//277 +f 254//254 277//277 276//276 +f 255//255 256//256 278//278 +f 255//255 278//278 277//277 +f 256//256 257//257 279//279 +f 256//256 279//279 278//278 +f 257//257 258//258 280//280 +f 257//257 280//280 279//279 +f 258//258 259//259 281//281 +f 258//258 281//281 280//280 +f 259//259 260//260 282//282 +f 259//259 282//282 281//281 +f 260//260 261//261 283//283 +f 260//260 283//283 282//282 +f 261//261 262//262 284//284 +f 261//261 284//284 283//283 +f 262//262 263//263 285//285 +f 262//262 285//285 284//284 +f 263//263 264//264 286//286 +f 263//263 286//286 285//285 +f 264//264 265//265 287//287 +f 264//264 287//287 286//286 +f 265//265 266//266 288//288 +f 265//265 288//288 287//287 +f 267//267 268//268 290//290 +f 267//267 290//290 289//289 +f 268//268 269//269 291//291 +f 268//268 291//291 290//290 +f 269//269 270//270 292//292 +f 269//269 292//292 291//291 +f 270//270 271//271 293//293 +f 270//270 293//293 292//292 +f 271//271 272//272 294//294 +f 271//271 294//294 293//293 +f 272//272 273//273 295//295 +f 272//272 295//295 294//294 +f 273//273 274//274 296//296 +f 273//273 296//296 295//295 +f 274//274 275//275 297//297 +f 274//274 297//297 296//296 +f 275//275 276//276 298//298 +f 275//275 298//298 297//297 +f 276//276 277//277 299//299 +f 276//276 299//299 298//298 +f 277//277 278//278 300//300 +f 277//277 300//300 299//299 +f 278//278 279//279 301//301 +f 278//278 301//301 300//300 +f 279//279 280//280 302//302 +f 279//279 302//302 301//301 +f 280//280 281//281 303//303 +f 280//280 303//303 302//302 +f 281//281 282//282 304//304 +f 281//281 304//304 303//303 +f 282//282 283//283 305//305 +f 282//282 305//305 304//304 +f 283//283 284//284 306//306 +f 283//283 306//306 305//305 +f 284//284 285//285 307//307 +f 284//284 307//307 306//306 +f 285//285 286//286 308//308 +f 285//285 308//308 307//307 +f 286//286 287//287 309//309 +f 286//286 309//309 308//308 +f 287//287 288//288 310//310 +f 287//287 310//310 309//309 +f 289//289 290//290 312//312 +f 289//289 312//312 311//311 +f 290//290 291//291 313//313 +f 290//290 313//313 312//312 +f 291//291 292//292 314//314 +f 291//291 314//314 313//313 +f 292//292 293//293 315//315 +f 292//292 315//315 314//314 +f 293//293 294//294 316//316 +f 293//293 316//316 315//315 +f 294//294 295//295 317//317 +f 294//294 317//317 316//316 +f 295//295 296//296 318//318 +f 295//295 318//318 317//317 +f 296//296 297//297 319//319 +f 296//296 319//319 318//318 +f 297//297 298//298 320//320 +f 297//297 320//320 319//319 +f 298//298 299//299 321//321 +f 298//298 321//321 320//320 +f 299//299 300//300 322//322 +f 299//299 322//322 321//321 +f 300//300 301//301 323//323 +f 300//300 323//323 322//322 +f 301//301 302//302 324//324 +f 301//301 324//324 323//323 +f 302//302 303//303 325//325 +f 302//302 325//325 324//324 +f 303//303 304//304 326//326 +f 303//303 326//326 325//325 +f 304//304 305//305 327//327 +f 304//304 327//327 326//326 +f 305//305 306//306 328//328 +f 305//305 328//328 327//327 +f 306//306 307//307 329//329 +f 306//306 329//329 328//328 +f 307//307 308//308 330//330 +f 307//307 330//330 329//329 +f 308//308 309//309 331//331 +f 308//308 331//331 330//330 +f 309//309 310//310 332//332 +f 309//309 332//332 331//331 +f 311//311 312//312 334//334 +f 311//311 334//334 333//333 +f 312//312 313//313 335//335 +f 312//312 335//335 334//334 +f 313//313 314//314 336//336 +f 313//313 336//336 335//335 +f 314//314 315//315 337//337 +f 314//314 337//337 336//336 +f 315//315 316//316 338//338 +f 315//315 338//338 337//337 +f 316//316 317//317 339//339 +f 316//316 339//339 338//338 +f 317//317 318//318 340//340 +f 317//317 340//340 339//339 +f 318//318 319//319 341//341 +f 318//318 341//341 340//340 +f 319//319 320//320 342//342 +f 319//319 342//342 341//341 +f 320//320 321//321 343//343 +f 320//320 343//343 342//342 +f 321//321 322//322 344//344 +f 321//321 344//344 343//343 +f 322//322 323//323 345//345 +f 322//322 345//345 344//344 +f 323//323 324//324 346//346 +f 323//323 346//346 345//345 +f 324//324 325//325 347//347 +f 324//324 347//347 346//346 +f 325//325 326//326 348//348 +f 325//325 348//348 347//347 +f 326//326 327//327 349//349 +f 326//326 349//349 348//348 +f 327//327 328//328 350//350 +f 327//327 350//350 349//349 +f 328//328 329//329 351//351 +f 328//328 351//351 350//350 +f 329//329 330//330 352//352 +f 329//329 352//352 351//351 +f 330//330 331//331 353//353 +f 330//330 353//353 352//352 +f 331//331 332//332 354//354 +f 331//331 354//354 353//353 +f 333//333 334//334 356//356 +f 333//333 356//356 355//355 +f 334//334 335//335 357//357 +f 334//334 357//357 356//356 +f 335//335 336//336 358//358 +f 335//335 358//358 357//357 +f 336//336 337//337 359//359 +f 336//336 359//359 358//358 +f 337//337 338//338 360//360 +f 337//337 360//360 359//359 +f 338//338 339//339 361//361 +f 338//338 361//361 360//360 +f 339//339 340//340 362//362 +f 339//339 362//362 361//361 +f 340//340 341//341 363//363 +f 340//340 363//363 362//362 +f 341//341 342//342 364//364 +f 341//341 364//364 363//363 +f 342//342 343//343 365//365 +f 342//342 365//365 364//364 +f 343//343 344//344 366//366 +f 343//343 366//366 365//365 +f 344//344 345//345 367//367 +f 344//344 367//367 366//366 +f 345//345 346//346 368//368 +f 345//345 368//368 367//367 +f 346//346 347//347 369//369 +f 346//346 369//369 368//368 +f 347//347 348//348 370//370 +f 347//347 370//370 369//369 +f 348//348 349//349 371//371 +f 348//348 371//371 370//370 +f 349//349 350//350 372//372 +f 349//349 372//372 371//371 +f 350//350 351//351 373//373 +f 350//350 373//373 372//372 +f 351//351 352//352 374//374 +f 351//351 374//374 373//373 +f 352//352 353//353 375//375 +f 352//352 375//375 374//374 +f 353//353 354//354 376//376 +f 353//353 376//376 375//375 +f 355//355 356//356 378//378 +f 355//355 378//378 377//377 +f 356//356 357//357 379//379 +f 356//356 379//379 378//378 +f 357//357 358//358 380//380 +f 357//357 380//380 379//379 +f 358//358 359//359 381//381 +f 358//358 381//381 380//380 +f 359//359 360//360 382//382 +f 359//359 382//382 381//381 +f 360//360 361//361 383//383 +f 360//360 383//383 382//382 +f 361//361 362//362 384//384 +f 361//361 384//384 383//383 +f 362//362 363//363 385//385 +f 362//362 385//385 384//384 +f 363//363 364//364 386//386 +f 363//363 386//386 385//385 +f 364//364 365//365 387//387 +f 364//364 387//387 386//386 +f 365//365 366//366 388//388 +f 365//365 388//388 387//387 +f 366//366 367//367 389//389 +f 366//366 389//389 388//388 +f 367//367 368//368 390//390 +f 367//367 390//390 389//389 +f 368//368 369//369 391//391 +f 368//368 391//391 390//390 +f 369//369 370//370 392//392 +f 369//369 392//392 391//391 +f 370//370 371//371 393//393 +f 370//370 393//393 392//392 +f 371//371 372//372 394//394 +f 371//371 394//394 393//393 +f 372//372 373//373 395//395 +f 372//372 395//395 394//394 +f 373//373 374//374 396//396 +f 373//373 396//396 395//395 +f 374//374 375//375 397//397 +f 374//374 397//397 396//396 +f 375//375 376//376 398//398 +f 375//375 398//398 397//397 +f 377//377 378//378 400//400 +f 377//377 400//400 399//399 +f 378//378 379//379 401//401 +f 378//378 401//401 400//400 +f 379//379 380//380 402//402 +f 379//379 402//402 401//401 +f 380//380 381//381 403//403 +f 380//380 403//403 402//402 +f 381//381 382//382 404//404 +f 381//381 404//404 403//403 +f 382//382 383//383 405//405 +f 382//382 405//405 404//404 +f 383//383 384//384 406//406 +f 383//383 406//406 405//405 +f 384//384 385//385 407//407 +f 384//384 407//407 406//406 +f 385//385 386//386 408//408 +f 385//385 408//408 407//407 +f 386//386 387//387 409//409 +f 386//386 409//409 408//408 +f 387//387 388//388 410//410 +f 387//387 410//410 409//409 +f 388//388 389//389 411//411 +f 388//388 411//411 410//410 +f 389//389 390//390 412//412 +f 389//389 412//412 411//411 +f 390//390 391//391 413//413 +f 390//390 413//413 412//412 +f 391//391 392//392 414//414 +f 391//391 414//414 413//413 +f 392//392 393//393 415//415 +f 392//392 415//415 414//414 +f 393//393 394//394 416//416 +f 393//393 416//416 415//415 +f 394//394 395//395 417//417 +f 394//394 417//417 416//416 +f 395//395 396//396 418//418 +f 395//395 418//418 417//417 +f 396//396 397//397 419//419 +f 396//396 419//419 418//418 +f 397//397 398//398 420//420 +f 397//397 420//420 419//419 +f 399//399 400//400 422//422 +f 399//399 422//422 421//421 +f 400//400 401//401 423//423 +f 400//400 423//423 422//422 +f 401//401 402//402 424//424 +f 401//401 424//424 423//423 +f 402//402 403//403 425//425 +f 402//402 425//425 424//424 +f 403//403 404//404 426//426 +f 403//403 426//426 425//425 +f 404//404 405//405 427//427 +f 404//404 427//427 426//426 +f 405//405 406//406 428//428 +f 405//405 428//428 427//427 +f 406//406 407//407 429//429 +f 406//406 429//429 428//428 +f 407//407 408//408 430//430 +f 407//407 430//430 429//429 +f 408//408 409//409 431//431 +f 408//408 431//431 430//430 +f 409//409 410//410 432//432 +f 409//409 432//432 431//431 +f 410//410 411//411 433//433 +f 410//410 433//433 432//432 +f 411//411 412//412 434//434 +f 411//411 434//434 433//433 +f 412//412 413//413 435//435 +f 412//412 435//435 434//434 +f 413//413 414//414 436//436 +f 413//413 436//436 435//435 +f 414//414 415//415 437//437 +f 414//414 437//437 436//436 +f 415//415 416//416 438//438 +f 415//415 438//438 437//437 +f 416//416 417//417 439//439 +f 416//416 439//439 438//438 +f 417//417 418//418 440//440 +f 417//417 440//440 439//439 +f 418//418 419//419 441//441 +f 418//418 441//441 440//440 +f 419//419 420//420 442//442 +f 419//419 442//442 441//441 +f 421//421 422//422 444//444 +f 421//421 444//444 443//443 +f 422//422 423//423 445//445 +f 422//422 445//445 444//444 +f 423//423 424//424 446//446 +f 423//423 446//446 445//445 +f 424//424 425//425 447//447 +f 424//424 447//447 446//446 +f 425//425 426//426 448//448 +f 425//425 448//448 447//447 +f 426//426 427//427 449//449 +f 426//426 449//449 448//448 +f 427//427 428//428 450//450 +f 427//427 450//450 449//449 +f 428//428 429//429 451//451 +f 428//428 451//451 450//450 +f 429//429 430//430 452//452 +f 429//429 452//452 451//451 +f 430//430 431//431 453//453 +f 430//430 453//453 452//452 +f 431//431 432//432 454//454 +f 431//431 454//454 453//453 +f 432//432 433//433 455//455 +f 432//432 455//455 454//454 +f 433//433 434//434 456//456 +f 433//433 456//456 455//455 +f 434//434 435//435 457//457 +f 434//434 457//457 456//456 +f 435//435 436//436 458//458 +f 435//435 458//458 457//457 +f 436//436 437//437 459//459 +f 436//436 459//459 458//458 +f 437//437 438//438 460//460 +f 437//437 460//460 459//459 +f 438//438 439//439 461//461 +f 438//438 461//461 460//460 +f 439//439 440//440 462//462 +f 439//439 462//462 461//461 +f 440//440 441//441 463//463 +f 440//440 463//463 462//462 +f 441//441 442//442 464//464 +f 441//441 464//464 463//463 +f 443//443 444//444 466//466 +f 443//443 466//466 465//465 +f 444//444 445//445 467//467 +f 444//444 467//467 466//466 +f 445//445 446//446 468//468 +f 445//445 468//468 467//467 +f 446//446 447//447 469//469 +f 446//446 469//469 468//468 +f 447//447 448//448 470//470 +f 447//447 470//470 469//469 +f 448//448 449//449 471//471 +f 448//448 471//471 470//470 +f 449//449 450//450 472//472 +f 449//449 472//472 471//471 +f 450//450 451//451 473//473 +f 450//450 473//473 472//472 +f 451//451 452//452 474//474 +f 451//451 474//474 473//473 +f 452//452 453//453 475//475 +f 452//452 475//475 474//474 +f 453//453 454//454 476//476 +f 453//453 476//476 475//475 +f 454//454 455//455 477//477 +f 454//454 477//477 476//476 +f 455//455 456//456 478//478 +f 455//455 478//478 477//477 +f 456//456 457//457 479//479 +f 456//456 479//479 478//478 +f 457//457 458//458 480//480 +f 457//457 480//480 479//479 +f 458//458 459//459 481//481 +f 458//458 481//481 480//480 +f 459//459 460//460 482//482 +f 459//459 482//482 481//481 +f 460//460 461//461 483//483 +f 460//460 483//483 482//482 +f 461//461 462//462 484//484 +f 461//461 484//484 483//483 +f 462//462 463//463 485//485 +f 462//462 485//485 484//484 +f 463//463 464//464 486//486 +f 463//463 486//486 485//485 +f 465//465 466//466 488//488 +f 465//465 488//488 487//487 +f 466//466 467//467 489//489 +f 466//466 489//489 488//488 +f 467//467 468//468 490//490 +f 467//467 490//490 489//489 +f 468//468 469//469 491//491 +f 468//468 491//491 490//490 +f 469//469 470//470 492//492 +f 469//469 492//492 491//491 +f 470//470 471//471 493//493 +f 470//470 493//493 492//492 +f 471//471 472//472 494//494 +f 471//471 494//494 493//493 +f 472//472 473//473 495//495 +f 472//472 495//495 494//494 +f 473//473 474//474 496//496 +f 473//473 496//496 495//495 +f 474//474 475//475 497//497 +f 474//474 497//497 496//496 +f 475//475 476//476 498//498 +f 475//475 498//498 497//497 +f 476//476 477//477 499//499 +f 476//476 499//499 498//498 +f 477//477 478//478 500//500 +f 477//477 500//500 499//499 +f 478//478 479//479 501//501 +f 478//478 501//501 500//500 +f 479//479 480//480 502//502 +f 479//479 502//502 501//501 +f 480//480 481//481 503//503 +f 480//480 503//503 502//502 +f 481//481 482//482 504//504 +f 481//481 504//504 503//503 +f 482//482 483//483 505//505 +f 482//482 505//505 504//504 +f 483//483 484//484 506//506 +f 483//483 506//506 505//505 +f 484//484 485//485 507//507 +f 484//484 507//507 506//506 +f 485//485 486//486 508//508 +f 485//485 508//508 507//507 +f 487//487 488//488 510//510 +f 487//487 510//510 509//509 +f 488//488 489//489 511//511 +f 488//488 511//511 510//510 +f 489//489 490//490 512//512 +f 489//489 512//512 511//511 +f 490//490 491//491 513//513 +f 490//490 513//513 512//512 +f 491//491 492//492 514//514 +f 491//491 514//514 513//513 +f 492//492 493//493 515//515 +f 492//492 515//515 514//514 +f 493//493 494//494 516//516 +f 493//493 516//516 515//515 +f 494//494 495//495 517//517 +f 494//494 517//517 516//516 +f 495//495 496//496 518//518 +f 495//495 518//518 517//517 +f 496//496 497//497 519//519 +f 496//496 519//519 518//518 +f 497//497 498//498 520//520 +f 497//497 520//520 519//519 +f 498//498 499//499 521//521 +f 498//498 521//521 520//520 +f 499//499 500//500 522//522 +f 499//499 522//522 521//521 +f 500//500 501//501 523//523 +f 500//500 523//523 522//522 +f 501//501 502//502 524//524 +f 501//501 524//524 523//523 +f 502//502 503//503 525//525 +f 502//502 525//525 524//524 +f 503//503 504//504 526//526 +f 503//503 526//526 525//525 +f 504//504 505//505 527//527 +f 504//504 527//527 526//526 +f 505//505 506//506 528//528 +f 505//505 528//528 527//527 +f 506//506 507//507 529//529 +f 506//506 529//529 528//528 +f 507//507 508//508 530//530 +f 507//507 530//530 529//529 +f 509//509 510//510 4//4 +f 509//509 4//4 3//3 +f 510//510 511//511 5//5 +f 510//510 5//5 4//4 +f 511//511 512//512 6//6 +f 511//511 6//6 5//5 +f 512//512 513//513 7//7 +f 512//512 7//7 6//6 +f 513//513 514//514 8//8 +f 513//513 8//8 7//7 +f 514//514 515//515 9//9 +f 514//514 9//9 8//8 +f 515//515 516//516 10//10 +f 515//515 10//10 9//9 +f 516//516 517//517 11//11 +f 516//516 11//11 10//10 +f 517//517 518//518 12//12 +f 517//517 12//12 11//11 +f 518//518 519//519 13//13 +f 518//518 13//13 12//12 +f 519//519 520//520 14//14 +f 519//519 14//14 13//13 +f 520//520 521//521 15//15 +f 520//520 15//15 14//14 +f 521//521 522//522 16//16 +f 521//521 16//16 15//15 +f 522//522 523//523 17//17 +f 522//522 17//17 16//16 +f 523//523 524//524 18//18 +f 523//523 18//18 17//17 +f 524//524 525//525 19//19 +f 524//524 19//19 18//18 +f 525//525 526//526 20//20 +f 525//525 20//20 19//19 +f 526//526 527//527 21//21 +f 526//526 21//21 20//20 +f 527//527 528//528 22//22 +f 527//527 22//22 21//21 +f 528//528 529//529 23//23 +f 528//528 23//23 22//22 +f 529//529 530//530 24//24 +f 529//529 24//24 23//23 diff --git a/sample_meshes/torus.obj b/sample_meshes/torus.obj new file mode 100644 index 0000000..9bc1164 --- /dev/null +++ b/sample_meshes/torus.obj @@ -0,0 +1,2123 @@ +# wavefront obj file written by the visualization toolkit + +mtllib torus.mtl + +v 0 1.5 0 +v 0.39969274401664734 1.426522135734558 0.134898379445076 +v 0.40469515323638916 1.4443758726119995 0 +v 0 1.4814586639404297 0.134898379445076 +v 0.3850565552711487 1.3742848634719849 0.2597919702529907 +v 0 1.427209734916687 0.2597919702529907 +v 0.3618720769882202 1.2915383577346802 0.3654179871082306 +v 0 1.3412765264511108 0.3654179871082306 +v 0.3318588137626648 1.1844196319580078 0.4439426064491272 +v 0 1.2300325632095337 0.4439426064491272 +v 0.297242671251297 1.0608729124069214 0.48954203724861145 +v 0 1.1017279624938965 0.48954203724861145 +v 0.26059097051620483 0.930061399936676 0.49883437156677246 +v 0 0.9658787846565247 0.49883437156677246 +v 0.22462205588817596 0.8016865849494934 0.47113046050071716 +v 0 0.8325601816177368 0.47113046050071716 +v 0.192003533244133 0.6852695345878601 0.40848493576049805 +v 0 0.711659848690033 0.40848493576049805 +v 0.1651545763015747 0.5894443988800049 0.3155439794063568 +v 0 0.6121443510055542 0.3155439794063568 +v 0.14606644213199615 0.5213179588317871 0.19920054078102112 +v 0 0.5413943529129028 0.19920054078102112 +v 0.13615483045578003 0.4859429895877838 0.06808332353830338 +v 0 0.5046570301055908 0.06808332353830338 +v 0.13615483045578003 0.4859429895877838 -0.06808332353830338 +v 0 0.5046570301055908 -0.06808332353830338 +v 0.14606644213199615 0.5213179588317871 -0.19920054078102112 +v 0 0.5413943529129028 -0.19920054078102112 +v 0.1651545763015747 0.5894443988800049 -0.3155439794063568 +v 0 0.6121443510055542 -0.3155439794063568 +v 0.192003533244133 0.6852695345878601 -0.40848493576049805 +v 0 0.711659848690033 -0.40848493576049805 +v 0.22462205588817596 0.8016865849494934 -0.47113046050071716 +v 0 0.8325601816177368 -0.47113046050071716 +v 0.26059097051620483 0.930061399936676 -0.49883437156677246 +v 0 0.9658787846565247 -0.49883437156677246 +v 0.297242671251297 1.0608729124069214 -0.48954203724861145 +v 0 1.1017279624938965 -0.48954203724861145 +v 0.3318588137626648 1.1844196319580078 -0.4439426064491272 +v 0 1.2300325632095337 -0.4439426064491272 +v 0.3618720769882202 1.2915383577346802 -0.3654179871082306 +v 0 1.3412765264511108 -0.3654179871082306 +v 0.3850565552711487 1.3742848634719849 -0.2597919702529907 +v 0 1.427209734916687 -0.2597919702529907 +v 0.39969274401664734 1.426522135734558 -0.134898379445076 +v 0 1.4814586639404297 -0.134898379445076 +v 0.7697421312332153 1.2657870054244995 0.134898379445076 +v 0.7793759107589722 1.2816290855407715 0 +v 0.7415552735328674 1.219435691833496 0.2597919702529907 +v 0.696905791759491 1.146012783050537 0.3654179871082306 +v 0.6391051411628723 1.0509636402130127 0.4439426064491272 +v 0.5724402070045471 0.9413377642631531 0.48954203724861145 +v 0.5018551349639893 0.8252655863761902 0.49883437156677246 +v 0.4325849115848541 0.7113555669784546 0.47113046050071716 +v 0.36976704001426697 0.6080559492111206 0.40848493576049805 +v 0.31806036829948425 0.5230280160903931 0.3155439794063568 +v 0.28129979968070984 0.46257784962654114 0.19920054078102112 +v 0.2622116804122925 0.43118876218795776 0.06808332353830338 +v 0.2622116804122925 0.43118876218795776 -0.06808332353830338 +v 0.28129979968070984 0.46257784962654114 -0.19920054078102112 +v 0.31806036829948425 0.5230280160903931 -0.3155439794063568 +v 0.36976704001426697 0.6080559492111206 -0.40848493576049805 +v 0.4325849115848541 0.7113555669784546 -0.47113046050071716 +v 0.5018551349639893 0.8252655863761902 -0.49883437156677246 +v 0.5724402070045471 0.9413377642631531 -0.48954203724861145 +v 0.6391051411628723 1.0509636402130127 -0.4439426064491272 +v 0.696905791759491 1.146012783050537 -0.3654179871082306 +v 0.7415552735328674 1.219435691833496 -0.2597919702529907 +v 0.7697421312332153 1.2657870054244995 -0.134898379445076 +v 1.0827032327651978 1.011174201965332 0.134898379445076 +v 1.0962539911270142 1.023829698562622 0 +v 1.0430561304092407 0.9741464853286743 0.2597919702529907 +v 0.9802531599998474 0.9154925346374512 0.3654179871082306 +v 0.8989520072937012 0.8395625352859497 0.4439426064491272 +v 0.8051824569702148 0.7519879341125488 0.48954203724861145 +v 0.7058989405632019 0.6592636108398438 0.49883437156677246 +v 0.6084649562835693 0.5682665705680847 0.47113046050071716 +v 0.5201066136360168 0.4857456684112549 0.40848493576049805 +v 0.44737711548805237 0.4178210496902466 0.3155439794063568 +v 0.39567047357559204 0.36953040957450867 0.19920054078102112 +v 0.36882150173187256 0.3444552421569824 0.06808332353830338 +v 0.36882150173187256 0.3444552421569824 -0.06808332353830338 +v 0.39567047357559204 0.36953040957450867 -0.19920054078102112 +v 0.44737711548805237 0.4178210496902466 -0.3155439794063568 +v 0.5201066136360168 0.4857456684112549 -0.40848493576049805 +v 0.6084649562835693 0.5682665705680847 -0.47113046050071716 +v 0.7058989405632019 0.6592636108398438 -0.49883437156677246 +v 0.8051824569702148 0.7519879341125488 -0.48954203724861145 +v 0.8989520072937012 0.8395625352859497 -0.4439426064491272 +v 0.9802531599998474 0.9154925346374512 -0.3654179871082306 +v 1.0430561304092407 0.9741464853286743 -0.2597919702529907 +v 1.0827032327651978 1.011174201965332 -0.134898379445076 +v 1.315365195274353 0.6815673112869263 0.134898379445076 +v 1.3318278789520264 0.6900975704193115 0 +v 1.2671984434127808 0.656609296798706 0.2597919702529907 +v 1.1908996105194092 0.6170744299888611 0.3654179871082306 +v 1.0921276807785034 0.5658949613571167 0.4439426064491272 +v 0.9782080054283142 0.5068665146827698 0.48954203724861145 +v 0.8575894832611084 0.44436705112457275 0.49883437156677246 +v 0.7392178773880005 0.38303184509277344 0.47113046050071716 +v 0.6318722367286682 0.3274098038673401 0.40848493576049805 +v 0.5435139536857605 0.28162622451782227 0.3155439794063568 +v 0.48069605231285095 0.24907660484313965 0.19920054078102112 +v 0.4480774998664856 0.2321750521659851 0.06808332353830338 +v 0.4480774998664856 0.2321750521659851 -0.06808332353830338 +v 0.48069605231285095 0.24907660484313965 -0.19920054078102112 +v 0.5435139536857605 0.28162622451782227 -0.3155439794063568 +v 0.6318722367286682 0.3274098038673401 -0.40848493576049805 +v 0.7392178773880005 0.38303184509277344 -0.47113046050071716 +v 0.8575894832611084 0.44436705112457275 -0.49883437156677246 +v 0.9782080054283142 0.5068665146827698 -0.48954203724861145 +v 1.0921276807785034 0.5658949613571167 -0.4439426064491272 +v 1.1908996105194092 0.6170744299888611 -0.3654179871082306 +v 1.2671984434127808 0.656609296798706 -0.2597919702529907 +v 1.315365195274353 0.6815673112869263 -0.134898379445076 +v 1.4504725933074951 0.3014116585254669 0.134898379445076 +v 1.4686261415481567 0.305184006690979 0 +v 1.3973582983016968 0.29037439823150635 0.2597919702529907 +v 1.3132225275039673 0.27289077639579773 0.3654179871082306 +v 1.2043052911758423 0.2502575218677521 0.4439426064491272 +v 1.0786843299865723 0.22415319085121155 0.48954203724861145 +v 0.9456765651702881 0.1965138465166092 0.49883437156677246 +v 0.8151464462280273 0.16938938200473785 0.47113046050071716 +v 0.6967748403549194 0.14479146897792816 0.40848493576049805 +v 0.5993407964706421 0.12454444915056229 0.3155439794063568 +v 0.5300706028938293 0.11014993488788605 0.19920054078102112 +v 0.4941016733646393 0.10267550498247147 0.06808332353830338 +v 0.4941016733646393 0.10267550498247147 -0.06808332353830338 +v 0.5300706028938293 0.11014993488788605 -0.19920054078102112 +v 0.5993407964706421 0.12454444915056229 -0.3155439794063568 +v 0.6967748403549194 0.14479146897792816 -0.40848493576049805 +v 0.8151464462280273 0.16938938200473785 -0.47113046050071716 +v 0.9456765651702881 0.1965138465166092 -0.49883437156677246 +v 1.0786843299865723 0.22415319085121155 -0.48954203724861145 +v 1.2043052911758423 0.2502575218677521 -0.4439426064491272 +v 1.3132225275039673 0.27289077639579773 -0.3654179871082306 +v 1.3973582983016968 0.29037439823150635 -0.2597919702529907 +v 1.4504725933074951 0.3014116585254669 -0.134898379445076 +v 1.478005051612854 -0.10109831392765045 0.134898379445076 +v 1.4965031147003174 -0.10236362367868423 0 +v 1.4238826036453247 -0.09739623218774796 0.2597919702529907 +v 1.3381497859954834 -0.09153194725513458 0.3654179871082306 +v 1.2271649837493896 -0.08394038677215576 0.4439426064491272 +v 1.099159598350525 -0.07518457621335983 0.48954203724861145 +v 0.9636270999908447 -0.06591390073299408 0.49883437156677246 +v 0.8306192755699158 -0.056815918534994125 0.47113046050071716 +v 0.7100008130073547 -0.04856538400053978 0.40848493576049805 +v 0.6107172966003418 -0.0417742095887661 0.3155439794063568 +v 0.5401322245597839 -0.03694605827331543 0.19920054078102112 +v 0.5034805536270142 -0.03443901240825653 0.06808332353830338 +v 0.5034805536270142 -0.03443901240825653 -0.06808332353830338 +v 0.5401322245597839 -0.03694605827331543 -0.19920054078102112 +v 0.6107172966003418 -0.0417742095887661 -0.3155439794063568 +v 0.7100008130073547 -0.04856538400053978 -0.40848493576049805 +v 0.8306192755699158 -0.056815918534994125 -0.47113046050071716 +v 0.9636270999908447 -0.06591390073299408 -0.49883437156677246 +v 1.099159598350525 -0.07518457621335983 -0.48954203724861145 +v 1.2271649837493896 -0.08394038677215576 -0.4439426064491272 +v 1.3381497859954834 -0.09153194725513458 -0.3654179871082306 +v 1.4238826036453247 -0.09739623218774796 -0.2597919702529907 +v 1.478005051612854 -0.10109831392765045 -0.134898379445076 +v 1.3959206342697144 -0.49611029028892517 0.134898379445076 +v 1.413391351699829 -0.5023193955421448 0 +v 1.3448039293289185 -0.47794342041015625 0.2597919702529907 +v 1.263832449913025 -0.4491661787033081 0.3654179871082306 +v 1.1590116024017334 -0.41191279888153076 0.4439426064491272 +v 1.0381152629852295 -0.36894625425338745 0.48954203724861145 +v 0.91010981798172 -0.3234531283378601 0.49883437156677246 +v 0.7844889163970947 -0.2788074314594269 0.47113046050071716 +v 0.6705692410469055 -0.23832036554813385 0.40848493576049805 +v 0.5767996907234192 -0.20499466359615326 0.3155439794063568 +v 0.510134756565094 -0.18130193650722504 0.19920054078102112 +v 0.4755185842514038 -0.1689993441104889 0.06808332353830338 +v 0.4755185842514038 -0.1689993441104889 -0.06808332353830338 +v 0.510134756565094 -0.18130193650722504 -0.19920054078102112 +v 0.5767996907234192 -0.20499466359615326 -0.3155439794063568 +v 0.6705692410469055 -0.23832036554813385 -0.40848493576049805 +v 0.7844889163970947 -0.2788074314594269 -0.47113046050071716 +v 0.91010981798172 -0.3234531283378601 -0.49883437156677246 +v 1.0381152629852295 -0.36894625425338745 -0.48954203724861145 +v 1.1590116024017334 -0.41191279888153076 -0.4439426064491272 +v 1.263832449913025 -0.4491661787033081 -0.3654179871082306 +v 1.3448039293289185 -0.47794342041015625 -0.2597919702529907 +v 1.3959206342697144 -0.49611029028892517 -0.134898379445076 +v 1.2103071212768555 -0.8543280363082886 0.134898379445076 +v 1.2254548072814941 -0.8650204539299011 0 +v 1.1659873723983765 -0.8230437636375427 0.2597919702529907 +v 1.0957825183868408 -0.7734878063201904 0.3654179871082306 +v 1.004899501800537 -0.7093355655670166 0.4439426064491272 +v 0.9000785946846008 -0.6353448629379272 0.48954203724861145 +v 0.7890939116477966 -0.5570033192634583 0.49883437156677246 +v 0.6801766157150269 -0.48012107610702515 0.47113046050071716 +v 0.5814046859741211 -0.4104002118110657 0.40848493576049805 +v 0.5001035332679749 -0.3530116081237793 0.3155439794063568 +v 0.4423028826713562 -0.31221145391464233 0.19920054078102112 +v 0.4122895896434784 -0.2910257875919342 0.06808332353830338 +v 0.4122895896434784 -0.2910257875919342 -0.06808332353830338 +v 0.4423028826713562 -0.31221145391464233 -0.19920054078102112 +v 0.5001035332679749 -0.3530116081237793 -0.3155439794063568 +v 0.5814046859741211 -0.4104002118110657 -0.40848493576049805 +v 0.6801766157150269 -0.48012107610702515 -0.47113046050071716 +v 0.7890939116477966 -0.5570033192634583 -0.49883437156677246 +v 0.9000785946846008 -0.6353448629379272 -0.48954203724861145 +v 1.004899501800537 -0.7093355655670166 -0.4439426064491272 +v 1.0957825183868408 -0.7734878063201904 -0.3654179871082306 +v 1.1659873723983765 -0.8230437636375427 -0.2597919702529907 +v 1.2103071212768555 -0.8543280363082886 -0.134898379445076 +v 0.934930682182312 -1.149184226989746 0.134898379445076 +v 0.946631908416748 -1.1635669469833374 0 +v 0.9006948471069336 -1.107102632522583 0.2597919702529907 +v 0.8464635014533997 -1.0404434204101562 0.3654179871082306 +v 0.7762587070465088 -0.9541501402854919 0.4439426064491272 +v 0.69528728723526 -0.8546228408813477 0.48954203724861145 +v 0.6095544695854187 -0.7492430806159973 0.49883437156677246 +v 0.5254186987876892 -0.6458263397216797 0.47113046050071716 +v 0.4491199553012848 -0.552042543888092 0.40848493576049805 +v 0.3863169252872467 -0.47484728693962097 0.3155439794063568 +v 0.34166744351387024 -0.4199657142162323 0.19920054078102112 +v 0.3184829652309418 -0.3914681673049927 0.06808332353830338 +v 0.3184829652309418 -0.3914681673049927 -0.06808332353830338 +v 0.34166744351387024 -0.4199657142162323 -0.19920054078102112 +v 0.3863169252872467 -0.47484728693962097 -0.3155439794063568 +v 0.4491199553012848 -0.552042543888092 -0.40848493576049805 +v 0.5254186987876892 -0.6458263397216797 -0.47113046050071716 +v 0.6095544695854187 -0.7492430806159973 -0.49883437156677246 +v 0.69528728723526 -0.8546228408813477 -0.48954203724861145 +v 0.7762587070465088 -0.9541501402854919 -0.4439426064491272 +v 0.8464635014533997 -1.0404434204101562 -0.3654179871082306 +v 0.9006948471069336 -1.107102632522583 -0.2597919702529907 +v 0.934930682182312 -1.149184226989746 -0.134898379445076 +v 0.590214729309082 -1.3588106632232666 0.134898379445076 +v 0.5976016521453857 -1.3758169412612915 0 +v 0.5686019062995911 -1.30905282497406 0.2597919702529907 +v 0.5343660712242126 -1.2302340269088745 0.3654179871082306 +v 0.49004629254341125 -1.1281996965408325 0.4439426064491272 +v 0.43892964720726013 -1.0105173587799072 0.48954203724861145 +v 0.38480716943740845 -0.8859149217605591 0.49883437156677246 +v 0.3316928744316101 -0.7636336088180542 0.47113046050071716 +v 0.28352606296539307 -0.6527424454689026 0.40848493576049805 +v 0.24387897551059723 -0.5614657402038574 0.3155439794063568 +v 0.21569210290908813 -0.49657300114631653 0.19920054078102112 +v 0.20105591416358948 -0.4628771245479584 0.06808332353830338 +v 0.20105591416358948 -0.4628771245479584 -0.06808332353830338 +v 0.21569210290908813 -0.49657300114631653 -0.19920054078102112 +v 0.24387897551059723 -0.5614657402038574 -0.3155439794063568 +v 0.28352606296539307 -0.6527424454689026 -0.40848493576049805 +v 0.3316928744316101 -0.7636336088180542 -0.47113046050071716 +v 0.38480716943740845 -0.8859149217605591 -0.49883437156677246 +v 0.43892964720726013 -1.0105173587799072 -0.48954203724861145 +v 0.49004629254341125 -1.1281996965408325 -0.4439426064491272 +v 0.5343660712242126 -1.2302340269088745 -0.3654179871082306 +v 0.5686019062995911 -1.30905282497406 -0.2597919702529907 +v 0.590214729309082 -1.3588106632232666 -0.134898379445076 +v 0.20172525942325592 -1.4676603078842163 0.134898379445076 +v 0.20424997806549072 -1.4860289096832275 0 +v 0.1943383663892746 -1.4139165878295898 0.2597919702529907 +v 0.18263714015483856 -1.3287838697433472 0.3654179871082306 +v 0.1674894094467163 -1.2185759544372559 0.4439426064491272 +v 0.1500186175107956 -1.0914664268493652 0.48954203724861145 +v 0.13152047991752625 -0.9568825364112854 0.49883437156677246 +v 0.11336693167686462 -0.8248056769371033 0.47113046050071716 +v 0.09690433740615845 -0.7050313949584961 0.40848493576049805 +v 0.08335364609956741 -0.6064428091049194 0.3155439794063568 +v 0.07371985167264938 -0.5363517999649048 0.19920054078102112 +v 0.06871745735406876 -0.4999566376209259 0.06808332353830338 +v 0.06871745735406876 -0.4999566376209259 -0.06808332353830338 +v 0.07371985167264938 -0.5363517999649048 -0.19920054078102112 +v 0.08335364609956741 -0.6064428091049194 -0.3155439794063568 +v 0.09690433740615845 -0.7050313949584961 -0.40848493576049805 +v 0.11336693167686462 -0.8248056769371033 -0.47113046050071716 +v 0.13152047991752625 -0.9568825364112854 -0.49883437156677246 +v 0.1500186175107956 -1.0914664268493652 -0.48954203724861145 +v 0.1674894094467163 -1.2185759544372559 -0.4439426064491272 +v 0.18263714015483856 -1.3287838697433472 -0.3654179871082306 +v 0.1943383663892746 -1.4139165878295898 -0.2597919702529907 +v 0.20172525942325592 -1.4676603078842163 -0.134898379445076 +v -0.20172525942325592 -1.4676603078842163 0.134898379445076 +v -0.20424997806549072 -1.4860289096832275 0 +v -0.1943383663892746 -1.4139165878295898 0.2597919702529907 +v -0.18263714015483856 -1.3287838697433472 0.3654179871082306 +v -0.1674894094467163 -1.2185759544372559 0.4439426064491272 +v -0.1500186175107956 -1.0914664268493652 0.48954203724861145 +v -0.13152047991752625 -0.9568825364112854 0.49883437156677246 +v -0.11336693167686462 -0.8248056769371033 0.47113046050071716 +v -0.09690433740615845 -0.7050313949584961 0.40848493576049805 +v -0.08335364609956741 -0.6064428091049194 0.3155439794063568 +v -0.07371985167264938 -0.5363517999649048 0.19920054078102112 +v -0.06871745735406876 -0.4999566376209259 0.06808332353830338 +v -0.06871745735406876 -0.4999566376209259 -0.06808332353830338 +v -0.07371985167264938 -0.5363517999649048 -0.19920054078102112 +v -0.08335364609956741 -0.6064428091049194 -0.3155439794063568 +v -0.09690433740615845 -0.7050313949584961 -0.40848493576049805 +v -0.11336693167686462 -0.8248056769371033 -0.47113046050071716 +v -0.13152047991752625 -0.9568825364112854 -0.49883437156677246 +v -0.1500186175107956 -1.0914664268493652 -0.48954203724861145 +v -0.1674894094467163 -1.2185759544372559 -0.4439426064491272 +v -0.18263714015483856 -1.3287838697433472 -0.3654179871082306 +v -0.1943383663892746 -1.4139165878295898 -0.2597919702529907 +v -0.20172525942325592 -1.4676603078842163 -0.134898379445076 +v -0.590214729309082 -1.3588106632232666 0.134898379445076 +v -0.5976016521453857 -1.3758169412612915 0 +v -0.5686019062995911 -1.30905282497406 0.2597919702529907 +v -0.5343660712242126 -1.2302340269088745 0.3654179871082306 +v -0.49004629254341125 -1.1281996965408325 0.4439426064491272 +v -0.43892964720726013 -1.0105173587799072 0.48954203724861145 +v -0.38480716943740845 -0.8859149217605591 0.49883437156677246 +v -0.3316928744316101 -0.7636336088180542 0.47113046050071716 +v -0.28352606296539307 -0.6527424454689026 0.40848493576049805 +v -0.24387897551059723 -0.5614657402038574 0.3155439794063568 +v -0.21569210290908813 -0.49657300114631653 0.19920054078102112 +v -0.20105591416358948 -0.4628771245479584 0.06808332353830338 +v -0.20105591416358948 -0.4628771245479584 -0.06808332353830338 +v -0.21569210290908813 -0.49657300114631653 -0.19920054078102112 +v -0.24387897551059723 -0.5614657402038574 -0.3155439794063568 +v -0.28352606296539307 -0.6527424454689026 -0.40848493576049805 +v -0.3316928744316101 -0.7636336088180542 -0.47113046050071716 +v -0.38480716943740845 -0.8859149217605591 -0.49883437156677246 +v -0.43892964720726013 -1.0105173587799072 -0.48954203724861145 +v -0.49004629254341125 -1.1281996965408325 -0.4439426064491272 +v -0.5343660712242126 -1.2302340269088745 -0.3654179871082306 +v -0.5686019062995911 -1.30905282497406 -0.2597919702529907 +v -0.590214729309082 -1.3588106632232666 -0.134898379445076 +v -0.934930682182312 -1.149184226989746 0.134898379445076 +v -0.946631908416748 -1.1635669469833374 0 +v -0.9006948471069336 -1.107102632522583 0.2597919702529907 +v -0.8464635014533997 -1.0404434204101562 0.3654179871082306 +v -0.7762587070465088 -0.9541501402854919 0.4439426064491272 +v -0.69528728723526 -0.8546228408813477 0.48954203724861145 +v -0.6095544695854187 -0.7492430806159973 0.49883437156677246 +v -0.5254186987876892 -0.6458263397216797 0.47113046050071716 +v -0.4491199553012848 -0.552042543888092 0.40848493576049805 +v -0.3863169252872467 -0.47484728693962097 0.3155439794063568 +v -0.34166744351387024 -0.4199657142162323 0.19920054078102112 +v -0.3184829652309418 -0.3914681673049927 0.06808332353830338 +v -0.3184829652309418 -0.3914681673049927 -0.06808332353830338 +v -0.34166744351387024 -0.4199657142162323 -0.19920054078102112 +v -0.3863169252872467 -0.47484728693962097 -0.3155439794063568 +v -0.4491199553012848 -0.552042543888092 -0.40848493576049805 +v -0.5254186987876892 -0.6458263397216797 -0.47113046050071716 +v -0.6095544695854187 -0.7492430806159973 -0.49883437156677246 +v -0.69528728723526 -0.8546228408813477 -0.48954203724861145 +v -0.7762587070465088 -0.9541501402854919 -0.4439426064491272 +v -0.8464635014533997 -1.0404434204101562 -0.3654179871082306 +v -0.9006948471069336 -1.107102632522583 -0.2597919702529907 +v -0.934930682182312 -1.149184226989746 -0.134898379445076 +v -1.2103071212768555 -0.8543280363082886 0.134898379445076 +v -1.2254548072814941 -0.8650204539299011 0 +v -1.1659873723983765 -0.8230437636375427 0.2597919702529907 +v -1.0957825183868408 -0.7734878063201904 0.3654179871082306 +v -1.004899501800537 -0.7093355655670166 0.4439426064491272 +v -0.9000785946846008 -0.6353448629379272 0.48954203724861145 +v -0.7890939116477966 -0.5570033192634583 0.49883437156677246 +v -0.6801766157150269 -0.48012107610702515 0.47113046050071716 +v -0.5814046859741211 -0.4104002118110657 0.40848493576049805 +v -0.5001035332679749 -0.3530116081237793 0.3155439794063568 +v -0.4423028826713562 -0.31221145391464233 0.19920054078102112 +v -0.4122895896434784 -0.2910257875919342 0.06808332353830338 +v -0.4122895896434784 -0.2910257875919342 -0.06808332353830338 +v -0.4423028826713562 -0.31221145391464233 -0.19920054078102112 +v -0.5001035332679749 -0.3530116081237793 -0.3155439794063568 +v -0.5814046859741211 -0.4104002118110657 -0.40848493576049805 +v -0.6801766157150269 -0.48012107610702515 -0.47113046050071716 +v -0.7890939116477966 -0.5570033192634583 -0.49883437156677246 +v -0.9000785946846008 -0.6353448629379272 -0.48954203724861145 +v -1.004899501800537 -0.7093355655670166 -0.4439426064491272 +v -1.0957825183868408 -0.7734878063201904 -0.3654179871082306 +v -1.1659873723983765 -0.8230437636375427 -0.2597919702529907 +v -1.2103071212768555 -0.8543280363082886 -0.134898379445076 +v -1.3959206342697144 -0.49611029028892517 0.134898379445076 +v -1.413391351699829 -0.5023193955421448 0 +v -1.3448039293289185 -0.47794342041015625 0.2597919702529907 +v -1.263832449913025 -0.4491661787033081 0.3654179871082306 +v -1.1590116024017334 -0.41191279888153076 0.4439426064491272 +v -1.0381152629852295 -0.36894625425338745 0.48954203724861145 +v -0.91010981798172 -0.3234531283378601 0.49883437156677246 +v -0.7844889163970947 -0.2788074314594269 0.47113046050071716 +v -0.6705692410469055 -0.23832036554813385 0.40848493576049805 +v -0.5767996907234192 -0.20499466359615326 0.3155439794063568 +v -0.510134756565094 -0.18130193650722504 0.19920054078102112 +v -0.4755185842514038 -0.1689993441104889 0.06808332353830338 +v -0.4755185842514038 -0.1689993441104889 -0.06808332353830338 +v -0.510134756565094 -0.18130193650722504 -0.19920054078102112 +v -0.5767996907234192 -0.20499466359615326 -0.3155439794063568 +v -0.6705692410469055 -0.23832036554813385 -0.40848493576049805 +v -0.7844889163970947 -0.2788074314594269 -0.47113046050071716 +v -0.91010981798172 -0.3234531283378601 -0.49883437156677246 +v -1.0381152629852295 -0.36894625425338745 -0.48954203724861145 +v -1.1590116024017334 -0.41191279888153076 -0.4439426064491272 +v -1.263832449913025 -0.4491661787033081 -0.3654179871082306 +v -1.3448039293289185 -0.47794342041015625 -0.2597919702529907 +v -1.3959206342697144 -0.49611029028892517 -0.134898379445076 +v -1.478005051612854 -0.10109831392765045 0.134898379445076 +v -1.4965031147003174 -0.10236362367868423 0 +v -1.4238826036453247 -0.09739623218774796 0.2597919702529907 +v -1.3381497859954834 -0.09153194725513458 0.3654179871082306 +v -1.2271649837493896 -0.08394038677215576 0.4439426064491272 +v -1.099159598350525 -0.07518457621335983 0.48954203724861145 +v -0.9636270999908447 -0.06591390073299408 0.49883437156677246 +v -0.8306192755699158 -0.056815918534994125 0.47113046050071716 +v -0.7100008130073547 -0.04856538400053978 0.40848493576049805 +v -0.6107172966003418 -0.0417742095887661 0.3155439794063568 +v -0.5401322245597839 -0.03694605827331543 0.19920054078102112 +v -0.5034805536270142 -0.03443901240825653 0.06808332353830338 +v -0.5034805536270142 -0.03443901240825653 -0.06808332353830338 +v -0.5401322245597839 -0.03694605827331543 -0.19920054078102112 +v -0.6107172966003418 -0.0417742095887661 -0.3155439794063568 +v -0.7100008130073547 -0.04856538400053978 -0.40848493576049805 +v -0.8306192755699158 -0.056815918534994125 -0.47113046050071716 +v -0.9636270999908447 -0.06591390073299408 -0.49883437156677246 +v -1.099159598350525 -0.07518457621335983 -0.48954203724861145 +v -1.2271649837493896 -0.08394038677215576 -0.4439426064491272 +v -1.3381497859954834 -0.09153194725513458 -0.3654179871082306 +v -1.4238826036453247 -0.09739623218774796 -0.2597919702529907 +v -1.478005051612854 -0.10109831392765045 -0.134898379445076 +v -1.4504725933074951 0.3014116585254669 0.134898379445076 +v -1.4686261415481567 0.305184006690979 0 +v -1.3973582983016968 0.29037439823150635 0.2597919702529907 +v -1.3132225275039673 0.27289077639579773 0.3654179871082306 +v -1.2043052911758423 0.2502575218677521 0.4439426064491272 +v -1.0786843299865723 0.22415319085121155 0.48954203724861145 +v -0.9456765651702881 0.1965138465166092 0.49883437156677246 +v -0.8151464462280273 0.16938938200473785 0.47113046050071716 +v -0.6967748403549194 0.14479146897792816 0.40848493576049805 +v -0.5993407964706421 0.12454444915056229 0.3155439794063568 +v -0.5300706028938293 0.11014993488788605 0.19920054078102112 +v -0.4941016733646393 0.10267550498247147 0.06808332353830338 +v -0.4941016733646393 0.10267550498247147 -0.06808332353830338 +v -0.5300706028938293 0.11014993488788605 -0.19920054078102112 +v -0.5993407964706421 0.12454444915056229 -0.3155439794063568 +v -0.6967748403549194 0.14479146897792816 -0.40848493576049805 +v -0.8151464462280273 0.16938938200473785 -0.47113046050071716 +v -0.9456765651702881 0.1965138465166092 -0.49883437156677246 +v -1.0786843299865723 0.22415319085121155 -0.48954203724861145 +v -1.2043052911758423 0.2502575218677521 -0.4439426064491272 +v -1.3132225275039673 0.27289077639579773 -0.3654179871082306 +v -1.3973582983016968 0.29037439823150635 -0.2597919702529907 +v -1.4504725933074951 0.3014116585254669 -0.134898379445076 +v -1.315365195274353 0.6815673112869263 0.134898379445076 +v -1.3318278789520264 0.6900975704193115 0 +v -1.2671984434127808 0.656609296798706 0.2597919702529907 +v -1.1908996105194092 0.6170744299888611 0.3654179871082306 +v -1.0921276807785034 0.5658949613571167 0.4439426064491272 +v -0.9782080054283142 0.5068665146827698 0.48954203724861145 +v -0.8575894832611084 0.44436705112457275 0.49883437156677246 +v -0.7392178773880005 0.38303184509277344 0.47113046050071716 +v -0.6318722367286682 0.3274098038673401 0.40848493576049805 +v -0.5435139536857605 0.28162622451782227 0.3155439794063568 +v -0.48069605231285095 0.24907660484313965 0.19920054078102112 +v -0.4480774998664856 0.2321750521659851 0.06808332353830338 +v -0.4480774998664856 0.2321750521659851 -0.06808332353830338 +v -0.48069605231285095 0.24907660484313965 -0.19920054078102112 +v -0.5435139536857605 0.28162622451782227 -0.3155439794063568 +v -0.6318722367286682 0.3274098038673401 -0.40848493576049805 +v -0.7392178773880005 0.38303184509277344 -0.47113046050071716 +v -0.8575894832611084 0.44436705112457275 -0.49883437156677246 +v -0.9782080054283142 0.5068665146827698 -0.48954203724861145 +v -1.0921276807785034 0.5658949613571167 -0.4439426064491272 +v -1.1908996105194092 0.6170744299888611 -0.3654179871082306 +v -1.2671984434127808 0.656609296798706 -0.2597919702529907 +v -1.315365195274353 0.6815673112869263 -0.134898379445076 +v -1.0827032327651978 1.011174201965332 0.134898379445076 +v -1.0962539911270142 1.023829698562622 0 +v -1.0430561304092407 0.9741464853286743 0.2597919702529907 +v -0.9802531599998474 0.9154925346374512 0.3654179871082306 +v -0.8989520072937012 0.8395625352859497 0.4439426064491272 +v -0.8051824569702148 0.7519879341125488 0.48954203724861145 +v -0.7058989405632019 0.6592636108398438 0.49883437156677246 +v -0.6084649562835693 0.5682665705680847 0.47113046050071716 +v -0.5201066136360168 0.4857456684112549 0.40848493576049805 +v -0.44737711548805237 0.4178210496902466 0.3155439794063568 +v -0.39567047357559204 0.36953040957450867 0.19920054078102112 +v -0.36882150173187256 0.3444552421569824 0.06808332353830338 +v -0.36882150173187256 0.3444552421569824 -0.06808332353830338 +v -0.39567047357559204 0.36953040957450867 -0.19920054078102112 +v -0.44737711548805237 0.4178210496902466 -0.3155439794063568 +v -0.5201066136360168 0.4857456684112549 -0.40848493576049805 +v -0.6084649562835693 0.5682665705680847 -0.47113046050071716 +v -0.7058989405632019 0.6592636108398438 -0.49883437156677246 +v -0.8051824569702148 0.7519879341125488 -0.48954203724861145 +v -0.8989520072937012 0.8395625352859497 -0.4439426064491272 +v -0.9802531599998474 0.9154925346374512 -0.3654179871082306 +v -1.0430561304092407 0.9741464853286743 -0.2597919702529907 +v -1.0827032327651978 1.011174201965332 -0.134898379445076 +v -0.7697421312332153 1.2657870054244995 0.134898379445076 +v -0.7793759107589722 1.2816290855407715 0 +v -0.7415552735328674 1.219435691833496 0.2597919702529907 +v -0.696905791759491 1.146012783050537 0.3654179871082306 +v -0.6391051411628723 1.0509636402130127 0.4439426064491272 +v -0.5724402070045471 0.9413377642631531 0.48954203724861145 +v -0.5018551349639893 0.8252655863761902 0.49883437156677246 +v -0.4325849115848541 0.7113555669784546 0.47113046050071716 +v -0.36976704001426697 0.6080559492111206 0.40848493576049805 +v -0.31806036829948425 0.5230280160903931 0.3155439794063568 +v -0.28129979968070984 0.46257784962654114 0.19920054078102112 +v -0.2622116804122925 0.43118876218795776 0.06808332353830338 +v -0.2622116804122925 0.43118876218795776 -0.06808332353830338 +v -0.28129979968070984 0.46257784962654114 -0.19920054078102112 +v -0.31806036829948425 0.5230280160903931 -0.3155439794063568 +v -0.36976704001426697 0.6080559492111206 -0.40848493576049805 +v -0.4325849115848541 0.7113555669784546 -0.47113046050071716 +v -0.5018551349639893 0.8252655863761902 -0.49883437156677246 +v -0.5724402070045471 0.9413377642631531 -0.48954203724861145 +v -0.6391051411628723 1.0509636402130127 -0.4439426064491272 +v -0.696905791759491 1.146012783050537 -0.3654179871082306 +v -0.7415552735328674 1.219435691833496 -0.2597919702529907 +v -0.7697421312332153 1.2657870054244995 -0.134898379445076 +v -0.39969274401664734 1.426522135734558 0.134898379445076 +v -0.40469515323638916 1.4443758726119995 0 +v -0.3850565552711487 1.3742848634719849 0.2597919702529907 +v -0.3618720769882202 1.2915383577346802 0.3654179871082306 +v -0.3318588137626648 1.1844196319580078 0.4439426064491272 +v -0.297242671251297 1.0608729124069214 0.48954203724861145 +v -0.26059097051620483 0.930061399936676 0.49883437156677246 +v -0.22462205588817596 0.8016865849494934 0.47113046050071716 +v -0.192003533244133 0.6852695345878601 0.40848493576049805 +v -0.1651545763015747 0.5894443988800049 0.3155439794063568 +v -0.14606644213199615 0.5213179588317871 0.19920054078102112 +v -0.13615483045578003 0.4859429895877838 0.06808332353830338 +v -0.13615483045578003 0.4859429895877838 -0.06808332353830338 +v -0.14606644213199615 0.5213179588317871 -0.19920054078102112 +v -0.1651545763015747 0.5894443988800049 -0.3155439794063568 +v -0.192003533244133 0.6852695345878601 -0.40848493576049805 +v -0.22462205588817596 0.8016865849494934 -0.47113046050071716 +v -0.26059097051620483 0.930061399936676 -0.49883437156677246 +v -0.297242671251297 1.0608729124069214 -0.48954203724861145 +v -0.3318588137626648 1.1844196319580078 -0.4439426064491272 +v -0.3618720769882202 1.2915383577346802 -0.3654179871082306 +v -0.3850565552711487 1.3742848634719849 -0.2597919702529907 +v -0.39969274401664734 1.426522135734558 -0.134898379445076 +vn 0 1 0 +vn 0.2597920000553131 0.927209734916687 0.26979678869247437 +vn 0.26979678869247437 0.9629173278808594 0 +vn 0 0.9629173278808594 0.26979678869247437 +vn 0.2305196076631546 0.8227352499961853 0.5195840001106262 +vn 0 0.8544194102287292 0.5195839405059814 +vn 0.18415063619613647 0.6572422385215759 0.7308359742164612 +vn 0 0.6825531721115112 0.7308359742164612 +vn 0.12412406504154205 0.4430045783519745 0.8878852725028992 +vn 0 0.4600650668144226 0.8878852128982544 +vn 0.05489178001880646 0.19591131806373596 0.9790840744972229 +vn 0 0.20345602929592133 0.9790840744972229 +vn -0.018411584198474884 -0.06571180373430252 0.9976688027381897 +vn 0 -0.06824242323637009 0.9976688027381897 +vn -0.09034943580627441 -0.3224613666534424 0.9422609210014343 +vn 0 -0.334879606962204 0.9422609210014343 +vn -0.15558649599552155 -0.555295467376709 0.8169699311256409 +vn 0 -0.5766803026199341 0.8169699311256409 +vn -0.20928440988063812 -0.746945858001709 0.6310879588127136 +vn 0 -0.7757112979888916 0.6310879588127136 +vn -0.24746064841747284 -0.8831986784934998 0.3984011113643646 +vn 0 -0.9172112941741943 0.39840108156204224 +vn -0.2672838866710663 -0.9539486765861511 0.13616666197776794 +vn 0 -0.9906859993934631 0.13616666197776794 +vn -0.2672838866710663 -0.9539486765861511 -0.13616666197776794 +vn 0 -0.9906859993934631 -0.13616666197776794 +vn -0.24746064841747284 -0.8831986784934998 -0.3984011113643646 +vn 0 -0.9172112941741943 -0.39840108156204224 +vn -0.20928440988063812 -0.746945858001709 -0.6310879588127136 +vn 0 -0.7757112979888916 -0.6310879588127136 +vn -0.15558649599552155 -0.555295467376709 -0.8169699311256409 +vn 0 -0.5766803026199341 -0.8169699311256409 +vn -0.09034943580627441 -0.3224613666534424 -0.9422609210014343 +vn 0 -0.334879606962204 -0.9422609210014343 +vn -0.018411584198474884 -0.06571180373430252 -0.9976688027381897 +vn 0 -0.06824242323637009 -0.9976688027381897 +vn 0.05489178001880646 0.19591131806373596 -0.9790840744972229 +vn 0 0.20345602929592133 -0.9790840744972229 +vn 0.12412406504154205 0.4430045783519745 -0.8878852725028992 +vn 0 0.4600650668144226 -0.8878852128982544 +vn 0.18415063619613647 0.6572422385215759 -0.7308359742164612 +vn 0 0.6825531721115112 -0.7308359742164612 +vn 0.2305196076631546 0.8227352499961853 -0.5195840001106262 +vn 0 0.8544194102287292 -0.5195839405059814 +vn 0.2597920000553131 0.927209734916687 -0.26979678869247437 +vn 0 0.9629173278808594 -0.26979678869247437 +vn 0.5003163814544678 0.8227352499961853 0.269796758890152 +vn 0.5195839405059814 0.8544194102287292 0 +vn 0.4439426064491272 0.7300325036048889 0.5195839405059814 +vn 0.35464367270469666 0.583186686038971 0.7308359742164612 +vn 0.23904243111610413 0.39308851957321167 0.8878852128982544 +vn 0.10571248084306717 0.17383678257465363 0.9790840744972229 +vn -0.03545766696333885 -0.058307647705078125 0.9976688027381897 +vn -0.17399808764457703 -0.28612765669822693 0.9422609210014343 +vn -0.29963383078575134 -0.4927268624305725 0.8169699311256409 +vn -0.4030471444129944 -0.6627827882766724 0.6310879588127136 +vn -0.4765683114528656 -0.783683180809021 0.3984011113643646 +vn -0.5147445201873779 -0.846461296081543 0.13616664707660675 +vn -0.5147445201873779 -0.846461296081543 -0.13616664707660675 +vn -0.4765683114528656 -0.783683180809021 -0.3984011113643646 +vn -0.4030471444129944 -0.6627827882766724 -0.6310879588127136 +vn -0.29963383078575134 -0.4927268624305725 -0.8169699311256409 +vn -0.17399808764457703 -0.28612765669822693 -0.9422609210014343 +vn -0.03545766696333885 -0.058307647705078125 -0.9976688027381897 +vn 0.10571248084306717 0.17383678257465363 -0.9790840744972229 +vn 0.23904243111610413 0.39308851957321167 -0.8878852128982544 +vn 0.35464367270469666 0.583186686038971 -0.7308359742164612 +vn 0.4439426064491272 0.7300325036048889 -0.5195839405059814 +vn 0.5003163814544678 0.8227352499961853 -0.269796758890152 +vn 0.7037346363067627 0.6572422385215759 0.26979678869247437 +vn 0.7308359742164612 0.6825531125068665 0 +vn 0.6244404315948486 0.5831866264343262 0.5195839405059814 +vn 0.49883440136909485 0.46587881445884705 0.7308359742164612 +vn 0.33623209595680237 0.3140188455581665 0.8878852128982544 +vn 0.14869298040866852 0.13886955380439758 0.9790840744972229 +vn -0.049874015152454376 -0.04657907783985138 0.9976688027381897 +vn -0.24474206566810608 -0.22857314348220825 0.9422609210014343 +vn -0.42145872116088867 -0.3936149477958679 0.8169699311256409 +vn -0.5669177174568176 -0.5294641852378845 0.6310879588127136 +vn -0.6703310608863831 -0.6260454654693604 0.3984011113643646 +vn -0.7240289449691772 -0.6761958599090576 0.13616666197776794 +vn -0.7240289449691772 -0.6761958599090576 -0.13616666197776794 +vn -0.6703310608863831 -0.6260454654693604 -0.3984011113643646 +vn -0.5669177174568176 -0.5294641852378845 -0.6310879588127136 +vn -0.42145872116088867 -0.3936149477958679 -0.8169699311256409 +vn -0.24474206566810608 -0.22857314348220825 -0.9422609210014343 +vn -0.049874015152454376 -0.04657907783985138 -0.9976688027381897 +vn 0.14869298040866852 0.13886955380439758 -0.9790840744972229 +vn 0.33623209595680237 0.3140188455581665 -0.8878852128982544 +vn 0.49883440136909485 0.46587881445884705 -0.7308359742164612 +vn 0.6244404315948486 0.5831866264343262 -0.5195839405059814 +vn 0.7037346363067627 0.6572422385215759 -0.26979678869247437 +vn 0.8549600839614868 0.4430046081542969 0.26979678869247437 +vn 0.8878852725028992 0.4600650370121002 0 +vn 0.7586263418197632 0.39308851957321167 0.5195840001106262 +vn 0.6060289144515991 0.3140188455581665 0.7308359742164612 +vn 0.40848493576049805 0.21165986359119415 0.8878852128982544 +vn 0.18064559996128082 0.09360300004482269 0.9790840744972229 +vn -0.0605914369225502 -0.03139595314860344 0.9976688027381897 +vn -0.2973346710205078 -0.15406639873981476 0.9422609210014343 +vn -0.5120258927345276 -0.2653104364871979 0.8169699311256409 +vn -0.6887425780296326 -0.3568776547908783 0.6310879588127136 +vn -0.8143783807754517 -0.42197686433792114 0.39840108156204224 +vn -0.8796154260635376 -0.4557799696922302 0.13616664707660675 +vn -0.8796154260635376 -0.4557799696922302 -0.13616664707660675 +vn -0.8143783807754517 -0.42197686433792114 -0.39840108156204224 +vn -0.6887425780296326 -0.3568776547908783 -0.6310879588127136 +vn -0.5120258927345276 -0.2653104364871979 -0.8169699311256409 +vn -0.2973346710205078 -0.15406639873981476 -0.9422609210014343 +vn -0.0605914369225502 -0.03139595314860344 -0.9976688027381897 +vn 0.18064559996128082 0.09360300004482269 -0.9790840744972229 +vn 0.40848493576049805 0.21165986359119415 -0.8878852128982544 +vn 0.6060289144515991 0.3140188455581665 -0.7308359742164612 +vn 0.7586263418197632 0.39308851957321167 -0.5195840001106262 +vn 0.8549600839614868 0.4430046081542969 -0.26979678869247437 +vn 0.9427770376205444 0.19591131806373596 0.26979678869247437 +vn 0.9790840744972229 0.20345599949359894 0 +vn 0.8365484476089478 0.17383678257465363 0.5195840001106262 +vn 0.6682769656181335 0.1388695389032364 0.7308359742164612 +vn 0.450442373752594 0.09360300004482269 0.8878852725028992 +vn 0.1992005556821823 0.041394349187612534 0.9790840744972229 +vn -0.06681507080793381 -0.013884330168366432 0.9976688027381897 +vn -0.3278753161430359 -0.06813327223062515 0.9422609210014343 +vn -0.5646185278892517 -0.11732908338308334 0.8169699311256409 +vn -0.7594866156578064 -0.1578231304883957 0.6310879588127136 +vn -0.8980270028114319 -0.18661215901374817 0.39840108156204224 +vn -0.969964861869812 -0.20156101882457733 0.13616666197776794 +vn -0.969964861869812 -0.20156101882457733 -0.13616666197776794 +vn -0.8980270028114319 -0.18661215901374817 -0.39840108156204224 +vn -0.7594866156578064 -0.1578231304883957 -0.6310879588127136 +vn -0.5646185278892517 -0.11732908338308334 -0.8169699311256409 +vn -0.3278753161430359 -0.06813327223062515 -0.9422609210014343 +vn -0.06681507080793381 -0.013884330168366432 -0.9976688027381897 +vn 0.1992005556821823 0.041394349187612534 -0.9790840744972229 +vn 0.450442373752594 0.09360300004482269 -0.8878852725028992 +vn 0.6682769656181335 0.1388695389032364 -0.7308359742164612 +vn 0.8365484476089478 0.17383678257465363 -0.5195840001106262 +vn 0.9427770376205444 0.19591131806373596 -0.26979678869247437 +vn 0.9606725573539734 -0.06571180373430252 0.26979678869247437 +vn 0.9976688027381897 -0.06824242323637009 0 +vn 0.8524275422096252 -0.05830764025449753 0.5195839405059814 +vn 0.6809619665145874 -0.04657907411456108 0.7308359742164612 +vn 0.45899254083633423 -0.03139595314860344 0.8878852128982544 +vn 0.20298172533512115 -0.013884330168366432 0.9790840744972229 +vn -0.06808333098888397 0.004657027777284384 0.9976688027381897 +vn -0.3340989351272583 0.02285299263894558 0.9422609210014343 +vn -0.5753359794616699 0.03935405611991882 0.8169699311256409 +vn -0.773902952671051 0.052936408668756485 0.6310879588127136 +vn -0.9150730967521667 0.06259272247552872 0.3984011113643646 +vn -0.9883764386177063 0.06760680675506592 0.13616666197776794 +vn -0.9883764386177063 0.06760680675506592 -0.13616666197776794 +vn -0.9150730967521667 0.06259272247552872 -0.3984011113643646 +vn -0.773902952671051 0.052936408668756485 -0.6310879588127136 +vn -0.5753359794616699 0.03935405611991882 -0.8169699311256409 +vn -0.3340989351272583 0.02285299263894558 -0.9422609210014343 +vn -0.06808333098888397 0.004657027777284384 -0.9976688027381897 +vn 0.20298172533512115 -0.013884330168366432 -0.9790840744972229 +vn 0.45899254083633423 -0.03139595314860344 -0.8878852128982544 +vn 0.6809619665145874 -0.04657907411456108 -0.7308359742164612 +vn 0.8524275422096252 -0.05830764025449753 -0.5195839405059814 +vn 0.9606725573539734 -0.06571180373430252 -0.26979678869247437 +vn 0.9073193669319153 -0.3224613666534424 0.26979678869247437 +vn 0.9422609806060791 -0.33487963676452637 0 +vn 0.8050860166549683 -0.28612762689590454 0.5195839405059814 +vn 0.6431431770324707 -0.22857314348220825 0.7308359742164612 +vn 0.43350133299827576 -0.15406641364097595 0.8878852128982544 +vn 0.19170865416526794 -0.06813327223062515 0.9790840744972229 +vn -0.06430216878652573 0.02285299450159073 0.9976688027381897 +vn -0.3155439794063568 0.1121443584561348 0.9422609210014343 +vn -0.5433833003044128 0.19311846792697906 0.8169699311256409 +vn -0.7309224605560303 0.25976988673210144 0.6310879588127136 +vn -0.8642523884773254 0.3071553707122803 0.39840108156204224 +vn -0.933484673500061 0.3317605257034302 0.13616664707660675 +vn -0.933484673500061 0.3317605257034302 -0.13616664707660675 +vn -0.8642523884773254 0.3071553707122803 -0.39840108156204224 +vn -0.7309224605560303 0.25976988673210144 -0.6310879588127136 +vn -0.5433833003044128 0.19311846792697906 -0.8169699311256409 +vn -0.3155439794063568 0.1121443584561348 -0.9422609210014343 +vn -0.06430216878652573 0.02285299450159073 -0.9976688027381897 +vn 0.19170865416526794 -0.06813327223062515 -0.9790840744972229 +vn 0.43350133299827576 -0.15406641364097595 -0.8878852128982544 +vn 0.6431431770324707 -0.22857314348220825 -0.7308359742164612 +vn 0.8050860166549683 -0.28612762689590454 -0.5195839405059814 +vn 0.9073193669319153 -0.3224613666534424 -0.26979678869247437 +vn 0.786674439907074 -0.555295467376709 0.269796758890152 +vn 0.8169699311256409 -0.5766803622245789 0 +vn 0.698034942150116 -0.4927268326282501 0.5195839405059814 +vn 0.557625412940979 -0.3936149775981903 0.7308359742164612 +vn 0.3758592903614044 -0.26531049609184265 0.8878852128982544 +vn 0.16621744632720947 -0.11732907593250275 0.9790840744972229 +vn -0.05575200170278549 0.03935405984520912 0.9976688027381897 +vn -0.27358657121658325 0.19311848282814026 0.9422609210014343 +vn -0.4711304306983948 0.3325601816177368 0.8169699311256409 +vn -0.633732795715332 0.44733744859695435 0.6310879588127136 +vn -0.7493340373039246 0.5289377570152283 0.39840108156204224 +vn -0.8093606233596802 0.5713091492652893 0.13616666197776794 +vn -0.8093606233596802 0.5713091492652893 -0.13616666197776794 +vn -0.7493340373039246 0.5289377570152283 -0.39840108156204224 +vn -0.633732795715332 0.44733744859695435 -0.6310879588127136 +vn -0.4711304306983948 0.3325601816177368 -0.8169699311256409 +vn -0.27358657121658325 0.19311848282814026 -0.9422609210014343 +vn -0.05575200170278549 0.03935405984520912 -0.9976688027381897 +vn 0.16621744632720947 -0.11732907593250275 -0.9790840744972229 +vn 0.3758592903614044 -0.26531049609184265 -0.8878852128982544 +vn 0.557625412940979 -0.3936149775981903 -0.7308359742164612 +vn 0.698034942150116 -0.4927268326282501 -0.5195839405059814 +vn 0.786674439907074 -0.555295467376709 -0.269796758890152 +vn 0.6076855063438416 -0.7469457983970642 0.269796758890152 +vn 0.6310879588127136 -0.7757112979888916 0 +vn 0.5392138361930847 -0.6627827882766724 0.5195840001106262 +vn 0.4307510554790497 -0.5294641852378845 0.7308359742164612 +vn 0.2903415262699127 -0.3568776547908783 0.8878852128982544 +vn 0.12839864194393158 -0.1578231304883957 0.9790840744972229 +vn -0.04306696727871895 0.05293641611933708 0.9976688027381897 +vn -0.21133849024772644 0.25976988673210144 0.9422609210014343 +vn -0.3639359772205353 0.44733744859695435 0.8169699311256409 +vn -0.48954203724861145 0.6017280220985413 0.6310879588127136 +vn -0.5788410902023315 0.7114911675453186 0.3984011113643646 +vn -0.6252099871635437 0.7684863209724426 0.13616666197776794 +vn -0.6252099871635437 0.7684863209724426 -0.13616666197776794 +vn -0.5788410902023315 0.7114911675453186 -0.3984011113643646 +vn -0.48954203724861145 0.6017280220985413 -0.6310879588127136 +vn -0.3639359772205353 0.44733744859695435 -0.8169699311256409 +vn -0.21133849024772644 0.25976988673210144 -0.9422609210014343 +vn -0.04306696727871895 0.05293641611933708 -0.9976688027381897 +vn 0.12839864194393158 -0.1578231304883957 -0.9790840744972229 +vn 0.2903415262699127 -0.3568776547908783 -0.8878852128982544 +vn 0.4307510554790497 -0.5294641852378845 -0.7308359742164612 +vn 0.5392138361930847 -0.6627827882766724 -0.5195840001106262 +vn 0.6076855063438416 -0.7469457983970642 -0.269796758890152 +vn 0.383627325296402 -0.8831986784934998 0.26979678869247437 +vn 0.3984011113643646 -0.9172112941741943 0 +vn 0.34040161967277527 -0.7836831212043762 0.5195839405059814 +vn 0.27192991971969604 -0.6260454654693604 0.7308359742164612 +vn 0.18329042196273804 -0.42197686433792114 0.8878852128982544 +vn 0.0810571014881134 -0.18661215901374817 0.9790840744972229 +vn -0.027187854051589966 0.06259272247552872 0.9976688027381897 +vn -0.13341641426086426 0.3071553707122803 0.9422609210014343 +vn -0.22975006699562073 0.5289376974105835 0.8169699311256409 +vn -0.30904421210289 0.7114911675453186 0.6310879588127136 +vn -0.3654179871082306 0.8412765860557556 0.39840108156204224 +vn -0.3946903645992279 0.9086683392524719 0.13616664707660675 +vn -0.3946903645992279 0.9086683392524719 -0.13616664707660675 +vn -0.3654179871082306 0.8412765860557556 -0.39840108156204224 +vn -0.30904421210289 0.7114911675453186 -0.6310879588127136 +vn -0.22975006699562073 0.5289376974105835 -0.8169699311256409 +vn -0.13341641426086426 0.3071553707122803 -0.9422609210014343 +vn -0.027187854051589966 0.06259272247552872 -0.9976688027381897 +vn 0.0810571014881134 -0.18661215901374817 -0.9790840744972229 +vn 0.18329042196273804 -0.42197686433792114 -0.8878852128982544 +vn 0.27192991971969604 -0.6260454654693604 -0.7308359742164612 +vn 0.34040161967277527 -0.7836831212043762 -0.5195839405059814 +vn 0.383627325296402 -0.8831986784934998 -0.26979678869247437 +vn 0.13111722469329834 -0.9539486765861511 0.26979678869247437 +vn 0.13616666197776794 -0.9906859993934631 0 +vn 0.1163434237241745 -0.846461296081543 0.5195839405059814 +vn 0.09294097870588303 -0.6761958599090576 0.7308359742164612 +vn 0.06264551728963852 -0.4557799696922302 0.8878852128982544 +vn 0.027703924104571342 -0.20156103372573853 0.9790840744972229 +vn -0.009292341768741608 0.06760680675506592 0.9976688027381897 +vn -0.04559943452477455 0.3317605257034302 0.9422609210014343 +vn -0.0785246267914772 0.5713090896606445 0.8169699311256409 +vn -0.10562600940465927 0.7684862613677979 0.6310879588127136 +vn -0.12489359080791473 0.9086683392524719 0.39840108156204224 +vn -0.13489839434623718 0.9814586639404297 0.13616666197776794 +vn -0.13489839434623718 0.9814586639404297 -0.13616666197776794 +vn -0.12489359080791473 0.9086683392524719 -0.39840108156204224 +vn -0.10562600940465927 0.7684862613677979 -0.6310879588127136 +vn -0.0785246267914772 0.5713090896606445 -0.8169699311256409 +vn -0.04559943452477455 0.3317605257034302 -0.9422609210014343 +vn -0.009292341768741608 0.06760680675506592 -0.9976688027381897 +vn 0.027703924104571342 -0.20156103372573853 -0.9790840744972229 +vn 0.06264551728963852 -0.4557799696922302 -0.8878852128982544 +vn 0.09294097870588303 -0.6761958599090576 -0.7308359742164612 +vn 0.1163434237241745 -0.846461296081543 -0.5195839405059814 +vn 0.13111722469329834 -0.9539486765861511 -0.26979678869247437 +vn -0.13111722469329834 -0.9539486765861511 0.26979678869247437 +vn -0.13616666197776794 -0.9906859993934631 0 +vn -0.1163434237241745 -0.846461296081543 0.5195839405059814 +vn -0.09294097870588303 -0.6761958599090576 0.7308359742164612 +vn -0.06264551728963852 -0.4557799696922302 0.8878852128982544 +vn -0.027703924104571342 -0.20156103372573853 0.9790840744972229 +vn 0.009292341768741608 0.06760680675506592 0.9976688027381897 +vn 0.04559943452477455 0.3317605257034302 0.9422609210014343 +vn 0.0785246267914772 0.5713090896606445 0.8169699311256409 +vn 0.10562600940465927 0.7684862613677979 0.6310879588127136 +vn 0.12489359080791473 0.9086683392524719 0.39840108156204224 +vn 0.13489839434623718 0.9814586639404297 0.13616666197776794 +vn 0.13489839434623718 0.9814586639404297 -0.13616666197776794 +vn 0.12489359080791473 0.9086683392524719 -0.39840108156204224 +vn 0.10562600940465927 0.7684862613677979 -0.6310879588127136 +vn 0.0785246267914772 0.5713090896606445 -0.8169699311256409 +vn 0.04559943452477455 0.3317605257034302 -0.9422609210014343 +vn 0.009292341768741608 0.06760680675506592 -0.9976688027381897 +vn -0.027703924104571342 -0.20156103372573853 -0.9790840744972229 +vn -0.06264551728963852 -0.4557799696922302 -0.8878852128982544 +vn -0.09294097870588303 -0.6761958599090576 -0.7308359742164612 +vn -0.1163434237241745 -0.846461296081543 -0.5195839405059814 +vn -0.13111722469329834 -0.9539486765861511 -0.26979678869247437 +vn -0.383627325296402 -0.8831986784934998 0.26979678869247437 +vn -0.3984011113643646 -0.9172112941741943 0 +vn -0.34040161967277527 -0.7836831212043762 0.5195839405059814 +vn -0.27192991971969604 -0.6260454654693604 0.7308359742164612 +vn -0.18329042196273804 -0.42197686433792114 0.8878852128982544 +vn -0.0810571014881134 -0.18661215901374817 0.9790840744972229 +vn 0.027187854051589966 0.06259272247552872 0.9976688027381897 +vn 0.13341641426086426 0.3071553707122803 0.9422609210014343 +vn 0.22975006699562073 0.5289376974105835 0.8169699311256409 +vn 0.30904421210289 0.7114911675453186 0.6310879588127136 +vn 0.3654179871082306 0.8412765860557556 0.39840108156204224 +vn 0.3946903645992279 0.9086683392524719 0.13616664707660675 +vn 0.3946903645992279 0.9086683392524719 -0.13616664707660675 +vn 0.3654179871082306 0.8412765860557556 -0.39840108156204224 +vn 0.30904421210289 0.7114911675453186 -0.6310879588127136 +vn 0.22975006699562073 0.5289376974105835 -0.8169699311256409 +vn 0.13341641426086426 0.3071553707122803 -0.9422609210014343 +vn 0.027187854051589966 0.06259272247552872 -0.9976688027381897 +vn -0.0810571014881134 -0.18661215901374817 -0.9790840744972229 +vn -0.18329042196273804 -0.42197686433792114 -0.8878852128982544 +vn -0.27192991971969604 -0.6260454654693604 -0.7308359742164612 +vn -0.34040161967277527 -0.7836831212043762 -0.5195839405059814 +vn -0.383627325296402 -0.8831986784934998 -0.26979678869247437 +vn -0.6076855063438416 -0.7469457983970642 0.269796758890152 +vn -0.6310879588127136 -0.7757112979888916 0 +vn -0.5392138361930847 -0.6627827882766724 0.5195840001106262 +vn -0.4307510554790497 -0.5294641852378845 0.7308359742164612 +vn -0.2903415262699127 -0.3568776547908783 0.8878852128982544 +vn -0.12839864194393158 -0.1578231304883957 0.9790840744972229 +vn 0.04306696727871895 0.05293641611933708 0.9976688027381897 +vn 0.21133849024772644 0.25976988673210144 0.9422609210014343 +vn 0.3639359772205353 0.44733744859695435 0.8169699311256409 +vn 0.48954203724861145 0.6017280220985413 0.6310879588127136 +vn 0.5788410902023315 0.7114911675453186 0.3984011113643646 +vn 0.6252099871635437 0.7684863209724426 0.13616666197776794 +vn 0.6252099871635437 0.7684863209724426 -0.13616666197776794 +vn 0.5788410902023315 0.7114911675453186 -0.3984011113643646 +vn 0.48954203724861145 0.6017280220985413 -0.6310879588127136 +vn 0.3639359772205353 0.44733744859695435 -0.8169699311256409 +vn 0.21133849024772644 0.25976988673210144 -0.9422609210014343 +vn 0.04306696727871895 0.05293641611933708 -0.9976688027381897 +vn -0.12839864194393158 -0.1578231304883957 -0.9790840744972229 +vn -0.2903415262699127 -0.3568776547908783 -0.8878852128982544 +vn -0.4307510554790497 -0.5294641852378845 -0.7308359742164612 +vn -0.5392138361930847 -0.6627827882766724 -0.5195840001106262 +vn -0.6076855063438416 -0.7469457983970642 -0.269796758890152 +vn -0.786674439907074 -0.555295467376709 0.269796758890152 +vn -0.8169699311256409 -0.5766803622245789 0 +vn -0.698034942150116 -0.4927268326282501 0.5195839405059814 +vn -0.557625412940979 -0.3936149775981903 0.7308359742164612 +vn -0.3758592903614044 -0.26531049609184265 0.8878852128982544 +vn -0.16621744632720947 -0.11732907593250275 0.9790840744972229 +vn 0.05575200170278549 0.03935405984520912 0.9976688027381897 +vn 0.27358657121658325 0.19311848282814026 0.9422609210014343 +vn 0.4711304306983948 0.3325601816177368 0.8169699311256409 +vn 0.633732795715332 0.44733744859695435 0.6310879588127136 +vn 0.7493340373039246 0.5289377570152283 0.39840108156204224 +vn 0.8093606233596802 0.5713091492652893 0.13616666197776794 +vn 0.8093606233596802 0.5713091492652893 -0.13616666197776794 +vn 0.7493340373039246 0.5289377570152283 -0.39840108156204224 +vn 0.633732795715332 0.44733744859695435 -0.6310879588127136 +vn 0.4711304306983948 0.3325601816177368 -0.8169699311256409 +vn 0.27358657121658325 0.19311848282814026 -0.9422609210014343 +vn 0.05575200170278549 0.03935405984520912 -0.9976688027381897 +vn -0.16621744632720947 -0.11732907593250275 -0.9790840744972229 +vn -0.3758592903614044 -0.26531049609184265 -0.8878852128982544 +vn -0.557625412940979 -0.3936149775981903 -0.7308359742164612 +vn -0.698034942150116 -0.4927268326282501 -0.5195839405059814 +vn -0.786674439907074 -0.555295467376709 -0.269796758890152 +vn -0.9073193669319153 -0.3224613666534424 0.26979678869247437 +vn -0.9422609806060791 -0.33487963676452637 0 +vn -0.8050860166549683 -0.28612762689590454 0.5195839405059814 +vn -0.6431431770324707 -0.22857314348220825 0.7308359742164612 +vn -0.43350133299827576 -0.15406641364097595 0.8878852128982544 +vn -0.19170865416526794 -0.06813327223062515 0.9790840744972229 +vn 0.06430216878652573 0.02285299450159073 0.9976688027381897 +vn 0.3155439794063568 0.1121443584561348 0.9422609210014343 +vn 0.5433833003044128 0.19311846792697906 0.8169699311256409 +vn 0.7309224605560303 0.25976988673210144 0.6310879588127136 +vn 0.8642523884773254 0.3071553707122803 0.39840108156204224 +vn 0.933484673500061 0.3317605257034302 0.13616664707660675 +vn 0.933484673500061 0.3317605257034302 -0.13616664707660675 +vn 0.8642523884773254 0.3071553707122803 -0.39840108156204224 +vn 0.7309224605560303 0.25976988673210144 -0.6310879588127136 +vn 0.5433833003044128 0.19311846792697906 -0.8169699311256409 +vn 0.3155439794063568 0.1121443584561348 -0.9422609210014343 +vn 0.06430216878652573 0.02285299450159073 -0.9976688027381897 +vn -0.19170865416526794 -0.06813327223062515 -0.9790840744972229 +vn -0.43350133299827576 -0.15406641364097595 -0.8878852128982544 +vn -0.6431431770324707 -0.22857314348220825 -0.7308359742164612 +vn -0.8050860166549683 -0.28612762689590454 -0.5195839405059814 +vn -0.9073193669319153 -0.3224613666534424 -0.26979678869247437 +vn -0.9606725573539734 -0.06571180373430252 0.26979678869247437 +vn -0.9976688027381897 -0.06824242323637009 0 +vn -0.8524275422096252 -0.05830764025449753 0.5195839405059814 +vn -0.6809619665145874 -0.04657907411456108 0.7308359742164612 +vn -0.45899254083633423 -0.03139595314860344 0.8878852128982544 +vn -0.20298172533512115 -0.013884330168366432 0.9790840744972229 +vn 0.06808333098888397 0.004657027777284384 0.9976688027381897 +vn 0.3340989351272583 0.02285299263894558 0.9422609210014343 +vn 0.5753359794616699 0.03935405611991882 0.8169699311256409 +vn 0.773902952671051 0.052936408668756485 0.6310879588127136 +vn 0.9150730967521667 0.06259272247552872 0.3984011113643646 +vn 0.9883764386177063 0.06760680675506592 0.13616666197776794 +vn 0.9883764386177063 0.06760680675506592 -0.13616666197776794 +vn 0.9150730967521667 0.06259272247552872 -0.3984011113643646 +vn 0.773902952671051 0.052936408668756485 -0.6310879588127136 +vn 0.5753359794616699 0.03935405611991882 -0.8169699311256409 +vn 0.3340989351272583 0.02285299263894558 -0.9422609210014343 +vn 0.06808333098888397 0.004657027777284384 -0.9976688027381897 +vn -0.20298172533512115 -0.013884330168366432 -0.9790840744972229 +vn -0.45899254083633423 -0.03139595314860344 -0.8878852128982544 +vn -0.6809619665145874 -0.04657907411456108 -0.7308359742164612 +vn -0.8524275422096252 -0.05830764025449753 -0.5195839405059814 +vn -0.9606725573539734 -0.06571180373430252 -0.26979678869247437 +vn -0.9427770376205444 0.19591131806373596 0.26979678869247437 +vn -0.9790840744972229 0.20345599949359894 0 +vn -0.8365484476089478 0.17383678257465363 0.5195840001106262 +vn -0.6682769656181335 0.1388695389032364 0.7308359742164612 +vn -0.450442373752594 0.09360300004482269 0.8878852725028992 +vn -0.1992005556821823 0.041394349187612534 0.9790840744972229 +vn 0.06681507080793381 -0.013884330168366432 0.9976688027381897 +vn 0.3278753161430359 -0.06813327223062515 0.9422609210014343 +vn 0.5646185278892517 -0.11732908338308334 0.8169699311256409 +vn 0.7594866156578064 -0.1578231304883957 0.6310879588127136 +vn 0.8980270028114319 -0.18661215901374817 0.39840108156204224 +vn 0.969964861869812 -0.20156101882457733 0.13616666197776794 +vn 0.969964861869812 -0.20156101882457733 -0.13616666197776794 +vn 0.8980270028114319 -0.18661215901374817 -0.39840108156204224 +vn 0.7594866156578064 -0.1578231304883957 -0.6310879588127136 +vn 0.5646185278892517 -0.11732908338308334 -0.8169699311256409 +vn 0.3278753161430359 -0.06813327223062515 -0.9422609210014343 +vn 0.06681507080793381 -0.013884330168366432 -0.9976688027381897 +vn -0.1992005556821823 0.041394349187612534 -0.9790840744972229 +vn -0.450442373752594 0.09360300004482269 -0.8878852725028992 +vn -0.6682769656181335 0.1388695389032364 -0.7308359742164612 +vn -0.8365484476089478 0.17383678257465363 -0.5195840001106262 +vn -0.9427770376205444 0.19591131806373596 -0.26979678869247437 +vn -0.8549600839614868 0.4430046081542969 0.26979678869247437 +vn -0.8878852725028992 0.4600650370121002 0 +vn -0.7586263418197632 0.39308851957321167 0.5195840001106262 +vn -0.6060289144515991 0.3140188455581665 0.7308359742164612 +vn -0.40848493576049805 0.21165986359119415 0.8878852128982544 +vn -0.18064559996128082 0.09360300004482269 0.9790840744972229 +vn 0.0605914369225502 -0.03139595314860344 0.9976688027381897 +vn 0.2973346710205078 -0.15406639873981476 0.9422609210014343 +vn 0.5120258927345276 -0.2653104364871979 0.8169699311256409 +vn 0.6887425780296326 -0.3568776547908783 0.6310879588127136 +vn 0.8143783807754517 -0.42197686433792114 0.39840108156204224 +vn 0.8796154260635376 -0.4557799696922302 0.13616664707660675 +vn 0.8796154260635376 -0.4557799696922302 -0.13616664707660675 +vn 0.8143783807754517 -0.42197686433792114 -0.39840108156204224 +vn 0.6887425780296326 -0.3568776547908783 -0.6310879588127136 +vn 0.5120258927345276 -0.2653104364871979 -0.8169699311256409 +vn 0.2973346710205078 -0.15406639873981476 -0.9422609210014343 +vn 0.0605914369225502 -0.03139595314860344 -0.9976688027381897 +vn -0.18064559996128082 0.09360300004482269 -0.9790840744972229 +vn -0.40848493576049805 0.21165986359119415 -0.8878852128982544 +vn -0.6060289144515991 0.3140188455581665 -0.7308359742164612 +vn -0.7586263418197632 0.39308851957321167 -0.5195840001106262 +vn -0.8549600839614868 0.4430046081542969 -0.26979678869247437 +vn -0.7037346363067627 0.6572422385215759 0.26979678869247437 +vn -0.7308359742164612 0.6825531125068665 0 +vn -0.6244404315948486 0.5831866264343262 0.5195839405059814 +vn -0.49883440136909485 0.46587881445884705 0.7308359742164612 +vn -0.33623209595680237 0.3140188455581665 0.8878852128982544 +vn -0.14869298040866852 0.13886955380439758 0.9790840744972229 +vn 0.049874015152454376 -0.04657907783985138 0.9976688027381897 +vn 0.24474206566810608 -0.22857314348220825 0.9422609210014343 +vn 0.42145872116088867 -0.3936149477958679 0.8169699311256409 +vn 0.5669177174568176 -0.5294641852378845 0.6310879588127136 +vn 0.6703310608863831 -0.6260454654693604 0.3984011113643646 +vn 0.7240289449691772 -0.6761958599090576 0.13616666197776794 +vn 0.7240289449691772 -0.6761958599090576 -0.13616666197776794 +vn 0.6703310608863831 -0.6260454654693604 -0.3984011113643646 +vn 0.5669177174568176 -0.5294641852378845 -0.6310879588127136 +vn 0.42145872116088867 -0.3936149477958679 -0.8169699311256409 +vn 0.24474206566810608 -0.22857314348220825 -0.9422609210014343 +vn 0.049874015152454376 -0.04657907783985138 -0.9976688027381897 +vn -0.14869298040866852 0.13886955380439758 -0.9790840744972229 +vn -0.33623209595680237 0.3140188455581665 -0.8878852128982544 +vn -0.49883440136909485 0.46587881445884705 -0.7308359742164612 +vn -0.6244404315948486 0.5831866264343262 -0.5195839405059814 +vn -0.7037346363067627 0.6572422385215759 -0.26979678869247437 +vn -0.5003163814544678 0.8227352499961853 0.269796758890152 +vn -0.5195839405059814 0.8544194102287292 0 +vn -0.4439426064491272 0.7300325036048889 0.5195839405059814 +vn -0.35464367270469666 0.583186686038971 0.7308359742164612 +vn -0.23904243111610413 0.39308851957321167 0.8878852128982544 +vn -0.10571248084306717 0.17383678257465363 0.9790840744972229 +vn 0.03545766696333885 -0.058307647705078125 0.9976688027381897 +vn 0.17399808764457703 -0.28612765669822693 0.9422609210014343 +vn 0.29963383078575134 -0.4927268624305725 0.8169699311256409 +vn 0.4030471444129944 -0.6627827882766724 0.6310879588127136 +vn 0.4765683114528656 -0.783683180809021 0.3984011113643646 +vn 0.5147445201873779 -0.846461296081543 0.13616664707660675 +vn 0.5147445201873779 -0.846461296081543 -0.13616664707660675 +vn 0.4765683114528656 -0.783683180809021 -0.3984011113643646 +vn 0.4030471444129944 -0.6627827882766724 -0.6310879588127136 +vn 0.29963383078575134 -0.4927268624305725 -0.8169699311256409 +vn 0.17399808764457703 -0.28612765669822693 -0.9422609210014343 +vn 0.03545766696333885 -0.058307647705078125 -0.9976688027381897 +vn -0.10571248084306717 0.17383678257465363 -0.9790840744972229 +vn -0.23904243111610413 0.39308851957321167 -0.8878852128982544 +vn -0.35464367270469666 0.583186686038971 -0.7308359742164612 +vn -0.4439426064491272 0.7300325036048889 -0.5195839405059814 +vn -0.5003163814544678 0.8227352499961853 -0.269796758890152 +vn -0.2597920000553131 0.927209734916687 0.26979678869247437 +vn -0.26979678869247437 0.9629173278808594 0 +vn -0.2305196076631546 0.8227352499961853 0.5195840001106262 +vn -0.18415063619613647 0.6572422385215759 0.7308359742164612 +vn -0.12412406504154205 0.4430045783519745 0.8878852725028992 +vn -0.05489178001880646 0.19591131806373596 0.9790840744972229 +vn 0.018411584198474884 -0.06571180373430252 0.9976688027381897 +vn 0.09034943580627441 -0.3224613666534424 0.9422609210014343 +vn 0.15558649599552155 -0.555295467376709 0.8169699311256409 +vn 0.20928440988063812 -0.746945858001709 0.6310879588127136 +vn 0.24746064841747284 -0.8831986784934998 0.3984011113643646 +vn 0.2672838866710663 -0.9539486765861511 0.13616666197776794 +vn 0.2672838866710663 -0.9539486765861511 -0.13616666197776794 +vn 0.24746064841747284 -0.8831986784934998 -0.3984011113643646 +vn 0.20928440988063812 -0.746945858001709 -0.6310879588127136 +vn 0.15558649599552155 -0.555295467376709 -0.8169699311256409 +vn 0.09034943580627441 -0.3224613666534424 -0.9422609210014343 +vn 0.018411584198474884 -0.06571180373430252 -0.9976688027381897 +vn -0.05489178001880646 0.19591131806373596 -0.9790840744972229 +vn -0.12412406504154205 0.4430045783519745 -0.8878852725028992 +vn -0.18415063619613647 0.6572422385215759 -0.7308359742164612 +vn -0.2305196076631546 0.8227352499961853 -0.5195840001106262 +vn -0.2597920000553131 0.927209734916687 -0.26979678869247437 + +g grp1 +usemtl mtl1 +f 1//1 2//2 3//3 +f 1//1 4//4 2//2 +f 4//4 5//5 2//2 +f 4//4 6//6 5//5 +f 6//6 7//7 5//5 +f 6//6 8//8 7//7 +f 8//8 9//9 7//7 +f 8//8 10//10 9//9 +f 10//10 11//11 9//9 +f 10//10 12//12 11//11 +f 12//12 13//13 11//11 +f 12//12 14//14 13//13 +f 14//14 15//15 13//13 +f 14//14 16//16 15//15 +f 16//16 17//17 15//15 +f 16//16 18//18 17//17 +f 18//18 19//19 17//17 +f 18//18 20//20 19//19 +f 20//20 21//21 19//19 +f 20//20 22//22 21//21 +f 22//22 23//23 21//21 +f 22//22 24//24 23//23 +f 24//24 25//25 23//23 +f 24//24 26//26 25//25 +f 26//26 27//27 25//25 +f 26//26 28//28 27//27 +f 28//28 29//29 27//27 +f 28//28 30//30 29//29 +f 30//30 31//31 29//29 +f 30//30 32//32 31//31 +f 32//32 33//33 31//31 +f 32//32 34//34 33//33 +f 34//34 35//35 33//33 +f 34//34 36//36 35//35 +f 36//36 37//37 35//35 +f 36//36 38//38 37//37 +f 38//38 39//39 37//37 +f 38//38 40//40 39//39 +f 40//40 41//41 39//39 +f 40//40 42//42 41//41 +f 42//42 43//43 41//41 +f 42//42 44//44 43//43 +f 44//44 45//45 43//43 +f 44//44 46//46 45//45 +f 46//46 3//3 45//45 +f 46//46 1//1 3//3 +f 3//3 47//47 48//48 +f 3//3 2//2 47//47 +f 2//2 49//49 47//47 +f 2//2 5//5 49//49 +f 5//5 50//50 49//49 +f 5//5 7//7 50//50 +f 7//7 51//51 50//50 +f 7//7 9//9 51//51 +f 9//9 52//52 51//51 +f 9//9 11//11 52//52 +f 11//11 53//53 52//52 +f 11//11 13//13 53//53 +f 13//13 54//54 53//53 +f 13//13 15//15 54//54 +f 15//15 55//55 54//54 +f 15//15 17//17 55//55 +f 17//17 56//56 55//55 +f 17//17 19//19 56//56 +f 19//19 57//57 56//56 +f 19//19 21//21 57//57 +f 21//21 58//58 57//57 +f 21//21 23//23 58//58 +f 23//23 59//59 58//58 +f 23//23 25//25 59//59 +f 25//25 60//60 59//59 +f 25//25 27//27 60//60 +f 27//27 61//61 60//60 +f 27//27 29//29 61//61 +f 29//29 62//62 61//61 +f 29//29 31//31 62//62 +f 31//31 63//63 62//62 +f 31//31 33//33 63//63 +f 33//33 64//64 63//63 +f 33//33 35//35 64//64 +f 35//35 65//65 64//64 +f 35//35 37//37 65//65 +f 37//37 66//66 65//65 +f 37//37 39//39 66//66 +f 39//39 67//67 66//66 +f 39//39 41//41 67//67 +f 41//41 68//68 67//67 +f 41//41 43//43 68//68 +f 43//43 69//69 68//68 +f 43//43 45//45 69//69 +f 45//45 48//48 69//69 +f 45//45 3//3 48//48 +f 48//48 70//70 71//71 +f 48//48 47//47 70//70 +f 47//47 72//72 70//70 +f 47//47 49//49 72//72 +f 49//49 73//73 72//72 +f 49//49 50//50 73//73 +f 50//50 74//74 73//73 +f 50//50 51//51 74//74 +f 51//51 75//75 74//74 +f 51//51 52//52 75//75 +f 52//52 76//76 75//75 +f 52//52 53//53 76//76 +f 53//53 77//77 76//76 +f 53//53 54//54 77//77 +f 54//54 78//78 77//77 +f 54//54 55//55 78//78 +f 55//55 79//79 78//78 +f 55//55 56//56 79//79 +f 56//56 80//80 79//79 +f 56//56 57//57 80//80 +f 57//57 81//81 80//80 +f 57//57 58//58 81//81 +f 58//58 82//82 81//81 +f 58//58 59//59 82//82 +f 59//59 83//83 82//82 +f 59//59 60//60 83//83 +f 60//60 84//84 83//83 +f 60//60 61//61 84//84 +f 61//61 85//85 84//84 +f 61//61 62//62 85//85 +f 62//62 86//86 85//85 +f 62//62 63//63 86//86 +f 63//63 87//87 86//86 +f 63//63 64//64 87//87 +f 64//64 88//88 87//87 +f 64//64 65//65 88//88 +f 65//65 89//89 88//88 +f 65//65 66//66 89//89 +f 66//66 90//90 89//89 +f 66//66 67//67 90//90 +f 67//67 91//91 90//90 +f 67//67 68//68 91//91 +f 68//68 92//92 91//91 +f 68//68 69//69 92//92 +f 69//69 71//71 92//92 +f 69//69 48//48 71//71 +f 71//71 93//93 94//94 +f 71//71 70//70 93//93 +f 70//70 95//95 93//93 +f 70//70 72//72 95//95 +f 72//72 96//96 95//95 +f 72//72 73//73 96//96 +f 73//73 97//97 96//96 +f 73//73 74//74 97//97 +f 74//74 98//98 97//97 +f 74//74 75//75 98//98 +f 75//75 99//99 98//98 +f 75//75 76//76 99//99 +f 76//76 100//100 99//99 +f 76//76 77//77 100//100 +f 77//77 101//101 100//100 +f 77//77 78//78 101//101 +f 78//78 102//102 101//101 +f 78//78 79//79 102//102 +f 79//79 103//103 102//102 +f 79//79 80//80 103//103 +f 80//80 104//104 103//103 +f 80//80 81//81 104//104 +f 81//81 105//105 104//104 +f 81//81 82//82 105//105 +f 82//82 106//106 105//105 +f 82//82 83//83 106//106 +f 83//83 107//107 106//106 +f 83//83 84//84 107//107 +f 84//84 108//108 107//107 +f 84//84 85//85 108//108 +f 85//85 109//109 108//108 +f 85//85 86//86 109//109 +f 86//86 110//110 109//109 +f 86//86 87//87 110//110 +f 87//87 111//111 110//110 +f 87//87 88//88 111//111 +f 88//88 112//112 111//111 +f 88//88 89//89 112//112 +f 89//89 113//113 112//112 +f 89//89 90//90 113//113 +f 90//90 114//114 113//113 +f 90//90 91//91 114//114 +f 91//91 115//115 114//114 +f 91//91 92//92 115//115 +f 92//92 94//94 115//115 +f 92//92 71//71 94//94 +f 94//94 116//116 117//117 +f 94//94 93//93 116//116 +f 93//93 118//118 116//116 +f 93//93 95//95 118//118 +f 95//95 119//119 118//118 +f 95//95 96//96 119//119 +f 96//96 120//120 119//119 +f 96//96 97//97 120//120 +f 97//97 121//121 120//120 +f 97//97 98//98 121//121 +f 98//98 122//122 121//121 +f 98//98 99//99 122//122 +f 99//99 123//123 122//122 +f 99//99 100//100 123//123 +f 100//100 124//124 123//123 +f 100//100 101//101 124//124 +f 101//101 125//125 124//124 +f 101//101 102//102 125//125 +f 102//102 126//126 125//125 +f 102//102 103//103 126//126 +f 103//103 127//127 126//126 +f 103//103 104//104 127//127 +f 104//104 128//128 127//127 +f 104//104 105//105 128//128 +f 105//105 129//129 128//128 +f 105//105 106//106 129//129 +f 106//106 130//130 129//129 +f 106//106 107//107 130//130 +f 107//107 131//131 130//130 +f 107//107 108//108 131//131 +f 108//108 132//132 131//131 +f 108//108 109//109 132//132 +f 109//109 133//133 132//132 +f 109//109 110//110 133//133 +f 110//110 134//134 133//133 +f 110//110 111//111 134//134 +f 111//111 135//135 134//134 +f 111//111 112//112 135//135 +f 112//112 136//136 135//135 +f 112//112 113//113 136//136 +f 113//113 137//137 136//136 +f 113//113 114//114 137//137 +f 114//114 138//138 137//137 +f 114//114 115//115 138//138 +f 115//115 117//117 138//138 +f 115//115 94//94 117//117 +f 117//117 139//139 140//140 +f 117//117 116//116 139//139 +f 116//116 141//141 139//139 +f 116//116 118//118 141//141 +f 118//118 142//142 141//141 +f 118//118 119//119 142//142 +f 119//119 143//143 142//142 +f 119//119 120//120 143//143 +f 120//120 144//144 143//143 +f 120//120 121//121 144//144 +f 121//121 145//145 144//144 +f 121//121 122//122 145//145 +f 122//122 146//146 145//145 +f 122//122 123//123 146//146 +f 123//123 147//147 146//146 +f 123//123 124//124 147//147 +f 124//124 148//148 147//147 +f 124//124 125//125 148//148 +f 125//125 149//149 148//148 +f 125//125 126//126 149//149 +f 126//126 150//150 149//149 +f 126//126 127//127 150//150 +f 127//127 151//151 150//150 +f 127//127 128//128 151//151 +f 128//128 152//152 151//151 +f 128//128 129//129 152//152 +f 129//129 153//153 152//152 +f 129//129 130//130 153//153 +f 130//130 154//154 153//153 +f 130//130 131//131 154//154 +f 131//131 155//155 154//154 +f 131//131 132//132 155//155 +f 132//132 156//156 155//155 +f 132//132 133//133 156//156 +f 133//133 157//157 156//156 +f 133//133 134//134 157//157 +f 134//134 158//158 157//157 +f 134//134 135//135 158//158 +f 135//135 159//159 158//158 +f 135//135 136//136 159//159 +f 136//136 160//160 159//159 +f 136//136 137//137 160//160 +f 137//137 161//161 160//160 +f 137//137 138//138 161//161 +f 138//138 140//140 161//161 +f 138//138 117//117 140//140 +f 140//140 162//162 163//163 +f 140//140 139//139 162//162 +f 139//139 164//164 162//162 +f 139//139 141//141 164//164 +f 141//141 165//165 164//164 +f 141//141 142//142 165//165 +f 142//142 166//166 165//165 +f 142//142 143//143 166//166 +f 143//143 167//167 166//166 +f 143//143 144//144 167//167 +f 144//144 168//168 167//167 +f 144//144 145//145 168//168 +f 145//145 169//169 168//168 +f 145//145 146//146 169//169 +f 146//146 170//170 169//169 +f 146//146 147//147 170//170 +f 147//147 171//171 170//170 +f 147//147 148//148 171//171 +f 148//148 172//172 171//171 +f 148//148 149//149 172//172 +f 149//149 173//173 172//172 +f 149//149 150//150 173//173 +f 150//150 174//174 173//173 +f 150//150 151//151 174//174 +f 151//151 175//175 174//174 +f 151//151 152//152 175//175 +f 152//152 176//176 175//175 +f 152//152 153//153 176//176 +f 153//153 177//177 176//176 +f 153//153 154//154 177//177 +f 154//154 178//178 177//177 +f 154//154 155//155 178//178 +f 155//155 179//179 178//178 +f 155//155 156//156 179//179 +f 156//156 180//180 179//179 +f 156//156 157//157 180//180 +f 157//157 181//181 180//180 +f 157//157 158//158 181//181 +f 158//158 182//182 181//181 +f 158//158 159//159 182//182 +f 159//159 183//183 182//182 +f 159//159 160//160 183//183 +f 160//160 184//184 183//183 +f 160//160 161//161 184//184 +f 161//161 163//163 184//184 +f 161//161 140//140 163//163 +f 163//163 185//185 186//186 +f 163//163 162//162 185//185 +f 162//162 187//187 185//185 +f 162//162 164//164 187//187 +f 164//164 188//188 187//187 +f 164//164 165//165 188//188 +f 165//165 189//189 188//188 +f 165//165 166//166 189//189 +f 166//166 190//190 189//189 +f 166//166 167//167 190//190 +f 167//167 191//191 190//190 +f 167//167 168//168 191//191 +f 168//168 192//192 191//191 +f 168//168 169//169 192//192 +f 169//169 193//193 192//192 +f 169//169 170//170 193//193 +f 170//170 194//194 193//193 +f 170//170 171//171 194//194 +f 171//171 195//195 194//194 +f 171//171 172//172 195//195 +f 172//172 196//196 195//195 +f 172//172 173//173 196//196 +f 173//173 197//197 196//196 +f 173//173 174//174 197//197 +f 174//174 198//198 197//197 +f 174//174 175//175 198//198 +f 175//175 199//199 198//198 +f 175//175 176//176 199//199 +f 176//176 200//200 199//199 +f 176//176 177//177 200//200 +f 177//177 201//201 200//200 +f 177//177 178//178 201//201 +f 178//178 202//202 201//201 +f 178//178 179//179 202//202 +f 179//179 203//203 202//202 +f 179//179 180//180 203//203 +f 180//180 204//204 203//203 +f 180//180 181//181 204//204 +f 181//181 205//205 204//204 +f 181//181 182//182 205//205 +f 182//182 206//206 205//205 +f 182//182 183//183 206//206 +f 183//183 207//207 206//206 +f 183//183 184//184 207//207 +f 184//184 186//186 207//207 +f 184//184 163//163 186//186 +f 186//186 208//208 209//209 +f 186//186 185//185 208//208 +f 185//185 210//210 208//208 +f 185//185 187//187 210//210 +f 187//187 211//211 210//210 +f 187//187 188//188 211//211 +f 188//188 212//212 211//211 +f 188//188 189//189 212//212 +f 189//189 213//213 212//212 +f 189//189 190//190 213//213 +f 190//190 214//214 213//213 +f 190//190 191//191 214//214 +f 191//191 215//215 214//214 +f 191//191 192//192 215//215 +f 192//192 216//216 215//215 +f 192//192 193//193 216//216 +f 193//193 217//217 216//216 +f 193//193 194//194 217//217 +f 194//194 218//218 217//217 +f 194//194 195//195 218//218 +f 195//195 219//219 218//218 +f 195//195 196//196 219//219 +f 196//196 220//220 219//219 +f 196//196 197//197 220//220 +f 197//197 221//221 220//220 +f 197//197 198//198 221//221 +f 198//198 222//222 221//221 +f 198//198 199//199 222//222 +f 199//199 223//223 222//222 +f 199//199 200//200 223//223 +f 200//200 224//224 223//223 +f 200//200 201//201 224//224 +f 201//201 225//225 224//224 +f 201//201 202//202 225//225 +f 202//202 226//226 225//225 +f 202//202 203//203 226//226 +f 203//203 227//227 226//226 +f 203//203 204//204 227//227 +f 204//204 228//228 227//227 +f 204//204 205//205 228//228 +f 205//205 229//229 228//228 +f 205//205 206//206 229//229 +f 206//206 230//230 229//229 +f 206//206 207//207 230//230 +f 207//207 209//209 230//230 +f 207//207 186//186 209//209 +f 209//209 231//231 232//232 +f 209//209 208//208 231//231 +f 208//208 233//233 231//231 +f 208//208 210//210 233//233 +f 210//210 234//234 233//233 +f 210//210 211//211 234//234 +f 211//211 235//235 234//234 +f 211//211 212//212 235//235 +f 212//212 236//236 235//235 +f 212//212 213//213 236//236 +f 213//213 237//237 236//236 +f 213//213 214//214 237//237 +f 214//214 238//238 237//237 +f 214//214 215//215 238//238 +f 215//215 239//239 238//238 +f 215//215 216//216 239//239 +f 216//216 240//240 239//239 +f 216//216 217//217 240//240 +f 217//217 241//241 240//240 +f 217//217 218//218 241//241 +f 218//218 242//242 241//241 +f 218//218 219//219 242//242 +f 219//219 243//243 242//242 +f 219//219 220//220 243//243 +f 220//220 244//244 243//243 +f 220//220 221//221 244//244 +f 221//221 245//245 244//244 +f 221//221 222//222 245//245 +f 222//222 246//246 245//245 +f 222//222 223//223 246//246 +f 223//223 247//247 246//246 +f 223//223 224//224 247//247 +f 224//224 248//248 247//247 +f 224//224 225//225 248//248 +f 225//225 249//249 248//248 +f 225//225 226//226 249//249 +f 226//226 250//250 249//249 +f 226//226 227//227 250//250 +f 227//227 251//251 250//250 +f 227//227 228//228 251//251 +f 228//228 252//252 251//251 +f 228//228 229//229 252//252 +f 229//229 253//253 252//252 +f 229//229 230//230 253//253 +f 230//230 232//232 253//253 +f 230//230 209//209 232//232 +f 232//232 254//254 255//255 +f 232//232 231//231 254//254 +f 231//231 256//256 254//254 +f 231//231 233//233 256//256 +f 233//233 257//257 256//256 +f 233//233 234//234 257//257 +f 234//234 258//258 257//257 +f 234//234 235//235 258//258 +f 235//235 259//259 258//258 +f 235//235 236//236 259//259 +f 236//236 260//260 259//259 +f 236//236 237//237 260//260 +f 237//237 261//261 260//260 +f 237//237 238//238 261//261 +f 238//238 262//262 261//261 +f 238//238 239//239 262//262 +f 239//239 263//263 262//262 +f 239//239 240//240 263//263 +f 240//240 264//264 263//263 +f 240//240 241//241 264//264 +f 241//241 265//265 264//264 +f 241//241 242//242 265//265 +f 242//242 266//266 265//265 +f 242//242 243//243 266//266 +f 243//243 267//267 266//266 +f 243//243 244//244 267//267 +f 244//244 268//268 267//267 +f 244//244 245//245 268//268 +f 245//245 269//269 268//268 +f 245//245 246//246 269//269 +f 246//246 270//270 269//269 +f 246//246 247//247 270//270 +f 247//247 271//271 270//270 +f 247//247 248//248 271//271 +f 248//248 272//272 271//271 +f 248//248 249//249 272//272 +f 249//249 273//273 272//272 +f 249//249 250//250 273//273 +f 250//250 274//274 273//273 +f 250//250 251//251 274//274 +f 251//251 275//275 274//274 +f 251//251 252//252 275//275 +f 252//252 276//276 275//275 +f 252//252 253//253 276//276 +f 253//253 255//255 276//276 +f 253//253 232//232 255//255 +f 255//255 277//277 278//278 +f 255//255 254//254 277//277 +f 254//254 279//279 277//277 +f 254//254 256//256 279//279 +f 256//256 280//280 279//279 +f 256//256 257//257 280//280 +f 257//257 281//281 280//280 +f 257//257 258//258 281//281 +f 258//258 282//282 281//281 +f 258//258 259//259 282//282 +f 259//259 283//283 282//282 +f 259//259 260//260 283//283 +f 260//260 284//284 283//283 +f 260//260 261//261 284//284 +f 261//261 285//285 284//284 +f 261//261 262//262 285//285 +f 262//262 286//286 285//285 +f 262//262 263//263 286//286 +f 263//263 287//287 286//286 +f 263//263 264//264 287//287 +f 264//264 288//288 287//287 +f 264//264 265//265 288//288 +f 265//265 289//289 288//288 +f 265//265 266//266 289//289 +f 266//266 290//290 289//289 +f 266//266 267//267 290//290 +f 267//267 291//291 290//290 +f 267//267 268//268 291//291 +f 268//268 292//292 291//291 +f 268//268 269//269 292//292 +f 269//269 293//293 292//292 +f 269//269 270//270 293//293 +f 270//270 294//294 293//293 +f 270//270 271//271 294//294 +f 271//271 295//295 294//294 +f 271//271 272//272 295//295 +f 272//272 296//296 295//295 +f 272//272 273//273 296//296 +f 273//273 297//297 296//296 +f 273//273 274//274 297//297 +f 274//274 298//298 297//297 +f 274//274 275//275 298//298 +f 275//275 299//299 298//298 +f 275//275 276//276 299//299 +f 276//276 278//278 299//299 +f 276//276 255//255 278//278 +f 278//278 300//300 301//301 +f 278//278 277//277 300//300 +f 277//277 302//302 300//300 +f 277//277 279//279 302//302 +f 279//279 303//303 302//302 +f 279//279 280//280 303//303 +f 280//280 304//304 303//303 +f 280//280 281//281 304//304 +f 281//281 305//305 304//304 +f 281//281 282//282 305//305 +f 282//282 306//306 305//305 +f 282//282 283//283 306//306 +f 283//283 307//307 306//306 +f 283//283 284//284 307//307 +f 284//284 308//308 307//307 +f 284//284 285//285 308//308 +f 285//285 309//309 308//308 +f 285//285 286//286 309//309 +f 286//286 310//310 309//309 +f 286//286 287//287 310//310 +f 287//287 311//311 310//310 +f 287//287 288//288 311//311 +f 288//288 312//312 311//311 +f 288//288 289//289 312//312 +f 289//289 313//313 312//312 +f 289//289 290//290 313//313 +f 290//290 314//314 313//313 +f 290//290 291//291 314//314 +f 291//291 315//315 314//314 +f 291//291 292//292 315//315 +f 292//292 316//316 315//315 +f 292//292 293//293 316//316 +f 293//293 317//317 316//316 +f 293//293 294//294 317//317 +f 294//294 318//318 317//317 +f 294//294 295//295 318//318 +f 295//295 319//319 318//318 +f 295//295 296//296 319//319 +f 296//296 320//320 319//319 +f 296//296 297//297 320//320 +f 297//297 321//321 320//320 +f 297//297 298//298 321//321 +f 298//298 322//322 321//321 +f 298//298 299//299 322//322 +f 299//299 301//301 322//322 +f 299//299 278//278 301//301 +f 301//301 323//323 324//324 +f 301//301 300//300 323//323 +f 300//300 325//325 323//323 +f 300//300 302//302 325//325 +f 302//302 326//326 325//325 +f 302//302 303//303 326//326 +f 303//303 327//327 326//326 +f 303//303 304//304 327//327 +f 304//304 328//328 327//327 +f 304//304 305//305 328//328 +f 305//305 329//329 328//328 +f 305//305 306//306 329//329 +f 306//306 330//330 329//329 +f 306//306 307//307 330//330 +f 307//307 331//331 330//330 +f 307//307 308//308 331//331 +f 308//308 332//332 331//331 +f 308//308 309//309 332//332 +f 309//309 333//333 332//332 +f 309//309 310//310 333//333 +f 310//310 334//334 333//333 +f 310//310 311//311 334//334 +f 311//311 335//335 334//334 +f 311//311 312//312 335//335 +f 312//312 336//336 335//335 +f 312//312 313//313 336//336 +f 313//313 337//337 336//336 +f 313//313 314//314 337//337 +f 314//314 338//338 337//337 +f 314//314 315//315 338//338 +f 315//315 339//339 338//338 +f 315//315 316//316 339//339 +f 316//316 340//340 339//339 +f 316//316 317//317 340//340 +f 317//317 341//341 340//340 +f 317//317 318//318 341//341 +f 318//318 342//342 341//341 +f 318//318 319//319 342//342 +f 319//319 343//343 342//342 +f 319//319 320//320 343//343 +f 320//320 344//344 343//343 +f 320//320 321//321 344//344 +f 321//321 345//345 344//344 +f 321//321 322//322 345//345 +f 322//322 324//324 345//345 +f 322//322 301//301 324//324 +f 324//324 346//346 347//347 +f 324//324 323//323 346//346 +f 323//323 348//348 346//346 +f 323//323 325//325 348//348 +f 325//325 349//349 348//348 +f 325//325 326//326 349//349 +f 326//326 350//350 349//349 +f 326//326 327//327 350//350 +f 327//327 351//351 350//350 +f 327//327 328//328 351//351 +f 328//328 352//352 351//351 +f 328//328 329//329 352//352 +f 329//329 353//353 352//352 +f 329//329 330//330 353//353 +f 330//330 354//354 353//353 +f 330//330 331//331 354//354 +f 331//331 355//355 354//354 +f 331//331 332//332 355//355 +f 332//332 356//356 355//355 +f 332//332 333//333 356//356 +f 333//333 357//357 356//356 +f 333//333 334//334 357//357 +f 334//334 358//358 357//357 +f 334//334 335//335 358//358 +f 335//335 359//359 358//358 +f 335//335 336//336 359//359 +f 336//336 360//360 359//359 +f 336//336 337//337 360//360 +f 337//337 361//361 360//360 +f 337//337 338//338 361//361 +f 338//338 362//362 361//361 +f 338//338 339//339 362//362 +f 339//339 363//363 362//362 +f 339//339 340//340 363//363 +f 340//340 364//364 363//363 +f 340//340 341//341 364//364 +f 341//341 365//365 364//364 +f 341//341 342//342 365//365 +f 342//342 366//366 365//365 +f 342//342 343//343 366//366 +f 343//343 367//367 366//366 +f 343//343 344//344 367//367 +f 344//344 368//368 367//367 +f 344//344 345//345 368//368 +f 345//345 347//347 368//368 +f 345//345 324//324 347//347 +f 347//347 369//369 370//370 +f 347//347 346//346 369//369 +f 346//346 371//371 369//369 +f 346//346 348//348 371//371 +f 348//348 372//372 371//371 +f 348//348 349//349 372//372 +f 349//349 373//373 372//372 +f 349//349 350//350 373//373 +f 350//350 374//374 373//373 +f 350//350 351//351 374//374 +f 351//351 375//375 374//374 +f 351//351 352//352 375//375 +f 352//352 376//376 375//375 +f 352//352 353//353 376//376 +f 353//353 377//377 376//376 +f 353//353 354//354 377//377 +f 354//354 378//378 377//377 +f 354//354 355//355 378//378 +f 355//355 379//379 378//378 +f 355//355 356//356 379//379 +f 356//356 380//380 379//379 +f 356//356 357//357 380//380 +f 357//357 381//381 380//380 +f 357//357 358//358 381//381 +f 358//358 382//382 381//381 +f 358//358 359//359 382//382 +f 359//359 383//383 382//382 +f 359//359 360//360 383//383 +f 360//360 384//384 383//383 +f 360//360 361//361 384//384 +f 361//361 385//385 384//384 +f 361//361 362//362 385//385 +f 362//362 386//386 385//385 +f 362//362 363//363 386//386 +f 363//363 387//387 386//386 +f 363//363 364//364 387//387 +f 364//364 388//388 387//387 +f 364//364 365//365 388//388 +f 365//365 389//389 388//388 +f 365//365 366//366 389//389 +f 366//366 390//390 389//389 +f 366//366 367//367 390//390 +f 367//367 391//391 390//390 +f 367//367 368//368 391//391 +f 368//368 370//370 391//391 +f 368//368 347//347 370//370 +f 370//370 392//392 393//393 +f 370//370 369//369 392//392 +f 369//369 394//394 392//392 +f 369//369 371//371 394//394 +f 371//371 395//395 394//394 +f 371//371 372//372 395//395 +f 372//372 396//396 395//395 +f 372//372 373//373 396//396 +f 373//373 397//397 396//396 +f 373//373 374//374 397//397 +f 374//374 398//398 397//397 +f 374//374 375//375 398//398 +f 375//375 399//399 398//398 +f 375//375 376//376 399//399 +f 376//376 400//400 399//399 +f 376//376 377//377 400//400 +f 377//377 401//401 400//400 +f 377//377 378//378 401//401 +f 378//378 402//402 401//401 +f 378//378 379//379 402//402 +f 379//379 403//403 402//402 +f 379//379 380//380 403//403 +f 380//380 404//404 403//403 +f 380//380 381//381 404//404 +f 381//381 405//405 404//404 +f 381//381 382//382 405//405 +f 382//382 406//406 405//405 +f 382//382 383//383 406//406 +f 383//383 407//407 406//406 +f 383//383 384//384 407//407 +f 384//384 408//408 407//407 +f 384//384 385//385 408//408 +f 385//385 409//409 408//408 +f 385//385 386//386 409//409 +f 386//386 410//410 409//409 +f 386//386 387//387 410//410 +f 387//387 411//411 410//410 +f 387//387 388//388 411//411 +f 388//388 412//412 411//411 +f 388//388 389//389 412//412 +f 389//389 413//413 412//412 +f 389//389 390//390 413//413 +f 390//390 414//414 413//413 +f 390//390 391//391 414//414 +f 391//391 393//393 414//414 +f 391//391 370//370 393//393 +f 393//393 415//415 416//416 +f 393//393 392//392 415//415 +f 392//392 417//417 415//415 +f 392//392 394//394 417//417 +f 394//394 418//418 417//417 +f 394//394 395//395 418//418 +f 395//395 419//419 418//418 +f 395//395 396//396 419//419 +f 396//396 420//420 419//419 +f 396//396 397//397 420//420 +f 397//397 421//421 420//420 +f 397//397 398//398 421//421 +f 398//398 422//422 421//421 +f 398//398 399//399 422//422 +f 399//399 423//423 422//422 +f 399//399 400//400 423//423 +f 400//400 424//424 423//423 +f 400//400 401//401 424//424 +f 401//401 425//425 424//424 +f 401//401 402//402 425//425 +f 402//402 426//426 425//425 +f 402//402 403//403 426//426 +f 403//403 427//427 426//426 +f 403//403 404//404 427//427 +f 404//404 428//428 427//427 +f 404//404 405//405 428//428 +f 405//405 429//429 428//428 +f 405//405 406//406 429//429 +f 406//406 430//430 429//429 +f 406//406 407//407 430//430 +f 407//407 431//431 430//430 +f 407//407 408//408 431//431 +f 408//408 432//432 431//431 +f 408//408 409//409 432//432 +f 409//409 433//433 432//432 +f 409//409 410//410 433//433 +f 410//410 434//434 433//433 +f 410//410 411//411 434//434 +f 411//411 435//435 434//434 +f 411//411 412//412 435//435 +f 412//412 436//436 435//435 +f 412//412 413//413 436//436 +f 413//413 437//437 436//436 +f 413//413 414//414 437//437 +f 414//414 416//416 437//437 +f 414//414 393//393 416//416 +f 416//416 438//438 439//439 +f 416//416 415//415 438//438 +f 415//415 440//440 438//438 +f 415//415 417//417 440//440 +f 417//417 441//441 440//440 +f 417//417 418//418 441//441 +f 418//418 442//442 441//441 +f 418//418 419//419 442//442 +f 419//419 443//443 442//442 +f 419//419 420//420 443//443 +f 420//420 444//444 443//443 +f 420//420 421//421 444//444 +f 421//421 445//445 444//444 +f 421//421 422//422 445//445 +f 422//422 446//446 445//445 +f 422//422 423//423 446//446 +f 423//423 447//447 446//446 +f 423//423 424//424 447//447 +f 424//424 448//448 447//447 +f 424//424 425//425 448//448 +f 425//425 449//449 448//448 +f 425//425 426//426 449//449 +f 426//426 450//450 449//449 +f 426//426 427//427 450//450 +f 427//427 451//451 450//450 +f 427//427 428//428 451//451 +f 428//428 452//452 451//451 +f 428//428 429//429 452//452 +f 429//429 453//453 452//452 +f 429//429 430//430 453//453 +f 430//430 454//454 453//453 +f 430//430 431//431 454//454 +f 431//431 455//455 454//454 +f 431//431 432//432 455//455 +f 432//432 456//456 455//455 +f 432//432 433//433 456//456 +f 433//433 457//457 456//456 +f 433//433 434//434 457//457 +f 434//434 458//458 457//457 +f 434//434 435//435 458//458 +f 435//435 459//459 458//458 +f 435//435 436//436 459//459 +f 436//436 460//460 459//459 +f 436//436 437//437 460//460 +f 437//437 439//439 460//460 +f 437//437 416//416 439//439 +f 439//439 461//461 462//462 +f 439//439 438//438 461//461 +f 438//438 463//463 461//461 +f 438//438 440//440 463//463 +f 440//440 464//464 463//463 +f 440//440 441//441 464//464 +f 441//441 465//465 464//464 +f 441//441 442//442 465//465 +f 442//442 466//466 465//465 +f 442//442 443//443 466//466 +f 443//443 467//467 466//466 +f 443//443 444//444 467//467 +f 444//444 468//468 467//467 +f 444//444 445//445 468//468 +f 445//445 469//469 468//468 +f 445//445 446//446 469//469 +f 446//446 470//470 469//469 +f 446//446 447//447 470//470 +f 447//447 471//471 470//470 +f 447//447 448//448 471//471 +f 448//448 472//472 471//471 +f 448//448 449//449 472//472 +f 449//449 473//473 472//472 +f 449//449 450//450 473//473 +f 450//450 474//474 473//473 +f 450//450 451//451 474//474 +f 451//451 475//475 474//474 +f 451//451 452//452 475//475 +f 452//452 476//476 475//475 +f 452//452 453//453 476//476 +f 453//453 477//477 476//476 +f 453//453 454//454 477//477 +f 454//454 478//478 477//477 +f 454//454 455//455 478//478 +f 455//455 479//479 478//478 +f 455//455 456//456 479//479 +f 456//456 480//480 479//479 +f 456//456 457//457 480//480 +f 457//457 481//481 480//480 +f 457//457 458//458 481//481 +f 458//458 482//482 481//481 +f 458//458 459//459 482//482 +f 459//459 483//483 482//482 +f 459//459 460//460 483//483 +f 460//460 462//462 483//483 +f 460//460 439//439 462//462 +f 462//462 484//484 485//485 +f 462//462 461//461 484//484 +f 461//461 486//486 484//484 +f 461//461 463//463 486//486 +f 463//463 487//487 486//486 +f 463//463 464//464 487//487 +f 464//464 488//488 487//487 +f 464//464 465//465 488//488 +f 465//465 489//489 488//488 +f 465//465 466//466 489//489 +f 466//466 490//490 489//489 +f 466//466 467//467 490//490 +f 467//467 491//491 490//490 +f 467//467 468//468 491//491 +f 468//468 492//492 491//491 +f 468//468 469//469 492//492 +f 469//469 493//493 492//492 +f 469//469 470//470 493//493 +f 470//470 494//494 493//493 +f 470//470 471//471 494//494 +f 471//471 495//495 494//494 +f 471//471 472//472 495//495 +f 472//472 496//496 495//495 +f 472//472 473//473 496//496 +f 473//473 497//497 496//496 +f 473//473 474//474 497//497 +f 474//474 498//498 497//497 +f 474//474 475//475 498//498 +f 475//475 499//499 498//498 +f 475//475 476//476 499//499 +f 476//476 500//500 499//499 +f 476//476 477//477 500//500 +f 477//477 501//501 500//500 +f 477//477 478//478 501//501 +f 478//478 502//502 501//501 +f 478//478 479//479 502//502 +f 479//479 503//503 502//502 +f 479//479 480//480 503//503 +f 480//480 504//504 503//503 +f 480//480 481//481 504//504 +f 481//481 505//505 504//504 +f 481//481 482//482 505//505 +f 482//482 506//506 505//505 +f 482//482 483//483 506//506 +f 483//483 485//485 506//506 +f 483//483 462//462 485//485 +f 485//485 507//507 508//508 +f 485//485 484//484 507//507 +f 484//484 509//509 507//507 +f 484//484 486//486 509//509 +f 486//486 510//510 509//509 +f 486//486 487//487 510//510 +f 487//487 511//511 510//510 +f 487//487 488//488 511//511 +f 488//488 512//512 511//511 +f 488//488 489//489 512//512 +f 489//489 513//513 512//512 +f 489//489 490//490 513//513 +f 490//490 514//514 513//513 +f 490//490 491//491 514//514 +f 491//491 515//515 514//514 +f 491//491 492//492 515//515 +f 492//492 516//516 515//515 +f 492//492 493//493 516//516 +f 493//493 517//517 516//516 +f 493//493 494//494 517//517 +f 494//494 518//518 517//517 +f 494//494 495//495 518//518 +f 495//495 519//519 518//518 +f 495//495 496//496 519//519 +f 496//496 520//520 519//519 +f 496//496 497//497 520//520 +f 497//497 521//521 520//520 +f 497//497 498//498 521//521 +f 498//498 522//522 521//521 +f 498//498 499//499 522//522 +f 499//499 523//523 522//522 +f 499//499 500//500 523//523 +f 500//500 524//524 523//523 +f 500//500 501//501 524//524 +f 501//501 525//525 524//524 +f 501//501 502//502 525//525 +f 502//502 526//526 525//525 +f 502//502 503//503 526//526 +f 503//503 527//527 526//526 +f 503//503 504//504 527//527 +f 504//504 528//528 527//527 +f 504//504 505//505 528//528 +f 505//505 529//529 528//528 +f 505//505 506//506 529//529 +f 506//506 508//508 529//529 +f 506//506 485//485 508//508 +f 508//508 4//4 1//1 +f 508//508 507//507 4//4 +f 507//507 6//6 4//4 +f 507//507 509//509 6//6 +f 509//509 8//8 6//6 +f 509//509 510//510 8//8 +f 510//510 10//10 8//8 +f 510//510 511//511 10//10 +f 511//511 12//12 10//10 +f 511//511 512//512 12//12 +f 512//512 14//14 12//12 +f 512//512 513//513 14//14 +f 513//513 16//16 14//14 +f 513//513 514//514 16//16 +f 514//514 18//18 16//16 +f 514//514 515//515 18//18 +f 515//515 20//20 18//18 +f 515//515 516//516 20//20 +f 516//516 22//22 20//20 +f 516//516 517//517 22//22 +f 517//517 24//24 22//22 +f 517//517 518//518 24//24 +f 518//518 26//26 24//24 +f 518//518 519//519 26//26 +f 519//519 28//28 26//26 +f 519//519 520//520 28//28 +f 520//520 30//30 28//28 +f 520//520 521//521 30//30 +f 521//521 32//32 30//30 +f 521//521 522//522 32//32 +f 522//522 34//34 32//32 +f 522//522 523//523 34//34 +f 523//523 36//36 34//34 +f 523//523 524//524 36//36 +f 524//524 38//38 36//36 +f 524//524 525//525 38//38 +f 525//525 40//40 38//38 +f 525//525 526//526 40//40 +f 526//526 42//42 40//40 +f 526//526 527//527 42//42 +f 527//527 44//44 42//42 +f 527//527 528//528 44//44 +f 528//528 46//46 44//44 +f 528//528 529//529 46//46 +f 529//529 1//1 46//46 +f 529//529 508//508 1//1 diff --git a/tests/test_canvas3d.py b/tests/test_canvas3d.py new file mode 100644 index 0000000..cc19015 --- /dev/null +++ b/tests/test_canvas3d.py @@ -0,0 +1,167 @@ +"""Headless tests for the Canvas3D data model. + +The full mesh-labeling UX needs an interactive VTK render window — a real +display, or `vtk-osmesa` plus the offscreen Qt platform. The tests below +exercise only the data-model layer (mesh loading, vertex_label_ids array, +the label↔lid mapping, mode switching) and skip cleanly when the heavy +deps or a working VTK backend are not available. + +Run: + QT_QPA_PLATFORM=offscreen python -m unittest tests.test_canvas3d -v +""" +import os +import sys +import unittest + +os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +try: + import numpy as np + import pyvista as pv + from PyQt6.QtWidgets import QApplication + + pv.OFF_SCREEN = True + _APP = QApplication.instance() or QApplication(sys.argv) + + from anylabeling.views.labeling.widgets.canvas3d import Canvas3D + _IMPORT_ERROR = None +except Exception as exc: # pragma: no cover - environment-dependent + Canvas3D = None # type: ignore[assignment] + _IMPORT_ERROR = exc + + +# Skip in any CI environment. VTK/pyvista wheels on macOS GitHub runners +# segfault when Canvas3D() initialises without a real display — a hard SIGSEGV +# kills the process before any Python-level skipTest can fire. Linux's Mesa +# software fallback works fine, but rather than gate per-platform we just +# disable for all CI and run this test locally where a real GL context exists. +_IN_CI = os.environ.get("CI", "").lower() in ("1", "true", "yes") + + +@unittest.skipIf(Canvas3D is None, f"mesh deps unavailable: {_IMPORT_ERROR}") +@unittest.skipIf(_IN_CI, "Canvas3D test requires a real display; CI runners segfault on init") +class TestCanvas3DDataModel(unittest.TestCase): + """Verify Canvas3D's pure-data operations work without an X display.""" + + @classmethod + def setUpClass(cls): + # Use the bundled sphere sample — exercises a non-trivial vertex count + # (530 verts) without an off-disk fixture. Falls back to a synthetic + # sphere if the sample file moves. + repo_root = os.path.abspath( + os.path.join(os.path.dirname(__file__), "..") + ) + sample = os.path.join(repo_root, "sample_meshes", "sphere.obj") + if os.path.exists(sample): + cls.mesh_path = sample + cls.expected_n_points = pv.read(sample).n_points + else: + cls.mesh_path = "/tmp/anylabeling_test_mesh.ply" + sphere = pv.Sphere(radius=1.0, theta_resolution=8, phi_resolution=8) + sphere.save(cls.mesh_path) + cls.expected_n_points = sphere.n_points + + try: + cls.canvas = Canvas3D() + cls.canvas.load_mesh(cls.mesh_path) + except Exception as exc: + # CI runners without a real (or virtual) display can't bring up + # the VTK render window. Skip cleanly rather than fail the cell. + raise unittest.SkipTest( + f"Canvas3D could not initialise (no working VTK backend): " + f"{type(exc).__name__}: {exc}" + ) + + def test_load_mesh_creates_actor_and_locator(self): + self.assertIsNotNone(self.canvas._get_main_actor()) + self.assertIsNotNone(self.canvas._point_locator) + + def test_vertex_label_ids_match_mesh_size(self): + ids = self.canvas.vertex_label_ids + self.assertIsNotNone(ids) + self.assertEqual(len(ids), self.expected_n_points) + self.assertEqual(ids.dtype.kind, "i") # integer dtype + + def test_label_to_id_is_stable(self): + a = self.canvas._get_or_create_label_id("alpha") + b = self.canvas._get_or_create_label_id("beta") + a_again = self.canvas._get_or_create_label_id("alpha") + self.assertEqual(a, a_again, "same label string must yield same id") + self.assertNotEqual(a, b, "different labels must yield different ids") + + def test_lid_reverse_lookup(self): + a = self.canvas._get_or_create_label_id("gamma") + self.assertEqual(self.canvas._get_lid_to_label(a), "gamma") + + def test_vertex_label_ids_round_trip(self): + a = self.canvas._get_or_create_label_id("x") + b = self.canvas._get_or_create_label_id("y") + ids = self.canvas.vertex_label_ids + ids[:3] = a + ids[3:6] = b + self.canvas.vertex_label_ids = ids + snapshot = self.canvas.vertex_label_ids.copy() + + self.canvas.load_vertex_label_ids(snapshot.tolist()) + self.assertTrue(np.array_equal(self.canvas.vertex_label_ids, snapshot)) + + def test_mode_switching_does_not_crash_in_headless(self): + # The fix in canvas3d.py is exactly that these calls used to AttributeError + # on `self.iren.interactor` when no interactive window existed. + self.canvas.set_mode("brush") + self.canvas.set_mode("view") + self.canvas.set_mode("brush") + + def test_set_brush_radius_stores_value(self): + self.canvas.set_brush_radius(0.42) + self.assertEqual(self.canvas.brush_radius, 0.42) + + def test_in_place_paint_avoids_actor_rebuild(self): + """After the first paint flips _scalar_mode_active to True, every + subsequent _apply_colors_and_render must skip _redraw_mesh and just + push the colour array to VTK in place. Regression test for the + per-stroke add_mesh slowdown on dense meshes.""" + # First paint kicks off the switch from PBR to scalar shading. + self.canvas._scalar_mode_active = False + self.canvas._vertex_colors[0] = [10, 20, 30] + self.canvas._apply_colors_and_render() + self.assertTrue(self.canvas._scalar_mode_active) + + # Subsequent paints must NOT rebuild — verify by spying on _redraw_mesh. + calls = {"n": 0} + original = self.canvas._redraw_mesh + self.canvas._redraw_mesh = lambda: calls.__setitem__("n", calls["n"] + 1) + try: + for _ in range(5): + self.canvas._vertex_colors[0] = [40, 50, 60] + self.canvas._apply_colors_and_render() + self.assertEqual( + calls["n"], 0, + "_apply_colors_and_render should not rebuild the actor " + "while scalar mode is already active", + ) + finally: + self.canvas._redraw_mesh = original + + def test_cursor_actor_is_reused(self): + """Brush cursor sphere must be one persistent actor that we just + reposition + scale, not a new actor per mouse-move.""" + self.canvas._cursor_actor = None # force first creation + self.canvas._show_cursor((0.0, 0.0, 0.0)) + first = id(self.canvas._cursor_actor) + self.assertIsNotNone(self.canvas._cursor_actor) + for i in range(20): + self.canvas._show_cursor((float(i) * 0.05, 0.0, 0.0)) + self.assertEqual(id(self.canvas._cursor_actor), first) + + def test_mode_constants_reduced_to_view_and_brush(self): + """Keypoint mode was removed for simplicity; verify.""" + self.assertEqual(Canvas3D.VIEW, "view") + self.assertEqual(Canvas3D.BRUSH, "brush") + self.assertFalse(hasattr(Canvas3D, "KEYPOINT")) + + +if __name__ == "__main__": + unittest.main(verbosity=2)