View-Toggle 2x4: TOP/ISO/PERSP/Cam + N/O/S/W mit Norden-Rotation
User-Vorschlag: Architektur-konformes View-Layout — 3D-Views oben, 4 Gebaeudeansichten unten. Plus Norden-Rotation als Doc-Setting damit bei rotierten Projekten (swissBUILDINGS, Sonnenberechnungen) die richtigen Wandansichten gepickt werden. Backend (rhino/kamera.py): - get_north_angle/set_north_angle — doc.Strings["dossier_north_angle"] (Grad im Uhrzeigersinn von +Y, default 0°) - _scene_target_and_diag(doc) — gemeinsamer Helper fuer Szenen-Center + Diagonal-Distanz - set_cardinal_view(vp, 'N'|'O'|'S'|'W'): rotiert Kamera-Position via Norden-Vektor. Parallel-Projektion, Camera-Z = Target-Z (echte Elevation), Up-Vektor +Z. - set_top_view(vp): Plan-Ansicht mit Norden = Up-Vektor (Plan rotiert visuell wenn Norden != +Y) - _set_iso(vp, octant): Octant-Richtung jetzt aus north+east-Vektoren konstruiert → ISO rotiert mit Norden mit - Bridge-Handler SET_NORTH_ANGLE + state.northAngle, notify Oberleiste Backend (oberleiste.py): - SET_VIEW erweitert: Top → kamera.set_top_view, N/O/S/W → kamera.set_cardinal_view, Iso → kamera._set_iso. Front/Right/etc bleibt als Legacy direkt-Rhino-Call. - State liefert northAngle Frontend (OberleisteApp): - VIEWS_ROW1: TOP/ISO/PERSP + Kamera-Settings-Button (Icons only) - VIEWS_ROW2: N/O/S/W als DM-Mono-Buchstaben - 2x4-Grid, VIEW_W=140 (konsistent mit Massstab-Pills), CELL_W=35 - matchView nur fuer Top/Iso/Perspective; Cardinals haben keinen Active-State (Viewport-Name ist nicht zuverlaessig erkennbar) Frontend (KameraApp): - Plan-Norden Section mit Number-Input (Grad, 0.5°-Step) + Reset-Button - Hinweis-Text dass Wirkung auf TOP/ISO/N/O/S/W geht Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
onMessage, notifyReady,
|
||||
setKameraViewport, setKameraProjection, setKameraIso,
|
||||
kameraZoomExtents, saveKameraPreset, applyKameraPreset, deleteKameraPreset,
|
||||
setKameraNorthAngle,
|
||||
} from './lib/rhinoBridge'
|
||||
|
||||
const labelXs = {
|
||||
@@ -76,11 +77,13 @@ export default function KameraApp() {
|
||||
const [vp, setVp] = useState(null)
|
||||
const [presets, setPresets] = useState([])
|
||||
const [presetName, setPresetName] = useState('')
|
||||
const [northAngle, setNorthAngleState] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
onMessage('STATE', (s) => {
|
||||
setVp(s.viewport || null)
|
||||
setPresets(s.presets || [])
|
||||
if (typeof s.northAngle === 'number') setNorthAngleState(s.northAngle)
|
||||
})
|
||||
notifyReady()
|
||||
}, [])
|
||||
@@ -142,6 +145,38 @@ export default function KameraApp() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Plan-Norden — Rotations-Winkel im Uhrzeigersinn von +Y */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
||||
<span style={labelXs}>Plan-Norden (Rotation von +Y, im Uhrzeigersinn)</span>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<input
|
||||
type="number" min={0} max={360} step={0.5}
|
||||
value={northAngle.toFixed(1)}
|
||||
onChange={(e) => {
|
||||
const a = parseFloat(e.target.value)
|
||||
if (!isNaN(a)) {
|
||||
setNorthAngleState(a)
|
||||
setKameraNorthAngle(a)
|
||||
}
|
||||
}}
|
||||
style={{ flex: 1, fontSize: 12, padding: '4px 8px',
|
||||
fontFamily: 'DM Mono, monospace' }}
|
||||
/>
|
||||
<span style={{ fontSize: 11, color: 'var(--text-muted)' }}>°</span>
|
||||
<button
|
||||
onClick={() => { setNorthAngleState(0); setKameraNorthAngle(0) }}
|
||||
className="btn-outlined"
|
||||
style={{ padding: '4px 10px', fontSize: 10 }}
|
||||
title="Norden zurueck auf +Y (0°)"
|
||||
>Reset</button>
|
||||
</div>
|
||||
<span style={{ fontSize: 10, color: 'var(--text-muted)', lineHeight: 1.4 }}>
|
||||
Norden = +Y bei 0°. Bei rotierten Projekten (z.B. swissBUILDINGS in
|
||||
LV95-Orientierung oder Sonnenberechnungen) hier den Plan-Norden in
|
||||
Grad eintragen. Wirkt auf TOP, ISO und N/O/S/W-Ansichten.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Iso-Quick-Picker */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
||||
<span style={labelXs}>Isometrie (Standard, true-iso 35°/45°)</span>
|
||||
|
||||
Reference in New Issue
Block a user