@ae-studio/dxf-viewer
Advanced tools
Comparing version
{ | ||
"name": "@ae-studio/dxf-viewer", | ||
"version": "1.1.7", | ||
"version": "1.1.9", | ||
"description": "JavaScript DXF file viewer", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -187,47 +187,187 @@ import * as three from 'three'; | ||
try { | ||
this.Clear(); | ||
this.Clear(); | ||
this.worker = new DxfWorker(workerFactory ? workerFactory() : null); | ||
const { scene, sceneData, dxf } = await this.worker.Load( | ||
url, | ||
fonts, | ||
this.options, | ||
progressCbk, | ||
); | ||
this.worker = new DxfWorker(workerFactory ? workerFactory() : null); | ||
const { scene, sceneData, dxf } = await this.worker.Load(url, fonts, this.options, progressCbk); | ||
await this.worker.Destroy(); | ||
this.worker = null; | ||
this.parsedDxf = dxf; | ||
// Add safety check | ||
if (!scene) { | ||
throw new Error('Failed to load scene data'); | ||
this.origin = scene.origin; | ||
this.bounds = scene.bounds; | ||
this.hasMissingChars = scene.hasMissingChars; | ||
this.sceneData = sceneData; | ||
for (const layer of scene.layers) { | ||
this.layers.set(layer.name, new Layer(layer.name, layer.displayName, layer.color)); | ||
} | ||
/* Load all blocks on the first pass. */ | ||
for (const batch of scene.batches) { | ||
if ( | ||
batch.key.blockName !== null && | ||
batch.key.geometryType !== BatchingKey.GeometryType.BLOCK_INSTANCE && | ||
batch.key.geometryType !== BatchingKey.GeometryType.POINT_INSTANCE | ||
) { | ||
let block = this.blocks.get(batch.key.blockName); | ||
if (!block) { | ||
block = new Block(); | ||
this.blocks.set(batch.key.blockName, block); | ||
} | ||
const positions = this.GetBatchPositions(batch.key.blockName, scene); | ||
block.PushBatch( | ||
new Batch( | ||
this, | ||
scene, | ||
{ | ||
...batch, | ||
positions, | ||
}, | ||
batch.key.blockName, | ||
), | ||
); | ||
} | ||
} | ||
await this.worker.Destroy(); | ||
this.worker = null; | ||
this.parsedDxf = dxf; | ||
console.log(`DXF scene: | ||
${scene.batches.length} batches, | ||
${this.layers.size} layers, | ||
${this.blocks.size} blocks, | ||
vertices ${scene.vertices.byteLength} B, | ||
indices ${scene.indices.byteLength} B | ||
transforms ${scene.transforms.byteLength} B`); | ||
// Add safety checks for scene properties | ||
this.origin = scene.origin || { x: 0, y: 0 }; | ||
this.bounds = scene.bounds || null; | ||
this.hasMissingChars = scene.hasMissingChars || false; | ||
/* Instantiate all entities. */ | ||
for (const batch of scene.batches) { | ||
this._LoadBatch(scene, batch); | ||
} | ||
this.sceneData = sceneData; | ||
const bypass = true; | ||
// Add safety check for layers | ||
if (scene.layers) { | ||
for (const layer of scene.layers) { | ||
if (layer && layer.name) { | ||
this.layers.set(layer.name, new Layer(layer.name, layer.displayName, layer.color)); | ||
// console.log('sceneData.insertBlocks', ) | ||
//XXX line type | ||
for (const [key, { batches }] of sceneData.insertBlocks.entries()) { | ||
const handledObjects = []; | ||
for (const batch of batches) { | ||
if (batch.chunks) { | ||
for (const chunk of batch.chunks) { | ||
const object = this.CreateViewerObject({ | ||
batch, | ||
indices: chunk.indices, | ||
vertices: chunk.vertices, | ||
}); | ||
handledObjects.push(object); | ||
} | ||
} else { | ||
const object = this.CreateViewerObject({ | ||
batch, | ||
indices: null, | ||
vertices: batch.vertices, | ||
}); | ||
handledObjects.push(object); | ||
} | ||
} | ||
// Rest of the loading logic... | ||
} catch (error) { | ||
// Clean up on error | ||
if (this.worker) { | ||
await this.worker.Destroy(); | ||
this.worker = null; | ||
this.objects.set(key, handledObjects); | ||
} | ||
for (const [key, { batches }] of this.blocks.entries()) { | ||
if (this.objects.has(key)) { | ||
continue; | ||
} | ||
throw error; | ||
const block = sceneData.blocks ? sceneData.blocks.get(key) : undefined; | ||
const handledObjects = []; | ||
for (const batch of batches) { | ||
if (batch.chunks) { | ||
for (const chunk of batch.chunks) { | ||
const object = this.CreateViewerObject({ | ||
batch, | ||
indices: chunk.indices, | ||
vertices: chunk.vertices, | ||
}); | ||
object.userData.block = block; | ||
handledObjects.push(object); | ||
} | ||
} else { | ||
if (batch.positions.size === 0) { | ||
const object = this.CreateViewerObject({ | ||
batch, | ||
indices: null, | ||
vertices: batch.vertices, | ||
}); | ||
object.userData.block = block; | ||
handledObjects.push(object); | ||
continue; | ||
} | ||
const [_key, { block: positionBlock }] = Array.from(batch.positions)[0]; | ||
const blockBatch = positionBlock.batches[0]; | ||
if (blockBatch.chunks) { | ||
for (const chunk of blockBatch.chunks) { | ||
const object = this.CreateViewerObject({ | ||
batch, | ||
indices: chunk.indices, | ||
vertices: chunk.vertices, | ||
}); | ||
object.userData.block = block; | ||
handledObjects.push(object); | ||
} | ||
} else { | ||
const object = this.CreateViewerObject({ | ||
batch, | ||
indices: null, | ||
vertices: blockBatch.vertices, | ||
}); | ||
object.userData.block = block; | ||
handledObjects.push(object); | ||
} | ||
} | ||
} | ||
this.objects.set(key, handledObjects); | ||
} | ||
this._Emit('loaded'); | ||
if (scene.bounds) { | ||
this.FitView( | ||
scene.bounds.minX - scene.origin.x, | ||
scene.bounds.maxX - scene.origin.x, | ||
scene.bounds.minY - scene.origin.y, | ||
scene.bounds.maxY - scene.origin.y, | ||
); | ||
} else { | ||
this._Message('Empty document', MessageLevel.WARN); | ||
} | ||
if (this.hasMissingChars) { | ||
this._Message( | ||
'Some characters cannot be properly displayed due to missing fonts', | ||
MessageLevel.WARN, | ||
); | ||
} | ||
this._CreateControls(); | ||
this.Render(); | ||
} | ||
@@ -324,7 +464,2 @@ | ||
} | ||
// Add explicit disposal | ||
this._disposeGeometries(); | ||
this._disposeMaterials(); | ||
this.scene.clear(); | ||
@@ -336,7 +471,4 @@ for (const layer of this.layers.values()) { | ||
this.blocks.clear(); | ||
// Clear references to large data | ||
this.sceneData = null; | ||
this.parsedDxf = null; | ||
this.materials.each((e) => e.material.dispose()); | ||
this.materials.clear(); | ||
this.SetView({ x: 0, y: 0 }, 2); | ||
@@ -850,38 +982,2 @@ this._Emit('cleared'); | ||
} | ||
_disposeGeometries() { | ||
if (!this.scene) return; | ||
this.scene.traverse((object) => { | ||
if (object?.geometry) { | ||
object.geometry.dispose(); | ||
} | ||
}); | ||
} | ||
_disposeMaterials() { | ||
if (!this.materials) return; | ||
this.materials.each((entry) => { | ||
if (entry?.material) { | ||
entry.material.dispose(); | ||
} | ||
}); | ||
this.materials.clear(); | ||
} | ||
_getPooledMaterial(color, instanceType) { | ||
const key = `${color}_${instanceType}`; | ||
if (!this._materialPool) { | ||
this._materialPool = new Map(); | ||
} | ||
if (this._materialPool.has(key)) { | ||
return this._materialPool.get(key); | ||
} | ||
const material = this._CreateSimpleColorMaterialInstance(color, instanceType); | ||
this._materialPool.set(key, material); | ||
return material; | ||
} | ||
} | ||
@@ -888,0 +984,0 @@ |
@@ -36,27 +36,11 @@ import { DxfFetcher } from './DxfFetcher'; | ||
async Load(url, fonts, options, progressCbk) { | ||
const { scene, sceneData, dxf } = await this._Load(url, fonts, options, progressCbk); | ||
// Only transfer buffers if they exist | ||
const transfers = []; | ||
if (scene.vertices && scene.vertices.buffer) { | ||
transfers.push(scene.vertices.buffer); | ||
if (this.worker) { | ||
return this._SendRequest( | ||
DxfWorker.WorkerMsg.LOAD, | ||
{ url, fonts, options: this._CloneOptions(options) }, | ||
progressCbk, | ||
); | ||
} else { | ||
return this._Load(url, fonts, options, progressCbk); | ||
} | ||
if (scene.indices && scene.indices.buffer) { | ||
transfers.push(scene.indices.buffer); | ||
} | ||
if (scene.transforms && scene.transforms.buffer) { | ||
transfers.push(scene.transforms.buffer); | ||
} | ||
// Only clear buffer references if they exist | ||
if (scene.vertices) scene.vertices = null; | ||
if (scene.indices) scene.indices = null; | ||
if (scene.transforms) scene.transforms = null; | ||
// Optimize and return the data | ||
return { | ||
scene, | ||
sceneData: this._optimizeSceneData(sceneData), | ||
dxf: options.retainParsedDxf === true ? this._optimizeDxf(dxf) : undefined, | ||
}; | ||
} | ||
@@ -237,44 +221,2 @@ | ||
} | ||
_optimizeSceneData(sceneData) { | ||
if (!sceneData) return null; | ||
// Safely remove properties if they exist | ||
if (sceneData.hasOwnProperty('unmappedInserts')) { | ||
delete sceneData.unmappedInserts; | ||
} | ||
if (sceneData.hasOwnProperty('vars')) { | ||
delete sceneData.vars; | ||
} | ||
// Safely handle blocks | ||
if (sceneData.blocks) { | ||
for (const [_key, block] of sceneData.blocks) { | ||
if (block) { | ||
if (block.hasOwnProperty('data')) { | ||
delete block.data; | ||
} | ||
if (block.hasOwnProperty('entities')) { | ||
delete block.entities; | ||
} | ||
} | ||
} | ||
} | ||
return sceneData; | ||
} | ||
_optimizeDxf(dxf) { | ||
if (!dxf) return null; | ||
const optimized = { | ||
header: dxf.header || {}, | ||
tables: { | ||
layer: { | ||
layers: dxf.tables?.layer?.layers || new Map(), | ||
}, | ||
}, | ||
}; | ||
return optimized; | ||
} | ||
} | ||
@@ -281,0 +223,0 @@ |
Sorry, the diff of this file is too big to display
880395
0.15%21887
0.12%