diff --git a/packages/abstract-3d/src/renderers/index.ts b/packages/abstract-3d/src/renderers/index.ts index 80f6c0d..d53525b 100644 --- a/packages/abstract-3d/src/renderers/index.ts +++ b/packages/abstract-3d/src/renderers/index.ts @@ -2,3 +2,4 @@ export * from "./dxf"; export * from "./svg"; export * from "./stl"; export * from "./react"; +export * from "./step"; diff --git a/packages/abstract-3d/src/renderers/step/index.ts b/packages/abstract-3d/src/renderers/step/index.ts new file mode 100644 index 0000000..84f1615 --- /dev/null +++ b/packages/abstract-3d/src/renderers/step/index.ts @@ -0,0 +1 @@ +export * from "./step"; diff --git a/packages/abstract-3d/src/renderers/step/step-encoding.ts b/packages/abstract-3d/src/renderers/step/step-encoding.ts new file mode 100644 index 0000000..50ff76c --- /dev/null +++ b/packages/abstract-3d/src/renderers/step/step-encoding.ts @@ -0,0 +1,29 @@ +import { Vec3 } from "../../abstract-3d"; + +export const CARTESIAN_POINT = (v: Vec3, cartRef: number): string => + `#${cartRef} = CARTESIAN_POINT('', (${v.x}, ${v.y}, ${v.z}));`; + +export const POLY_LOOP = ( + cartRef1: number, + cartRef2: number, + cartRef3: number, + cartRef4: number, + polyRef: number +): string => `#${polyRef} = POLY_LOOP('', (#${cartRef1}, #${cartRef2}, #${cartRef3}, #${cartRef4}));`; + +export const ADVANCED_FACE = (polyRef: number, advRef: number): string => + `#${advRef} = ADVANCED_FACE('', (#${polyRef}), .T.);`; + +export const CLOSED_SHELL = ( + advRef1: number, + advRef2: number, + advRef3: number, + advRef4: number, + advRef5: number, + advRef6: number, + closedRef: number +): string => + `#${closedRef} = CLOSED_SHELL('', (#${advRef1}, #${advRef2}, #${advRef3}, #${advRef4}, #${advRef5}, #${advRef6}));`; + +export const MANIFOLD_SOLID_BREP = (closedRef: number, maniRef: number): string => + `#${maniRef} = MANIFOLD_SOLID_BREP('', #${closedRef});`; diff --git a/packages/abstract-3d/src/renderers/step/step-geometries/step-box.ts b/packages/abstract-3d/src/renderers/step/step-geometries/step-box.ts new file mode 100644 index 0000000..e74654f --- /dev/null +++ b/packages/abstract-3d/src/renderers/step/step-geometries/step-box.ts @@ -0,0 +1,50 @@ +import * as A3D from "../../../abstract-3d"; +import { ADVANCED_FACE, CARTESIAN_POINT, CLOSED_SHELL, MANIFOLD_SOLID_BREP, POLY_LOOP } from "../step-encoding"; + +export function stepBox( + b: A3D.Box, + _m: A3D.Material, + parentPos: A3D.Vec3, + parentRot: A3D.Vec3, + refIdx: number +): readonly [string, number] { + const half = A3D.vec3Scale(b.size, 0.5); + const pos = A3D.vec3TransRot(b.pos, parentPos, parentRot); + const rot = A3D.vec3RotCombine(parentRot, b.rot ?? A3D.vec3Zero); + const vec3tr = (x: number, y: number, z: number): A3D.Vec3 => A3D.vec3TransRot(A3D.vec3(x, y, z), pos, rot); + + const v1 = vec3tr(-half.x, -half.y, -half.z); + const v2 = vec3tr(half.x, -half.y, -half.z); + const v3 = vec3tr(half.x, half.y, -half.z); + const v4 = vec3tr(-half.x, half.y, -half.z); + const v5 = vec3tr(-half.x, -half.y, half.z); + const v6 = vec3tr(half.x, -half.y, half.z); + const v7 = vec3tr(half.x, half.y, half.z); + const v8 = vec3tr(-half.x, half.y, half.z); + + const step = ` +${CARTESIAN_POINT(v1, refIdx + 1)} +${CARTESIAN_POINT(v2, refIdx + 2)} +${CARTESIAN_POINT(v3, refIdx + 3)} +${CARTESIAN_POINT(v4, refIdx + 4)} +${CARTESIAN_POINT(v5, refIdx + 5)} +${CARTESIAN_POINT(v6, refIdx + 6)} +${CARTESIAN_POINT(v7, refIdx + 7)} +${CARTESIAN_POINT(v8, refIdx + 8)} +${POLY_LOOP(refIdx + 1, refIdx + 2, refIdx + 3, refIdx + 4, refIdx + 9)} +${POLY_LOOP(refIdx + 5, refIdx + 6, refIdx + 7, refIdx + 8, refIdx + 10)} +${POLY_LOOP(refIdx + 1, refIdx + 5, refIdx + 8, refIdx + 4, refIdx + 11)} +${POLY_LOOP(refIdx + 2, refIdx + 6, refIdx + 7, refIdx + 3, refIdx + 12)} +${POLY_LOOP(refIdx + 1, refIdx + 2, refIdx + 6, refIdx + 5, refIdx + 13)} +${POLY_LOOP(refIdx + 4, refIdx + 3, refIdx + 7, refIdx + 8, refIdx + 14)} +${ADVANCED_FACE(refIdx + 9, refIdx + 15)} +${ADVANCED_FACE(refIdx + 10, refIdx + 16)} +${ADVANCED_FACE(refIdx + 11, refIdx + 17)} +${ADVANCED_FACE(refIdx + 12, refIdx + 18)} +${ADVANCED_FACE(refIdx + 13, refIdx + 19)} +${ADVANCED_FACE(refIdx + 14, refIdx + 20)} +${CLOSED_SHELL(refIdx + 15, refIdx + 16, refIdx + 17, refIdx + 18, refIdx + 19, refIdx + 20, refIdx + 21)} +${MANIFOLD_SOLID_BREP(refIdx + 21, refIdx + 22)}`; + + return [step, 22]; +} diff --git a/packages/abstract-3d/src/renderers/step/step.ts b/packages/abstract-3d/src/renderers/step/step.ts new file mode 100644 index 0000000..3790b66 --- /dev/null +++ b/packages/abstract-3d/src/renderers/step/step.ts @@ -0,0 +1,55 @@ +import * as A3D from "../../abstract-3d"; +import { stepBox } from "./step-geometries/step-box"; + +export const toStep = (scene: A3D.Scene): string => { + let step = ""; + let nbrRefs = 0; + + for (const g of scene.groups ?? []) { + const [newStep, newNbrRefs] = stepGroup( + g, + scene.center_deprecated ?? A3D.vec3Zero, + scene.rotation_deprecated ?? A3D.vec3Zero, + nbrRefs + ); + step += newStep; + nbrRefs += newNbrRefs; + } + + return `ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('Aircalc'), '1'); +FILE_NAME('aircalc.stp', '2024-09-09T12:00:00', (''), (''), 'Author', '', ''); +FILE_SCHEMA(('AP214')); +ENDSEC; +DATA;${step} +ENDSEC; +END-ISO-10303-21;`; +}; + +function stepGroup(g: A3D.Group, parentPos: A3D.Vec3, parentRot: A3D.Vec3, refIdx: number): [string, number] { + let step = ""; + let nbrRefs = 0; + const pos = A3D.vec3TransRot(g.pos, parentPos, parentRot); + const rot = A3D.vec3RotCombine(parentRot, g.rot ?? A3D.vec3Zero); + for (const m of g.meshes ?? []) { + switch (m.geometry.type) { + case "Box": { + const [newStep, newNbrRefs] = stepBox(m.geometry, m.material, pos, rot, refIdx + nbrRefs); + step += newStep; + nbrRefs += newNbrRefs; + break; + } + default: + break; + } + } + + for (const c of g.groups ?? []) { + const [newStep, newNbrRefs] = stepGroup(c, pos, rot, refIdx + nbrRefs); + step += newStep; + nbrRefs += newNbrRefs; + } + + return [step, nbrRefs]; +} diff --git a/packages/abstract-visuals-example/src/app/abstract-3d-example.tsx b/packages/abstract-visuals-example/src/app/abstract-3d-example.tsx index 9529438..a6a221e 100644 --- a/packages/abstract-visuals-example/src/app/abstract-3d-example.tsx +++ b/packages/abstract-visuals-example/src/app/abstract-3d-example.tsx @@ -14,6 +14,9 @@ export function Abstract3DExample(): React.ReactNode { +