export interface Section2DOverlayCapStyle { fillColor: [number, number, number, number]; strokeColor: [number, number, number, number]; patternId: number; spacingPx: number; angleRad: number; widthPx: number; secondaryAngleRad: number; } export interface Section2DOverlayOptions { axis: 'down' | 'front' | 'side'; position: number; bounds: { min: { x: number; y: number; z: number; }; max: { x: number; y: number; z: number; }; }; viewProj: Float32Array; flipped?: boolean; min?: number; max?: number; /** * If provided, the 2D overlay's polygon fills render as the 3D section * cap with this screen-space hatch style. If omitted or `showFills` is * false, the filled hatch is skipped. */ capStyle?: Section2DOverlayCapStyle; showFills?: boolean; /** * Whether to draw the polygon outline + hidden lines on the cap. Users * can turn surfaces and outlines on/off independently. Defaults to true * so existing call sites keep showing outlines. */ showOutlines?: boolean; } export interface CutPolygon2D { polygon: { outer: Array<{ x: number; y: number; }>; holes: Array>; }; ifcType: string; expressId: number; /** Optional per-polygon RGBA (0–1). When present, this cap polygon fills with * this colour (an `IfcMaterialLayerSet` wall/slab layer, or a frame+glass * window part) instead of the uniform cap fill. Absent ⇒ uniform cap style + * per-`ifcType` fallback, unchanged. */ color?: [number, number, number, number]; } export interface DrawingLine2D { line: { start: { x: number; y: number; }; end: { x: number; y: number; }; }; category: string; /** * Express ID of the entity that authored this segment. Optional — only the * IfcAnnotation / IfcGridAxis symbolic overlay sets it (so per-entity hide * can drop an annotation's curves without a mesh). The section-cut and * drawing-2d cutters leave it undefined. */ ownerId?: number; } export declare class Section2DOverlayRenderer { private device; private fillPipeline; private linePipeline; private bindGroupLayout; private uniformBuffer; private bindGroup; private format; private sampleCount; private initialized; private overlayLineColor; private fillVertexBuffer; private fillIndexBuffer; private fillIndexCount; private lineVertexBuffer; private lineVertexCount; private annotationLineVertexBuffer; private annotationLineVertexCount; private alignmentLineVertexBuffer; private alignmentLineVertexCount; private gridLineVertexBuffer; private gridLineVertexCount; private clashBoxLineVertexBuffer; private clashBoxLineVertexCount; private clashBoxLineColor; constructor(device: GPUDevice, format: GPUTextureFormat, sampleCount?: number); private init; /** * Transform 2D coordinates to 3D coordinates on the section plane. * * Cardinal axis path (legacy, unchanged): * - Y axis (down): 2D (x, y) = 3D (x, z) - looking down at XZ plane * - Z axis (front): 2D (x, y) = 3D (x, y) - looking along Z at XY plane * - X axis (side): 2D (x, y) = 3D (z, y) - looking along X at ZY plane * When flipped, the 2D x coordinate is negated. * * Custom-plane path (issue #243): when `customPlane` is supplied, the * 3D point is `origin + tangent*x2d + bitangent*y2d`. The same basis * is used by `SectionCutter` to project triangle-plane intersections * to 2D, so the round-trip is exact and the cap polygons land * precisely on the user's tilted plane. */ private transform2Dto3D; /** * Upload 2D drawing data to GPU buffers. * * For cardinal-axis section planes, pass `axis` + `planePosition` (+ * `flipped`) and 2D points are lifted to 3D via the cardinal-axis * coordinate swap. For arbitrary face-picked planes (issue #243), * pass `customPlane = { origin, tangent, bitangent }` instead — the * 2D points are then lifted via `origin + tangent·x + bitangent·y`, * matching the basis the upstream `SectionCutter` used to project * the cut polygons in the first place. Without that the cap silhouette * would land off the actual cutting plane (the bug PR #581 hid by * suppressing the cap entirely for non-cardinal planes). */ uploadDrawing(polygons: CutPolygon2D[], lines: DrawingLine2D[], axis: 'down' | 'front' | 'side', planePosition: number, flipped?: boolean, customPlane?: { origin: [number, number, number]; tangent: [number, number, number]; bitangent: [number, number, number]; }): void; /** * Clear uploaded geometry */ clearGeometry(): void; /** * Set the colour of the overlay lines (annotation / alignment / grid) and the * section-cut outline, which share the line pipeline. RGBA components are in * 0..1. Defaults to opaque black; set e.g. a light colour to keep the lines * legible on a dark canvas. Takes effect on the next draw. */ setOverlayLineColor(color: readonly [number, number, number, number]): void; /** * Upload a flat Float32Array of 3D line-list vertices for the standalone * annotation overlay. Each segment is `[x1, y1, z1, x2, y2, z2]` in world * space. The buffer is independent of the section cut's line buffer and * is drawn regardless of `sectionPlane.enabled`. * * Pass an empty array (or omit) to clear. */ uploadAnnotationLines3D(vertices: Float32Array): void; clearAnnotationLines3D(): void; hasAnnotationLines3D(): boolean; /** * Upload a flat Float32Array of 3D line-list vertices for the alignment * centerline overlay. Same format/pipeline as the annotation lines, kept in * a separate buffer so alignment visibility is independent. * Pass an empty array (or omit) to clear. */ uploadAlignmentLines3D(vertices: Float32Array): void; clearAlignmentLines3D(): void; hasAlignmentLines3D(): boolean; /** * Draw the standalone annotation line overlay. Uses the same line pipeline * as the section cut outlines (vertex format: 3 floats per vertex, line-list * topology) but reads from a separate vertex buffer. The pipeline's * `planeOffset` uniform is zeroed so vertices render at their authored * world position. */ drawAnnotationLines3D(pass: GPURenderPassEncoder, viewProj: Float32Array): void; /** * Draw the alignment centerline overlay. Identical pipeline/uniform setup as * `drawAnnotationLines3D`, reading from the separate alignment buffer. */ drawAlignmentLines3D(pass: GPURenderPassEncoder, viewProj: Float32Array): void; /** * Upload structural-grid (IfcGridAxis) segments as a flat * `[x,y,z, x,y,z, …]` line-list in world space (issue #967). Mirrors * `uploadAlignmentLines3D` with a separate buffer so grid visibility is * independent. Pass an empty array (or omit) to clear. */ uploadGridLines3D(vertices: Float32Array): void; clearGridLines3D(): void; hasGridLines3D(): boolean; /** * Draw the structural-grid overlay. Identical pipeline/uniform setup as * `drawAlignmentLines3D`, reading from the separate grid buffer. */ drawGridLines3D(pass: GPURenderPassEncoder, viewProj: Float32Array): void; /** Colour for the clash-overlap box (its own, not the shared overlay colour). */ setClashBoxLineColor(color: readonly [number, number, number, number]): void; /** * Upload the clash-overlap-box wireframe as a flat `[x,y,z, …]` line-list in * world space (12 AABB edges = 24 vertices). Separate buffer + colour from the * other overlays. Pass an empty array to clear. (#1277) */ uploadClashBoxLines3D(vertices: Float32Array): void; clearClashBoxLines3D(): void; hasClashBoxLines3D(): boolean; /** Draw the clash-overlap box in its own colour. Same line pipeline. (#1277) */ drawClashBoxLines3D(pass: GPURenderPassEncoder, viewProj: Float32Array): void; /** * Check if there is geometry to draw */ hasGeometry(): boolean; /** * Draw the 2D overlay on the section plane */ draw(pass: GPURenderPassEncoder, options: Section2DOverlayOptions): void; /** * Dispose of GPU resources */ dispose(): void; } //# sourceMappingURL=section-2d-overlay.d.ts.map