51 lines
2.9 KiB
JavaScript
51 lines
2.9 KiB
JavaScript
import fs from 'node:fs';
|
|
import assert from 'node:assert/strict';
|
|
import { loadWasmProbe } from './wasm-probe-runtime.mjs';
|
|
|
|
let kernel;
|
|
const directory = `docs/current/ifc-source-roundtrip-diagnostics/${new Date().toISOString().replace(/[:.]/g,'-')}`;
|
|
fs.mkdirSync(directory, { recursive: true });
|
|
try {
|
|
({ kernel } = await loadWasmProbe('web/public/kernel', 'FreeCADWebBimRuntimeProbe'));
|
|
const fixture = fs.readFileSync('freecad-source/build-web/ifcopenshell-native/fixtures/ColumnPSetsOfSets.ifc');
|
|
const reply = JSON.parse(kernel.ccall('fc_web_bim_test_python', 'string', ['string'], [`
|
|
import FreeCAD as App, IfcOpenShellNative, json, base64
|
|
with open('/tmp/source.ifc','wb') as stream: stream.write(base64.b64decode('${fixture.toString('base64')}'))
|
|
d=App.newDocument('SourceRoundtrip')
|
|
IfcOpenShellNative.insert('/tmp/source.ifc',d.Name)
|
|
IfcOpenShellNative.exportDocument(d.Name,'/tmp/output.ifc')
|
|
result=json.dumps({'sourcePath':d.getObject('IfcSource').OriginalIFC,
|
|
'input':open('/tmp/source.ifc').read(),'output':open('/tmp/output.ifc').read()})
|
|
`]));
|
|
if (reply.ok === false) throw Error(reply.error);
|
|
fs.writeFileSync(`${directory}/source.ifc`, reply.input);
|
|
fs.writeFileSync(`${directory}/output.ifc`, reply.output);
|
|
const actual = JSON.parse(kernel.ccall('fc_web_bim_test_python', 'string', ['string'], [`
|
|
import FreeCAD as App, IfcOpenShellNative, json
|
|
d=App.getDocument('SourceRoundtrip')
|
|
r=App.newDocument('SourceRoundtripRead')
|
|
IfcOpenShellNative.insert('/tmp/output.ifc',r.Name)
|
|
def snapshot(doc):
|
|
return sorted([(o.IfcGlobalId,o.Shape.Volume,o.Shape.isValid(),len(o.Shape.Solids)) for o in doc.Objects if o.isDerivedFrom('Part::Feature')])
|
|
result=json.dumps({'source':snapshot(d),'restored':snapshot(r)})
|
|
`]));
|
|
console.log(JSON.stringify({ sourcePath: reply.sourcePath, inputLength: reply.input.length, outputLength: reply.output.length, directory, actual }));
|
|
if (actual.ok === false) throw Error(actual.error);
|
|
assert.ok(actual.source.length>0);
|
|
assert.equal(actual.source.length,actual.restored.length);
|
|
for(const [index,source] of actual.source.entries()) {
|
|
const restored=actual.restored[index];
|
|
assert.equal(restored[0],source[0],'IFC identity changed');
|
|
assert.ok(source[2]&&restored[2]&&source[3]>0&&restored[3]>0,'IFC roundtrip must preserve valid solids');
|
|
assert.equal(restored[3],source[3],'IFC solid count changed');
|
|
assert.ok(Number.isFinite(restored[1])&&Number.isFinite(source[1])&&Math.abs(restored[1]-source[1])<=1e-6,'IFC volume changed beyond 1e-6 mm^3');
|
|
}
|
|
fs.writeFileSync(`${directory}/result.json`,JSON.stringify({status:'passed',actual,volumeAbsoluteTolerance:1e-6},null,2)+'\n');
|
|
} catch(error) {
|
|
fs.writeFileSync(`${directory}/failure.json`,JSON.stringify({status:'failed',error:String(error.stack??error)},null,2)+'\n');
|
|
console.error(String(error));process.exitCode=1;
|
|
} finally {
|
|
kernel?.PThread?.terminateAllThreads?.();
|
|
}
|
|
process.exit(process.exitCode??0);
|