Save verified native IFC import and user validation evidence
Real IFC2X3/IFC4 import tested. Full BIM authoring/export remains out of scope; 349-second building import performance remains to optimize.
This commit is contained in:
@@ -83,6 +83,7 @@ export async function executeOpenDocument(router: WebModuleRouter, args: Record<
|
||||
}, value.activeDocument);
|
||||
if (scene.kind === "error") throw new Error(scene.error.message);
|
||||
if ((scene.result as DocumentViewResult).documentId !== value.activeDocument) throw new Error("Opened document scene identity mismatch");
|
||||
value.scene = scene.result as DocumentViewResult;
|
||||
window.dispatchEvent(new CustomEvent("freecad-document-view", { detail: { owner, documentId: value.activeDocument, value: scene.result } }));
|
||||
} catch (error) { value.sceneError = String(error); }
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { DocumentViewResult } from "./part-view-facade.js";
|
||||
export interface OpenFileEntry { filename: string; fileData: string; module?: string }
|
||||
export interface OpenResult {
|
||||
command: "Std_Open"; documentId: string; operation: "list" | "open"; activeDocument: string | null;
|
||||
@@ -7,6 +8,7 @@ export interface OpenResult {
|
||||
errors: Array<{ filename: string; message: string }>;
|
||||
storedFiles?: Array<{ key: string; filename: string }>;
|
||||
sceneError?: string;
|
||||
scene?: DocumentViewResult;
|
||||
}
|
||||
export function validOpenResult(value: unknown, documentId: string): value is OpenResult {
|
||||
const r = value as OpenResult | null;
|
||||
|
||||
@@ -13,10 +13,11 @@ type ViewResult = {
|
||||
annotations?: NativeAnnotation[];
|
||||
};
|
||||
|
||||
export function WebViewTask({ router, command, documentId, selection, onSelection, runtimeOwner, disabled = false }: {
|
||||
export function WebViewTask({ router, command, documentId, selection, onSelection, runtimeOwner, initialScene, disabled = false }: {
|
||||
router: WebModuleRouter; command: string; documentId: string; selection: Selection[];
|
||||
onSelection: (documentId: string, selection: Selection[]) => void;
|
||||
runtimeOwner?: ViewOwner; disabled?: boolean;
|
||||
initialScene?: ViewResult;
|
||||
}) {
|
||||
const host = useRef<HTMLDivElement>(null);
|
||||
const projection = useRef<number[]>([]);
|
||||
@@ -55,9 +56,9 @@ export function WebViewTask({ router, command, documentId, selection, onSelectio
|
||||
return () => window.removeEventListener("freecad-document-view", receive);
|
||||
}, [documentId, owner]);
|
||||
|
||||
useEffect(() => { current.current = `${owner}:${documentId}`; setValue(undefined); setError(""); projection.current = []; setDrag(undefined);
|
||||
useEffect(() => { current.current = `${owner}:${documentId}`; setValue(initialScene?.documentId === documentId ? initialScene : undefined); setError(""); projection.current = []; setDrag(undefined);
|
||||
return () => { current.current = ""; };
|
||||
}, [documentId, owner]);
|
||||
}, [documentId, owner, initialScene]);
|
||||
|
||||
async function execute(name: string, args: Record<string, unknown> = {}) {
|
||||
if (busy || disabled) return;
|
||||
@@ -78,8 +79,8 @@ export function WebViewTask({ router, command, documentId, selection, onSelectio
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (command === "Std_SceneInspector" && !disabled) void execute("Std_DrawStyle", { action: "read" });
|
||||
}, [command, documentId, owner, disabled]);
|
||||
if (command === "Std_SceneInspector" && !disabled && initialScene?.documentId !== documentId) void execute("Std_DrawStyle", { action: "read" });
|
||||
}, [command, documentId, owner, disabled, initialScene]);
|
||||
|
||||
useEffect(() => {
|
||||
const node = host.current;
|
||||
@@ -222,7 +223,8 @@ export function WebViewTask({ router, command, documentId, selection, onSelectio
|
||||
</>}
|
||||
</div>
|
||||
{error && <pre role="alert" style={{ whiteSpace: "pre-wrap", overflowWrap: "anywhere" }}>{error}</pre>}
|
||||
<div ref={host} style={{ position: "relative", width: "100%", height: 420, maxHeight: "65vh", touchAction: "none" }}
|
||||
<div ref={host} data-native-mesh-count={value?.meshes.length ?? 0}
|
||||
style={{ position: "relative", width: "100%", height: 420, maxHeight: "65vh", touchAction: "none" }}
|
||||
onPointerDown={event => {
|
||||
if (!isBox || busy || disabled || !value || event.button !== 0) return;
|
||||
const rect = event.currentTarget.getBoundingClientRect();
|
||||
|
||||
@@ -1155,6 +1155,16 @@ function App() {
|
||||
<style>{css}</style>
|
||||
{(module === "Web" || module === "Std") && command?.replace(/^(Web|Std):desktop:/, "") === "Std_Open" &&
|
||||
<WebOpenTask response={response} busy={busy} execute={values => { void run(undefined, values); }} />}
|
||||
{(module === "Web" || module === "Std") && command?.replace(/^(Web|Std):desktop:/, "") === "Std_Open"
|
||||
&& response?.kind === "result" && (() => {
|
||||
const batch = response.result as { owner?: "PartBox" | "DocumentProbe"; records?: Array<{ name?: string; result?: { activeDocument?: string; opened?: unknown[]; scene?: import("./part-view-facade.js").DocumentViewResult } }> };
|
||||
const opened = batch.records?.find(row => row.name === "Std_Open")?.result;
|
||||
return opened?.activeDocument && opened.opened?.length && WebViewTask ? <WebViewTask router={router}
|
||||
command="Std_SceneInspector" documentId={opened.activeDocument} runtimeOwner={batch.owner ?? "PartBox"}
|
||||
initialScene={opened.scene}
|
||||
disabled={busy} selection={documentSelection.selection}
|
||||
onSelection={(documentId, selection) => setDocumentSelection({ documentId, selection })} /> : null;
|
||||
})()}
|
||||
{module === "BIM" && command?.replace(/^BIM:desktop:/, "") === "BIM_Windows" &&
|
||||
<BimWindowsTask key={documentSelection.documentId} documentId={documentSelection.documentId}
|
||||
response={response} busy={busy} execute={values => { void run(undefined, values); }}
|
||||
|
||||
Reference in New Issue
Block a user