Display-Modes: 3D-Template + Auto-Assign + Material/Raytracing-Slots
- Neues Template rhino/templates/dossier_3d.ini fuer perspektivische Views - Registry-Loop in oberleiste.py generalisiert (Plan + 3D + Material + Raytracing) — Material/Raytracing skippen wenn kein Template vorhanden, um Cycles-Pipeline-Clone-Crash zu vermeiden - Guid-Replace praezisiert: nur Section-Header-Guid, nie PipelineId - Plan-spezifische ini-Patches auf target_name=="Dossier Plan" gegated - Auto-Assign in startup.py: Parallel-Viewports -> Plan, Perspective -> 3D, einmal-pro-Doc via doc.Strings-Flag (User-Overrides bleiben) - schnitte.activate_schnitt setzt Dossier Plan explizit (Hatches auch in Schnittperspektive sichtbar) - GestaltungApp Section-Block neu strukturiert: PenBlock fuer 3D als 'Fill' innerhalb der Section, Solid-Fill-Toggle entfernt (war Duplikat)
This commit is contained in:
+79
-35
@@ -185,9 +185,23 @@ def _import_display_modes(paths):
|
||||
return count
|
||||
|
||||
|
||||
# Fest-Guid fuer 'Dossier Plan' damit Re-Imports denselben Slot
|
||||
# Fest-Guids fuer die Dossier-Display-Modes damit Re-Imports denselben Slot
|
||||
# wiederverwenden statt Duplikate zu erzeugen.
|
||||
_DOSSIER_PLAN_GUID = "d0551e72-7e72-4170-b1a4-d0551e72d055"
|
||||
_DOSSIER_PLAN_GUID = "d0551e72-7e72-4170-b1a4-d0551e72d055"
|
||||
_DOSSIER_3D_GUID = "d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d"
|
||||
_DOSSIER_MATERIAL_GUID = "d0551e72-7e72-4170-b1a4-555555555555"
|
||||
_DOSSIER_RAYTRACING_GUID = "d0551e72-7e72-4170-b1a4-666666666666"
|
||||
|
||||
# Registrierte Dossier-Display-Modes: (name, guid, template_basename, default_pipeline_fallback)
|
||||
# Material + Raytracing haben (noch) kein Template — werden vom Fallback-Base
|
||||
# (Rendered / Raytraced) geklont. User kann sie in Rhino anpassen und spaeter
|
||||
# als Template exportieren.
|
||||
_DOSSIER_DISPLAY_MODES = (
|
||||
("Dossier Plan", _DOSSIER_PLAN_GUID, "dossier_plan.ini", "Technical"),
|
||||
("Dossier 3D", _DOSSIER_3D_GUID, "dossier_3d.ini", "Shaded"),
|
||||
("Dossier Material", _DOSSIER_MATERIAL_GUID, "dossier_material.ini", "Rendered"),
|
||||
("Dossier Raytracing", _DOSSIER_RAYTRACING_GUID, "dossier_raytracing.ini", "Raytraced"),
|
||||
)
|
||||
|
||||
def _apply_dossier_plan_attrs(dmd):
|
||||
"""Wendet die Dossier-Plan-Visual-Settings auf einen DisplayMode an.
|
||||
@@ -303,38 +317,54 @@ def _apply_dossier_plan_attrs(dmd):
|
||||
print("[OBERLEISTE] Plan-Mode update:", ex)
|
||||
|
||||
|
||||
_TEMPLATE_INI_PATH = os.path.join(_HERE, "templates", "dossier_plan.ini")
|
||||
_TEMPLATES_DIR = os.path.join(_HERE, "templates")
|
||||
|
||||
|
||||
def _ensure_dossier_plan_display_mode():
|
||||
"""Stellt sicher dass der 'Dossier Plan' Display-Mode existiert.
|
||||
def _ensure_dossier_display_mode(target_name, target_guid, template_basename,
|
||||
fallback_base_name):
|
||||
"""Stellt sicher dass ein Dossier-Display-Mode existiert.
|
||||
|
||||
Strategie: wenn eine Template-ini im Repo existiert
|
||||
(rhino/templates/dossier_plan.ini), laden wir die. Sonst Fallback auf
|
||||
Clone-Technical + ini-Patch. Template ist die bevorzugte Methode weil
|
||||
sich Mac-Rhino-Display-Mode-Properties via Python-API unzuverlaessig
|
||||
setzen lassen — der User baut den Mode einmal manuell perfekt zusammen
|
||||
und exportiert ihn dort hin.
|
||||
(rhino/templates/<template_basename>), laden wir die. Sonst Fallback auf
|
||||
Clone-eines-Built-in-Mode + ini-Patch. Template ist die bevorzugte
|
||||
Methode weil sich Mac-Rhino-Display-Mode-Properties via Python-API
|
||||
unzuverlaessig setzen lassen.
|
||||
|
||||
Args:
|
||||
target_name: 'Dossier Plan' / 'Dossier 3D' / ...
|
||||
target_guid: Fix-Guid die wir fuer Re-Imports wiederverwenden
|
||||
template_basename: 'dossier_plan.ini' / 'dossier_3d.ini'
|
||||
fallback_base_name: 'Technical' / 'Shaded' — Mode zum Klonen
|
||||
"""
|
||||
print("[OBERLEISTE] Plan-Mode: check...")
|
||||
print("[OBERLEISTE] {}: check...".format(target_name))
|
||||
try:
|
||||
from Rhino.Display import DisplayModeDescription
|
||||
except Exception as ex:
|
||||
print("[OBERLEISTE] Plan-Mode: DMD nicht verfuegbar:", ex)
|
||||
print("[OBERLEISTE] {}: DMD nicht verfuegbar: {}".format(target_name, ex))
|
||||
return False
|
||||
import re # fuer ini-checks unten
|
||||
target_name = "Dossier Plan"
|
||||
import re
|
||||
template_ini_path = os.path.join(_TEMPLATES_DIR, template_basename)
|
||||
try:
|
||||
import System
|
||||
target_guid_obj = System.Guid(_DOSSIER_PLAN_GUID)
|
||||
target_guid_obj = System.Guid(target_guid)
|
||||
except Exception:
|
||||
target_guid_obj = None
|
||||
# Template-Datei vorhanden? Wenn ja, Hash davon als "version key"
|
||||
# benutzen — wir nur neu importieren wenn sich die Template-Datei
|
||||
# geaendert hat.
|
||||
template_exists = os.path.isfile(_TEMPLATE_INI_PATH)
|
||||
print("[OBERLEISTE] Plan-Mode template: {}".format(
|
||||
"found at " + _TEMPLATE_INI_PATH if template_exists else "missing → fallback"))
|
||||
template_exists = os.path.isfile(template_ini_path)
|
||||
print("[OBERLEISTE] {} template: {}".format(target_name,
|
||||
"found at " + template_ini_path if template_exists else "missing"))
|
||||
# Fallback-Clone nur fuer "Dossier Plan" erlauben. Bei anderen Modes
|
||||
# ohne Template skippen — sonst klonen wir z.B. den Raytraced-Mode mit
|
||||
# Cycles-PipelineId, was Rhinos Display-Mode-State auf Mac korrumpieren
|
||||
# und ALLE Modes nach Restart verschwinden lassen kann. User soll den
|
||||
# Mode in Rhino bauen + per "Save As" -> templates/<basename> exportieren.
|
||||
if not template_exists and target_name != "Dossier Plan":
|
||||
print("[OBERLEISTE] {}: kein Template → skip (in Rhino bauen, "
|
||||
"Display-Mode -> Save As -> {})".format(
|
||||
target_name, template_ini_path))
|
||||
return False
|
||||
# Schon registriert?
|
||||
try:
|
||||
existing = None
|
||||
@@ -385,23 +415,24 @@ def _ensure_dossier_plan_display_mode():
|
||||
# exportiert) — sonst Fallback auf Technical-Clone.
|
||||
# ----------------------------------------------------------------
|
||||
import tempfile
|
||||
tmp_path = os.path.join(tempfile.gettempdir(), "dossier_plan.ini")
|
||||
tmp_path = os.path.join(tempfile.gettempdir(), template_basename)
|
||||
base = None
|
||||
if template_exists:
|
||||
# Template-ini lesen + ueberschreiben den tmp_path
|
||||
try:
|
||||
with open(_TEMPLATE_INI_PATH, "r", encoding="utf-8", errors="ignore") as f:
|
||||
with open(template_ini_path, "r", encoding="utf-8", errors="ignore") as f:
|
||||
content = f.read()
|
||||
print("[OBERLEISTE] Plan-Mode: Template geladen ({} bytes)".format(len(content)))
|
||||
print("[OBERLEISTE] {}: Template geladen ({} bytes)".format(
|
||||
target_name, len(content)))
|
||||
except Exception as ex:
|
||||
print("[OBERLEISTE] Plan-Mode Template read:", ex)
|
||||
print("[OBERLEISTE] {} Template read: {}".format(target_name, ex))
|
||||
return False
|
||||
else:
|
||||
# Fallback: Technical exportieren + patchen
|
||||
# Fallback: einen Base-Mode exportieren + patchen
|
||||
try:
|
||||
all_modes = list(DisplayModeDescription.GetDisplayModes())
|
||||
except Exception: all_modes = []
|
||||
for prefer in ("Technical", "Pen", "Shaded"):
|
||||
for prefer in (fallback_base_name, "Technical", "Pen", "Shaded"):
|
||||
for dm in all_modes:
|
||||
try:
|
||||
if dm.EnglishName == prefer:
|
||||
@@ -434,18 +465,24 @@ def _ensure_dossier_plan_display_mode():
|
||||
r'(?i)^(\s*Name\s*=\s*)(.*)$',
|
||||
r'\1' + target_name, content, count=1, flags=re.MULTILINE)
|
||||
except Exception: pass
|
||||
# Guid (im ini meist als [<guid>] Section-Header oder als "id="-Feld)
|
||||
# Mode-Guid PRAEZISE per Section-Header finden — nicht irgendeine
|
||||
# Guid im ini erwischen (PipelineId etc. sind eigene Guids die wir
|
||||
# NICHT anfassen duerfen, sonst geht die Pipeline-Referenz kaputt
|
||||
# und Rhino verliert den Mode bzw. crasht beim Klick).
|
||||
try:
|
||||
# Bestehende Guid aus dem File extrahieren + ueberall ersetzen
|
||||
old_guid_match = re.search(
|
||||
r'([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})',
|
||||
r'\[DisplayMode\\([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})',
|
||||
content)
|
||||
if old_guid_match:
|
||||
old_guid = old_guid_match.group(1)
|
||||
content = content.replace(old_guid, _DOSSIER_PLAN_GUID)
|
||||
content = content.replace(old_guid, target_guid)
|
||||
content = content.replace(old_guid.upper(),
|
||||
_DOSSIER_PLAN_GUID.upper())
|
||||
except Exception: pass
|
||||
target_guid.upper())
|
||||
else:
|
||||
print("[OBERLEISTE] {}: kein DisplayMode-Section-Header "
|
||||
"gefunden — Mode-Guid nicht ersetzt".format(target_name))
|
||||
except Exception as ex:
|
||||
print("[OBERLEISTE] {} Guid-Replace: {}".format(target_name, ex))
|
||||
# Plan-Mode-Settings in der ini patchen — Rhino-DisplayMode-ini hat
|
||||
# nested Sections wie [DisplayMode\<guid>\Objects\Surfaces]. Wir
|
||||
# patchen nur EXISTIERENDE Keys (Rhino's Parser stripped unbekannte
|
||||
@@ -460,8 +497,12 @@ def _ensure_dossier_plan_display_mode():
|
||||
|
||||
# Bei Template-Pfad: NUR Name+Guid normalisieren, KEINE inhaltlichen
|
||||
# Patches (User hat das Template bewusst so konfiguriert).
|
||||
# Bei Fallback-Pfad (Technical-Clone): die bekannten Settings forcen.
|
||||
if not template_exists:
|
||||
# Bei Fallback-Pfad fuer Dossier Plan (Technical-Clone): die Plan-
|
||||
# spezifischen Settings forcen. Andere Modes (Material/Raytracing)
|
||||
# uebernehmen den Fallback-Base 1:1 — sonst wuerden Plan-Settings
|
||||
# wie TechnicalMask in eine Rendered/Raytraced-ini gequetscht und
|
||||
# alles zerschiessen.
|
||||
if not template_exists and target_name == "Dossier Plan":
|
||||
for key, val in (
|
||||
("ClipSectionUsage", "1"),
|
||||
("TechnicalMask", "15"),
|
||||
@@ -2092,9 +2133,12 @@ def _bridge_factory():
|
||||
# Custom Display-Mode 'Dossier Plan' beim Modul-Load registrieren — laeuft
|
||||
# bei jedem startup.py oder _reset_panels.py, unabhaengig davon ob das
|
||||
# Panel jemals geoeffnet wird. Funktion ist idempotent.
|
||||
try: _ensure_dossier_plan_display_mode()
|
||||
except Exception as ex:
|
||||
print("[OBERLEISTE] ensure_dossier_plan_display_mode:", ex)
|
||||
# Alle Dossier-Display-Modes registrieren (Plan, 3D, ...)
|
||||
for _name, _guid, _tmpl, _fallback in _DOSSIER_DISPLAY_MODES:
|
||||
try:
|
||||
_ensure_dossier_display_mode(_name, _guid, _tmpl, _fallback)
|
||||
except Exception as _ex:
|
||||
print("[OBERLEISTE] ensure {}: {}".format(_name, _ex))
|
||||
|
||||
|
||||
panel_base.register_and_open("oberleiste", "Oberleiste", PANEL_GUID_STR, _bridge_factory,
|
||||
|
||||
Reference in New Issue
Block a user