Schnitt/Ansicht-Feature + Terrain-Volumen + Geschoss-Add-Dialog

Schnitt-Feature V1+V2:
- Neues rhino/schnitte.py mit Pick-Workflow, Activation (Clipping-Planes +
  Parallel-View), 2D-Plan-Symbol auf 18_Schnittlinien-Sublayer
- Doppelklick auf Symbol aktiviert den Schnitt
- Schnitt-Settings (cutAtLine/Tiefe/Höhen/Blickrichtung) im GeschossSettingsDialog
- View-Snapshot + Restore beim Wechsel Schnitt → Geschoss
- Symbol-Cleanup bei Delete via normalem Ebenen-Menü

Terrain als Volumen:
- swisstopo.volumize_terrain_object: Skirt + Bottom-Cap auf Mesh/Brep
  damit Clipping-Planes gefuellte Querschnitte erzeugen
- UI im SwisstopoApp mit Nachbearbeitung-Section + Tiefen-Eingabe

Geschoss-Add mit Dialog:
- + im GeschossManager oeffnet 3-Optionen-Picker (Geschoss/Schnitt/Zeichnung)
- Geschoss-Dialog mit Anker-Dropdown, Position über/unter, Auto-Name,
  Höhen-Prefill aus Anker

Fix: _send_state fallback — Element gilt als selektiert wenn Source ODER
Volume in der Selection ist (robust gegen Layer-Visibility wenn Referenz-
linien-Layer im aktuellen Mode versteckt ist)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 18:28:59 +02:00
parent 3277f61ced
commit 059cbf8d4d
8 changed files with 1356 additions and 22 deletions
+32
View File
@@ -76,6 +76,11 @@ export default function SwisstopoApp() {
const [replaceExisting, setReplaceExisting] = useState(true)
const [clipToBbox, setClipToBbox] = useState(false)
const [terrainRes, setTerrainRes] = useState('2.0')
// Terrain als geschlossenes Volumen (mit Boden 10m unter tiefstem Punkt)
// damit Section-Cuts gefuellte Querschnitte zeigen statt nur Linien.
// Wirkt auf 3D-Mesh / TIN / Patch — nicht auf 2D-Hoehenlinien und Schichten.
const [terrainVolume, setTerrainVolume] = useState(false)
const [terrainVolumeDepth, setTerrainVolumeDepth] = useState('10')
// Live-Log
const [logs, setLogs] = useState([])
const [running, setRunning] = useState(false)
@@ -165,6 +170,8 @@ export default function SwisstopoApp() {
buildVariant,
contourInterval: contourInt,
tlmKinds: tlmList,
terrainAsVolume: terrainVolume,
terrainVolumeDepth: parseFloat(terrainVolumeDepth) || 10,
})
}
@@ -366,6 +373,31 @@ export default function SwisstopoApp() {
onChange={setContourInt} />
</Field>
)}
{(getTerrain || getContourTin || getContourPatch) && (
<>
<SectionLabel>Nachbearbeitung</SectionLabel>
<Field label=""
hint="Wandelt die oben gewaehlten 3D-Terrain-Quellen (Terrain / TIN / Patch) in geschlossene Mesh-Volumen um — Skirt + Boden bei (min_z Tiefe). Damit liefert eine Clipping-Plane einen gefuellten Querschnitt statt nur Konturlinien. 2D-Linien und Schichten sind nicht betroffen.">
<label style={{ display: 'flex', alignItems: 'center', gap: 6,
fontSize: 11, cursor: 'pointer' }}>
<input type="checkbox" checked={terrainVolume}
onChange={(e) => setTerrainVolume(e.target.checked)} />
<Icon name="layers" size={13} /> Terrain als Volumen (mit Boden, schneidbar)
</label>
</Field>
{terrainVolume && (
<Field label="TIEFE">
<input type="text"
value={terrainVolumeDepth}
onChange={(e) => setTerrainVolumeDepth(e.target.value)}
style={{ width: 60, textAlign: 'right' }} />
<span style={{ fontSize: 10, color: 'var(--text-muted)' }}>
m unter tiefstem Punkt
</span>
</Field>
)}
</>
)}
<SectionLabel>Positionierung</SectionLabel>