1
1
import { BlobReader , Entry , TextWriter , Uint8ArrayWriter , ZipReader } from '@zip.js/zip.js'
2
- import { Color , Group , Mesh , MeshStandardMaterial , Object3D , Vector3 } from 'three'
2
+ import { BufferGeometry , Color , EdgesGeometry , Group , LineBasicMaterial , LineSegments , Mesh , MeshStandardMaterial , Object3D , Vector3 } from 'three'
3
3
import { GLTF , GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
4
4
5
5
const GLTF = new GLTFLoader ( )
@@ -68,7 +68,6 @@ export async function parseFCStdModel(data: ReadableStream | BlobReader, brep2Gl
68
68
// Data stuctures
69
69
const colors : { [ name : string ] : MeshStandardMaterial [ ] } = { }
70
70
const breps : { [ name : string ] : Entry } = { }
71
- const gltfs : { [ name : string ] : GLTF } = { }
72
71
// Main document
73
72
let doc : FreeCADDocument
74
73
let guiDoc : Document
@@ -126,13 +125,40 @@ export async function parseFCStdModel(data: ReadableStream | BlobReader, brep2Gl
126
125
model . rotateX ( - Math . PI / 2 )
127
126
for ( const obj of Object . values ( doc . objects ) ) {
128
127
if ( obj . isVisible ( ) ) {
129
- model . add ( await convertFCObject ( obj , colors , breps , gltfs , brep2Glb ) )
128
+ model . add ( await convertFCObject ( obj , colors , breps , brep2Glb ) )
130
129
}
131
130
}
132
131
return model
133
132
}
134
133
135
- async function convertFCObject ( obj : FreeCADObject , colors : { [ name : string ] : MeshStandardMaterial [ ] } , breps : { [ name : string ] : Entry } , gltfs : { [ name : string ] : GLTF } , brep2Glb : ( content : string ) => Promise < Uint8Array > ) {
134
+ function makeWire ( object : Object3D ) : Object3D {
135
+ if ( object instanceof Group ) {
136
+ const group = new Group ( )
137
+ group . rotation . copy ( object . rotation )
138
+ group . position . copy ( object . position )
139
+
140
+ for ( const child of object . children ) {
141
+ group . add ( makeWire ( child ) )
142
+ }
143
+
144
+ return group
145
+ } else if ( object instanceof Mesh ) {
146
+ const geometry = object . geometry as BufferGeometry
147
+
148
+ const edge_geometry = new EdgesGeometry ( geometry . clone ( ) , 45 )
149
+ const edge_material = new LineBasicMaterial ( { color : 'black' } )
150
+
151
+ const lines = new LineSegments ( edge_geometry , edge_material )
152
+ lines . position . copy ( object . position )
153
+ lines . rotation . copy ( object . rotation )
154
+
155
+ return lines
156
+ } else {
157
+ throw 'Unexpected object type: ' + object . constructor . name
158
+ }
159
+ }
160
+
161
+ async function convertFCObject ( obj : FreeCADObject , colors : { [ name : string ] : MeshStandardMaterial [ ] } , breps : { [ name : string ] : Entry } , brep2Glb : ( content : string ) => Promise < Uint8Array > ) {
136
162
const container = new Group ( )
137
163
container . name = obj . label
138
164
if ( obj . placement ) {
@@ -146,20 +172,17 @@ async function convertFCObject(obj: FreeCADObject, colors: {[name: string]: Mesh
146
172
try {
147
173
const file = obj . brep
148
174
// Parse brep
149
- if ( ! ( file in gltfs ) ) {
150
- const entry = breps [ obj . brep ]
151
- const writer = new TextWriter ( )
152
- const content = await entry . getData ( writer )
153
- //console.log('Converting', file)
154
- const data = await brep2Glb ( content )
155
- //console.log('Parsing', file)
156
- gltfs [ file ] = await new Promise < GLTF > ( ( resolve , reject ) => {
157
- GLTF . parse ( data . buffer , undefined , resolve , reject )
158
- } )
159
- }
160
- // Clone scene
161
- const face = gltfs [ file ] . scene . clone ( true )
162
- const wire = gltfs [ file ] . scene . clone ( true )
175
+ const entry = breps [ file ]
176
+ const writer = new TextWriter ( )
177
+ const content = await entry . getData ( writer )
178
+ //console.log('Converting', file)
179
+ const data = await brep2Glb ( content )
180
+ const gltf = await new Promise < GLTF > ( ( resolve , reject ) => {
181
+ GLTF . parse ( data . buffer , undefined , resolve , reject )
182
+ } )
183
+ //console.log('Parsing', file)
184
+ const face = gltf . scene
185
+ const wire = makeWire ( face )
163
186
// Update mesh materials
164
187
traverse ( face , colors [ obj . diffuse ] [ 0 ] )
165
188
traverse ( wire , new MeshStandardMaterial ( { color : 'black' , wireframe : true } ) )
@@ -172,7 +195,7 @@ async function convertFCObject(obj: FreeCADObject, colors: {[name: string]: Mesh
172
195
} else if ( obj . group ) {
173
196
for ( const child of obj . group ) {
174
197
if ( child . isVisible ( ) ) {
175
- container . add ( await convertFCObject ( child , colors , breps , gltfs , brep2Glb ) )
198
+ container . add ( await convertFCObject ( child , colors , breps , brep2Glb ) )
176
199
}
177
200
}
178
201
}
0 commit comments