Skip to content

Commit

Permalink
Merge branch 'main' into feature/config-unit
Browse files Browse the repository at this point in the history
  • Loading branch information
Licini authored Jul 11, 2024
2 parents 28c9cd4 + 96d005e commit a0ab1d3
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 46 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added `list` to accepted types for `Scene.add`.
* Added `list[float]` to accepted types for `Camera.position` and `Camera.target`.
* Added `unit` to `Viewer` and `Config`.
* Added `bounding_box` and `_update_bounding_box` to `BufferObject`.

### Changed

* Fixed `opacity` bug with `BufferObject`.
* Updated `SceneForm` to avoid completely reload when scene objects not changed.

### Removed

Expand Down
103 changes: 57 additions & 46 deletions src/compas_viewer/components/sceneform.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def __init__(
self.setColumnCount(len(columns))
self.setHeaderLabels(col["title"] for col in self.columns)
self.setHeaderHidden(not show_headers)
self._sceneobjects = []

self.callback = callback

Expand All @@ -65,52 +66,62 @@ def scene(self):
return self.viewer.scene

def update(self):
self.clear() # TODO: do not clear when objects are same.
self.checkbox_columns = {}

for node in self.scene.traverse("breadthfirst"):
if node.is_root:
continue

strings = []

for i, column in enumerate(self.columns):
type = column.get("type", None)
if type == "checkbox":
action = column.get("action")
checked = column.get("checked")
if not action or not checked:
raise ValueError("Both action and checked must be provided for checkbox")
self.checkbox_columns[i] = {"action": action, "checked": checked}
strings.append("")
elif type == "label":
text = column.get("text")
if not text:
raise ValueError("Text must be provided for label")
strings.append(text(node))

parent_widget = self if node.parent.is_root else node.parent.attributes["widget"]
widget = QTreeWidgetItem(parent_widget, strings)
widget.node = node
widget.setSelected(node.is_selected)
if node.is_selected:

def expand(node):
if node.attributes.get("widget"):
node.attributes["widget"].setExpanded(True)
if node.parent and not node.parent.is_root:
expand(node.parent)

expand(node.parent)

widget.setFlags(widget.flags() | Qt.ItemIsUserCheckable | Qt.ItemIsSelectable | Qt.ItemIsEnabled)

for col, col_data in self.checkbox_columns.items():
widget.setCheckState(col, Qt.Checked if col_data["checked"](node) else Qt.Unchecked)

node.attributes["widget"] = widget

self.adjust_column_widths()
if list(self.scene.objects) == self._sceneobjects:
for node in self.scene.traverse("breadthfirst"):
widget = node.attributes.get("widget")
if widget:
widget.setSelected(node.is_selected)
if node.is_selected:
self.expand(node.parent)

else:
self._sceneobjects = list(self.scene.objects)

self.clear()
self.checkbox_columns = {}

for node in self.scene.traverse("breadthfirst"):
if node.is_root:
continue

strings = []

for i, column in enumerate(self.columns):
type = column.get("type", None)
if type == "checkbox":
action = column.get("action")
checked = column.get("checked")
if not action or not checked:
raise ValueError("Both action and checked must be provided for checkbox")
self.checkbox_columns[i] = {"action": action, "checked": checked}
strings.append("")
elif type == "label":
text = column.get("text")
if not text:
raise ValueError("Text must be provided for label")
strings.append(text(node))

parent_widget = self if node.parent.is_root else node.parent.attributes["widget"]
widget = QTreeWidgetItem(parent_widget, strings)
widget.node = node
widget.setSelected(node.is_selected)
if node.is_selected:
self.expand(node.parent)

widget.setFlags(widget.flags() | Qt.ItemIsUserCheckable | Qt.ItemIsSelectable | Qt.ItemIsEnabled)

for col, col_data in self.checkbox_columns.items():
widget.setCheckState(col, Qt.Checked if col_data["checked"](node) else Qt.Unchecked)

node.attributes["widget"] = widget

self.adjust_column_widths()

def expand(self, node):
if node.attributes.get("widget"):
node.attributes["widget"].setExpanded(True)
if node.parent and not node.parent.is_root:
self.expand(node.parent)

def on_item_clicked(self, item, column):
if column in self.checkbox_columns:
Expand Down
12 changes: 12 additions & 0 deletions src/compas_viewer/scene/bufferobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,30 @@ def __init__(
self.is_selected = False
self.background = False
self._matrix_buffer = None
self._bounding_box = None
self._bounding_box_center = None

@property
def buffergeometry(self) -> BufferGeometry:
return self.item

@property
def bounding_box(self) -> NDArray:
if self._bounding_box is None:
self._bounding_box = np.array([np.min(self.buffergeometry.points, axis=0), np.max(self.buffergeometry.points, axis=0)])
return self._bounding_box

@property
def bounding_box_center(self) -> NDArray:
if self._bounding_box_center is None:
self._bounding_box_center = np.mean(self.buffergeometry.points.reshape(-1, 3), axis=0)
return self._bounding_box_center

def _update_bounding_box(self):
self._bounding_box = None
self._bounding_box_center = None
# Set to None so that they are recalculated next time they are accessed

def init(self):
"""Initialize the object"""
self.instance_color = Color.from_rgb255(*next(self.scene._instance_colors_generator))
Expand Down

0 comments on commit a0ab1d3

Please sign in to comment.