Kamera-Panel + Iso-Button in der Oberleiste

Oberleiste:
- View-Gruppe: Iso-Button neu zwischen Right und Persp
- matchView: Iso = parallel ohne orthogonalen Standard-Namen,
  Perspektive = !parallel — beide via Projektions-Flag unterschieden
  (Rhino-Viewport-Name ist oft "Perspective" fuer beide)
- Camera-Knopf (Icon: videocam) oeffnet das neue Kamera-Panel
- SET_VIEW Backend: 'Iso' faelltt auf kamera._set_iso(vp, "NE")
- OPEN_KAMERA_PANEL Handler

Kamera-Panel (neu — rhino/kamera.py + src/KameraApp.jsx):
- Viewport-Name + Projektions-Toggle (Persp/Parallel)
- 4 Iso-Quick-Buttons (NW/NE/SE/SW) — true-iso 35°/45°,
  Kamera-Distanz auto aus Szenen-BBox
- Vec3-Felder fuer Kamera-Position + Blick-Ziel (numerisch
  editierbar, m)
- Distanz read-only
- Brennweite (mm) bei Persp, Frustum-Breite (m) bei Parallel
- Zoom-Extents-Button
- Presets: speichern + anwenden + loeschen, persistiert in
  doc.Strings["dossier_kamera_presets"] (JSON)
- Eto-Form-Satelliten-Fenster (420x600) via panel_base.open_satellite_window

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-20 20:41:50 +02:00
parent de1fc887f5
commit b69dd8e279
6 changed files with 630 additions and 5 deletions
+25 -5
View File
@@ -9,7 +9,7 @@ import {
toggleOverrides, setOverridesPreset, openOverridesPanel,
pickLayerCombination, saveLayerCombination,
deleteLayerCombination, openLayerCombinationsDialog,
openDossierSettings,
openDossierSettings, openKameraPanel,
} from './lib/rhinoBridge'
const PRESETS = [
@@ -24,7 +24,8 @@ const VIEWS = [
{ value: 'Top', icon: 'view_quilt', label: 'Top' },
{ value: 'Front', icon: 'north', label: 'Front' },
{ value: 'Right', icon: 'east', label: 'Right' },
{ value: 'Perspective', icon: 'view_in_ar', label: 'Persp' },
{ value: 'Iso', icon: 'view_in_ar', label: 'Iso' },
{ value: 'Perspective', icon: '3d_rotation', label: 'Persp' },
]
function fmtScale(s) {
@@ -186,10 +187,20 @@ export default function OberleisteApp() {
if (appliedScale && appliedScale > 0) setMassstab(appliedScale)
}
// Aktuelles View-Match (manche User haben "Top" / "Right" als view name)
// Aktuelles View-Match. Orthogonale Standard-Views matchen via viewName.
// 'Iso' und 'Perspective' werden via parallel-Flag unterschieden — die
// Rhino-Viewport-Namen sind beide oft "Perspective".
const matchView = (v) => {
if (!state.viewName) return false
return state.viewName === v || state.viewName.toLowerCase() === v.toLowerCase()
const name = (state.viewName || '').toLowerCase()
const ortho = ['top', 'front', 'right', 'bottom', 'left', 'back']
if (v === 'Iso') {
// Parallel-Projektion + kein orthogonaler Standardname → Iso
return state.parallel === true && !ortho.includes(name)
}
if (v === 'Perspective') {
return state.parallel === false
}
return name === v.toLowerCase()
}
// (Command-Bar wurde entfernt — Rhinos eigene Command-Line wird benutzt.)
@@ -264,6 +275,15 @@ export default function OberleisteApp() {
title={`Ansicht ${v.label}`}
/>
))}
<button
onClick={() => openKameraPanel()}
title="Kamera-Einstellungen (Position, Target, Linse, Presets)"
className="btn-outlined"
style={{ height: PILL_H, padding: '0 6px', boxSizing: 'border-box',
fontSize: 9 }}
>
<Icon name="videocam" size={12} />
</button>
<div style={sep} />