Snapshot: Wand/Öffnung Multi-Surface-Select + Z-Drag + Brüstungs-Mitnahme
Stable working state after a long iteration session. The plugin now supports:
- Multi-Surface-Select für alle Element-Typen (Türen/Fenster/Treppen/Tragwerk)
- Wand-Z-Drag → unbound mode (UK/OK-Override, Wand vom Geschoss entkoppelt)
- Wand-Z-Drag nimmt verknüpfte Öffnungen mit (Brüstung += delta_z via Idle-Pfad)
- Öffnungs-XY-Drag snapt direktional auf Wand-Tangente
- Öffnungs-Z-Drag passt Brüstung an (Fenster sofort sync, Tür deferred)
- Wand-Delete kaskadiert Öffnungen (deferred via Idle, robust gegen _Rotate/_Move)
- Source-Cascade beim Öffnungs-Delete (deferred analog Wand-Kaskade)
- Listener-Cleanup robust gegen _reset_panels.py Reload (Refs in
_dossier_runtime_event_refs gespeichert, vor Re-Install deregistriert)
- _count_same_id_type filtert IsDeleted (verhindert Source-Duplikat-Bug bei Move)
- Frontend: Brüstungs-Slider für Tür ("Schwelle"), Flügel-Block nur bei Fenster
Plus aus früherer Phase dieser Session:
- Dossier-Launcher Auto-Load via Rhinos StartupCommands-XML
- Default-Pfad zeigt auf gebundeltes startup.py (out-of-the-box für neue User)
- Splash-Window beim Plugin-Load mit native macOS rounded corners
- Diverse Launcher-Verbesserungen (Brüstungs-Default, tauri.conf, capabilities)
Known issue: bei Multi-Select-Move mit vielen Sub-Volumen kann sporadisch
"Unable to transform" auftreten (Rhinos Move-Operation kollidiert mit Wand-
Regen). Tür-spezifischer Defer-Pfad mildert das, Fenster läuft sync.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+26
-6
@@ -92,10 +92,21 @@ export default function App() {
|
||||
setCombDialog(d => d ? { ...d, layers: layers || d.layers, presets: presets || [] } : d)
|
||||
}
|
||||
})
|
||||
onMessage('FIRST_RUN', () => {
|
||||
applyAll(INITIAL_ZEICHNUNGSEBENEN, INITIAL_EBENEN)
|
||||
onMessage('FIRST_RUN', ({ defaultEbenen } = {}) => {
|
||||
// Wenn der Dossier-Launcher ein eigenes Schema definiert hat, nutzen wir
|
||||
// das statt der hardcoded INITIAL_EBENEN. Felder ohne `visible`/`locked`
|
||||
// werden mit Defaults ergaenzt damit die UI-Komponenten keine undefineds
|
||||
// sehen.
|
||||
const useEbenen = (Array.isArray(defaultEbenen) && defaultEbenen.length)
|
||||
? defaultEbenen.map(e => ({
|
||||
visible: true, locked: false,
|
||||
...e,
|
||||
}))
|
||||
: INITIAL_EBENEN
|
||||
setEbenen(useEbenen)
|
||||
applyAll(INITIAL_ZEICHNUNGSEBENEN, useEbenen)
|
||||
setAppliedZ(INITIAL_ZEICHNUNGSEBENEN)
|
||||
setAppliedE(INITIAL_EBENEN)
|
||||
setAppliedE(useEbenen)
|
||||
const active = INITIAL_ZEICHNUNGSEBENEN.find(zz => zz.id === activeId) || INITIAL_ZEICHNUNGSEBENEN[0]
|
||||
if (active) {
|
||||
setActiveZeichnungsebene(active)
|
||||
@@ -136,13 +147,22 @@ export default function App() {
|
||||
if (!f || !f.pattern || f.pattern === 'None') return ''
|
||||
return [f.pattern, f.source || 'layer', f.color || '', f.scale ?? 1, f.rotation ?? 0].join('|')
|
||||
}
|
||||
// WICHTIG: alle Felder die das Backend braucht hier mit drin haben — sonst
|
||||
// triggert Aenderung an z.B. hasClipping/schnitthoehe kein Apply, und das
|
||||
// Backend sieht den neuen Stand nie. Frueher waren nur id/name/isGeschoss
|
||||
// drin -> Clipping-Toggle blieb wirkungslos.
|
||||
const zSig = (z) => [
|
||||
z.id, z.name, z.isGeschoss ? 1 : 0,
|
||||
z.hoehe ?? '', z.schnitthoehe ?? '',
|
||||
z.hasClipping ? 1 : 0,
|
||||
].join(':')
|
||||
const structureKey = useMemo(() => (
|
||||
zeichnungsebenen.map(z => `${z.id}:${z.name}:${z.isGeschoss ? 1 : 0}`).join(',') + '|' +
|
||||
zeichnungsebenen.map(zSig).join(',') + '|' +
|
||||
ebenen.map(e => `${e.code}:${e.name}:${fillSig(e)}`).join(',')
|
||||
), [zeichnungsebenen, ebenen])
|
||||
|
||||
const appliedStructureKey = useMemo(() => (
|
||||
appliedZ.map(z => `${z.id}:${z.name}:${z.isGeschoss ? 1 : 0}`).join(',') + '|' +
|
||||
appliedZ.map(zSig).join(',') + '|' +
|
||||
appliedE.map(e => `${e.code}:${e.name}:${fillSig(e)}`).join(',')
|
||||
), [appliedZ, appliedE])
|
||||
|
||||
@@ -176,7 +196,7 @@ export default function App() {
|
||||
const name = (window.prompt('Name für Ebenenkombination:', suggested) || '').trim()
|
||||
if (!name) return
|
||||
if (combinations.some(p => p.name === name) &&
|
||||
!window.confirm(`"${name}" ueberschreiben?`)) return
|
||||
!window.confirm(`"${name}" überschreiben?`)) return
|
||||
saveCurrentAsCombination(name)
|
||||
setActiveCombName(name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user