geom.settings - add a tooltip for available settings #4832

example - https://i.imgur.com/eTdqv5J.png
added a test so we won't miss if some setting will be added/removed
This commit is contained in:
Andrej730
2024-06-11 11:45:27 +05:00
parent acd4274136
commit f54f45a051
2 changed files with 100 additions and 21 deletions
@@ -27,7 +27,7 @@ from ..entity_instance import entity_instance
from . import has_occ from . import has_occ
from typing import TypeVar, Union, Optional, Generator, Any from typing import TypeVar, Union, Optional, Generator, Any, Literal
T = TypeVar("T") T = TypeVar("T")
ShapeElementType = Union[ ShapeElementType = Union[
@@ -54,8 +54,53 @@ if has_occ:
else: else:
return shape return shape
SETTING = Literal[
"mesher-linear-deflection",
"mesher-angular-deflection",
"reorient-shells",
"length-unit",
"angle-unit",
"precision",
"dimensionality",
"layerset-first",
"disable-boolean-result",
"no-wire-intersection-check",
"no-wire-intersection-tolerance",
"precision-factor",
"debug-boolean",
"boolean-attempt-2d",
"weld-vertices",
"use-world-coords",
"use-material-names",
"convert-back-units",
"context-ids",
"context-types",
"context-identifiers",
"iterator-output",
"disable-opening-subtractions",
"apply-default-materials",
"no-normals",
"generate-uvs",
"enable-layerset-slicing",
"element-hierarchy",
"validate",
"edge-arrows",
"building-local-placement",
"site-local-placement",
"force-space-transparency",
"circle-segments",
"keep-bounding-boxes",
"piecewise-step-type",
"piecewise-step-param",
"use-python-opencascade",
]
class missing_setting: class missing_setting:
def __repr__(self): return '-' def __repr__(self):
return '-'
class settings_mixin: class settings_mixin:
""" """
@@ -64,7 +109,7 @@ class settings_mixin:
when available when available
""" """
USE_PYTHON_OPENCASCADE = 'USE_PYTHON_OPENCASCADE' use_python_opencascade = False
def __init__(self, **kwargs): def __init__(self, **kwargs):
super(settings_mixin, self).__init__() super(settings_mixin, self).__init__()
@@ -73,8 +118,11 @@ class settings_mixin:
def __repr__(self): def __repr__(self):
def safe_get(x): def safe_get(x):
try: return self.get_(x) try:
except: return missing_setting() return self.get(x)
except RuntimeError:
return missing_setting()
fmt_pair = lambda x: "%s = %r" % (self.rname(x), safe_get(x)) fmt_pair = lambda x: "%s = %r" % (self.rname(x), safe_get(x))
return "%s(%s)" % ( return "%s(%s)" % (
type(self).__name__, type(self).__name__,
@@ -82,20 +130,21 @@ class settings_mixin:
) )
@staticmethod @staticmethod
def name(k): def name(k: str) -> SETTING:
return k.lower().replace('_', '-') return k.lower().replace("_", "-")
@staticmethod @staticmethod
def rname(k): def rname(k: SETTING) -> str:
return k.upper().replace('-', '_') return k.upper().replace("-", "_")
def set(self, k: str, v: Any) -> None: def set(self, k: SETTING, v: Any) -> None:
""" """
Set value of the setting named `k` to `v`. Set value of the setting named `k` to `v`.
:raises RuntimeError: If there is no setting with name `k`. :raises RuntimeError: If there is no setting with name `k`.
""" """
if k == "USE_PYTHON_OPENCASCADE": k = self.name(k)
if k == "use-python-opencascade":
if not has_occ: if not has_occ:
raise AttributeError("Python OpenCASCADE is not installed") raise AttributeError("Python OpenCASCADE is not installed")
if v: if v:
@@ -105,16 +154,21 @@ class settings_mixin:
else: else:
self.set_(self.name(k), v) self.set_(self.name(k), v)
def get(self, k: str) -> Any: def get(self, k: SETTING) -> Any:
""" """
Return value of the setting named `k`. Return value of the setting named `k`.
:raises RuntimeError: If there is no setting with name `k`. :raises RuntimeError: If there is no setting with name `k`.
""" """
k = self.name(k)
if k == "use-python-opencascade":
return self.use_python_opencascade
return self.get_(k)
return self.get_(self.name(k)) def setting_names(self) -> tuple[SETTING, ...]:
return super().setting_names() + ("use-python-opencascade",)
def __getattr__(self, k): def __getattr__(self, k: str) -> SETTING:
if k in map(self.rname, self.setting_names()): if k in map(self.rname, self.setting_names()):
return k return k
else: else:
@@ -1,7 +1,32 @@
import pytest
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.geom import ifcopenshell.geom
import ifcopenshell.api.owner.settings import ifcopenshell.api.owner.settings
from typing import get_args
class TestGeomSettings:
def test_run(self):
settings = ifcopenshell.geom.settings()
assert set(get_args(ifcopenshell.geom.SETTING)) == set(settings.setting_names())
assert settings.get(settings.USE_PYTHON_OPENCASCADE) is False
assert settings.get("use-python-opencascade") is False
assert "USE_PYTHON_OPENCASCADE = False" in repr(settings)
if ifcopenshell.geom.has_occ:
settings.set("use-python-opencascade", True)
settings.set(settings.USE_PYTHON_OPENCASCADE, True)
assert settings.get(settings.USE_PYTHON_OPENCASCADE) is True
assert "USE_PYTHON_OPENCASCADE = True" in repr(settings)
else:
with pytest.raises(AttributeError):
settings.set("use-python-opencascade", True)
with pytest.raises(AttributeError):
settings.set(settings.USE_PYTHON_OPENCASCADE, True)
assert "USE_PYTHON_OPENCASCADE = False" in repr(settings)
class TestAssignObject: class TestAssignObject:
def test_no_welding_on_distinct_items(self): def test_no_welding_on_distinct_items(self):