supervisely 6.73.410__py3-none-any.whl → 6.73.470__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of supervisely might be problematic. Click here for more details.

Files changed (190) hide show
  1. supervisely/__init__.py +136 -1
  2. supervisely/_utils.py +81 -0
  3. supervisely/annotation/json_geometries_map.py +2 -0
  4. supervisely/annotation/label.py +80 -3
  5. supervisely/api/annotation_api.py +9 -9
  6. supervisely/api/api.py +67 -43
  7. supervisely/api/app_api.py +72 -5
  8. supervisely/api/dataset_api.py +108 -33
  9. supervisely/api/entity_annotation/figure_api.py +113 -49
  10. supervisely/api/image_api.py +82 -0
  11. supervisely/api/module_api.py +10 -0
  12. supervisely/api/nn/deploy_api.py +15 -9
  13. supervisely/api/nn/ecosystem_models_api.py +201 -0
  14. supervisely/api/nn/neural_network_api.py +12 -3
  15. supervisely/api/pointcloud/pointcloud_api.py +38 -0
  16. supervisely/api/pointcloud/pointcloud_episode_annotation_api.py +3 -0
  17. supervisely/api/project_api.py +213 -6
  18. supervisely/api/task_api.py +11 -1
  19. supervisely/api/video/video_annotation_api.py +4 -2
  20. supervisely/api/video/video_api.py +79 -1
  21. supervisely/api/video/video_figure_api.py +24 -11
  22. supervisely/api/volume/volume_api.py +38 -0
  23. supervisely/app/__init__.py +1 -1
  24. supervisely/app/content.py +14 -6
  25. supervisely/app/fastapi/__init__.py +1 -0
  26. supervisely/app/fastapi/custom_static_files.py +1 -1
  27. supervisely/app/fastapi/multi_user.py +88 -0
  28. supervisely/app/fastapi/subapp.py +175 -42
  29. supervisely/app/fastapi/templating.py +1 -1
  30. supervisely/app/fastapi/websocket.py +77 -9
  31. supervisely/app/singleton.py +21 -0
  32. supervisely/app/v1/app_service.py +18 -2
  33. supervisely/app/v1/constants.py +7 -1
  34. supervisely/app/widgets/__init__.py +11 -1
  35. supervisely/app/widgets/agent_selector/template.html +1 -0
  36. supervisely/app/widgets/card/card.py +20 -0
  37. supervisely/app/widgets/dataset_thumbnail/dataset_thumbnail.py +11 -2
  38. supervisely/app/widgets/dataset_thumbnail/template.html +3 -1
  39. supervisely/app/widgets/deploy_model/deploy_model.py +750 -0
  40. supervisely/app/widgets/dialog/dialog.py +12 -0
  41. supervisely/app/widgets/dialog/template.html +2 -1
  42. supervisely/app/widgets/dropdown_checkbox_selector/__init__.py +0 -0
  43. supervisely/app/widgets/dropdown_checkbox_selector/dropdown_checkbox_selector.py +87 -0
  44. supervisely/app/widgets/dropdown_checkbox_selector/template.html +12 -0
  45. supervisely/app/widgets/ecosystem_model_selector/__init__.py +0 -0
  46. supervisely/app/widgets/ecosystem_model_selector/ecosystem_model_selector.py +195 -0
  47. supervisely/app/widgets/experiment_selector/experiment_selector.py +454 -263
  48. supervisely/app/widgets/fast_table/fast_table.py +713 -126
  49. supervisely/app/widgets/fast_table/script.js +492 -95
  50. supervisely/app/widgets/fast_table/style.css +54 -0
  51. supervisely/app/widgets/fast_table/template.html +45 -5
  52. supervisely/app/widgets/heatmap/__init__.py +0 -0
  53. supervisely/app/widgets/heatmap/heatmap.py +523 -0
  54. supervisely/app/widgets/heatmap/script.js +378 -0
  55. supervisely/app/widgets/heatmap/style.css +227 -0
  56. supervisely/app/widgets/heatmap/template.html +21 -0
  57. supervisely/app/widgets/input_tag/input_tag.py +102 -15
  58. supervisely/app/widgets/input_tag_list/__init__.py +0 -0
  59. supervisely/app/widgets/input_tag_list/input_tag_list.py +274 -0
  60. supervisely/app/widgets/input_tag_list/template.html +70 -0
  61. supervisely/app/widgets/radio_table/radio_table.py +10 -2
  62. supervisely/app/widgets/radio_tabs/radio_tabs.py +18 -2
  63. supervisely/app/widgets/radio_tabs/template.html +1 -0
  64. supervisely/app/widgets/select/select.py +6 -4
  65. supervisely/app/widgets/select_dataset/select_dataset.py +6 -0
  66. supervisely/app/widgets/select_dataset_tree/select_dataset_tree.py +83 -7
  67. supervisely/app/widgets/table/table.py +68 -13
  68. supervisely/app/widgets/tabs/tabs.py +22 -6
  69. supervisely/app/widgets/tabs/template.html +5 -1
  70. supervisely/app/widgets/transfer/style.css +3 -0
  71. supervisely/app/widgets/transfer/template.html +3 -1
  72. supervisely/app/widgets/transfer/transfer.py +48 -45
  73. supervisely/app/widgets/tree_select/tree_select.py +2 -0
  74. supervisely/convert/image/csv/csv_converter.py +24 -15
  75. supervisely/convert/pointcloud/nuscenes_conv/nuscenes_converter.py +43 -41
  76. supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_converter.py +75 -51
  77. supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_helper.py +137 -124
  78. supervisely/convert/video/video_converter.py +2 -2
  79. supervisely/geometry/polyline_3d.py +110 -0
  80. supervisely/io/env.py +161 -1
  81. supervisely/nn/artifacts/__init__.py +1 -1
  82. supervisely/nn/artifacts/artifacts.py +10 -2
  83. supervisely/nn/artifacts/detectron2.py +1 -0
  84. supervisely/nn/artifacts/hrda.py +1 -0
  85. supervisely/nn/artifacts/mmclassification.py +20 -0
  86. supervisely/nn/artifacts/mmdetection.py +5 -3
  87. supervisely/nn/artifacts/mmsegmentation.py +1 -0
  88. supervisely/nn/artifacts/ritm.py +1 -0
  89. supervisely/nn/artifacts/rtdetr.py +1 -0
  90. supervisely/nn/artifacts/unet.py +1 -0
  91. supervisely/nn/artifacts/utils.py +3 -0
  92. supervisely/nn/artifacts/yolov5.py +2 -0
  93. supervisely/nn/artifacts/yolov8.py +1 -0
  94. supervisely/nn/benchmark/semantic_segmentation/metric_provider.py +18 -18
  95. supervisely/nn/experiments.py +9 -0
  96. supervisely/nn/inference/cache.py +37 -17
  97. supervisely/nn/inference/gui/serving_gui_template.py +39 -13
  98. supervisely/nn/inference/inference.py +953 -211
  99. supervisely/nn/inference/inference_request.py +15 -8
  100. supervisely/nn/inference/instance_segmentation/instance_segmentation.py +1 -0
  101. supervisely/nn/inference/object_detection/object_detection.py +1 -0
  102. supervisely/nn/inference/predict_app/__init__.py +0 -0
  103. supervisely/nn/inference/predict_app/gui/__init__.py +0 -0
  104. supervisely/nn/inference/predict_app/gui/classes_selector.py +160 -0
  105. supervisely/nn/inference/predict_app/gui/gui.py +915 -0
  106. supervisely/nn/inference/predict_app/gui/input_selector.py +344 -0
  107. supervisely/nn/inference/predict_app/gui/model_selector.py +77 -0
  108. supervisely/nn/inference/predict_app/gui/output_selector.py +179 -0
  109. supervisely/nn/inference/predict_app/gui/preview.py +93 -0
  110. supervisely/nn/inference/predict_app/gui/settings_selector.py +881 -0
  111. supervisely/nn/inference/predict_app/gui/tags_selector.py +110 -0
  112. supervisely/nn/inference/predict_app/gui/utils.py +399 -0
  113. supervisely/nn/inference/predict_app/predict_app.py +176 -0
  114. supervisely/nn/inference/session.py +47 -39
  115. supervisely/nn/inference/tracking/bbox_tracking.py +5 -1
  116. supervisely/nn/inference/tracking/point_tracking.py +5 -1
  117. supervisely/nn/inference/tracking/tracker_interface.py +4 -0
  118. supervisely/nn/inference/uploader.py +9 -5
  119. supervisely/nn/model/model_api.py +44 -22
  120. supervisely/nn/model/prediction.py +15 -1
  121. supervisely/nn/model/prediction_session.py +70 -14
  122. supervisely/nn/prediction_dto.py +7 -0
  123. supervisely/nn/tracker/__init__.py +6 -8
  124. supervisely/nn/tracker/base_tracker.py +54 -0
  125. supervisely/nn/tracker/botsort/__init__.py +1 -0
  126. supervisely/nn/tracker/botsort/botsort_config.yaml +30 -0
  127. supervisely/nn/tracker/botsort/osnet_reid/__init__.py +0 -0
  128. supervisely/nn/tracker/botsort/osnet_reid/osnet.py +566 -0
  129. supervisely/nn/tracker/botsort/osnet_reid/osnet_reid_interface.py +88 -0
  130. supervisely/nn/tracker/botsort/tracker/__init__.py +0 -0
  131. supervisely/nn/tracker/{bot_sort → botsort/tracker}/basetrack.py +1 -2
  132. supervisely/nn/tracker/{utils → botsort/tracker}/gmc.py +51 -59
  133. supervisely/nn/tracker/{deep_sort/deep_sort → botsort/tracker}/kalman_filter.py +71 -33
  134. supervisely/nn/tracker/botsort/tracker/matching.py +202 -0
  135. supervisely/nn/tracker/{bot_sort/bot_sort.py → botsort/tracker/mc_bot_sort.py} +68 -81
  136. supervisely/nn/tracker/botsort_tracker.py +273 -0
  137. supervisely/nn/tracker/calculate_metrics.py +264 -0
  138. supervisely/nn/tracker/utils.py +273 -0
  139. supervisely/nn/tracker/visualize.py +520 -0
  140. supervisely/nn/training/gui/gui.py +152 -49
  141. supervisely/nn/training/gui/hyperparameters_selector.py +1 -1
  142. supervisely/nn/training/gui/model_selector.py +8 -6
  143. supervisely/nn/training/gui/train_val_splits_selector.py +144 -71
  144. supervisely/nn/training/gui/training_artifacts.py +3 -1
  145. supervisely/nn/training/train_app.py +225 -46
  146. supervisely/project/pointcloud_episode_project.py +12 -8
  147. supervisely/project/pointcloud_project.py +12 -8
  148. supervisely/project/project.py +221 -75
  149. supervisely/template/experiment/experiment.html.jinja +105 -55
  150. supervisely/template/experiment/experiment_generator.py +258 -112
  151. supervisely/template/experiment/header.html.jinja +31 -13
  152. supervisely/template/experiment/sly-style.css +7 -2
  153. supervisely/versions.json +3 -1
  154. supervisely/video/sampling.py +42 -20
  155. supervisely/video/video.py +41 -12
  156. supervisely/video_annotation/video_figure.py +38 -4
  157. supervisely/volume/stl_converter.py +2 -0
  158. supervisely/worker_api/agent_rpc.py +24 -1
  159. supervisely/worker_api/rpc_servicer.py +31 -7
  160. {supervisely-6.73.410.dist-info → supervisely-6.73.470.dist-info}/METADATA +22 -14
  161. {supervisely-6.73.410.dist-info → supervisely-6.73.470.dist-info}/RECORD +167 -148
  162. supervisely_lib/__init__.py +6 -1
  163. supervisely/app/widgets/experiment_selector/style.css +0 -27
  164. supervisely/app/widgets/experiment_selector/template.html +0 -61
  165. supervisely/nn/tracker/bot_sort/__init__.py +0 -21
  166. supervisely/nn/tracker/bot_sort/fast_reid_interface.py +0 -152
  167. supervisely/nn/tracker/bot_sort/matching.py +0 -127
  168. supervisely/nn/tracker/bot_sort/sly_tracker.py +0 -401
  169. supervisely/nn/tracker/deep_sort/__init__.py +0 -6
  170. supervisely/nn/tracker/deep_sort/deep_sort/__init__.py +0 -1
  171. supervisely/nn/tracker/deep_sort/deep_sort/detection.py +0 -49
  172. supervisely/nn/tracker/deep_sort/deep_sort/iou_matching.py +0 -81
  173. supervisely/nn/tracker/deep_sort/deep_sort/linear_assignment.py +0 -202
  174. supervisely/nn/tracker/deep_sort/deep_sort/nn_matching.py +0 -176
  175. supervisely/nn/tracker/deep_sort/deep_sort/track.py +0 -166
  176. supervisely/nn/tracker/deep_sort/deep_sort/tracker.py +0 -145
  177. supervisely/nn/tracker/deep_sort/deep_sort.py +0 -301
  178. supervisely/nn/tracker/deep_sort/generate_clip_detections.py +0 -90
  179. supervisely/nn/tracker/deep_sort/preprocessing.py +0 -70
  180. supervisely/nn/tracker/deep_sort/sly_tracker.py +0 -273
  181. supervisely/nn/tracker/tracker.py +0 -285
  182. supervisely/nn/tracker/utils/kalman_filter.py +0 -492
  183. supervisely/nn/tracking/__init__.py +0 -1
  184. supervisely/nn/tracking/boxmot.py +0 -114
  185. supervisely/nn/tracking/tracking.py +0 -24
  186. /supervisely/{nn/tracker/utils → app/widgets/deploy_model}/__init__.py +0 -0
  187. {supervisely-6.73.410.dist-info → supervisely-6.73.470.dist-info}/LICENSE +0 -0
  188. {supervisely-6.73.410.dist-info → supervisely-6.73.470.dist-info}/WHEEL +0 -0
  189. {supervisely-6.73.410.dist-info → supervisely-6.73.470.dist-info}/entry_points.txt +0 -0
  190. {supervisely-6.73.410.dist-info → supervisely-6.73.470.dist-info}/top_level.txt +0 -0
