Arbeitseinheit als Project-Setting + Doc-Open-Check
Statt jeden Wert im Code zu konvertieren wird sichergestellt dass das
Doc in der gewuenschten Unit ist:
- defaults.unit ('meters'|'millimeters'|'centimeters') in
dossier_project_settings, Default 'meters'
- ProjectSettings-Dialog "Voreinstellungen" Tab: neue Sektion
"Arbeitseinheit" mit Toggle-Group fuer m/cm/mm
- get_project_unit() + get_project_unit_enum() Helper in rhinopanel
- startup._check_doc_unit() prueft beim Doc-Open ob ModelUnitSystem
matched — bei Mismatch Eto-MessageBox "Doc auf X umstellen?"
- "Yes" ruft _-Units _Model _<Unit> _Yes (Geometrie wird mit-skaliert)
- "No" setzt doc.Strings-Flag dossier_unit_checked → keine erneute Frage
- Check laeuft beim _on_doc_opened-Hook + initial fuer aktives Doc
Vorgehen ist deutlich sauberer als der vor-revert unit-aware Code
(135 Zeilen Konvertierungslogik vs 80 Zeilen Check+Convert).
This commit is contained in:
@@ -303,6 +303,10 @@ _PROJECT_SETTINGS_DEFAULTS = {
|
|||||||
"schnittDepthBack": 8.0,
|
"schnittDepthBack": 8.0,
|
||||||
"schnittHeightMin": -1.0,
|
"schnittHeightMin": -1.0,
|
||||||
"schnittHeightMax": 12.0,
|
"schnittHeightMax": 12.0,
|
||||||
|
# Arbeitseinheit. DOSSIER-Default ist Meter (Architektur-Standard).
|
||||||
|
# Beim Doc-Open prueft startup.py ob doc.ModelUnitSystem dem hier
|
||||||
|
# entspricht — sonst Dialog mit "Umstellen"-Option.
|
||||||
|
"unit": "meters", # "meters" | "millimeters" | "centimeters"
|
||||||
},
|
},
|
||||||
"materials": [],
|
"materials": [],
|
||||||
"project": {
|
"project": {
|
||||||
@@ -319,6 +323,44 @@ _PROJECT_SETTINGS_DEFAULTS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Mapping Setting-String → Rhino.UnitSystem Enum (lazy import vermeidet
|
||||||
|
# Bootstrap-Problem wenn Rhino.dll noch nicht da ist)
|
||||||
|
_UNIT_STRING_TO_ENUM = None
|
||||||
|
|
||||||
|
|
||||||
|
def _unit_string_to_enum():
|
||||||
|
global _UNIT_STRING_TO_ENUM
|
||||||
|
if _UNIT_STRING_TO_ENUM is not None:
|
||||||
|
return _UNIT_STRING_TO_ENUM
|
||||||
|
try:
|
||||||
|
import Rhino
|
||||||
|
_UNIT_STRING_TO_ENUM = {
|
||||||
|
"meters": Rhino.UnitSystem.Meters,
|
||||||
|
"millimeters": Rhino.UnitSystem.Millimeters,
|
||||||
|
"centimeters": Rhino.UnitSystem.Centimeters,
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
_UNIT_STRING_TO_ENUM = {}
|
||||||
|
return _UNIT_STRING_TO_ENUM
|
||||||
|
|
||||||
|
|
||||||
|
def get_project_unit(doc):
|
||||||
|
"""Liefert die Arbeitseinheit aus den Project-Settings als String
|
||||||
|
('meters'|'millimeters'|'centimeters'). Default 'meters'.
|
||||||
|
"""
|
||||||
|
ps = load_project_settings(doc) or {}
|
||||||
|
d = ps.get("defaults") or {}
|
||||||
|
u = (d.get("unit") or "meters").lower()
|
||||||
|
if u not in ("meters", "millimeters", "centimeters"):
|
||||||
|
u = "meters"
|
||||||
|
return u
|
||||||
|
|
||||||
|
|
||||||
|
def get_project_unit_enum(doc):
|
||||||
|
"""Wie get_project_unit, aber als Rhino.UnitSystem Enum."""
|
||||||
|
return _unit_string_to_enum().get(get_project_unit(doc))
|
||||||
|
|
||||||
|
|
||||||
def _normalize_project_meta(p):
|
def _normalize_project_meta(p):
|
||||||
"""Garantiert das project-Schema. Strings werden gestripped, mum als
|
"""Garantiert das project-Schema. Strings werden gestripped, mum als
|
||||||
float (default 0.0 wenn nicht parsebar)."""
|
float (default 0.0 wenn nicht parsebar)."""
|
||||||
|
|||||||
@@ -141,6 +141,74 @@ def _assign_default_display_modes(doc):
|
|||||||
print("[STARTUP] view-modes: {} Viewport(s) gesetzt".format(n_set))
|
print("[STARTUP] view-modes: {} Viewport(s) gesetzt".format(n_set))
|
||||||
|
|
||||||
|
|
||||||
|
_DOC_FLAG_UNIT_CHECKED = "dossier_unit_checked"
|
||||||
|
|
||||||
|
|
||||||
|
def _check_doc_unit(doc):
|
||||||
|
"""Prueft ob doc.ModelUnitSystem der DOSSIER-Project-Setting-Arbeitseinheit
|
||||||
|
entspricht. Bei Mismatch: Modal-Dialog mit "Umstellen" / "Spaeter"-Option.
|
||||||
|
|
||||||
|
Idempotent pro Doc via doc.Strings-Flag — wird nur EINMAL pro Doc gefragt.
|
||||||
|
Wenn User "Spaeter" waehlt, fragt DOSSIER beim selben Doc nicht mehr (Flag
|
||||||
|
bleibt gesetzt). Fuer erneute Frage: doc.Strings-Key loeschen.
|
||||||
|
"""
|
||||||
|
if doc is None: return
|
||||||
|
try:
|
||||||
|
if doc.Strings.GetValue(_DOC_FLAG_UNIT_CHECKED) == "1":
|
||||||
|
return
|
||||||
|
except Exception: pass
|
||||||
|
try:
|
||||||
|
import rhinopanel
|
||||||
|
target_unit_str = rhinopanel.get_project_unit(doc)
|
||||||
|
target_unit_enum = rhinopanel.get_project_unit_enum(doc)
|
||||||
|
except Exception as ex:
|
||||||
|
print("[STARTUP] unit-check: project-setting lesen:", ex)
|
||||||
|
return
|
||||||
|
if target_unit_enum is None: return
|
||||||
|
try:
|
||||||
|
current = doc.ModelUnitSystem
|
||||||
|
except Exception:
|
||||||
|
return
|
||||||
|
if current == target_unit_enum:
|
||||||
|
# Schon passend → einmalig Flag setzen, beim naechsten Open kein Check
|
||||||
|
try: doc.Strings.SetString(_DOC_FLAG_UNIT_CHECKED, "1")
|
||||||
|
except Exception: pass
|
||||||
|
return
|
||||||
|
# Mismatch — Dialog zeigen
|
||||||
|
try:
|
||||||
|
import Eto.Forms as ef
|
||||||
|
msg = ("Dieses Doc ist in '{}'.\n"
|
||||||
|
"DOSSIER-Projekteinstellung: '{}'.\n\n"
|
||||||
|
"Doc auf '{}' umstellen?\n"
|
||||||
|
"(Bestehende Geometrie wird skaliert)").format(
|
||||||
|
str(current), target_unit_str, target_unit_str)
|
||||||
|
result = ef.MessageBox.Show(
|
||||||
|
msg, "DOSSIER — Arbeitseinheit",
|
||||||
|
ef.MessageBoxButtons.YesNo,
|
||||||
|
ef.MessageBoxType.Question)
|
||||||
|
try:
|
||||||
|
doc.Strings.SetString(_DOC_FLAG_UNIT_CHECKED, "1")
|
||||||
|
except Exception: pass
|
||||||
|
if str(result).lower().endswith("yes"):
|
||||||
|
# _-Units _<unit> _Yes konvertiert Geometrie automatisch mit
|
||||||
|
unit_cmd = {"meters": "_Meters",
|
||||||
|
"millimeters": "_Millimeters",
|
||||||
|
"centimeters": "_Centimeters"}.get(target_unit_str)
|
||||||
|
if unit_cmd:
|
||||||
|
try:
|
||||||
|
Rhino.RhinoApp.RunScript(
|
||||||
|
"_-Units _Model {} _Yes _EnterEnd".format(unit_cmd),
|
||||||
|
False)
|
||||||
|
print("[STARTUP] Doc auf {} umgestellt (Geometrie skaliert)".format(
|
||||||
|
target_unit_str))
|
||||||
|
except Exception as ex:
|
||||||
|
print("[STARTUP] unit-convert RunScript:", ex)
|
||||||
|
else:
|
||||||
|
print("[STARTUP] User hat Unit-Umstellung verweigert — Doc bleibt {}".format(current))
|
||||||
|
except Exception as ex:
|
||||||
|
print("[STARTUP] unit-check dialog:", ex)
|
||||||
|
|
||||||
|
|
||||||
def _on_doc_opened(sender, e):
|
def _on_doc_opened(sender, e):
|
||||||
"""Greift bei jedem geoeffneten Doc nach Rhino-Start. Migration ist
|
"""Greift bei jedem geoeffneten Doc nach Rhino-Start. Migration ist
|
||||||
idempotent (Flag in doc.Strings)."""
|
idempotent (Flag in doc.Strings)."""
|
||||||
@@ -149,6 +217,7 @@ def _on_doc_opened(sender, e):
|
|||||||
import panel_base
|
import panel_base
|
||||||
panel_base.migrate_to_dossier(doc)
|
panel_base.migrate_to_dossier(doc)
|
||||||
_assign_default_display_modes(doc)
|
_assign_default_display_modes(doc)
|
||||||
|
_check_doc_unit(doc)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print("[STARTUP] _on_doc_opened:", ex)
|
print("[STARTUP] _on_doc_opened:", ex)
|
||||||
|
|
||||||
@@ -212,6 +281,12 @@ def _load_all(sender, e):
|
|||||||
_assign_default_display_modes(Rhino.RhinoDoc.ActiveDoc)
|
_assign_default_display_modes(Rhino.RhinoDoc.ActiveDoc)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print("[STARTUP] view-modes assign:", ex)
|
print("[STARTUP] view-modes assign:", ex)
|
||||||
|
# Unit-Check fuer das beim Start aktive Doc — fragt einmal pro Doc
|
||||||
|
# wenn doc.ModelUnitSystem != Project-Setting
|
||||||
|
try:
|
||||||
|
_check_doc_unit(Rhino.RhinoDoc.ActiveDoc)
|
||||||
|
except Exception as ex:
|
||||||
|
print("[STARTUP] unit-check active doc:", ex)
|
||||||
# DOSSIERUI Window-Layout — Hinweis fuer manuelles Laden
|
# DOSSIERUI Window-Layout — Hinweis fuer manuelles Laden
|
||||||
_hint_dossier_ui()
|
_hint_dossier_ui()
|
||||||
# Startup-Timing-Summary 3 Sekunden spaeter (nachdem alle async Idle-
|
# Startup-Timing-Summary 3 Sekunden spaeter (nachdem alle async Idle-
|
||||||
|
|||||||
@@ -799,6 +799,32 @@ export default function ProjectSettingsDialog({
|
|||||||
Voreinstellungen fuer neue Elemente. Pro-Element editierte
|
Voreinstellungen fuer neue Elemente. Pro-Element editierte
|
||||||
Werte bleiben davon unberuehrt.
|
Werte bleiben davon unberuehrt.
|
||||||
</div>
|
</div>
|
||||||
|
<DetailSection title="Arbeitseinheit">
|
||||||
|
<div style={{ padding: '5px 0',
|
||||||
|
display: 'flex', alignItems: 'center', gap: 6 }}>
|
||||||
|
<span style={{ flex: 1, fontSize: 11,
|
||||||
|
color: 'var(--text-primary)' }}>
|
||||||
|
Einheit
|
||||||
|
</span>
|
||||||
|
<div style={{ display: 'flex', gap: 3 }}>
|
||||||
|
{[
|
||||||
|
{ code: 'meters', label: 'Meter (m)' },
|
||||||
|
{ code: 'centimeters', label: 'cm' },
|
||||||
|
{ code: 'millimeters', label: 'mm' },
|
||||||
|
].map(u => (
|
||||||
|
<BarToggle key={u.code} label={u.label}
|
||||||
|
active={(draft.defaults.unit || 'meters') === u.code}
|
||||||
|
onClick={() => setDefault('unit', u.code)}
|
||||||
|
title={`Doc-Unit auf ${u.label} einstellen`} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: 9, color: 'var(--text-muted)',
|
||||||
|
lineHeight: 1.4, padding: '2px 0 4px' }}>
|
||||||
|
Wenn ein geoeffnetes Doc nicht in dieser Einheit ist, fragt
|
||||||
|
DOSSIER ob umgestellt werden soll. Architektur-Standard: Meter.
|
||||||
|
</div>
|
||||||
|
</DetailSection>
|
||||||
<DetailSection title="Geschoss">
|
<DetailSection title="Geschoss">
|
||||||
<InlineNumberField label="Standard-Geschosshöhe"
|
<InlineNumberField label="Standard-Geschosshöhe"
|
||||||
value={draft.defaults.geschossHoehe ?? 3.0}
|
value={draft.defaults.geschossHoehe ?? 3.0}
|
||||||
|
|||||||
Reference in New Issue
Block a user