import React, { useEffect, useMemo, useState } from "react"; import type { FacadeResponse } from "./facade-envelope.js"; import { MeshGeometryView, type MeshGeometry } from "./mesh-geometry-view.js"; const fields: Record = { box: ["length", "width", "height"], cylinder: ["radius", "length", "edgeLength", "sampling"], cone: ["radius1", "radius2", "length", "edgeLength", "sampling"], sphere: ["radius", "sampling"], ellipsoid: ["radius1", "radius2", "sampling"], torus: ["radius1", "radius2", "sampling"], }; const labels: Record = { length: "Length", width: "Width", height: "Height", radius: "Radius", radius1: "Radius 1", radius2: "Radius 2", edgeLength: "Edge Length", sampling: "Sampling" }; interface Result { action: string; typeId: string; geometry?: MeshGeometry; document?: string; object?: string; file?: { name: string; base64: string } } export function MeshPrimitiveTask({ response, busy, execute, onCreated }: { response: FacadeResponse | null; busy: boolean; execute: (args: Record) => void; onCreated: (documentId: string, object: string) => void; }) { const [solid, setSolid] = useState("box"); const [values, setValues] = useState>({ length: 10, width: 10, height: 10, radius: 5, radius1: 10, radius2: 3, edgeLength: 1, sampling: 32 }); const [closed, setClosed] = useState(true); const [documentName, setDocumentName] = useState("MeshDesign"); const [newDocument, setNewDocument] = useState(true); const [result, setResult] = useState(); const [fileStatus, setFileStatus] = useState(""); const [saving, setSaving] = useState(false); useEffect(() => { if (response?.kind !== "result") return; const batch = response.result as { records?: Array<{ apiId: string; status: string; value?: Result }> }; const value = batch.records?.find(row => row.apiId === "Mesh:desktop:Mesh_BuildRegularSolid" && row.status === "exposed")?.value; if (!value) return; setResult(value); if (value.document) { setDocumentName(value.document); setNewDocument(false); if (value.object && value.action === "accept") onCreated(value.document, value.object); } }, [response]); const geometries = useMemo(() => result?.geometry ? [result.geometry] : [], [result]); const submit = (action: string) => { setResult(undefined); execute({ action, solid, ...Object.fromEntries(fields[solid].map(key => [key, values[key]])), closed, document: documentName, documentId: documentName, createDocument: newDocument, selection: [] }); }; const save = async () => { if (!result?.file) return; setSaving(true); setFileStatus(""); try { const root = await navigator.storage.getDirectory(); const directory = await root.getDirectoryHandle("Mesh", { create: true }); const name = `${crypto.randomUUID()}-${result.file.name}`; const handle = await directory.getFileHandle(name, { create: true }); const writer = await handle.createWritable(); try { await writer.write(Uint8Array.from(atob(result.file.base64), char => char.charCodeAt(0))); await writer.close(); } catch (error) { await writer.abort().catch(() => undefined); throw error; } const url = URL.createObjectURL(await handle.getFile()); const link = document.createElement("a"); link.href = url; link.download = result.file.name; link.click(); setTimeout(() => URL.revokeObjectURL(url), 1000); setFileStatus(`Mesh/${name}`); } catch (error) { setFileStatus(error instanceof Error ? error.message : String(error)); } finally { setSaving(false); } }; return
{ event.preventDefault(); submit("accept"); }}>
Regular Mesh {fields[solid].map(key => )} {["cylinder", "cone"].includes(solid) && }
{result?.object &&

{result.document} / {result.object} ({result.typeId})

} {geometries.length > 0 && } {result?.file && } {fileStatus &&

{fileStatus}

}
; }