@@ -14,13 +14,6 @@ from supervisely.sly_logger import logger
14
14
  from supervisely.task.progress import Progress
15
15
 
16
16
 
17
- def generate_uuid(self) -> str:
18
- """
19
- Generates a unique UUID for the inference request.
20
- """
21
- return uuid.uuid5(namespace=uuid.NAMESPACE_URL, name=f"{time.time()}-{rand_str(10)}").hex
22
-
23
-
24
17
  class InferenceRequest:
25
18
  class Stage:
26
19
  PREPARING = "Preparing model for inference..."
@@ -47,6 +40,8 @@ class InferenceRequest:
47
40
  self._final_result = None
48
41
  self._exception = None
49
42
  self._stopped = threading.Event()
43
+ self._progress_log_interval = 5.0
44
+ self._last_progress_report_time = 0
50
45
  self.progress = Progress(
51
46
  message=self._stage,
52
47
  total_cnt=1,
@@ -58,6 +53,8 @@ class InferenceRequest:
58
53
  self._updated_at = self._created_at
59
54
  self._finished = False
60
55
 
56
+ self.tracker = None
57
+
61
58
  self.global_progress = None
62
59
  self.global_progress_total = 1
63
60
  self.global_progress_current = 0
@@ -135,9 +132,19 @@ class InferenceRequest:
135
132
  )
