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:
2026-05-26 18:26:49 +02:00
parent 13a5e1eb7a
commit 02a00a9b4a
5 changed files with 497 additions and 59 deletions
+79 -35
View File
@@ -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,
+11
View File
@@ -293,6 +293,17 @@ def activate_schnitt(doc, z, skip_view=False):
vp.ChangeToParallelProjection(True)
vp.SetCameraLocations(target, cam_pos)
vp.CameraUp = rg.Vector3d(0, 0, 1)
# Display-Mode auf 'Dossier Plan' — auch bei Perspektive, damit
# die Section-Hatches sichtbar sind. User kann manuell wechseln.
try:
from Rhino.Display import DisplayModeDescription
for dm in DisplayModeDescription.GetDisplayModes():
try:
if dm.EnglishName == "Dossier Plan":
vp.DisplayMode = dm
break
except Exception: pass
except Exception: pass
# Zoom auf Schnitt-BoundingBox + etwas Rand. Bei Perspektive
# macht ZoomBoundingBox auch Sinn — Rhino passt das FOV-Frame
# entsprechend an.
+71
View File
@@ -76,6 +76,71 @@ def _migrate_active_doc(*_):
print("[STARTUP] Migration:", ex)
_DOC_FLAG_VIEW_MODES = "dossier_view_modes_initialized"
def _assign_default_display_modes(doc):
"""Setzt einmalig pro Doc die Display-Modes auf die Dossier-Defaults:
- Parallel-Projektionen (Top/Front/Right/Schnitt-parallel) -> 'Dossier Plan'
- Perspektive (Perspective/Schnittperspektive) -> 'Dossier 3D'
Persistiert einen Flag in doc.Strings → laeuft nur EINMAL pro Doc.
User-Overrides (manuelles Wechseln) bleiben damit erhalten.
"""
if doc is None: return
try:
if doc.Strings.GetValue(_DOC_FLAG_VIEW_MODES) == "1":
return # schon initialisiert
except Exception: pass
try:
from Rhino.Display import DisplayModeDescription
except Exception as ex:
print("[STARTUP] view-modes: DMD nicht verfuegbar:", ex); return
# Mode-Lookup per Name
mode_plan = mode_3d = None
try:
for dm in DisplayModeDescription.GetDisplayModes():
try:
n = dm.EnglishName
if n == "Dossier Plan": mode_plan = dm
elif n == "Dossier 3D": mode_3d = dm
except Exception: pass
except Exception as ex:
print("[STARTUP] view-modes: Mode-List:", ex); return
if mode_plan is None and mode_3d is None:
print("[STARTUP] view-modes: keine Dossier-Modes registriert — skip")
return
n_set = 0
try:
for view in doc.Views:
try:
vp = view.ActiveViewport
if vp is None: continue
is_par = bool(vp.IsParallelProjection)
target = mode_plan if is_par else mode_3d
if target is None: continue
try:
vp.DisplayMode = target
n_set += 1
except Exception as ex:
print("[STARTUP] view-modes set ({}): {}".format(
vp.Name, ex))
except Exception: pass
try:
doc.Views.Redraw()
except Exception: pass
except Exception as ex:
print("[STARTUP] view-modes iterate:", ex)
try:
doc.Strings.SetString(_DOC_FLAG_VIEW_MODES, "1")
except Exception: pass
print("[STARTUP] view-modes: {} Viewport(s) gesetzt".format(n_set))
def _on_doc_opened(sender, e):
"""Greift bei jedem geoeffneten Doc nach Rhino-Start. Migration ist
idempotent (Flag in doc.Strings)."""
@@ -83,6 +148,7 @@ def _on_doc_opened(sender, e):
doc = e.Document if hasattr(e, "Document") else Rhino.RhinoDoc.ActiveDoc
import panel_base
panel_base.migrate_to_dossier(doc)
_assign_default_display_modes(doc)
except Exception as ex:
print("[STARTUP] _on_doc_opened:", ex)
@@ -141,6 +207,11 @@ def _load_all(sender, e):
text_editor._ensure_double_click_hook()
except Exception as ex:
print("[STARTUP] text_editor hook:", ex)
# Display-Modes auf Default fuer aktives Doc setzen (einmalig)
try:
_assign_default_display_modes(Rhino.RhinoDoc.ActiveDoc)
except Exception as ex:
print("[STARTUP] view-modes assign:", ex)
# DOSSIERUI Window-Layout — Hinweis fuer manuelles Laden
_hint_dossier_ui()
# Startup-Timing-Summary 3 Sekunden spaeter (nachdem alle async Idle-
+323
View File
@@ -0,0 +1,323 @@
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d]
PipelineId=e1eb7363-87f2-4a2b-a861-256e77835369
SupportsShading=y
SupportsStereo=y
AddToMenu=y
AllowObjectAssignment=y
ShadedPipelineRequired=y
WireframePipelineRequired=y
PipelineLocked=y
Order=-5
DerivedFrom=00000000-0000-0000-0000-000000000000
Name=Dossier 3D
XrayAllObjects=n
IgnoreHighlights=n
DisableConduits=n
DisableTransparency=n
BBoxMode=0
RealtimeDisplayId=00000000-0000-0000-0000-000000000000
SupportsShadeCmd=y
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Lighting]
ShadowIntensity=40
ShadowClippingRadius=0
ShadowClippingUsage=0
PerPixelLighting=n
TransparencyTolerance=40
ShadowBlur=0
ShadowBias=10,12,0
ShowLights=n
UseHiddenLights=n
UseLightColor=n
LightingScheme=2
Luminosity=0
AmbientColor=0,0,0
LightCount=0
CastShadows=y
ShadowMapSize=2048
SkylightShadowQuality=4
NumSamples=4
ShadowMapType=2
ShadowBitDepth=32
ShadowColor=0,0,0
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Objects]
CPHidePoints=n
CPHighlight=y
CPHidden=n
nCPWireThickness=1
LockedUsage=2
LockedTrans=50
GhostLockedObjects=n
ClipSectionUsage=0
CPColor=0,0,0
eCVStyle=102
nCVSize=3
LayersFollowLockUsage=n
LockedObjectsBehind=n
LockedColor=100,100,100
CPSolidLines=n
CPSingleColor=n
CPHideSurface=n
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Objects\Annotations]
DotBorderColor=-1
ShowText=y
ShowAnnotations=y
DotTextColor=-1
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Objects\Curves]
ShowCurves=y
CurveThicknessUsage=0
LineJoinStyle=0
LineEndCapStyle=0
CurvePattern=-1
CurveTrans=0
CurveThickness=1
CurveColor=0,0,0
SingleCurveColor=n
ShowCurvatureHair=n
CurveThicknessScale=1
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Objects\Meshes]
ShowMeshNakedEdges=n
MeshNonmanifoldEdgeColor=0,0,0
MeshNakedEdgeColor=0,0,0
MeshEdgeColor=0,0,0
MeshNonmanifoldEdgeColorReduction=0
MeshNakedEdgeColorReduction=0
MeshEdgeColorReduction=0
MeshNonmanifoldEdgeThickness=0
MeshNakedEdgeThickness=2
MeshEdgeThickness=2
ShowMeshNonmanifoldEdges=n
ShowMeshEdges=n
MeshVertexSize=0
ShowMeshVertices=n
ShowMeshWires=n
MeshWirePattern=-1
MeshWireThickness=1
MeshWireColor=0,0,0
SingleMeshWireColor=n
HighlightMeshes=n
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Objects\Points]
PCSize=2
ShowPoints=y
PointStyle=51
PointSize=3
PCGripStyle=102
PCGripSize=2
PCStyle=50
ShowPointClouds=y
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Objects\SubD]
CreaseVisible=n
CreaseUsage=0
CreaseColor=255,255,255
CreaseColorReduction=0
CreaseThickness=2
CreaseThicknessScale=1
CreaseApplyPattern=y
NonmanifoldVisible=n
NonmanifoldUsage=0
NonmanifoldColor=255,255,255
NonmanifoldColorReduction=0
NonmanifoldThickness=1
NonmanifoldThicknessScale=1
NonmanifoldApplyPattern=y
BoundaryVisible=n
BoundaryUsage=0
BoundaryColor=255,255,255
SmoothColorReduction=0
SmoothColor=255,255,255
ShowSymmetryAxis=y
SmoothVisible=n
SubDThicknessUsage=0
BoundaryColorReduction=0
BoundaryThickness=2
SmoothThickness=1
BoundaryThicknessScale=2
BoundaryApplyPattern=y
ShowReflectedPlane=y
SmoothUsage=0
PlaneColorUsage=2
SymmetryAxisThickness=0.02500000037252903
ReflectedColor=64,64,64
ColorPercentage=30
AxisColor=255,0,0
SmoothThicknessScale=1
SmoothApplyPattern=y
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Objects\Surfaces]
EdgeColorReduction=0
SurfaceKappaHair=n
HighlightSurfaces=n
ShowIsocurves=n
IsoThicknessUsed=n
IsocurveThickness=1
IsoUThickness=1
IsoVThickness=1
IsoWThickness=1
SingleIsoColor=n
IsoColor=0,0,0
IsoColorsUsed=n
IsoUColor=0,0,0
IsoVColor=0,0,0
IsoWColor=0,0,0
IsoPatternUsed=n
IsocurvePattern=-1
IsoUPattern=-1
IsoVPattern=-1
IsoWPattern=-1
ShowEdges=y
ShowNakedEdges=n
ShowTangentEdges=n
ShowTangentSeams=n
ShowNonmanifoldEdges=n
ShowEdgeEndpoints=n
EdgeThickness=1
EdgeColorUsage=0
NakedEdgeThickness=2
NakedEdgeColorUsage=0
NakedEdgeColorReduction=0
EdgeColor=0,0,0
NakedEdgeColor=0,0,0
NonmanifoldEdgeColor=0,0,0
EdgePattern=-1
NakedEdgePattern=-1
NonmanifoldEdgePattern=-1
SurfaceThicknessUsage=0
SurfaceEdgeThicknessScale=2
SurfaceEdgeApplyPattern=y
SurfaceNakedEdgeUseNormalEdgeThickness=y
SurfaceNakedEdgeThicknessScale=2
SurfaceNakedEdgeApplyPattern=y
SurfaceIsoUThicknessScale=1
SurfaceIsoVThicknessScale=1
SurfaceIsoWThicknessScale=1
SurfaceIsoUApplyPattern=y
SurfaceIsoVApplyPattern=y
SurfaceIsoWApplyPattern=y
ShowFlatSurfaceIsos=n
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Objects\Technical]
TEThickness=1
TCThickness=1
TSThickness=1
TIThickness=1
THColor=0,0,0
TEColor=0,0,0
TSiColor=0,0,0
TCColor=0,0,0
TSColor=0,0,0
TIColor=0,0,0
TechnicalMask=14
TechnicalUsageMask=0
THThickness=1
TSiThickness=1
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Shading]
ParallelLineRotation=0
CullBackfaces=n
ShadeVertexColors=n
SingleWireColor=n
WireColor=0,0,0
ShadeSurface=y
UseObjectMaterial=n
UseObjectBFMaterial=n
BakeTextures=y
ShowDecals=y
SurfaceColorWriting=y
ShadingEffect=0
ParallelLineWidth=2
ParallelLineSeparation=3
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Shading\Material]
BackIsCustom=y
FrontIsCustom=n
UseBackMaterial=y
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Shading\Material\Back Material]
ShineIntensity=100
Luminosity=0
Reflectivity=0
Transparency=0
Specular=255,255,255
Shine=0
Diffuse=126,126,126
OverrideObjectReflectivity=y
OverrideObjectTransparency=y
OverrideObjectColor=n
FlatShaded=n
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Shading\Material\Back Material\BitmapTexture]
=
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Shading\Material\Back Material\EmapTexture]
=
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Shading\Material\Back Material\TransparencyTexture]
=
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Shading\Material\Front Material]
Diffuse=126,126,126
Specular=255,255,255
Shine=128
ShineIntensity=100
Reflectivity=0
Transparency=0
FlatShaded=y
OverrideObjectColor=n
OverrideObjectTransparency=y
OverrideObjectReflectivity=y
Luminosity=0
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Shading\Material\Front Material\BitmapTexture]
=
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Shading\Material\Front Material\EmapTexture]
=
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\Shading\Material\Front Material\TransparencyTexture]
=
[DisplayMode\d0551e72-7e72-4170-b1a4-3d3d3d3d3d3d\View settings]
ShowClippingPlanes=n
FlipGlasses=n
AGViewingMode=0
AGColorMode=0
StereoParallax=1
StereoSeparation=1
StereoModeEnabled=0
BackgroundBitmap=
GradBotRight=210,210,210
WzColor=0,0,150
GridTrans=60
WyColor=75,150,75
WxColor=150,75,75
WorldAxesColor=0
GridPlaneColor=0,0,0
PlaneUsesGridColor=n
AxesPercentage=100
PlaneVisibility=0
GridPlaneTrans=90
DrawTransGridPlane=n
GradTopRight=240,240,240
GradBotLeft=210,210,210
GradTopLeft=240,240,240
SolidColor=250,250,250
FillMode=2
CustomLinearWorkflowPostProcessGamma=2.200000047683716
CustomLinearWorkflowPreProcessGamma=2.200000047683716
CustomLinearWorkflowPostProcessFrameBuffer=n
CustomLinearWorkflowPreProcessTextures=y
CustomLinearWorkflowPreProcessColors=y
LinearWorkflowUsage=0
CustomGroundPlaneShadowOnly=y
CustomGroundPlaneAutomaticAltitude=y
CustomGroundPlaneAltitude=0
CustomGroundPlaneShow=y
GroundPlaneUsage=1
UseDocumentGrid=n
DrawGrid=n
DrawAxes=n
DrawZAxis=n
DrawWorldAxes=n
ShowGridOnTop=n
ShowTransGrid=n
BlendGrid=n
VertScale=1
HorzScale=1
ClippingCPColor=255,255,255
ClippingEdgeColor=0,0,0
ClippingSurfaceColor=128,128,128
ClippingEdgeThickness=3
ClippingCPTrans=95
ClippingCPUsage=0
ClippingEdgesUsage=2
ClippingSurfaceUsage=0
ClippingShowCP=n
ClippingClipSelected=y
ClippingShowXEdges=y
ClippingShowXSurface=y
+13 -24
View File
@@ -485,28 +485,10 @@ function SectionBlock({ sel }) {
setter={setSectionStyle}
/>
{/* Hintergrund (Solid-Fill hinter dem Hatch-Pattern) */}
{!isLayerSource && enabled && (
<>
<SectionHead title="Solid-Fill" />
<div style={{ padding: '0 14px 12px', display: 'flex', flexDirection: 'column', gap: 6 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
<BarToggle label={backgroundColor ? 'Solid' : 'Transparent'}
icon={backgroundColor ? 'format_color_fill' : 'check_box_outline_blank'}
active={!!backgroundColor}
onClick={() => callSetter({
backgroundColor: backgroundColor ? null : '#ffffff'
})} />
</div>
{backgroundColor && (
<ColorBar
color={backgroundColor}
onChange={(c) => callSetter({ backgroundColor: c })}
/>
)}
</div>
</>
)}
{/* Fill — Objekt-Pen (Color/LW/Linetype) als 'Fill' weil dessen
Color in Plan-Mode visuell die Schnittflaeche fuellt. */}
<SectionHead title="Fill" />
<PenBlock sel={sel} />
</>
}
@@ -565,8 +547,15 @@ export default function GestaltungApp() {
</>
)}
<SectionHead title={penLabel} />
<PenBlock sel={sel} />
{/* PenBlock fuer 2D/Curves oben, fuer 3D innerhalb der
SectionBlock als 'Fill' weiter unten (User-Erfahrung:
ObjektFarbe fuehlt sich wie Section-Fill an). */}
{kind !== '3d' && (
<>
<SectionHead title={penLabel} />
<PenBlock sel={sel} />
</>
)}
{showSection && (
<SectionBlock sel={sel} />