Merge: Schnittfunktion ausgebaut (Schnittlinie, Editieren im Schnitt, Tiefe)
- Befehl 'sectionline'/'viewline' (Aliase schnittlinie/ansichtslinie): zwei Klicks setzen die Schnitt-/Ansichtslinie, neue Ebene bei Bedarf - Schnittführungs-Symbol im Grundriss (Strichpunkt, Endmarken, Richtungs- pfeile, Label) + Pick-Band, Auswahl + Attribut-Sektion (Name, Richtung umkehren, Endpunkte, Tiefe, Löschen) - Editieren IM Schnitt: Cut-Polygone tragen die Quell-Element-Id (durch Schicht-Zerlegung/Terminierung/Dominanz propagiert) → Klick wählt das Bauteil, Panels editieren, Schnitt rechnet neu - Schnitt-Tiefe (DrawingLevel.depth): Ansichtskanten ferner Bauteile werden ausgeblendet (Owner-Distanz-Näherung, dokumentiert) # Conflicts: # src/model/types.ts
This commit is contained in:
@@ -197,6 +197,12 @@ export interface PlanSelection {
|
||||
* Element höherer Priorität (alle anderen gehen vor); sonst `null`.
|
||||
*/
|
||||
roofId: string | null;
|
||||
/**
|
||||
* ID der getroffenen Schnitt-/Ansichtslinie (DrawingLevel), wenn der Klick ihr
|
||||
* dünnes Pick-Band traf; sonst `null`. Höchste Priorität (das schmale Band liegt
|
||||
* über allem — ein Klick genau darauf meint die Linie).
|
||||
*/
|
||||
sectionLineId: string | null;
|
||||
/**
|
||||
* War beim Klick Shift gedrückt? Dann ERWEITERT der Aufrufer (App) die
|
||||
* Auswahl um das getroffene Element (bzw. schaltet es ab/zu), statt sie zu
|
||||
@@ -287,6 +293,11 @@ export interface PlanViewProps {
|
||||
selectedRoomIds?: string[];
|
||||
/** Aktuell ausgewählte Dach-IDs (von App); die Ansicht markiert die Traufe. */
|
||||
selectedRoofIds?: string[];
|
||||
/**
|
||||
* Aktuell ausgewählte Schnitt-/Ansichtslinien-IDs (DrawingLevel; von App). Die
|
||||
* Ansicht markiert das Pick-Band JEDER dieser Linien mit einer Akzentkontur.
|
||||
*/
|
||||
selectedSectionLineIds?: string[];
|
||||
/**
|
||||
* Aktuell ausgewählte IDs extrudierter Körper (truck-Integration; kontrolliert
|
||||
* von App). Die Ansicht markiert den Footprint-Umriss JEDES dieser Körper mit
|
||||
@@ -416,6 +427,7 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
|
||||
selectedStairIds,
|
||||
selectedRoomIds,
|
||||
selectedRoofIds,
|
||||
selectedSectionLineIds,
|
||||
selectedExtrudedSolidIds,
|
||||
selectedColumnIds,
|
||||
roomStamp,
|
||||
@@ -1007,6 +1019,20 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
|
||||
return null;
|
||||
};
|
||||
|
||||
// Getroffene Schnitt-/Ansichtslinie: ihr schmales, unsichtbares Pick-Band
|
||||
// (Polygon mit sectionLineId) per Punkt-in-Polygon.
|
||||
const pickSectionLine = (clientX: number, clientY: number): string | null => {
|
||||
const v = clientToView(clientX, clientY, view);
|
||||
const m = viewToModel(v.x, v.y);
|
||||
for (let i = plan.primitives.length - 1; i >= 0; i--) {
|
||||
const p = plan.primitives[i];
|
||||
if (p.kind === "polygon" && p.sectionLineId && pointInPolygon(m, p.pts)) {
|
||||
return p.sectionLineId;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// Getroffener extrudierter Körper (truck-Integration): der Footprint-Umriss
|
||||
// ist ein reiner Haarlinien-Umriss (fill:"none"), aber per Punkt-in-Polygon
|
||||
// trotzdem als FLÄCHE anklickbar (analog Raum, nicht nur auf der Linie).
|
||||
@@ -1518,6 +1544,28 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
|
||||
const hit = hitIndex !== null ? plan.primitives[hitIndex] : undefined;
|
||||
// Öffnung (Fenster/Tür) zuerst: ihr Symbol sitzt in der ausgesparten Lücke
|
||||
// bzw. schlägt über die Wand — ein Klick nahe am Symbol wählt die Öffnung.
|
||||
// Schnitt-/Ansichtslinie zuerst: ihr schmales Band liegt über allem, ein
|
||||
// Klick genau darauf meint die Linie (nicht die darunterliegende Wand) —
|
||||
// dann sofort melden (kein anderes Element konkurriert).
|
||||
const sectionLineId = pickSectionLine(e.clientX, e.clientY);
|
||||
if (sectionLineId) {
|
||||
onSelect({
|
||||
model: viewToModel(v.x, v.y),
|
||||
hitIndex,
|
||||
wallId: null,
|
||||
drawingId: null,
|
||||
ceilingId: null,
|
||||
openingId: null,
|
||||
stairId: null,
|
||||
roomId: null,
|
||||
extrudedSolidId: null,
|
||||
columnId: null,
|
||||
roofId: null,
|
||||
sectionLineId,
|
||||
shift: e.shiftKey,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const openingId = pickOpening(e.clientX, e.clientY);
|
||||
const wallId =
|
||||
openingId ? null : hit && hit.kind === "polygon" ? hit.wallId ?? null : null;
|
||||
@@ -1581,6 +1629,7 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
|
||||
extrudedSolidId,
|
||||
columnId,
|
||||
roofId,
|
||||
sectionLineId: null,
|
||||
shift: e.shiftKey,
|
||||
});
|
||||
}
|
||||
@@ -1780,6 +1829,20 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
|
||||
);
|
||||
}, [plan, selectedRoofIds]);
|
||||
|
||||
// Hervorhebung der selektierten Schnitt-/Ansichtslinie: das (unsichtbare)
|
||||
// Pick-Band (Polygon mit sectionLineId) mit Akzentkontur überzeichnen.
|
||||
const highlightSectionLinePolys = useMemo(() => {
|
||||
const ids =
|
||||
selectedSectionLineIds && selectedSectionLineIds.length
|
||||
? new Set(selectedSectionLineIds)
|
||||
: null;
|
||||
if (!ids) return [];
|
||||
return plan.primitives.filter(
|
||||
(p): p is Extract<Primitive, { kind: "polygon" }> =>
|
||||
p.kind === "polygon" && p.sectionLineId != null && ids.has(p.sectionLineId),
|
||||
);
|
||||
}, [plan, selectedSectionLineIds]);
|
||||
|
||||
// Hervorhebung der selektierten extrudierten Körper (truck-Integration): der
|
||||
// Footprint-Umriss (Polygon mit extrudedSolidId) mit Akzentkontur überzeichnen
|
||||
// — analog zur Raum-Auswahl.
|
||||
@@ -2024,6 +2087,18 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
|
||||
pointerEvents="none"
|
||||
/>
|
||||
))}
|
||||
{/* Auswahl-Hervorhebung der gewählten Schnitt-/Ansichtslinie (Pick-Band). */}
|
||||
{highlightSectionLinePolys.map((poly, i) => (
|
||||
<polygon
|
||||
key={`selsl-${i}`}
|
||||
className="plan-selected"
|
||||
points={poly.pts
|
||||
.map(toScreen)
|
||||
.map((s) => `${s.x},${s.y}`)
|
||||
.join(" ")}
|
||||
pointerEvents="none"
|
||||
/>
|
||||
))}
|
||||
{/* Auswahl-Hervorhebung der gewählten extrudierten Körper (truck-Integration). */}
|
||||
{highlightExtrudedSolidPolys.map((poly, i) => (
|
||||
<polygon
|
||||
|
||||
Reference in New Issue
Block a user