136
133
  self._updated()
137
134
 
135
+ def set_progress_log_interval(self, interval: float):
136
+ self._progress_log_interval = interval
137
+
138
138
  def done(self, n=1):
139
139
  with self._lock:
140
- self.progress.iters_done_report(n)
140
+ if (
141
+ self._progress_log_interval is None
142
+ or time.monotonic() - self._last_progress_report_time > self._progress_log_interval
143
+ ) or (self.progress.current + n >= self.progress.total):
144
+ self.progress.iters_done_report(n)
145
+ self._last_progress_report_time = time.monotonic()
146
+ else:
147
+ self.progress.iters_done(n)
141
148
  if self._stage == InferenceRequest.Stage.INFERENCE:
142
149
  self.global_progress_current += n
143
150
  if self.manager is not None:
@@ -12,6 +12,7 @@ class InstanceSegmentation(Inference):
12
12
  def get_info(self) -> dict:
13
13
  info = super().get_info()
14
14
  info["task type"] = "instance segmentation"
15
+ info["tracking_on_videos_support"] = True
15
16
  # recommended parameters:
16
17
  # info["model_name"] = ""
17
18
  # info["checkpoint_name"] = ""
@@ -17,6 +17,7 @@ class ObjectDetection(Inference):
17
17
  def get_info(self) -> dict:
