1- import { BlobReader , TextWriter , Uint8ArrayWriter , ZipReader } from '@zip.js/zip.js'
1+ import { BlobReader , Entry , TextWriter , Uint8ArrayWriter , ZipReader } from '@zip.js/zip.js'
22import { Color , Group , Mesh , MeshStandardMaterial , Object3D } from 'three'
33import { GLTF , GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
44
@@ -29,7 +29,6 @@ export class FreeCADObject {
2929 public visibility : boolean
3030
3131 public shape_file : string
32- public shape_gltf : GLTF
3332
3433 constructor ( public name : string , public type : string ) { }
3534
@@ -58,7 +57,7 @@ function traverse(object: Object3D, material: MeshStandardMaterial) {
5857
5958export async function parseFCStdModel ( data : ReadableStream | BlobReader , brep2Glb : ( content : string ) => Promise < Uint8Array > ) {
6059 const diffuse : { [ name : string ] : MeshStandardMaterial [ ] } = { }
61- const gltfs : { [ name : string ] : GLTF } = { }
60+ const breps : { [ name : string ] : Entry } = { }
6261 let doc : FreeCADDocument
6362 const reader = new ZipReader ( data )
6463 const parser = new DOMParser ( )
@@ -87,35 +86,10 @@ export async function parseFCStdModel(data: ReadableStream | BlobReader, brep2Gl
8786 diffuse [ entry . filename ] . push ( material )
8887 }
8988 } else if ( entry . filename . endsWith ( '.brp' ) ) {
90- try {
91- // Parse BRep file
92- const writer = new TextWriter ( )
93- const content = await entry . getData ( writer )
94- console . log ( 'Parsing' , entry . filename )
95- const glbFileData = await brep2Glb ( content )
96- gltfs [ entry . filename ] = await new Promise < GLTF > ( ( resolve , reject ) => {
97- GLTF . parse ( glbFileData . buffer , undefined , resolve , reject )
98- } )
99- } catch ( e ) {
100- console . log ( e )
101- }
89+ breps [ entry . filename ] = entry
10290 }
10391 }
10492 await reader . close ( )
105- // Update mesh materials
106- for ( const file of Object . keys ( gltfs ) ) {
107- const other = file . replace ( 'PartShape' , 'DiffuseColor' ) . replace ( '.brp' , '' )
108- if ( other in diffuse ) {
109- const material = diffuse [ other ] [ 0 ]
110- traverse ( gltfs [ file ] . scene , material )
111- }
112- }
113- // Connect BReps to objects
114- for ( const object of Object . values ( doc . objects ) ) {
115- if ( object . shape_file in gltfs ) {
116- object . shape_gltf = gltfs [ object . shape_file ]
117- }
118- }
11993 // Delete objects with parents
12094 for ( const object of Object . values ( doc . objects ) ) {
12195 if ( object . parents . length > 0 ) {
@@ -130,27 +104,45 @@ export async function parseFCStdModel(data: ReadableStream | BlobReader, brep2Gl
130104 model . rotateX ( - Math . PI / 2 )
131105 for ( const obj of Object . values ( doc . objects ) ) {
132106 if ( obj . hasShapeBRep ( ) ) {
133- model . add ( convertFCObject ( obj ) )
107+ model . add ( await convertFCObject ( obj , diffuse , breps , brep2Glb ) )
134108 }
135109 }
136110 return model
137111}
138112
139- function convertFCObject ( obj : FreeCADObject ) {
113+ async function convertFCObject ( obj : FreeCADObject , diffuse : { [ name : string ] : MeshStandardMaterial [ ] } , breps : { [ name : string ] : Entry } , brep2Glb : ( content : string ) => Promise < Uint8Array > ) {
140114 const container = new Group ( )
141115 container . name = obj . label
142116
143117 if ( obj . shape_file ) {
144- if ( obj . shape_gltf ) {
145- const clone = obj . shape_gltf . scene . clone ( true )
118+ try {
119+ // Parse BRep file
120+ const entry = breps [ obj . shape_file ]
121+ const writer = new TextWriter ( )
122+ const content = await entry . getData ( writer )
123+ console . log ( 'Parsing' , entry . filename )
124+ const glbFileData = await brep2Glb ( content )
125+ const gltf = await new Promise < GLTF > ( ( resolve , reject ) => {
126+ GLTF . parse ( glbFileData . buffer , undefined , resolve , reject )
127+ } )
128+ const clone = gltf . scene . clone ( true )
129+ // Update mesh materials
130+ const other = entry . filename . replace ( 'PartShape' , 'DiffuseColor' ) . replace ( '.brp' , '' )
131+ if ( other in diffuse ) {
132+ const material = diffuse [ other ] [ 0 ]
133+ traverse ( gltf . scene , material )
134+ }
146135 traverse ( clone , new MeshStandardMaterial ( { color : 'black' , wireframe : true } ) )
136+ // Add scene objects
147137 container . add ( clone )
148- container . add ( obj . shape_gltf . scene )
138+ container . add ( gltf . scene )
139+ } catch ( e ) {
140+ console . log ( e )
149141 }
150142 } else if ( obj . group ) {
151143 for ( const child of obj . group ) {
152144 if ( child . hasShapeBRep ( ) ) {
153- container . add ( convertFCObject ( child ) )
145+ container . add ( await convertFCObject ( child , diffuse , breps , brep2Glb ) )
154146 }
155147 }
156148 }
0 commit comments