From ae5f9cbb2ed9b18167530727d7f8323c99f72394 Mon Sep 17 00:00:00 2001 From: Licini Date: Thu, 11 Jul 2024 11:02:05 +0200 Subject: [PATCH 1/2] add unit to viewer and config --- CHANGELOG.md | 1 + scripts/unit.py | 20 ++++++++++++++++++++ src/compas_viewer/config.py | 1 + src/compas_viewer/viewer.py | 33 +++++++++++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 scripts/unit.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 525d30b4cd..8361774ffd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ 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`. ### Changed diff --git a/scripts/unit.py b/scripts/unit.py new file mode 100644 index 0000000000..b262a933fd --- /dev/null +++ b/scripts/unit.py @@ -0,0 +1,20 @@ +from compas.colors import Color +from compas.geometry import Box +from compas.geometry import Frame +from compas_viewer.viewer import Viewer +from compas_viewer.config import Config + +config = Config() +config.unit = "mm" +viewer = Viewer(config) + +for i in range(10): + for j in range(10): + viewer.scene.add( + Box(500, 500, 500, Frame([i * 1000, j * 1000, 0], [1, 0, 0], [0, 1, 0])), + show_lines=True, + surfacecolor=Color(i / 10, j / 10, 0.0), + name=f"Box_{i}_{j}", + ) + +viewer.show() diff --git a/src/compas_viewer/config.py b/src/compas_viewer/config.py index fcf5c06ca2..3c4da0fc26 100644 --- a/src/compas_viewer/config.py +++ b/src/compas_viewer/config.py @@ -369,6 +369,7 @@ class UIConfig(ConfigBase): @dataclass class Config(ConfigBase): vectorsize: float = 0.1 + unit: Literal["m", "cm", "mm"] = "m" ui: UIConfig = field(default_factory=UIConfig) window: WindowConfig = field(default_factory=WindowConfig) renderer: RendererConfig = field(default_factory=RendererConfig) diff --git a/src/compas_viewer/viewer.py b/src/compas_viewer/viewer.py index 04e763550d..283a59d001 100644 --- a/src/compas_viewer/viewer.py +++ b/src/compas_viewer/viewer.py @@ -20,14 +20,18 @@ class Viewer(Singleton): def __init__(self, config: Optional[Config] = None, **kwargs): + + self.running = False self.app = QApplication(sys.argv) self.app.setApplicationName("COMPAS Viewer") self.app.setApplicationDisplayName("COMPAS Viewer") self.app.setWindowIcon(QIcon(os.path.join(HERE, "assets", "icons", "compas_icon_white.png"))) self._scene = None + self._unit = "m" self.config = config or Config() + self.unit = self.config.unit self.timer = QTimer() self.mouse = Mouse() @@ -37,8 +41,6 @@ def __init__(self, config: Optional[Config] = None, **kwargs): self.renderer = Renderer(self) self.ui = UI(self) - self.running = False - @property def scene(self) -> ViewerScene: if self._scene is None: @@ -52,6 +54,33 @@ def scene(self, scene: Scene): for obj in self._scene.objects: obj.init() + @property + def unit(self) -> str: + return self._unit + + @unit.setter + def unit(self, unit: str): + if unit != self._unit: + if self.running: + raise NotImplementedError("Changing the unit after the viewer is running is not yet supported.") + else: + if unit == "m": + self.config.renderer.gridsize = (10.0, 10, 10.0, 10) + self.config.camera.scale = 1.0 + self.config.camera.position = [-10.0, -10.0, 10.0] + elif unit == "cm": + self.config.renderer.gridsize = (1000.0, 10, 1000.0, 10) + self.config.camera.scale = 100.0 + self.config.camera.position = [-1000.0, -1000.0, 1000.0] + elif unit == "mm": + self.config.renderer.gridsize = (10000.0, 10, 10000.0, 10) + self.config.camera.scale = 1000.0 + self.config.camera.position = [-10000.0, -10000.0, 10000.0] + else: + raise ValueError(f"Invalid unit: {unit}. Valid units are 'm', 'cm', 'mm'.") + + self._unit = unit + def show(self): self.running = True self.ui.init() From 28c9cd4989e25ffe9655b12cfd5c0b00dfdbacd3 Mon Sep 17 00:00:00 2001 From: Licini Date: Thu, 11 Jul 2024 11:16:59 +0200 Subject: [PATCH 2/2] allow viewer.unit = "..." --- src/compas_viewer/viewer.py | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/compas_viewer/viewer.py b/src/compas_viewer/viewer.py index 283a59d001..0c60588ef9 100644 --- a/src/compas_viewer/viewer.py +++ b/src/compas_viewer/viewer.py @@ -31,7 +31,6 @@ def __init__(self, config: Optional[Config] = None, **kwargs): self._unit = "m" self.config = config or Config() - self.unit = self.config.unit self.timer = QTimer() self.mouse = Mouse() @@ -40,6 +39,7 @@ def __init__(self, config: Optional[Config] = None, **kwargs): # renderer should be part of UI self.renderer = Renderer(self) self.ui = UI(self) + self.unit = self.config.unit @property def scene(self) -> ViewerScene: @@ -60,26 +60,24 @@ def unit(self) -> str: @unit.setter def unit(self, unit: str): + if self.running: + raise NotImplementedError("Changing the unit after the viewer is running is not yet supported.") if unit != self._unit: - if self.running: - raise NotImplementedError("Changing the unit after the viewer is running is not yet supported.") + previous_scale = self.config.camera.scale + if unit == "m": + self.config.renderer.gridsize = (10.0, 10, 10.0, 10) + self.renderer.camera.scale = 1.0 + elif unit == "cm": + self.config.renderer.gridsize = (1000.0, 10, 1000.0, 10) + self.renderer.camera.scale = 100.0 + elif unit == "mm": + self.config.renderer.gridsize = (10000.0, 10, 10000.0, 10) + self.renderer.camera.scale = 1000.0 else: - if unit == "m": - self.config.renderer.gridsize = (10.0, 10, 10.0, 10) - self.config.camera.scale = 1.0 - self.config.camera.position = [-10.0, -10.0, 10.0] - elif unit == "cm": - self.config.renderer.gridsize = (1000.0, 10, 1000.0, 10) - self.config.camera.scale = 100.0 - self.config.camera.position = [-1000.0, -1000.0, 1000.0] - elif unit == "mm": - self.config.renderer.gridsize = (10000.0, 10, 10000.0, 10) - self.config.camera.scale = 1000.0 - self.config.camera.position = [-10000.0, -10000.0, 10000.0] - else: - raise ValueError(f"Invalid unit: {unit}. Valid units are 'm', 'cm', 'mm'.") - - self._unit = unit + raise ValueError(f"Invalid unit: {unit}. Valid units are 'm', 'cm', 'mm'.") + self.renderer.camera.distance *= self.renderer.camera.scale / previous_scale + + self._unit = unit def show(self): self.running = True