occt-gltf-addon 0.1.13 → 0.1.14
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/CMakeLists.txt +11 -1
- package/README.md +10 -3
- package/example.js +2 -2
- package/index.js +306 -34
- package/package.json +2 -1
package/CMakeLists.txt
CHANGED
|
@@ -127,7 +127,17 @@ add_library(${PROJECT_NAME} SHARED
|
|
|
127
127
|
)
|
|
128
128
|
|
|
129
129
|
# --- Optional: Draco (KHR_draco_mesh_compression) ---
|
|
130
|
-
|
|
130
|
+
# Default to OFF to avoid linking native Draco (which may require newer glibc).
|
|
131
|
+
option(OCCT_GLTF_ADDON_ENABLE_DRACO "Enable Draco mesh compression support" OFF)
|
|
132
|
+
if(DEFINED ENV{OCCT_GLTF_ADDON_ENABLE_DRACO})
|
|
133
|
+
string(TOLOWER "$ENV{OCCT_GLTF_ADDON_ENABLE_DRACO}" _draco_env)
|
|
134
|
+
if(_draco_env STREQUAL "1" OR _draco_env STREQUAL "on" OR _draco_env STREQUAL "true" OR _draco_env STREQUAL "yes")
|
|
135
|
+
set(OCCT_GLTF_ADDON_ENABLE_DRACO ON CACHE BOOL "Enable Draco mesh compression support" FORCE)
|
|
136
|
+
else()
|
|
137
|
+
set(OCCT_GLTF_ADDON_ENABLE_DRACO OFF CACHE BOOL "Enable Draco mesh compression support" FORCE)
|
|
138
|
+
endif()
|
|
139
|
+
endif()
|
|
140
|
+
|
|
131
141
|
if(OCCT_GLTF_ADDON_ENABLE_DRACO)
|
|
132
142
|
if(DEFINED ENV{DRACO_ROOT} AND NOT "$ENV{DRACO_ROOT}" STREQUAL "")
|
|
133
143
|
set(DRACO_ROOT "$ENV{DRACO_ROOT}" CACHE PATH "Draco install prefix" FORCE)
|
package/README.md
CHANGED
|
@@ -45,6 +45,12 @@ await convertSTEPToGLTF({
|
|
|
45
45
|
export OCCT_GLTF_ADDON_PREBUILT_BASE_URL=https://cdn2-1304552240.cos.ap-shanghai.myqcloud.com/libs/occt/
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
运行时自检(兼容安装脚本被禁用的场景):
|
|
49
|
+
- 首次调用时若本地没有对应 `prebuilt/<platform>-<arch>/`,会尝试在运行时下载预编译包并缓存(优先写入包内 `node_modules/occt-gltf-addon/prebuilt/`,不可写时回退到 `/tmp/occt-gltf-addon/prebuilt`)。
|
|
50
|
+
- 可设置 `OCCT_GLTF_ADDON_RUNTIME_DOWNLOAD=0` 关闭运行时下载。
|
|
51
|
+
- 可设置 `OCCT_GLTF_ADDON_PREBUILT_CACHE_DIR=/tmp/occt-gltf-addon/prebuilt` 自定义缓存目录。
|
|
52
|
+
- 可设置 `OCCT_GLTF_ADDON_PREBUILT_ROOT` 或 `OCCT_GLTF_ADDON_PREBUILT_DIR` 指定本地预编译包位置。
|
|
53
|
+
|
|
48
54
|
本地编译时通过环境变量指定 OCCT 安装前缀:
|
|
49
55
|
|
|
50
56
|
```bash
|
|
@@ -70,8 +76,9 @@ OCCT_GLTF_ADDON_SKIP_BUILD=1 npm i occt-gltf-addon
|
|
|
70
76
|
OCCT_GLTF_ADDON_SKIP_DOWNLOAD=1 npm i occt-gltf-addon
|
|
71
77
|
```
|
|
72
78
|
|
|
73
|
-
Draco
|
|
74
|
-
-
|
|
79
|
+
Draco(Node.js 层压缩,避免原生依赖):
|
|
80
|
+
- 默认不链接原生 Draco;当设置 `output.draco` 时,会在 JS 层使用 `gltf-pipeline` + `draco3d` 压缩。
|
|
81
|
+
- 如需恢复原生 Draco(可能引入 glibc 兼容问题),构建时设置:`OCCT_GLTF_ADDON_ENABLE_DRACO=1`
|
|
75
82
|
|
|
76
83
|
---
|
|
77
84
|
|
|
@@ -104,7 +111,7 @@ Draco(仅源码编译时启用,需要开发包):
|
|
|
104
111
|
- `bakeTransforms`:烘焙节点变换到顶点
|
|
105
112
|
- `center`:`'none'|'xy'|'xz'|'yz'`(配合 bake 使用)
|
|
106
113
|
- `zUp`:导出为 Z-up 坐标(非标准 glTF)
|
|
107
|
-
- `draco`:`boolean | { enabled, compressionLevel, quantizationBitsPosition, quantizationBitsNormal }
|
|
114
|
+
- `draco`:`boolean | { enabled, compressionLevel, quantizationBitsPosition, quantizationBitsNormal }`(Node.js 层 Draco 压缩)
|
|
108
115
|
|
|
109
116
|
---
|
|
110
117
|
|
package/example.js
CHANGED
|
@@ -40,8 +40,8 @@ async function main() {
|
|
|
40
40
|
// If your runtime uses Z-up world (e.g. three.js: THREE.Object3D.DEFAULT_UP.set(0,0,1)),
|
|
41
41
|
// enable this to export Z-up coordinates (note: non-standard glTF; Y-up viewers may show it rotated).
|
|
42
42
|
zUp: true,
|
|
43
|
-
// Draco (KHR_draco_mesh_compression)
|
|
44
|
-
//
|
|
43
|
+
// Draco (KHR_draco_mesh_compression) is applied in JS after conversion to avoid native deps.
|
|
44
|
+
// NOTE: some importers (e.g. Blender) may not support Draco.
|
|
45
45
|
draco: {
|
|
46
46
|
enabled: true,
|
|
47
47
|
compressionLevel: 7, // 0..10 (越大越小/越慢)
|
package/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// CommonJS entrypoint. cmake-js outputs: build/<Config>/<target>.node
|
|
2
2
|
const fs = require('fs');
|
|
3
|
+
const http = require('http');
|
|
4
|
+
const https = require('https');
|
|
5
|
+
const os = require('os');
|
|
3
6
|
const path = require('path');
|
|
7
|
+
const tar = require('tar');
|
|
4
8
|
|
|
5
9
|
function prependEnvPath(key, dir) {
|
|
6
10
|
if (!dir) return;
|
|
@@ -41,12 +45,100 @@ function setOcctResourceEnv(resRoot) {
|
|
|
41
45
|
setIfEmpty('CSF_MIGRATION_TYPES', path.join(R, 'StdResource', 'MigrationSheet.txt'));
|
|
42
46
|
}
|
|
43
47
|
|
|
48
|
+
function normalizeBaseUrl(base) {
|
|
49
|
+
if (!base) return '';
|
|
50
|
+
return base.endsWith('/') ? base : `${base}/`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getPrebuiltUrl(tag, version) {
|
|
54
|
+
const base =
|
|
55
|
+
process.env.OCCT_GLTF_ADDON_PREBUILT_BASE_URL ||
|
|
56
|
+
'https://cdn2-1304552240.cos.ap-shanghai.myqcloud.com/libs/occt/';
|
|
57
|
+
const normalized = normalizeBaseUrl(base);
|
|
58
|
+
return `${normalized}occt-gltf-addon-${version}-${tag}.tgz`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getPackageVersion() {
|
|
62
|
+
try {
|
|
63
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
|
|
64
|
+
return pkg.version || '0.0.0';
|
|
65
|
+
} catch (e) {
|
|
66
|
+
return '0.0.0';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isWritableDir(dir) {
|
|
71
|
+
try {
|
|
72
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
73
|
+
fs.accessSync(dir, fs.constants.W_OK);
|
|
74
|
+
return true;
|
|
75
|
+
} catch (e) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function resolvePrebuiltDirCandidates(baseDir, tag) {
|
|
81
|
+
if (!baseDir) return [];
|
|
82
|
+
const candidates = [baseDir];
|
|
83
|
+
if (path.basename(baseDir) !== tag) {
|
|
84
|
+
candidates.push(path.join(baseDir, tag));
|
|
85
|
+
}
|
|
86
|
+
return candidates;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getPrebuiltSearchDirs(tag) {
|
|
90
|
+
const dirs = [];
|
|
91
|
+
const fromDir = process.env.OCCT_GLTF_ADDON_PREBUILT_DIR;
|
|
92
|
+
const fromRoot = process.env.OCCT_GLTF_ADDON_PREBUILT_ROOT;
|
|
93
|
+
const cacheRoot =
|
|
94
|
+
process.env.OCCT_GLTF_ADDON_PREBUILT_CACHE_DIR ||
|
|
95
|
+
path.join(os.tmpdir(), 'occt-gltf-addon', 'prebuilt');
|
|
96
|
+
|
|
97
|
+
resolvePrebuiltDirCandidates(fromDir, tag).forEach((d) => dirs.push(d));
|
|
98
|
+
if (fromRoot) dirs.push(path.join(fromRoot, tag));
|
|
99
|
+
dirs.push(path.join(cacheRoot, tag));
|
|
100
|
+
dirs.push(path.join(__dirname, 'prebuilt', tag));
|
|
101
|
+
|
|
102
|
+
return [...new Set(dirs)];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function resolveDownloadPrebuiltDir(tag) {
|
|
106
|
+
const candidates = [];
|
|
107
|
+
const fromDir = process.env.OCCT_GLTF_ADDON_PREBUILT_DIR;
|
|
108
|
+
const fromRoot = process.env.OCCT_GLTF_ADDON_PREBUILT_ROOT;
|
|
109
|
+
const cacheRoot =
|
|
110
|
+
process.env.OCCT_GLTF_ADDON_PREBUILT_CACHE_DIR ||
|
|
111
|
+
path.join(os.tmpdir(), 'occt-gltf-addon', 'prebuilt');
|
|
112
|
+
|
|
113
|
+
resolvePrebuiltDirCandidates(fromDir, tag).forEach((d) => candidates.push(d));
|
|
114
|
+
if (fromRoot) candidates.push(path.join(fromRoot, tag));
|
|
115
|
+
candidates.push(path.join(__dirname, 'prebuilt', tag));
|
|
116
|
+
candidates.push(path.join(cacheRoot, tag));
|
|
117
|
+
|
|
118
|
+
for (const dir of candidates) {
|
|
119
|
+
if (isWritableDir(dir)) return dir;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return path.join(cacheRoot, tag);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function findPrebuiltNode(tag) {
|
|
126
|
+
const candidates = getPrebuiltSearchDirs(tag);
|
|
127
|
+
for (const prebuiltDir of candidates) {
|
|
128
|
+
const prebuiltNode = path.join(prebuiltDir, 'occt_gltf_addon.node');
|
|
129
|
+
if (fs.existsSync(prebuiltNode)) {
|
|
130
|
+
return { prebuiltDir, prebuiltNode };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
44
136
|
function tryLoadPrebuilt() {
|
|
45
137
|
if (process.env.OCCT_GLTF_ADDON_BINDING_PATH) return null;
|
|
46
138
|
const tag = `${process.platform}-${process.arch}`;
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
139
|
+
const found = findPrebuiltNode(tag);
|
|
140
|
+
if (!found) return null;
|
|
141
|
+
const { prebuiltDir, prebuiltNode } = found;
|
|
50
142
|
|
|
51
143
|
const libDir = path.join(prebuiltDir, 'lib');
|
|
52
144
|
const resDir = path.join(prebuiltDir, 'resources');
|
|
@@ -76,44 +168,224 @@ function tryLoadPrebuilt() {
|
|
|
76
168
|
return require(prebuiltNode);
|
|
77
169
|
}
|
|
78
170
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
171
|
+
function downloadFile(url, dest) {
|
|
172
|
+
return new Promise((resolve, reject) => {
|
|
173
|
+
const client = url.startsWith('https:') ? https : http;
|
|
174
|
+
const req = client.get(url, (res) => {
|
|
175
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
176
|
+
downloadFile(res.headers.location, dest).then(resolve).catch(reject);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (res.statusCode !== 200) {
|
|
180
|
+
reject(new Error(`Download failed with status ${res.statusCode}`));
|
|
181
|
+
res.resume();
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const file = fs.createWriteStream(dest);
|
|
185
|
+
res.pipe(file);
|
|
186
|
+
file.on('finish', () => file.close(resolve));
|
|
187
|
+
file.on('error', reject);
|
|
188
|
+
});
|
|
189
|
+
req.on('error', reject);
|
|
190
|
+
});
|
|
83
191
|
}
|
|
84
192
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
path.join(__dirname, 'build', 'Debug', 'occt_gltf_addon.node'),
|
|
92
|
-
];
|
|
193
|
+
async function ensurePrebuiltDownloaded(tag) {
|
|
194
|
+
if (process.env.OCCT_GLTF_ADDON_SKIP_DOWNLOAD === '1') return null;
|
|
195
|
+
if (process.env.OCCT_GLTF_ADDON_RUNTIME_DOWNLOAD === '0') return null;
|
|
196
|
+
|
|
197
|
+
const existing = findPrebuiltNode(tag);
|
|
198
|
+
if (existing) return existing.prebuiltDir;
|
|
93
199
|
|
|
94
|
-
|
|
95
|
-
|
|
200
|
+
const prebuiltDir = resolveDownloadPrebuiltDir(tag);
|
|
201
|
+
const parentDir = path.dirname(prebuiltDir);
|
|
202
|
+
const prebuiltNode = path.join(prebuiltDir, 'occt_gltf_addon.node');
|
|
203
|
+
|
|
204
|
+
if (fs.existsSync(prebuiltNode)) return prebuiltDir;
|
|
205
|
+
|
|
206
|
+
const version = getPackageVersion();
|
|
207
|
+
const url = getPrebuiltUrl(tag, version);
|
|
208
|
+
const tgzPath = path.join(parentDir, `prebuilt-${tag}.tgz`);
|
|
209
|
+
|
|
210
|
+
fs.mkdirSync(prebuiltDir, { recursive: true });
|
|
96
211
|
try {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return;
|
|
212
|
+
await downloadFile(url, tgzPath);
|
|
213
|
+
await tar.x({ file: tgzPath, cwd: prebuiltDir });
|
|
214
|
+
fs.rmSync(tgzPath, { force: true });
|
|
215
|
+
return prebuiltDir;
|
|
101
216
|
} catch (e) {
|
|
102
|
-
|
|
217
|
+
fs.rmSync(tgzPath, { force: true });
|
|
218
|
+
return null;
|
|
103
219
|
}
|
|
104
220
|
}
|
|
105
221
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
222
|
+
function loadNativeAddon() {
|
|
223
|
+
const prebuilt = tryLoadPrebuilt();
|
|
224
|
+
if (prebuilt) return prebuilt;
|
|
225
|
+
|
|
226
|
+
const overridePath = process.env.OCCT_GLTF_ADDON_BINDING_PATH;
|
|
227
|
+
const candidates = overridePath
|
|
228
|
+
? [overridePath]
|
|
229
|
+
: [
|
|
230
|
+
path.join(__dirname, 'build', 'Release', 'occt_gltf_addon.node'),
|
|
231
|
+
path.join(__dirname, 'build', 'RelWithDebInfo', 'occt_gltf_addon.node'),
|
|
232
|
+
path.join(__dirname, 'build', 'Debug', 'occt_gltf_addon.node'),
|
|
233
|
+
];
|
|
234
|
+
|
|
235
|
+
let lastErr = null;
|
|
236
|
+
for (const p of candidates) {
|
|
237
|
+
try {
|
|
238
|
+
if (!fs.existsSync(p)) continue;
|
|
239
|
+
// eslint-disable-next-line import/no-dynamic-require, global-require
|
|
240
|
+
return require(p);
|
|
241
|
+
} catch (e) {
|
|
242
|
+
lastErr = e;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const msg = [
|
|
247
|
+
'[occt-gltf-addon] Failed to load native addon (.node).',
|
|
248
|
+
`Tried: ${candidates.map((p) => JSON.stringify(p)).join(', ')}`,
|
|
249
|
+
'',
|
|
250
|
+
'If you installed from npm:',
|
|
251
|
+
'- This package bundles prebuilt binaries under `prebuilt/<platform>-<arch>/` for supported platforms.',
|
|
252
|
+
'- If prebuilt is missing for your platform, build from source with OCCT_ROOT set.',
|
|
253
|
+
'',
|
|
254
|
+
"You can try: 'npm rebuild occt-gltf-addon' (with OCCT_ROOT exported).",
|
|
255
|
+
].join('\n');
|
|
256
|
+
|
|
257
|
+
// Preserve original error for debugging.
|
|
258
|
+
throw new Error(`${msg}\n\n${String(lastErr && (lastErr.stack || lastErr.message || lastErr))}`);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function normalizeDracoOptions(draco) {
|
|
262
|
+
if (draco == null) return null;
|
|
263
|
+
if (typeof draco === 'boolean') return draco ? {} : null;
|
|
264
|
+
if (typeof draco !== 'object') return null;
|
|
265
|
+
if (draco.enabled === false) return null;
|
|
266
|
+
return { ...draco, enabled: true };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function stripDraco(output) {
|
|
270
|
+
if (!output || typeof output !== 'object') return output;
|
|
271
|
+
const { draco, ...rest } = output;
|
|
272
|
+
return rest;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function splitDracoOptions(options) {
|
|
276
|
+
const dracoJobs = [];
|
|
277
|
+
if (!options || typeof options !== 'object') {
|
|
278
|
+
return { nativeOptions: options, dracoJobs };
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (Array.isArray(options.variants) && options.variants.length > 0) {
|
|
282
|
+
const variants = options.variants.map((variant) => {
|
|
283
|
+
if (!variant || typeof variant !== 'object') return variant;
|
|
284
|
+
const draco = normalizeDracoOptions(variant.output && variant.output.draco);
|
|
285
|
+
if (!draco) return variant;
|
|
286
|
+
if (!variant.outputPath) {
|
|
287
|
+
throw new Error('[occt-gltf-addon] outputPath is required for Draco compression (variant).');
|
|
288
|
+
}
|
|
289
|
+
dracoJobs.push({ outputPath: variant.outputPath, draco });
|
|
290
|
+
return { ...variant, output: stripDraco(variant.output) };
|
|
291
|
+
});
|
|
292
|
+
return { nativeOptions: { ...options, variants }, dracoJobs };
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const draco = normalizeDracoOptions(options.output && options.output.draco);
|
|
296
|
+
if (!draco) {
|
|
297
|
+
return { nativeOptions: options, dracoJobs };
|
|
298
|
+
}
|
|
299
|
+
if (!options.outputPath) {
|
|
300
|
+
throw new Error('[occt-gltf-addon] outputPath is required for Draco compression.');
|
|
301
|
+
}
|
|
302
|
+
dracoJobs.push({ outputPath: options.outputPath, draco });
|
|
303
|
+
return { nativeOptions: { ...options, output: stripDraco(options.output) }, dracoJobs };
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function toGltfPipelineDracoOptions(draco) {
|
|
307
|
+
const options = {};
|
|
308
|
+
if (!draco || typeof draco !== 'object') return options;
|
|
309
|
+
if (typeof draco.compressionLevel === 'number') {
|
|
310
|
+
options.compressionLevel = draco.compressionLevel;
|
|
311
|
+
}
|
|
312
|
+
if (typeof draco.quantizationBitsPosition === 'number') {
|
|
313
|
+
options.quantizePositionBits = draco.quantizationBitsPosition;
|
|
314
|
+
}
|
|
315
|
+
if (typeof draco.quantizationBitsNormal === 'number') {
|
|
316
|
+
options.quantizeNormalBits = draco.quantizationBitsNormal;
|
|
317
|
+
}
|
|
318
|
+
return options;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async function compressGlbWithDraco({ outputPath, draco }) {
|
|
322
|
+
if (!outputPath) {
|
|
323
|
+
throw new Error('[occt-gltf-addon] Draco compression requires outputPath.');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
let gltfPipeline;
|
|
327
|
+
try {
|
|
328
|
+
// eslint-disable-next-line global-require
|
|
329
|
+
gltfPipeline = require('gltf-pipeline');
|
|
330
|
+
} catch (e) {
|
|
331
|
+
throw new Error(
|
|
332
|
+
`[occt-gltf-addon] Draco compression requested but "gltf-pipeline" is not installed.\n` +
|
|
333
|
+
"Install it with: npm i gltf-pipeline",
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const input = await fs.promises.readFile(outputPath);
|
|
338
|
+
const result = await gltfPipeline.processGlb(input, {
|
|
339
|
+
dracoOptions: toGltfPipelineDracoOptions(draco),
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
if (!result || !result.glb) {
|
|
343
|
+
throw new Error('[occt-gltf-addon] Draco compression failed: empty output.');
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
await fs.promises.writeFile(outputPath, result.glb);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
async function runNodeDracoCompression(jobs) {
|
|
350
|
+
for (const job of jobs) {
|
|
351
|
+
// eslint-disable-next-line no-await-in-loop
|
|
352
|
+
await compressGlbWithDraco(job);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function wrapNative(native) {
|
|
357
|
+
if (!native || typeof native.convertSTEPToGLTF !== 'function') return native;
|
|
358
|
+
const convert = native.convertSTEPToGLTF.bind(native);
|
|
359
|
+
return {
|
|
360
|
+
...native,
|
|
361
|
+
convertSTEPToGLTF: async (options) => {
|
|
362
|
+
const { nativeOptions, dracoJobs } = splitDracoOptions(options || {});
|
|
363
|
+
await convert(nativeOptions);
|
|
364
|
+
if (dracoJobs.length > 0) {
|
|
365
|
+
await runNodeDracoCompression(dracoJobs);
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
let wrappedNativePromise = null;
|
|
372
|
+
|
|
373
|
+
async function getWrappedNative() {
|
|
374
|
+
if (!wrappedNativePromise) {
|
|
375
|
+
wrappedNativePromise = (async () => {
|
|
376
|
+
const tag = `${process.platform}-${process.arch}`;
|
|
377
|
+
await ensurePrebuiltDownloaded(tag);
|
|
378
|
+
const native = loadNativeAddon();
|
|
379
|
+
return wrapNative(native);
|
|
380
|
+
})();
|
|
381
|
+
}
|
|
382
|
+
return wrappedNativePromise;
|
|
383
|
+
}
|
|
116
384
|
|
|
117
|
-
|
|
118
|
-
|
|
385
|
+
module.exports = {
|
|
386
|
+
convertSTEPToGLTF: async (options) => {
|
|
387
|
+
const native = await getWrappedNative();
|
|
388
|
+
return native.convertSTEPToGLTF(options);
|
|
389
|
+
},
|
|
390
|
+
};
|
|
119
391
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "occt-gltf-addon",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "STEP (.step/.stp) to glTF (GLB) converter using OpenCascade (OCCT) via a Node.js N-API addon",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "index.js",
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"cmake-js": "^7.3.1",
|
|
73
|
+
"gltf-pipeline": "^4.3.0",
|
|
73
74
|
"node-addon-api": "^7.1.0",
|
|
74
75
|
"tar": "^7.4.0"
|
|
75
76
|
},
|