@faicad/faijs 0.29.3 → 0.29.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/appearance.d.ts +138 -0
- package/dist/api/appearance.d.ts.map +1 -0
- package/dist/api/appearance.js +230 -0
- package/dist/api/appearance.js.map +1 -0
- package/dist/api/import-step.d.ts.map +1 -1
- package/dist/api/import-step.js +28 -0
- package/dist/api/import-step.js.map +1 -1
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/meta.d.ts +93 -0
- package/dist/api/meta.d.ts.map +1 -0
- package/dist/api/meta.js +99 -0
- package/dist/api/meta.js.map +1 -0
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +117 -2
- package/dist/api/primitives.js.map +1 -1
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +28 -3
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/engine/adapters/occt.js +1 -1
- package/dist/brep/engine/adapters/occt.js.map +1 -1
- package/dist/brep/export/export-model.d.ts +40 -0
- package/dist/brep/export/export-model.d.ts.map +1 -1
- package/dist/brep/export/export-model.js +268 -25
- package/dist/brep/export/export-model.js.map +1 -1
- package/dist/brep/export/step-meta-header.d.ts +102 -0
- package/dist/brep/export/step-meta-header.d.ts.map +1 -0
- package/dist/brep/export/step-meta-header.js +225 -0
- package/dist/brep/export/step-meta-header.js.map +1 -0
- package/dist/brep/export/step.d.ts +5 -1
- package/dist/brep/export/step.d.ts.map +1 -1
- package/dist/brep/export/step.js +11 -2
- package/dist/brep/export/step.js.map +1 -1
- package/dist/define-op.d.ts.map +1 -1
- package/dist/define-op.js +63 -1
- package/dist/define-op.js.map +1 -1
- package/dist/lang/metadata-extractor.d.ts.map +1 -1
- package/dist/lang/metadata-extractor.js +2 -21
- package/dist/lang/metadata-extractor.js.map +1 -1
- package/dist/lang/types.d.ts +5 -6
- package/dist/lang/types.d.ts.map +1 -1
- package/dist/lang/types.js.map +1 -1
- package/dist/mesh/io.d.ts +6 -0
- package/dist/mesh/io.d.ts.map +1 -1
- package/dist/mesh/io.js +25 -1
- package/dist/mesh/io.js.map +1 -1
- package/dist/mesh/primitives.d.ts.map +1 -1
- package/dist/mesh/primitives.js +41 -6
- package/dist/mesh/primitives.js.map +1 -1
- package/dist/mesh/threemf-loader.d.ts +23 -0
- package/dist/mesh/threemf-loader.d.ts.map +1 -1
- package/dist/mesh/threemf-loader.js +182 -8
- package/dist/mesh/threemf-loader.js.map +1 -1
- package/dist/mesh/types.d.ts +38 -0
- package/dist/mesh/types.d.ts.map +1 -1
- package/dist/mesh/types.js.map +1 -1
- package/dist/occt-kernel/highLevelApi.d.ts +4 -1
- package/dist/occt-kernel/highLevelApi.d.ts.map +1 -1
- package/dist/occt-kernel/highLevelApi.js +4 -2
- package/dist/occt-kernel/highLevelApi.js.map +1 -1
- package/dist/occt-kernel/occt-primitives.js +1 -1
- package/dist/occt-kernel/occt-primitives.js.map +1 -1
- package/dist/occt-kernel/occtKernel.d.ts +1 -1
- package/dist/occt-kernel/occtKernel.js +1 -1
- package/dist/occt-kernel/occtKernel.js.map +1 -1
- package/dist/occt-kernel/stepMetaParser.d.ts +44 -0
- package/dist/occt-kernel/stepMetaParser.d.ts.map +1 -0
- package/dist/occt-kernel/stepMetaParser.js +166 -0
- package/dist/occt-kernel/stepMetaParser.js.map +1 -0
- package/dist/shape.d.ts +11 -3
- package/dist/shape.d.ts.map +1 -1
- package/dist/shape.js +4 -2
- package/dist/shape.js.map +1 -1
- package/dist/step/stepMetaParser.d.ts +55 -0
- package/dist/step/stepMetaParser.d.ts.map +1 -0
- package/dist/step/stepMetaParser.js +177 -0
- package/dist/step/stepMetaParser.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* STEP 元数据解析器 — 从 STEP (P21) 文本头部与 PRODUCT 层提取
|
|
3
|
+
* FileMeta(文件级)与 ShapeMeta(零件级描述字/料号)。
|
|
4
|
+
*
|
|
5
|
+
* 与 stepColorParser 同一原则:纯文本扫描,不依赖 OCCT 内核(XCAF label 层
|
|
6
|
+
* 是否暴露 description/属性不确定,见设计文档 2026-10-05-meta §6.3 风险 2)。
|
|
7
|
+
*
|
|
8
|
+
* 读取面映射(§3.3):
|
|
9
|
+
* - HEADER FILE_NAME(name,time_stamp,author,organization,preprocessor,originator)
|
|
10
|
+
* → title / creationDate / author / organization / application / designer。
|
|
11
|
+
* - HEADER FILE_DESCRIPTION(...) → description(逗号拼接,去首尾引号)。
|
|
12
|
+
* - DATA PRODUCT(name,description,frame)(第一个、leaf 使用的)→ 零件 description。
|
|
13
|
+
* name 已由 OCCT label 提供(不在本解析器处理)。
|
|
14
|
+
* - PRODUCT → PRODUCT_DEFINITION_FORMATION/WITH_SPECIFIED_SOURCE-关联的料号通道:
|
|
15
|
+
* PART_NUMBER_PROPERTY/IDENTIFICATION 命名在 §3.3 表里列出的 PART 层通道(P4
|
|
16
|
+
* 标 "IDENTIFICATION 内核支持" 待实测),这里尽量从 PRODUCT_DEFINITION 挂的
|
|
17
|
+
* UDA(GENERAL_PROPERTY + PROPERTY_DEFINITION)捞自定义属性。
|
|
18
|
+
*
|
|
19
|
+
* 所有扫描都容错:找不到就不给对应字段,绝不让解析器抛(信息性收益)。
|
|
20
|
+
*/
|
|
21
|
+
/** Header 级人物贡献字段(FILE_NAME 组内的三四五参数)。 */
|
|
22
|
+
export interface StepFileMeta {
|
|
23
|
+
title?: string;
|
|
24
|
+
creationDate?: string;
|
|
25
|
+
designer?: string;
|
|
26
|
+
author?: string;
|
|
27
|
+
organization?: string;
|
|
28
|
+
application?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
/** 自定义 FILE_DESCRIPTION/FILE_NAME 之外的 vendor 属性(metadata 笼)。 */
|
|
31
|
+
metadata?: Record<string, string>;
|
|
32
|
+
}
|
|
33
|
+
/** STEP 伙伴级 P21 解析出的轻量属性。 */
|
|
34
|
+
export interface StepPartMeta {
|
|
35
|
+
/** 产品描述(PRODUCT( ..., description, id ))。空串/缺省不设。 */
|
|
36
|
+
description?: string;
|
|
37
|
+
/** 自定义属性:`PROPERTY_DEFINITION(...)` + `GENERAL_PROPERTY('name', value, ...)`。 */
|
|
38
|
+
metadata?: Record<string, string>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Header 段整块(FILE_NAME / FILE_DESCRIPTION)→ `StepFileMeta`。
|
|
42
|
+
*
|
|
43
|
+
* @param text STEP 全文(ISO-10303-21)。
|
|
44
|
+
* @returns 解析出的文件级元数据;无 header 时返回空对象。
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseStepHeaderMeta(text: string): StepFileMeta;
|
|
47
|
+
/**
|
|
48
|
+
* 伙伴层 `PRODUCT` 描述 + 根自定义属性(UDA,`GENERAL_PROPERTY`)解析
|
|
49
|
+
* (简化:description 只取第一个 `PRODUCT`)。
|
|
50
|
+
*
|
|
51
|
+
* @param text STEP 全文(ISO-10303-21)。
|
|
52
|
+
* @returns 解析出的部分级元数据(`description`/`metadata`)。
|
|
53
|
+
*/
|
|
54
|
+
export declare function parseStepPartMeta(text: string): StepPartMeta;
|
|
55
|
+
//# sourceMappingURL=stepMetaParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepMetaParser.d.ts","sourceRoot":"","sources":["../../src/step/stepMetaParser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,0CAA0C;AAC1C,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED,6BAA6B;AAC7B,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AA2DD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CA+C9D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAyB5D"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* STEP 元数据解析器 — 从 STEP (P21) 文本头部与 PRODUCT 层提取
|
|
3
|
+
* FileMeta(文件级)与 ShapeMeta(零件级描述字/料号)。
|
|
4
|
+
*
|
|
5
|
+
* 与 stepColorParser 同一原则:纯文本扫描,不依赖 OCCT 内核(XCAF label 层
|
|
6
|
+
* 是否暴露 description/属性不确定,见设计文档 2026-10-05-meta §6.3 风险 2)。
|
|
7
|
+
*
|
|
8
|
+
* 读取面映射(§3.3):
|
|
9
|
+
* - HEADER FILE_NAME(name,time_stamp,author,organization,preprocessor,originator)
|
|
10
|
+
* → title / creationDate / author / organization / application / designer。
|
|
11
|
+
* - HEADER FILE_DESCRIPTION(...) → description(逗号拼接,去首尾引号)。
|
|
12
|
+
* - DATA PRODUCT(name,description,frame)(第一个、leaf 使用的)→ 零件 description。
|
|
13
|
+
* name 已由 OCCT label 提供(不在本解析器处理)。
|
|
14
|
+
* - PRODUCT → PRODUCT_DEFINITION_FORMATION/WITH_SPECIFIED_SOURCE-关联的料号通道:
|
|
15
|
+
* PART_NUMBER_PROPERTY/IDENTIFICATION 命名在 §3.3 表里列出的 PART 层通道(P4
|
|
16
|
+
* 标 "IDENTIFICATION 内核支持" 待实测),这里尽量从 PRODUCT_DEFINITION 挂的
|
|
17
|
+
* UDA(GENERAL_PROPERTY + PROPERTY_DEFINITION)捞自定义属性。
|
|
18
|
+
*
|
|
19
|
+
* 所有扫描都容错:找不到就不给对应字段,绝不让解析器抛(信息性收益)。
|
|
20
|
+
*/
|
|
21
|
+
/** 剥离一层引号(STEP 字符串形如 `'abc'`),出双引号化转义;去末尾换行。 */
|
|
22
|
+
function unquote(s) {
|
|
23
|
+
const t = s.trim();
|
|
24
|
+
if (t.startsWith("'") && t.endsWith("'"))
|
|
25
|
+
return t.slice(1, -1);
|
|
26
|
+
return t;
|
|
27
|
+
}
|
|
28
|
+
/** 任一 `HEADER`/`DATA` 段中的实体文本(多行),从 header 段中取整行。 */
|
|
29
|
+
function headerLines(text) {
|
|
30
|
+
const m = /HEADER;\n([\s\S]*?)\nENDSEC;/.exec(text);
|
|
31
|
+
return m ? m[1] : '';
|
|
32
|
+
}
|
|
33
|
+
/** `TYPE(...)` 实体块捕获:从开括号起做括号配平扫描到闭合(容错 LIST/嵌套)。 */
|
|
34
|
+
function entityBlock(text, type) {
|
|
35
|
+
const re = new RegExp(`${type}\\s*\\(`, 'g');
|
|
36
|
+
let m;
|
|
37
|
+
while ((m = re.exec(text)) !== null) {
|
|
38
|
+
let depth = 0;
|
|
39
|
+
let inQuote = false;
|
|
40
|
+
let i = m.index + m[0].length - 1; // 停在开括号
|
|
41
|
+
for (; i < text.length; i++) {
|
|
42
|
+
const c = text[i];
|
|
43
|
+
if (c === "'")
|
|
44
|
+
inQuote = !inQuote;
|
|
45
|
+
if (inQuote)
|
|
46
|
+
continue;
|
|
47
|
+
if (c === '(')
|
|
48
|
+
depth++;
|
|
49
|
+
else if (c === ')') {
|
|
50
|
+
depth--;
|
|
51
|
+
if (depth === 0)
|
|
52
|
+
return text.slice(m.index, i + 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
/** 逗号分隔的顶层简单参数(忽略嵌套括号内容仍按逗号简单切——够用即可)。 */
|
|
59
|
+
function splitTopLevel(body) {
|
|
60
|
+
// 剥离外层括号后,按未被引号包裹的逗号切分(不处理嵌套括号——STEP 伙伴级
|
|
61
|
+
// FILE_NAME/FILE_DESCRIPTION 参数都是简单标量/字符串,不涉及深层嵌套)。
|
|
62
|
+
const s = body.slice(body.indexOf('(') + 1, body.lastIndexOf(')'));
|
|
63
|
+
const parts = [];
|
|
64
|
+
let cur = '';
|
|
65
|
+
let inQuote = false;
|
|
66
|
+
for (let i = 0; i < s.length; i++) {
|
|
67
|
+
const c = s[i];
|
|
68
|
+
if (c === "'")
|
|
69
|
+
inQuote = !inQuote;
|
|
70
|
+
if (c === ',' && !inQuote) {
|
|
71
|
+
parts.push(cur);
|
|
72
|
+
cur = '';
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
cur += c;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
parts.push(cur);
|
|
79
|
+
return parts.map((p) => p.trim());
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Header 段整块(FILE_NAME / FILE_DESCRIPTION)→ `StepFileMeta`。
|
|
83
|
+
*
|
|
84
|
+
* @param text STEP 全文(ISO-10303-21)。
|
|
85
|
+
* @returns 解析出的文件级元数据;无 header 时返回空对象。
|
|
86
|
+
*/
|
|
87
|
+
export function parseStepHeaderMeta(text) {
|
|
88
|
+
const meta = {};
|
|
89
|
+
const header = headerLines(text);
|
|
90
|
+
if (!header)
|
|
91
|
+
return meta;
|
|
92
|
+
const fileBlock = entityBlock(header, 'FILE_NAME');
|
|
93
|
+
if (fileBlock) {
|
|
94
|
+
const parts = splitTopLevel(fileBlock);
|
|
95
|
+
// FILE_NAME(name, time_stamp, author(list), organization(list), preprocessor, originator)
|
|
96
|
+
// 引号数组形如 `('x')`,去首尾括号后 unquote;author/organization 可能为列表。
|
|
97
|
+
const inline = (p) => {
|
|
98
|
+
if (!p)
|
|
99
|
+
return undefined;
|
|
100
|
+
const v = unquote(p.replace(/^\(|\)$/g, ''));
|
|
101
|
+
return v === '' ? undefined : v;
|
|
102
|
+
};
|
|
103
|
+
const title = inline(parts[0]);
|
|
104
|
+
if (title)
|
|
105
|
+
meta.title = title;
|
|
106
|
+
const cdate = inline(parts[1]);
|
|
107
|
+
if (cdate)
|
|
108
|
+
meta.creationDate = cdate;
|
|
109
|
+
const author = inline(parts[2] ?? '');
|
|
110
|
+
if (author)
|
|
111
|
+
meta.author = author;
|
|
112
|
+
const org = inline(parts[3] ?? '');
|
|
113
|
+
if (org)
|
|
114
|
+
meta.organization = org;
|
|
115
|
+
// preprocessor → application(编辑器导入后端把 preprocessor 视为 APP);
|
|
116
|
+
// originator → designer。
|
|
117
|
+
const pre = inline(parts[4] ?? '');
|
|
118
|
+
if (pre)
|
|
119
|
+
meta.application = pre;
|
|
120
|
+
const origin = inline(parts[5] ?? '');
|
|
121
|
+
if (origin)
|
|
122
|
+
meta.designer = origin;
|
|
123
|
+
}
|
|
124
|
+
const descBlock = entityBlock(header, 'FILE_DESCRIPTION');
|
|
125
|
+
if (descBlock) {
|
|
126
|
+
// FILE_DESCRIPTION(description_list, implementation_context):描述只取第一个
|
|
127
|
+
// 顶层参数(描述串列表,`('a','b')` 形态含内层逗号);实现上下文不算。
|
|
128
|
+
// 直接取 `FILE_DESCRIPTION((…),` 里第一层括号内的引号字符串列表。
|
|
129
|
+
const m = /FILE_DESCRIPTION\s*\(\s*\((.*?)\)\s*,\s*/.exec(descBlock);
|
|
130
|
+
if (m) {
|
|
131
|
+
const joined = m[1]
|
|
132
|
+
.split(',')
|
|
133
|
+
.map((p) => unquote(p.trim()))
|
|
134
|
+
.filter((v) => v !== '');
|
|
135
|
+
if (joined.length > 0)
|
|
136
|
+
meta.description = joined.join(', ');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return meta;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 伙伴层 `PRODUCT` 描述 + 根自定义属性(UDA,`GENERAL_PROPERTY`)解析
|
|
143
|
+
* (简化:description 只取第一个 `PRODUCT`)。
|
|
144
|
+
*
|
|
145
|
+
* @param text STEP 全文(ISO-10303-21)。
|
|
146
|
+
* @returns 解析出的部分级元数据(`description`/`metadata`)。
|
|
147
|
+
*/
|
|
148
|
+
export function parseStepPartMeta(text) {
|
|
149
|
+
const out = {};
|
|
150
|
+
// 逐 PRODUCT 取 description(第 2 个参数)。
|
|
151
|
+
const dataRe = /PRODUCT\s*\(/g;
|
|
152
|
+
let m;
|
|
153
|
+
while ((m = dataRe.exec(text)) !== null) {
|
|
154
|
+
const close = text.indexOf(')', m.index);
|
|
155
|
+
if (close < 0)
|
|
156
|
+
break;
|
|
157
|
+
const inner = text.slice(m.index, close + 1);
|
|
158
|
+
const descM = /,\s*'([^']*)'/.exec(inner);
|
|
159
|
+
if (descM) {
|
|
160
|
+
const d = descM[1];
|
|
161
|
+
if (d !== '')
|
|
162
|
+
out.description = d;
|
|
163
|
+
break; // 只取第一个
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// 属性笼(UDA:GENERAL_PROPERTY('name', value?) 挂在 PROPERTY_DEFINITION 上)。
|
|
167
|
+
const props = {};
|
|
168
|
+
const gpRe = /GENERAL_PROPERTY\s*\(\s*'([^']*)'\s*,\s*([^,)]+)/g;
|
|
169
|
+
let gm;
|
|
170
|
+
while ((gm = gpRe.exec(text)) !== null) {
|
|
171
|
+
props[gm[1]] = unquote(gm[2]);
|
|
172
|
+
}
|
|
173
|
+
if (Object.keys(props).length > 0)
|
|
174
|
+
out.metadata = props;
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=stepMetaParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepMetaParser.js","sourceRoot":"","sources":["../../src/step/stepMetaParser.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * STEP 元数据解析器 — 从 STEP (P21) 文本头部与 PRODUCT 层提取\n * FileMeta(文件级)与 ShapeMeta(零件级描述字/料号)。\n *\n * 与 stepColorParser 同一原则:纯文本扫描,不依赖 OCCT 内核(XCAF label 层\n * 是否暴露 description/属性不确定,见设计文档 2026-10-05-meta §6.3 风险 2)。\n *\n * 读取面映射(§3.3):\n * - HEADER FILE_NAME(name,time_stamp,author,organization,preprocessor,originator)\n * → title / creationDate / author / organization / application / designer。\n * - HEADER FILE_DESCRIPTION(...) → description(逗号拼接,去首尾引号)。\n * - DATA PRODUCT(name,description,frame)(第一个、leaf 使用的)→ 零件 description。\n * name 已由 OCCT label 提供(不在本解析器处理)。\n * - PRODUCT → PRODUCT_DEFINITION_FORMATION/WITH_SPECIFIED_SOURCE-关联的料号通道:\n * PART_NUMBER_PROPERTY/IDENTIFICATION 命名在 §3.3 表里列出的 PART 层通道(P4\n * 标 \"IDENTIFICATION 内核支持\" 待实测),这里尽量从 PRODUCT_DEFINITION 挂的\n * UDA(GENERAL_PROPERTY + PROPERTY_DEFINITION)捞自定义属性。\n *\n * 所有扫描都容错:找不到就不给对应字段,绝不让解析器抛(信息性收益)。\n */\n\n/** Header 级人物贡献字段(FILE_NAME 组内的三四五参数)。 */\nexport interface StepFileMeta {\n title?: string\n creationDate?: string\n designer?: string\n author?: string\n organization?: string\n application?: string\n description?: string\n /** 自定义 FILE_DESCRIPTION/FILE_NAME 之外的 vendor 属性(metadata 笼)。 */\n metadata?: Record<string, string>\n}\n\n/** STEP 伙伴级 P21 解析出的轻量属性。 */\nexport interface StepPartMeta {\n /** 产品描述(PRODUCT( ..., description, id ))。空串/缺省不设。 */\n description?: string\n /** 自定义属性:`PROPERTY_DEFINITION(...)` + `GENERAL_PROPERTY('name', value, ...)`。 */\n metadata?: Record<string, string>\n}\n\n/** 剥离一层引号(STEP 字符串形如 `'abc'`),出双引号化转义;去末尾换行。 */\nfunction unquote(s: string): string {\n const t = s.trim()\n if (t.startsWith(\"'\") && t.endsWith(\"'\")) return t.slice(1, -1)\n return t\n}\n\n/** 任一 `HEADER`/`DATA` 段中的实体文本(多行),从 header 段中取整行。 */\nfunction headerLines(text: string): string {\n const m = /HEADER;\\n([\\s\\S]*?)\\nENDSEC;/.exec(text)\n return m ? m[1] : ''\n}\n\n/** `TYPE(...)` 实体块捕获:从开括号起做括号配平扫描到闭合(容错 LIST/嵌套)。 */\nfunction entityBlock(text: string, type: string): string | undefined {\n const re = new RegExp(`${type}\\\\s*\\\\(`, 'g')\n let m: RegExpExecArray | null\n while ((m = re.exec(text)) !== null) {\n let depth = 0\n let inQuote = false\n let i = m.index + m[0].length - 1 // 停在开括号\n for (; i < text.length; i++) {\n const c = text[i]\n if (c === \"'\") inQuote = !inQuote\n if (inQuote) continue\n if (c === '(') depth++\n else if (c === ')') {\n depth--\n if (depth === 0) return text.slice(m.index, i + 1)\n }\n }\n }\n return undefined\n}\n\n/** 逗号分隔的顶层简单参数(忽略嵌套括号内容仍按逗号简单切——够用即可)。 */\nfunction splitTopLevel(body: string): string[] {\n // 剥离外层括号后,按未被引号包裹的逗号切分(不处理嵌套括号——STEP 伙伴级\n // FILE_NAME/FILE_DESCRIPTION 参数都是简单标量/字符串,不涉及深层嵌套)。\n const s = body.slice(body.indexOf('(') + 1, body.lastIndexOf(')'))\n const parts: string[] = []\n let cur = ''\n let inQuote = false\n for (let i = 0; i < s.length; i++) {\n const c = s[i]\n if (c === \"'\") inQuote = !inQuote\n if (c === ',' && !inQuote) {\n parts.push(cur)\n cur = ''\n } else {\n cur += c\n }\n }\n parts.push(cur)\n return parts.map((p) => p.trim())\n}\n\n/**\n * Header 段整块(FILE_NAME / FILE_DESCRIPTION)→ `StepFileMeta`。\n *\n * @param text STEP 全文(ISO-10303-21)。\n * @returns 解析出的文件级元数据;无 header 时返回空对象。\n */\nexport function parseStepHeaderMeta(text: string): StepFileMeta {\n const meta: StepFileMeta = {}\n const header = headerLines(text)\n if (!header) return meta\n\n const fileBlock = entityBlock(header, 'FILE_NAME')\n if (fileBlock) {\n const parts = splitTopLevel(fileBlock)\n // FILE_NAME(name, time_stamp, author(list), organization(list), preprocessor, originator)\n // 引号数组形如 `('x')`,去首尾括号后 unquote;author/organization 可能为列表。\n const inline = (p: string): string | undefined => {\n if (!p) return undefined\n const v = unquote(p.replace(/^\\(|\\)$/g, ''))\n return v === '' ? undefined : v\n }\n const title = inline(parts[0])\n if (title) meta.title = title\n const cdate = inline(parts[1])\n if (cdate) meta.creationDate = cdate\n const author = inline(parts[2] ?? '')\n if (author) meta.author = author\n const org = inline(parts[3] ?? '')\n if (org) meta.organization = org\n // preprocessor → application(编辑器导入后端把 preprocessor 视为 APP);\n // originator → designer。\n const pre = inline(parts[4] ?? '')\n if (pre) meta.application = pre\n const origin = inline(parts[5] ?? '')\n if (origin) meta.designer = origin\n }\n\n const descBlock = entityBlock(header, 'FILE_DESCRIPTION')\n if (descBlock) {\n // FILE_DESCRIPTION(description_list, implementation_context):描述只取第一个\n // 顶层参数(描述串列表,`('a','b')` 形态含内层逗号);实现上下文不算。\n // 直接取 `FILE_DESCRIPTION((…),` 里第一层括号内的引号字符串列表。\n const m = /FILE_DESCRIPTION\\s*\\(\\s*\\((.*?)\\)\\s*,\\s*/.exec(descBlock)\n if (m) {\n const joined = m[1]\n .split(',')\n .map((p) => unquote(p.trim()))\n .filter((v) => v !== '')\n if (joined.length > 0) meta.description = joined.join(', ')\n }\n }\n\n return meta\n}\n\n/**\n * 伙伴层 `PRODUCT` 描述 + 根自定义属性(UDA,`GENERAL_PROPERTY`)解析\n * (简化:description 只取第一个 `PRODUCT`)。\n *\n * @param text STEP 全文(ISO-10303-21)。\n * @returns 解析出的部分级元数据(`description`/`metadata`)。\n */\nexport function parseStepPartMeta(text: string): StepPartMeta {\n const out: StepPartMeta = {}\n // 逐 PRODUCT 取 description(第 2 个参数)。\n const dataRe = /PRODUCT\\s*\\(/g\n let m: RegExpExecArray | null\n while ((m = dataRe.exec(text)) !== null) {\n const close = text.indexOf(')', m.index)\n if (close < 0) break\n const inner = text.slice(m.index, close + 1)\n const descM = /,\\s*'([^']*)'/.exec(inner)\n if (descM) {\n const d = descM[1]\n if (d !== '') out.description = d\n break // 只取第一个\n }\n }\n // 属性笼(UDA:GENERAL_PROPERTY('name', value?) 挂在 PROPERTY_DEFINITION 上)。\n const props: Record<string, string> = {}\n const gpRe = /GENERAL_PROPERTY\\s*\\(\\s*'([^']*)'\\s*,\\s*([^,)]+)/g\n let gm: RegExpExecArray | null\n while ((gm = gpRe.exec(text)) !== null) {\n props[gm[1]] = unquote(gm[2])\n }\n if (Object.keys(props).length > 0) out.metadata = props\n return out\n}"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faicad/faijs",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
"opentype.js": "^1.3.4"
|
|
169
169
|
},
|
|
170
170
|
"peerDependencies": {
|
|
171
|
-
"occt-wasm": "^
|
|
171
|
+
"occt-wasm": "^5.6.0",
|
|
172
172
|
"three": "^0.162.0 || ^0.184.0"
|
|
173
173
|
},
|
|
174
174
|
"devDependencies": {
|