diff --git a/packages/iges/src/api.ts b/packages/iges/src/api.ts index 21da7a4305..470b28bb69 100644 --- a/packages/iges/src/api.ts +++ b/packages/iges/src/api.ts @@ -13,7 +13,7 @@ export enum Unit { UIN // microinches } -export enum Type { +export const enum Type { INT, FLOAT, STR, @@ -22,14 +22,14 @@ export enum Type { POINTER } -export enum SpecVersion { +export const enum SpecVersion { IGES50 = 8, IGES51 = 9, IGES52 = 10, IGES53 = 11 } -export enum DraftVersion { +export const enum DraftVersion { NONE = 0, ISO, AFNOR, @@ -40,7 +40,9 @@ export enum DraftVersion { JIS } -export enum LineFontPattern { +export type SectionType = "G" | "S" | "D" | "P" | "T"; + +export const enum LineFontPattern { NONE = 0, SOLID, DASHED, @@ -49,7 +51,7 @@ export enum LineFontPattern { DOTTED } -export enum Color { +export const enum Color { NONE = 0, BLACK, RED, @@ -61,19 +63,19 @@ export enum Color { WHITE } -export enum StatusBlank { +export const enum StatusBlank { VISIBLE = 0, BLANK } -export enum StatusSubord { +export const enum StatusSubord { INDEPENDENT = 0, PHYSICAL, LOGICAL, BOTH } -export enum StatusUsage { +export const enum StatusUsage { GEOMETRY = 0, ANNOTATION, DEFINITION, @@ -83,24 +85,35 @@ export enum StatusUsage { CONSTRUCTIVE } -export enum StatusHierarchy { +export const enum StatusHierarchy { GLOBAL_TOP_DOWN = 0, GLOBAL_DEFER, USE_PROP } -export enum PolylineMode { +export const enum PolylineMode { OPEN, CLOSED, FILLED } +export const enum EntityType { + POLYLINE = 106, + LINE = 110, + POINT = 116 +} + +export interface EntityOpts { + color: Color; + pattern: LineFontPattern; +} + // spec page 24 (53) export interface DictEntry { type: number; param: number; struct: number; - pattern: number; + pattern: LineFontPattern; level: number; view: number; matrix: number; @@ -108,7 +121,7 @@ export interface DictEntry { status: Partial; index: number; lineWeight: number; - color: number; + color: Color; lineCount: number; form: number; label: string; diff --git a/packages/iges/src/index.ts b/packages/iges/src/index.ts index efd9874c46..8d8072cc1d 100644 --- a/packages/iges/src/index.ts +++ b/packages/iges/src/index.ts @@ -1,5 +1,10 @@ import { defmulti } from "@thi.ng/defmulti"; -import { float, padLeft, padRight } from "@thi.ng/strings"; +import { + float, + hstr, + padLeft, + padRight +} from "@thi.ng/strings"; import { comp, map, @@ -14,28 +19,33 @@ import { import { DEFAULT_GLOBALS, DictEntry, + EntityOpts, EntityStatus, + EntityType, GlobalParams, IGESDocument, Param, PolylineMode, + SectionType, Type, Unit } from "./api"; +// https://wiki.eclipse.org/IGES_file_Specification +// http://paulbourke.net/dataformats/iges/IGES.pdf + const LINEWIDTH_GLOBALS = 72; const LINEWIDTH_PARAMS = 64; const $Z2 = padLeft(2, "0"); const $Z7 = padLeft(7, "0"); const $F8 = padLeft(8, " "); -const $STR = (x: any) => - x != null ? ((x = x.toString()), `${x.length}H${x}`) : ""; + const $SEQ = padLeft(7, " "); const $BODY = padRight(72, " "); const $PBODY = padRight(64, " "); const $DATE = (d: Date) => - $STR( + hstr( [ d.getUTCFullYear(), $Z2(d.getUTCMonth() + 1), @@ -55,9 +65,10 @@ export const newDocument = ( const $FF = float(globals.precision); const $PARAM = defmulti((x) => x[1]); $PARAM.add(Type.INT, (x) => x[0].toString()); + $PARAM.add(Type.POINTER, (x) => x[0].toString()); $PARAM.add(Type.FLOAT, (x) => $FF(x[0])); $PARAM.add(Type.STR, (x) => x[0]); - $PARAM.add(Type.HSTR, (x) => $STR(x[0])); + $PARAM.add(Type.HSTR, (x) => hstr(x[0])); $PARAM.add(Type.DATE, (x) => $DATE(x[0])); return { @@ -85,7 +96,7 @@ export const serialize = (doc: IGESDocument) => formatTerminate(doc) ].join("\n"); -const formatLine = (body: string, type: string, i: number) => +const formatLine = (body: string, type: SectionType, i: number) => `${$BODY(body)}${type}${$SEQ(i + 1)}`; const formatStart = (doc: IGESDocument) => { @@ -207,49 +218,107 @@ const formatParams = ( }); }; -// type table: page 38 (67) - -// sec 4.7, page 77 (106) -export const addPolyline2d = ( +const addEntity = ( doc: IGESDocument, - pts: ArrayLike[], - form = PolylineMode.OPEN + type: EntityType, + entry: Partial, + params: Param[], + opts: Partial = {} ) => { const did = doc.offsets.D; const pid = doc.offsets.P; - const params = formatParams( + const fparams = formatParams( doc, - [ - [106, Type.INT], - [1, Type.INT], - [pts.length + (form === PolylineMode.CLOSED ? 1 : 0), Type.INT], - [0, Type.FLOAT], - ...mapcat( - ([x, y]) => [[x, Type.FLOAT], [y, Type.FLOAT]], - form === PolylineMode.CLOSED - ? wrap(pts, 1, false, true) - : pts - ) - ], + [[type, Type.INT]].concat(params), formatParam(did, pid) ); - doc.offsets.P += params.length; + doc.offsets.P += fparams.length; doc.offsets.D += 2; doc.dict.push( ...formatDictEntry({ - type: 106, - form: form === PolylineMode.FILLED ? 63 : 11, + type, + pattern: opts.pattern || 0, + color: opts.color || 0, param: pid, index: did, - lineCount: params.length + lineCount: fparams.length, + ...entry }) ); - doc.param.push(...params); + doc.param.push(...fparams); return doc; }; -export const addPolygon2d = (doc: IGESDocument, pts: ArrayLike[]) => - addPolyline2d(doc, pts, PolylineMode.FILLED); +export const addPolyline = ( + doc: IGESDocument, + pts: ArrayLike[], + form = PolylineMode.OPEN, + opts?: Partial +) => + addEntity( + doc, + EntityType.POLYLINE, + { + form: form === PolylineMode.FILLED ? 63 : 11 + }, + [ + [pts[0].length == 2 ? 1 : 2, Type.INT], + [pts.length + (form === PolylineMode.CLOSED ? 1 : 0), Type.INT], + [0, Type.FLOAT], + ...mapcat( + (p) => map((x) => [x, Type.FLOAT], p), + form === PolylineMode.CLOSED + ? wrap(pts, 1, false, true) + : pts + ) + ], + opts + ); + +export const addPolygon = ( + doc: IGESDocument, + pts: ArrayLike[], + opts?: Partial +) => addPolyline(doc, pts, PolylineMode.FILLED, opts); + +export const addPoint = ( + doc: IGESDocument, + p: ArrayLike, + opts?: Partial +) => + addEntity( + doc, + EntityType.POINT, + null, + [ + [p[0], Type.FLOAT], + [p[1], Type.FLOAT], + [p[2] || 0, Type.FLOAT], + [0, Type.POINTER] + ], + opts + ); + +export const addLine = ( + doc: IGESDocument, + a: ArrayLike, + b: ArrayLike, + opts?: Partial +) => + addEntity( + doc, + EntityType.LINE, + null, + [ + [a[0], Type.FLOAT], + [a[1], Type.FLOAT], + [a[2] || 0, Type.FLOAT], + [b[0], Type.FLOAT], + [b[1], Type.FLOAT], + [b[2] || 0, Type.FLOAT] + ], + opts + ); // sec 4.23, page 123 (type 126) // export const addNurbsCurve2d = (doc: IGESDocument, degree: number, pts: number[][], closed = false) => { diff --git a/packages/iges/test/index.ts b/packages/iges/test/index.ts index b8977f1f15..243d941d87 100644 --- a/packages/iges/test/index.ts +++ b/packages/iges/test/index.ts @@ -9,14 +9,12 @@ describe("iges", () => { author: "toxi", authorOrg: "thi.ng", created: new Date(123456789), - modified: new Date(123456789), + modified: new Date(123456789) }); - doc.start = [ - "Example file for @thi.ng/iges", - ]; + doc.start = ["Example file for @thi.ng/iges"]; - iges.addPolyline2d(doc, [ + iges.addPolyline(doc, [ [0, 0], [0, 100], [50, 150], diff --git a/packages/iges/tsconfig.json b/packages/iges/tsconfig.json index bcf03f18b4..b445790069 100644 --- a/packages/iges/tsconfig.json +++ b/packages/iges/tsconfig.json @@ -3,9 +3,8 @@ "compilerOptions": { "outDir": ".", "module": "es6", - "target": "es6" + "target": "es6", + "preserveConstEnums": false }, - "include": [ - "./src/**/*.ts" - ] -} \ No newline at end of file + "include": ["./src/**/*.ts"] +}