setGeschossDialog(null)}
+ style={{ position: 'fixed', inset: 0, zIndex: 999,
+ background: 'transparent' }} />
+
ev.stopPropagation()}>
+
+ Neues Geschoss
+
+
+ {/* Position: Anker-Dropdown + Über/Unter-Toggle */}
+
+
+ Position relativ zu
+
+
+
+ updateGeschossDialog({ pos: 'above' })}
+ title="Über dem Anker einfügen" />
+ updateGeschossDialog({ pos: 'below' })}
+ title="Unter dem Anker einfügen" />
+
+
+
+ {/* Name */}
+
+ Name
+ updateGeschossDialog({ name: ev.target.value })}
+ autoFocus
+ onKeyDown={(ev) => {
+ if (ev.key === 'Enter') confirmGeschoss()
+ else if (ev.key === 'Escape') setGeschossDialog(null)
+ }}
+ style={{ width: '100%' }} />
+
+
+ {/* Hoehe + Schnitthoehe */}
+
+
+
+
+
+
+
+ >
+ )
+ })()}
>
)
}
diff --git a/src/components/GeschossSettingsDialog.jsx b/src/components/GeschossSettingsDialog.jsx
index eead6f1..fa2a986 100644
--- a/src/components/GeschossSettingsDialog.jsx
+++ b/src/components/GeschossSettingsDialog.jsx
@@ -39,12 +39,19 @@ export default function GeschossSettingsDialog({ geschoss, onSave, onClose, embe
const [draft, setDraft] = useState({ ...geschoss })
const set = (patch) => setDraft({ ...draft, ...patch })
- const isG = !!draft.isGeschoss
- const hoehe = draft.hoehe ?? 3.0
- const schnitt = draft.schnitthoehe ?? 1.0
- const hasClip = !!draft.hasClipping
- const okff = draft.okff ?? 0
- const clipZ = (okff + schnitt).toFixed(2)
+ const isG = !!draft.isGeschoss
+ const isSchnitt = draft.type === 'schnitt'
+ const hoehe = draft.hoehe ?? 3.0
+ const schnitt = draft.schnitthoehe ?? 1.0
+ const hasClip = !!draft.hasClipping
+ const okff = draft.okff ?? 0
+ const clipZ = (okff + schnitt).toFixed(2)
+ // Schnitt-Felder
+ const cutAtLine = draft.cutAtLine !== false // default true = Schnitt
+ const depthBack = draft.depthBack ?? 8.0
+ const heightMin = draft.heightMin ?? -1.0
+ const heightMax = draft.heightMax ?? 12.0
+ const dirSign = draft.dirSign ?? 1
// embedded=true: in einem Satelliten-Fenster gerendert — kein Backdrop,
// keine Width-Constraint, fuellt das ganze WebView.
@@ -103,14 +110,72 @@ export default function GeschossSettingsDialog({ geschoss, onSave, onClose, embe
/>
-
set({ isGeschoss: v })}
- hint={isG ? 'Höhe & Clipping verfügbar' : 'reines Zeichenblatt'}
- />
+ {/* Geschoss-Toggle nur fuer non-schnitt Eintraege — Schnitt-Type
+ ist exklusiv (kein Geschoss zugleich). */}
+ {!isSchnitt && (
+ set({ isGeschoss: v })}
+ hint={isG ? 'Höhe & Clipping verfügbar' : 'reines Zeichenblatt'}
+ />
+ )}
- {isG && (
+ {isSchnitt && (
+ <>
+
+
+ set({ cutAtLine: v })}
+ hint={cutAtLine
+ ? 'Schnitt: alles vor der Schnittlinie wird weggeschnitten'
+ : 'Ansicht: nur Tiefenbegrenzung hinten, kein Front-Cut'}
+ />
+
+
+ set({ depthBack: parseFloat(ev.target.value) || 8.0 })}
+ style={{ flex: 1, fontSize: 11, textAlign: 'right', minWidth: 0 }}
+ />
+
+
+
+
+ set({ heightMin: parseFloat(ev.target.value) })}
+ style={{ flex: 1, fontSize: 11, textAlign: 'right', minWidth: 0 }}
+ />
+
+
+ set({ heightMax: parseFloat(ev.target.value) })}
+ style={{ flex: 1, fontSize: 11, textAlign: 'right', minWidth: 0 }}
+ />
+
+
+
+
+
+
+
+ >
+ )}
+
+ {isG && !isSchnitt && (
<>
@@ -180,6 +245,13 @@ export default function GeschossSettingsDialog({ geschoss, onSave, onClose, embe
if (out.hoehe == null) out.hoehe = 3.0
if (out.schnitthoehe == null) out.schnitthoehe = 1.0
}
+ if (out.type === 'schnitt') {
+ if (out.depthBack == null) out.depthBack = 8.0
+ if (out.heightMin == null) out.heightMin = -1.0
+ if (out.heightMax == null) out.heightMax = 12.0
+ if (out.dirSign == null) out.dirSign = 1
+ if (out.cutAtLine == null) out.cutAtLine = true
+ }
onSave(out)
}}>Übernehmen
diff --git a/src/lib/rhinoBridge.js b/src/lib/rhinoBridge.js
index 9cc72ec..2466ea2 100644
--- a/src/lib/rhinoBridge.js
+++ b/src/lib/rhinoBridge.js
@@ -175,6 +175,16 @@ export function openElementeProperties() { send('OPEN_ELEMENTE_PROPERTIES', {})
export function setDarstellung(d) { send('SET_DARSTELLUNG', { darstellung: d || '' }) }
// Anordnen — 2D-Z-Stack via Rhino-DisplayOrder. dir: 'front'|'forward'|'backward'|'back'
export function arrangeSelection(dir) { send('ARRANGE', { dir }) }
+// Schnitt/Ansicht — interaktiver 2-Punkt-Pick im Rhino-Viewport. Erzeugt
+// eine neue Zeichnungsebene type=schnitt + 2D-Plan-Symbol + aktiviert sie.
+// opts: { cutAtLine: bool, depthBack: m, heightMin: m, heightMax: m, namePrefix }
+export function createSchnitt(opts = {}) {
+ send('CREATE_SCHNITT', {
+ cutAtLine: true, depthBack: 8.0, heightMin: -1.0, heightMax: 12.0,
+ ...opts,
+ })
+}
+export function deleteSchnitt(id) { send('DELETE_SCHNITT', { id }) }
export function saveOeffStyle(name, settings) {
send('SAVE_OEFF_STYLE', { name, settings })
}