18
18
  info = super().get_info()
19
19
  info["task type"] = "object detection"
20
+ info["tracking_on_videos_support"] = True
20
21
  # recommended parameters:
21
22
  # info["model_name"] = ""
22
23
  # info["checkpoint_name"] = ""
File without changes
File without changes
@@ -0,0 +1,160 @@
1
+ from typing import Any, Dict
2
+
3
+ import pandas as pd
4
+
5
+ from supervisely.app.widgets import (
6
+ Button,
7
+ Card,
8
+ ClassesTable,
9
+ Container,
10
+ FastTable,
11
+ Text,
12
+ )
13
+ from supervisely.geometry.any_geometry import AnyGeometry
14
+ from supervisely.geometry.bitmap import Bitmap
15
+ from supervisely.geometry.cuboid import Cuboid
16
+ from supervisely.geometry.cuboid_3d import Cuboid3d
17
+ from supervisely.geometry.geometry import Geometry
18
+ from supervisely.geometry.graph import GraphNodes
19
+ from supervisely.geometry.multichannel_bitmap import MultichannelBitmap
20
+ from supervisely.geometry.point import Point
21
+ from supervisely.geometry.point_3d import Point3d
22
+ from supervisely.geometry.pointcloud import Pointcloud
23
+ from supervisely.geometry.polygon import Polygon
24
+ from supervisely.geometry.polyline import Polyline
25
+ from supervisely.geometry.rectangle import Rectangle
26
+ from supervisely.project.project_meta import ProjectMeta
27
+
28
+ type_to_zmdi_icon = {
29
+ AnyGeometry: "zmdi zmdi-shape",
30
+ Rectangle: "zmdi zmdi-crop-din", # "zmdi zmdi-square-o"
31
+ # sly.Polygon: "icons8-polygon", # "zmdi zmdi-edit"
32
+ Polygon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAB6klEQVRYhe2Wuy8EURTGf+u5VESNXq2yhYZCoeBv8RcI1i6NVUpsoVCKkHjUGlFTiYb1mFmh2MiKjVXMudmb3cPOzB0VXzKZm5k53/nmvO6Ff4RHD5AD7gFP1l3Kd11AHvCBEpAVW2esAvWmK6t8l1O+W0lCQEnIJoAZxUnzNQNkZF36jrQjgoA+uaciCgc9VaExBOyh/6WWAi1VhbjOJ4FbIXkBtgkK0BNHnYqNKUIPeBPbKyDdzpld5T6wD9SE4AwYjfEDaXFeFzE/doUWuhqwiFsOCwqv2hV2lU/L+sHBscGTxdvSFVoXpAjCZdauMHVic6ndl6U1VBsJCFhTeNUU9IiIEo3qvQYGHAV0AyfC5wNLhKipXuBCjA5wT8WxcM1FMRoBymK44CjAE57hqIazwCfwQdARcXa3UXHuRXVucIjb7jYvNkdxBZg0TBFid7PQTRAtX2xOiXkuMAMqYwkIE848rZFbjyNAmw9bIeweaZ2A5TgC7PnwKkTPtN+cTOrsyN3FEWAjRTAX6sA5ek77gSL6+WHZVQDAIHAjhJtN78aAS3lXAXYIivBOnCdyOAUYB6o0xqsvziry7FLE/Cp20cNcJEjDr8MUmVOVRzkVN+Nd7vZGVXXgiwxtPiRS5WFhz4fEq/zv4AvToMn7vCn3eAAAAABJRU5ErkJggg==",
33
+ Bitmap: "zmdi zmdi-brush",
34
+ Polyline: "zmdi zmdi-gesture",
35
+ Point: "zmdi zmdi-dot-circle-alt",
36
+ Cuboid: "zmdi zmdi-ungroup", #
37
+ GraphNodes: "zmdi zmdi-grain",
38
+ Cuboid3d: "zmdi zmdi-codepen",
39
+ Pointcloud: "zmdi zmdi-cloud-outline", # "zmdi zmdi-border-clear"
40
+ MultichannelBitmap: "zmdi zmdi-layers", # "zmdi zmdi-collection-item"
41
+ Point3d: "zmdi zmdi-filter-center-focus", # "zmdi zmdi-select-all"
42
+ }
43
+ class ClassesSelector:
44
+ title = "Classes"
45
+ description = "Select classes that will be used for inference. This classes are defined by the deployed model"
46
+ lock_message = "Select previous step to unlock"
47
+
48
+ def __init__(self):
49
+ # Init Step
50
+ self.display_widgets = []
51
+ # -------------------------------- #
52
+
53
+ # Init Base Widgets
54
+ self.validator_text = None
55
+ self.button = None
56
+ self.container = None
57
+ self.card = None
58
+ # -------------------------------- #
59
+
60
+ # Init Step Widgets
61
+ self.classes_table = None
62
+ # -------------------------------- #
63
+
64
+ # Classes
65
+ columns = ["class", "shape"]
66
+ self.classes_table = FastTable(columns=columns, page_size=100, is_selectable=True)
67
+ # self.classes_table = ClassesTable()
68
+ self.classes_table.hide()
69
+ # Add widgets to display ------------ #
70
+ self.display_widgets.extend([self.classes_table])
71
+ # ----------------------------------- #
72
+
73
+ # Base Widgets
74
+ self.validator_text = Text("")
75
+ self.validator_text.hide()
76
+ self.button = Button("Select")
77
+ self.display_widgets.extend([self.validator_text, self.button])
78
+ # -------------------------------- #
79
+
80
+ # Card Layout
81
+ self.container = Container(self.display_widgets)
82
+ self.card = Card(
83
+ title=self.title,
84
+ description=self.description,
85
+ content=self.container,
86
+ lock_message=self.lock_message,
87
+ )
88
+ # -------------------------------- #
89
+
90
+ def lock(self):
91
+ self.card.lock()
92
+ self.classes_table.hide()
93
+ self.validator_text.hide()
94
+
95
+ def unlock(self):
96
+ self.card.unlock()
97
+ self.classes_table.show()
98
+
99
+ @property
100
+ def widgets_to_disable(self) -> list:
101
+ return [self.classes_table]
102
+
103
+ def set_project_meta(self, project_meta) -> None:
104
+ self._update_meta(project_meta)
105
+
106
+ def load_from_json(self, data: Dict[str, Any]) -> None:
107
+ if "classes" in data:
108
+ self.set_classes(data["classes"])
109
+
110
+ def get_selected_classes(self) -> list:
111
+ return [row.row[0] for row in self.classes_table.get_selected_rows()]
112
+
113
+ def set_classes(self, classes) -> None:
114
+ self.classes_table.select_rows_by_value("class", classes)
115
+
116
+ def select_all_classes(self) -> None:
117
+ self.classes_table.select_rows(list(range(len(self.classes_table._rows_total))))
118
+
119
+ def get_settings(self) -> Dict[str, Any]:
120
+ return {"classes": self.get_selected_classes()}
121
+
122
+ def validate_step(self) -> bool:
123
+ if self.classes_table.is_hidden():
124
+ return True
125
+
126
+ self.validator_text.hide()
127
+ selected_classes = self.get_selected_classes()
128
+ n_classes = len(selected_classes)
129
+
130
+ if n_classes == 0:
131
+ self.validator_text.set(text="Please select at least one class", status="error")
132
+ self.validator_text.show()
133
+ return False
134
+
135
+ class_word = "class" if n_classes == 1 else "classes"
136
+ message_parts = [f"Selected {n_classes} {class_word}"]
137
+ status = "success"
138
+ is_valid = True
139
+
140
+ self.validator_text.set(text=". ".join(message_parts), status=status)
141
+ self.validator_text.show()
142
+ return is_valid
143
+
144
+ def _update_meta(self, project_meta: ProjectMeta) -> None:
145
+ table_data = []
146
+ for obj_class in project_meta.obj_classes:
147
+ table_line = []
148
+ name = obj_class.name
149
+ icon = type_to_zmdi_icon[AnyGeometry]
150
+ icon = type_to_zmdi_icon.get(obj_class.geometry_type, icon)
151
+ shape = obj_class.geometry_type.geometry_name().lower()
152
+ if shape == "graph":
153
+ shape = "graph (keypoints)"
154
+ table_line = [name, shape]
155
+ table_data.append(table_line)
156
+ self._table_data = table_data
157
+ if self._table_data:
158
+ self.classes_table.read_pandas(pd.DataFrame(self._table_data))
159
+ else:
160
+ self.classes_table.clear()