dsh-cad 0.13.2 → 0.14.0
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/LICENSE +201 -201
- package/README.md +3 -3
- package/README.zh-CN.md +1 -1
- package/lib/cad_connector/freecad-executor.js +209 -209
- package/lib/cad_connector/fusion360-executor.js +244 -244
- package/lib/client.js +172 -172
- package/lib/convert/step-worker.mjs +61 -61
- package/lib/demo-bracket.brep +667 -667
- package/lib/demo-flange.brep +708 -708
- package/lib/demo-shaft.brep +515 -515
- package/lib/modeling/modeling-worker.cjs +2 -2
- package/lib/modeling/occt-adapter.cjs +90 -3
- package/lib/modeling/occtts-adapter.cjs +80 -7
- package/lib/routes.js +5 -0
- package/lib/tools/cad-model.js +16 -5
- package/lib/types/modeling/client.d.ts +19 -1
- package/package.json +1 -1
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* occt-import-js worker: parses STEP/IGES/BREP in a worker thread so the
|
|
3
|
-
* WASM tessellation never blocks the agent's event loop. Plain JavaScript —
|
|
4
|
-
* this file is copied verbatim into lib/ by the build.
|
|
5
|
-
*/
|
|
6
|
-
import { createRequire } from 'node:module'
|
|
7
|
-
import { parentPort } from 'node:worker_threads'
|
|
8
|
-
|
|
9
|
-
const require = createRequire(import.meta.url)
|
|
10
|
-
|
|
11
|
-
async function main() {
|
|
12
|
-
if (parentPort === null) return
|
|
13
|
-
const occtimportjs = require('occt-import-js')
|
|
14
|
-
const occt = await occtimportjs()
|
|
15
|
-
|
|
16
|
-
parentPort.on('message', (request) => {
|
|
17
|
-
try {
|
|
18
|
-
const bytes = new Uint8Array(request.buffer)
|
|
19
|
-
const result =
|
|
20
|
-
request.format === 'step' ? occt.ReadStepFile(bytes, null)
|
|
21
|
-
: request.format === 'iges' ? occt.ReadIgesFile(bytes, null)
|
|
22
|
-
: occt.ReadBrepFile(bytes, null)
|
|
23
|
-
if (!result.success || result.meshes === undefined || result.meshes.length === 0) {
|
|
24
|
-
parentPort.postMessage({ jobId: request.jobId, ok: false, error: `the ${request.format.toUpperCase()} file parsed but contains no tessellatable geometry` })
|
|
25
|
-
return
|
|
26
|
-
}
|
|
27
|
-
const transfers = []
|
|
28
|
-
const meshes = result.meshes.map((mesh) => {
|
|
29
|
-
const positionArray = mesh.attributes?.position?.array
|
|
30
|
-
if (positionArray === undefined || positionArray.length < 9) return null
|
|
31
|
-
const positions = Float32Array.from(positionArray)
|
|
32
|
-
const normalSource = mesh.attributes?.normal?.array
|
|
33
|
-
const normals = normalSource !== undefined && normalSource.length === positions.length ? Float32Array.from(normalSource) : null
|
|
34
|
-
const indexSource = mesh.index?.array
|
|
35
|
-
const indices = indexSource !== undefined && indexSource.length > 0
|
|
36
|
-
? Uint32Array.from(indexSource)
|
|
37
|
-
: Uint32Array.from({ length: positions.length / 3 }, (_, i) => i)
|
|
38
|
-
transfers.push(positions.buffer, indices.buffer)
|
|
39
|
-
if (normals !== null) transfers.push(normals.buffer)
|
|
40
|
-
const color = mesh.color
|
|
41
|
-
return {
|
|
42
|
-
name: mesh.name && mesh.name !== '' ? mesh.name : 'part',
|
|
43
|
-
positions,
|
|
44
|
-
normals: normals === null ? undefined : normals,
|
|
45
|
-
indices,
|
|
46
|
-
color: color === undefined ? undefined
|
|
47
|
-
: (Math.round(color[0] * 255) << 16) | (Math.round(color[1] * 255) << 8) | Math.round(color[2] * 255),
|
|
48
|
-
}
|
|
49
|
-
}).filter((mesh) => mesh !== null)
|
|
50
|
-
if (meshes.length === 0) {
|
|
51
|
-
parentPort.postMessage({ jobId: request.jobId, ok: false, error: `the ${request.format.toUpperCase()} file contains no meshes with geometry` })
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
parentPort.postMessage({ jobId: request.jobId, ok: true, meshes }, transfers)
|
|
55
|
-
} catch (error) {
|
|
56
|
-
parentPort.postMessage({ jobId: request.jobId, ok: false, error: error instanceof Error ? error.message : String(error) })
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
void main()
|
|
1
|
+
/**
|
|
2
|
+
* occt-import-js worker: parses STEP/IGES/BREP in a worker thread so the
|
|
3
|
+
* WASM tessellation never blocks the agent's event loop. Plain JavaScript —
|
|
4
|
+
* this file is copied verbatim into lib/ by the build.
|
|
5
|
+
*/
|
|
6
|
+
import { createRequire } from 'node:module'
|
|
7
|
+
import { parentPort } from 'node:worker_threads'
|
|
8
|
+
|
|
9
|
+
const require = createRequire(import.meta.url)
|
|
10
|
+
|
|
11
|
+
async function main() {
|
|
12
|
+
if (parentPort === null) return
|
|
13
|
+
const occtimportjs = require('occt-import-js')
|
|
14
|
+
const occt = await occtimportjs()
|
|
15
|
+
|
|
16
|
+
parentPort.on('message', (request) => {
|
|
17
|
+
try {
|
|
18
|
+
const bytes = new Uint8Array(request.buffer)
|
|
19
|
+
const result =
|
|
20
|
+
request.format === 'step' ? occt.ReadStepFile(bytes, null)
|
|
21
|
+
: request.format === 'iges' ? occt.ReadIgesFile(bytes, null)
|
|
22
|
+
: occt.ReadBrepFile(bytes, null)
|
|
23
|
+
if (!result.success || result.meshes === undefined || result.meshes.length === 0) {
|
|
24
|
+
parentPort.postMessage({ jobId: request.jobId, ok: false, error: `the ${request.format.toUpperCase()} file parsed but contains no tessellatable geometry` })
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
const transfers = []
|
|
28
|
+
const meshes = result.meshes.map((mesh) => {
|
|
29
|
+
const positionArray = mesh.attributes?.position?.array
|
|
30
|
+
if (positionArray === undefined || positionArray.length < 9) return null
|
|
31
|
+
const positions = Float32Array.from(positionArray)
|
|
32
|
+
const normalSource = mesh.attributes?.normal?.array
|
|
33
|
+
const normals = normalSource !== undefined && normalSource.length === positions.length ? Float32Array.from(normalSource) : null
|
|
34
|
+
const indexSource = mesh.index?.array
|
|
35
|
+
const indices = indexSource !== undefined && indexSource.length > 0
|
|
36
|
+
? Uint32Array.from(indexSource)
|
|
37
|
+
: Uint32Array.from({ length: positions.length / 3 }, (_, i) => i)
|
|
38
|
+
transfers.push(positions.buffer, indices.buffer)
|
|
39
|
+
if (normals !== null) transfers.push(normals.buffer)
|
|
40
|
+
const color = mesh.color
|
|
41
|
+
return {
|
|
42
|
+
name: mesh.name && mesh.name !== '' ? mesh.name : 'part',
|
|
43
|
+
positions,
|
|
44
|
+
normals: normals === null ? undefined : normals,
|
|
45
|
+
indices,
|
|
46
|
+
color: color === undefined ? undefined
|
|
47
|
+
: (Math.round(color[0] * 255) << 16) | (Math.round(color[1] * 255) << 8) | Math.round(color[2] * 255),
|
|
48
|
+
}
|
|
49
|
+
}).filter((mesh) => mesh !== null)
|
|
50
|
+
if (meshes.length === 0) {
|
|
51
|
+
parentPort.postMessage({ jobId: request.jobId, ok: false, error: `the ${request.format.toUpperCase()} file contains no meshes with geometry` })
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
parentPort.postMessage({ jobId: request.jobId, ok: true, meshes }, transfers)
|
|
55
|
+
} catch (error) {
|
|
56
|
+
parentPort.postMessage({ jobId: request.jobId, ok: false, error: error instanceof Error ? error.message : String(error) })
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
void main()
|