@ifc-lite/wasm 1.0.0 → 1.1.1
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/README.md +175 -332
- package/package.json +17 -25
- package/pkg/ifc-lite.d.ts +592 -0
- package/{ifc_lite_wasm.js → pkg/ifc-lite.js} +777 -12
- package/pkg/ifc-lite_bg.wasm +0 -0
- package/ifc_lite_wasm.d.ts +0 -296
- package/ifc_lite_wasm_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -1,402 +1,245 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/logo.svg" alt="IFC-Lite Logo" width="120" height="120">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">IFC-Lite</h1>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>High-performance browser-native IFC platform</strong>
|
|
9
|
+
</p>
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://github.com/louistrue/ifc-lite/actions"><img src="https://img.shields.io/github/actions/workflow/status/louistrue/ifc-lite/ci.yml?branch=main&style=flat-square&logo=github" alt="Build Status"></a>
|
|
13
|
+
<a href="https://github.com/louistrue/ifc-lite/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MPL--2.0-blue?style=flat-square" alt="License"></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/@ifc-lite/parser"><img src="https://img.shields.io/npm/v/@ifc-lite/parser?style=flat-square&logo=npm&label=parser" alt="npm parser"></a>
|
|
15
|
+
<a href="https://crates.io/crates/ifc-lite-core"><img src="https://img.shields.io/crates/v/ifc-lite-core?style=flat-square&logo=rust&label=core" alt="crates.io"></a>
|
|
16
|
+
</p>
|
|
8
17
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="#features">Features</a> •
|
|
20
|
+
<a href="#quick-start">Quick Start</a> •
|
|
21
|
+
<a href="#documentation">Documentation</a> •
|
|
22
|
+
<a href="#architecture">Architecture</a> •
|
|
23
|
+
<a href="#performance">Performance</a> •
|
|
24
|
+
<a href="#contributing">Contributing</a>
|
|
25
|
+
</p>
|
|
12
26
|
|
|
13
|
-
|
|
27
|
+
---
|
|
14
28
|
|
|
15
|
-
|
|
16
|
-
- **100x faster** queries with columnar data structures
|
|
17
|
-
- **Zero-copy** memory access for direct GPU upload
|
|
18
|
-
- **Streaming** parser for progressive rendering
|
|
29
|
+
## Overview
|
|
19
30
|
|
|
20
|
-
|
|
31
|
+
**IFC-Lite** is a next-generation IFC (Industry Foundation Classes) platform built with **Rust + WebAssembly** for parsing, geometry processing, and **WebGPU** for 3D visualization. It's designed to be a **95x smaller** and significantly faster alternative to existing web-based IFC solutions.
|
|
21
32
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
### Basic Usage
|
|
27
|
-
|
|
28
|
-
```javascript
|
|
29
|
-
import { IfcAPI } from '@ifc-lite/wasm';
|
|
30
|
-
|
|
31
|
-
// Initialize
|
|
32
|
-
const api = new IfcAPI();
|
|
33
|
-
|
|
34
|
-
// Parse IFC file
|
|
35
|
-
const result = await api.parse(ifcData);
|
|
36
|
-
console.log('Entities:', result.entityCount);
|
|
37
|
-
console.log('Types:', result.entityTypes);
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## 📚 API Documentation
|
|
33
|
+
<p align="center">
|
|
34
|
+
<strong>~86 KB total</strong> • <strong>1.9x faster</strong> • <strong>100% IFC4 schema</strong>
|
|
35
|
+
</p>
|
|
41
36
|
|
|
42
|
-
|
|
37
|
+
## Features
|
|
43
38
|
|
|
44
|
-
|
|
39
|
+
| Feature | Description |
|
|
40
|
+
|---------|-------------|
|
|
41
|
+
| **STEP/IFC Parsing** | Zero-copy tokenization at ~1,259 MB/s with full IFC4 schema support (776 entities) |
|
|
42
|
+
| **Streaming Pipeline** | Progressive geometry processing - first triangles render in 300-500ms |
|
|
43
|
+
| **WebGPU Rendering** | Modern GPU-accelerated 3D visualization with depth testing and frustum culling |
|
|
44
|
+
| **Columnar Storage** | Memory-efficient TypedArray storage with 30% string deduplication |
|
|
45
|
+
| **Zero-Copy GPU** | Direct WASM memory binding to GPU buffers |
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
## Quick Start
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
const api = new IfcAPI();
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Creates and initializes a new IFC API instance. Automatically sets up panic hooks for better error messages in development.
|
|
49
|
+
### Prerequisites
|
|
53
50
|
|
|
54
|
-
|
|
51
|
+
- **Node.js** 18.0+ with **pnpm** 8.0+
|
|
52
|
+
- **Rust** toolchain with wasm32-unknown-unknown target
|
|
53
|
+
- Modern browser with **WebGPU** support (Chrome 113+, Edge 113+, Firefox 127+, Safari 18+)
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
- `is_ready: boolean` - Check if API is initialized
|
|
55
|
+
### Installation
|
|
58
56
|
|
|
59
|
-
|
|
57
|
+
```bash
|
|
58
|
+
# Clone the repository
|
|
59
|
+
git clone https://github.com/louistrue/ifc-lite.git
|
|
60
|
+
cd ifc-lite
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
# Install dependencies
|
|
63
|
+
pnpm install
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
# Build all packages
|
|
66
|
+
pnpm build
|
|
64
67
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
# Run the viewer
|
|
69
|
+
cd apps/viewer
|
|
70
|
+
pnpm dev
|
|
68
71
|
```
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
- You need quick entity statistics
|
|
72
|
-
- File is small-to-medium size
|
|
73
|
-
- You don't need progressive feedback
|
|
74
|
-
|
|
75
|
-
**Example:**
|
|
76
|
-
```javascript
|
|
77
|
-
const result = await api.parse(ifcData);
|
|
78
|
-
|
|
79
|
-
console.log(`Total entities: ${result.entityCount}`);
|
|
73
|
+
### Basic Usage
|
|
80
74
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
```
|
|
75
|
+
```typescript
|
|
76
|
+
import { IfcParser } from '@ifc-lite/parser';
|
|
77
|
+
import { Renderer } from '@ifc-lite/renderer';
|
|
86
78
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
```javascript
|
|
92
|
-
await api.parseStreaming(ifcData, (event) => {
|
|
93
|
-
switch(event.type) {
|
|
94
|
-
case 'started':
|
|
95
|
-
console.log(`Parsing ${event.fileSize} bytes`);
|
|
96
|
-
break;
|
|
97
|
-
case 'progress':
|
|
98
|
-
updateProgressBar(event.percent);
|
|
99
|
-
break;
|
|
100
|
-
case 'entityScanned':
|
|
101
|
-
console.log(`Found ${event.ifcType} #${event.id}`);
|
|
102
|
-
break;
|
|
103
|
-
case 'completed':
|
|
104
|
-
console.log(`Done in ${event.durationMs}ms`);
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
```
|
|
79
|
+
// Parse IFC file
|
|
80
|
+
const parser = new IfcParser();
|
|
81
|
+
const result = await parser.parse(ifcArrayBuffer);
|
|
109
82
|
|
|
110
|
-
|
|
83
|
+
// Access entities
|
|
84
|
+
const walls = result.entities.filter(e => e.type === 'IFCWALL');
|
|
85
|
+
console.log(`Found ${walls.length} walls`);
|
|
111
86
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
| { type: 'geometryReady'; id: number; vertexCount: number; triangleCount: number }
|
|
117
|
-
| { type: 'progress'; phase: string; percent: number; entitiesProcessed: number; totalEntities: number }
|
|
118
|
-
| { type: 'completed'; durationMs: number; entityCount: number; triangleCount: number }
|
|
119
|
-
| { type: 'error'; message: string; position?: number };
|
|
87
|
+
// Render geometry
|
|
88
|
+
const renderer = new Renderer(canvas);
|
|
89
|
+
await renderer.loadGeometry(result.geometry);
|
|
90
|
+
renderer.render();
|
|
120
91
|
```
|
|
121
92
|
|
|
122
|
-
|
|
123
|
-
- File is large (>5 MB)
|
|
124
|
-
- You need to show progress
|
|
125
|
-
- You want to start rendering before parsing completes
|
|
126
|
-
|
|
127
|
-
**Example: Progressive Rendering**
|
|
128
|
-
```javascript
|
|
129
|
-
const viewer = new IFCViewer();
|
|
130
|
-
|
|
131
|
-
await api.parseStreaming(ifcData, (event) => {
|
|
132
|
-
if (event.type === 'geometryReady') {
|
|
133
|
-
// Render geometry as soon as it's ready
|
|
134
|
-
viewer.addMesh(event.id, /* ... */);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (event.type === 'progress') {
|
|
138
|
-
document.getElementById('progress').value = event.percent;
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
```
|
|
93
|
+
## Documentation
|
|
142
94
|
|
|
143
|
-
|
|
95
|
+
| Resource | Description |
|
|
96
|
+
|----------|-------------|
|
|
97
|
+
| [**User Guide**](https://louistrue.github.io/ifc-lite/) | Complete guide with tutorials and examples |
|
|
98
|
+
| [**API Reference**](https://louistrue.github.io/ifc-lite/api/) | Rustdoc API documentation |
|
|
99
|
+
| [**Architecture**](docs/architecture.md) | System design and data flow |
|
|
100
|
+
| [**Contributing**](CONTRIBUTING.md) | How to contribute to the project |
|
|
144
101
|
|
|
145
|
-
|
|
102
|
+
## Architecture
|
|
146
103
|
|
|
147
|
-
|
|
148
|
-
const mesh = await api.parseZeroCopy(ifcData);
|
|
149
|
-
const memory = await api.getMemory();
|
|
104
|
+
IFC files flow through three layers:
|
|
150
105
|
|
|
151
|
-
|
|
152
|
-
const positions = new Float32Array(
|
|
153
|
-
memory.buffer,
|
|
154
|
-
mesh.positions_ptr,
|
|
155
|
-
mesh.positions_len
|
|
156
|
-
);
|
|
106
|
+
**Parser** (Rust/WASM) — Zero-copy STEP tokenizer, entity scanner, and geometry processor using nom, earcutr, and nalgebra.
|
|
157
107
|
|
|
158
|
-
|
|
159
|
-
memory.buffer,
|
|
160
|
-
mesh.indices_ptr,
|
|
161
|
-
mesh.indices_len
|
|
162
|
-
);
|
|
108
|
+
**Data** (TypeScript) — Columnar TypedArrays for properties, CSR graph for relationships, GPU-ready geometry buffers.
|
|
163
109
|
|
|
164
|
-
|
|
165
|
-
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
|
|
166
|
-
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
|
167
|
-
```
|
|
110
|
+
**Output** — WebGPU renderer, Parquet analytics, glTF/JSON-LD/CSV export.
|
|
168
111
|
|
|
169
|
-
|
|
112
|
+
## Project Structure
|
|
170
113
|
|
|
171
|
-
```typescript
|
|
172
|
-
interface ZeroCopyMesh {
|
|
173
|
-
// Pointers to WASM memory
|
|
174
|
-
positions_ptr: number; // Float32Array pointer
|
|
175
|
-
normals_ptr: number; // Float32Array pointer
|
|
176
|
-
indices_ptr: number; // Uint32Array pointer
|
|
177
|
-
|
|
178
|
-
// Array lengths
|
|
179
|
-
positions_len: number; // Number of f32 elements
|
|
180
|
-
normals_len: number; // Number of f32 elements
|
|
181
|
-
indices_len: number; // Number of u32 elements
|
|
182
|
-
|
|
183
|
-
// Metadata
|
|
184
|
-
vertex_count: number;
|
|
185
|
-
triangle_count: number;
|
|
186
|
-
is_empty: boolean;
|
|
187
|
-
|
|
188
|
-
// Bounding box
|
|
189
|
-
bounds_min(): [number, number, number];
|
|
190
|
-
bounds_max(): [number, number, number];
|
|
191
|
-
}
|
|
192
114
|
```
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
);
|
|
215
|
-
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
|
|
216
|
-
|
|
217
|
-
const normals = new Float32Array(
|
|
218
|
-
memory.buffer,
|
|
219
|
-
mesh.normals_ptr,
|
|
220
|
-
mesh.normals_len
|
|
221
|
-
);
|
|
222
|
-
geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3));
|
|
223
|
-
|
|
224
|
-
const indices = new Uint32Array(
|
|
225
|
-
memory.buffer,
|
|
226
|
-
mesh.indices_ptr,
|
|
227
|
-
mesh.indices_len
|
|
228
|
-
);
|
|
229
|
-
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
|
|
230
|
-
|
|
231
|
-
// Create mesh and add to scene
|
|
232
|
-
const material = new THREE.MeshStandardMaterial({ color: 0x888888 });
|
|
233
|
-
const threeMesh = new THREE.Mesh(geometry, material);
|
|
234
|
-
scene.add(threeMesh);
|
|
115
|
+
ifc-lite/
|
|
116
|
+
├── rust/ # Rust/WASM backend
|
|
117
|
+
│ ├── core/ # IFC/STEP parsing (~2,000 LOC)
|
|
118
|
+
│ ├── geometry/ # Geometry processing (~2,500 LOC)
|
|
119
|
+
│ └── wasm-bindings/ # JavaScript API (~800 LOC)
|
|
120
|
+
│
|
|
121
|
+
├── packages/ # TypeScript packages
|
|
122
|
+
│ ├── parser/ # High-level IFC parser
|
|
123
|
+
│ ├── geometry/ # Geometry bridge (WASM)
|
|
124
|
+
│ ├── renderer/ # WebGPU rendering
|
|
125
|
+
│ ├── query/ # Query system
|
|
126
|
+
│ ├── data/ # Columnar data structures
|
|
127
|
+
│ ├── spatial/ # Spatial indexing
|
|
128
|
+
│ ├── export/ # Export formats
|
|
129
|
+
│ └── codegen/ # Schema generator
|
|
130
|
+
│
|
|
131
|
+
├── apps/
|
|
132
|
+
│ └── viewer/ # React web application
|
|
133
|
+
│
|
|
134
|
+
├── docs/ # Documentation (MkDocs)
|
|
135
|
+
└── plan/ # Technical specifications
|
|
235
136
|
```
|
|
236
137
|
|
|
237
|
-
##
|
|
138
|
+
## Performance
|
|
238
139
|
|
|
239
|
-
|
|
240
|
-
|--------|----------|-------------|--------|------------|
|
|
241
|
-
| `parse()` | Entity counting, stats | Fast | Low | ⭐ Simple |
|
|
242
|
-
| `parseStreaming()` | Large files, progress | Fast | Low | ⭐⭐ Moderate |
|
|
243
|
-
| `parseZeroCopy()` | 3D rendering, GPU | **Fastest** | **Lowest** | ⭐⭐⭐ Advanced |
|
|
140
|
+
### Bundle Size Comparison
|
|
244
141
|
|
|
245
|
-
|
|
142
|
+
| Library | Size | Gzipped |
|
|
143
|
+
|---------|------|---------|
|
|
144
|
+
| **IFC-Lite** | **~86 KB** | **~28 KB** |
|
|
145
|
+
| Traditional WASM | 8+ MB | N/A |
|
|
146
|
+
| **Reduction** | **93%** | - |
|
|
246
147
|
|
|
247
|
-
###
|
|
148
|
+
### Parse Performance
|
|
248
149
|
|
|
249
|
-
|
|
250
|
-
|
|
150
|
+
| Model Size | IFC-Lite | Notes |
|
|
151
|
+
|------------|----------|-------|
|
|
152
|
+
| 10 MB | ~800ms | Small models |
|
|
153
|
+
| 50 MB | ~2.7s | Typical models |
|
|
154
|
+
| 100+ MB | ~5s+ | Complex geometry |
|
|
251
155
|
|
|
252
|
-
|
|
253
|
-
// Use streaming for large files
|
|
254
|
-
await api.parseStreaming(ifcData, handleEvent);
|
|
255
|
-
} else {
|
|
256
|
-
// Use simple parse for small files
|
|
257
|
-
const result = await api.parse(ifcData);
|
|
258
|
-
}
|
|
259
|
-
```
|
|
156
|
+
### Geometry Processing
|
|
260
157
|
|
|
261
|
-
|
|
158
|
+
- **1.9x faster** mesh extraction than traditional solutions
|
|
159
|
+
- Streaming pipeline with batched processing (100 meshes/batch)
|
|
160
|
+
- First triangles visible in **300-500ms**
|
|
262
161
|
|
|
263
|
-
|
|
264
|
-
// ❌ Don't copy data unnecessarily
|
|
265
|
-
const positions = mesh.positions.slice(); // COPYING!
|
|
162
|
+
## Browser Requirements
|
|
266
163
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
```
|
|
164
|
+
| Browser | Minimum Version | WebGPU |
|
|
165
|
+
|---------|----------------|--------|
|
|
166
|
+
| Chrome | 113+ | ✅ |
|
|
167
|
+
| Edge | 113+ | ✅ |
|
|
168
|
+
| Firefox | 127+ | ✅ |
|
|
169
|
+
| Safari | 18+ | ✅ |
|
|
274
170
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
```javascript
|
|
278
|
-
try {
|
|
279
|
-
const result = await api.parse(ifcData);
|
|
280
|
-
// ... handle result
|
|
281
|
-
} catch (error) {
|
|
282
|
-
if (error.message.includes('Invalid entity reference')) {
|
|
283
|
-
// Handle corrupted IFC file
|
|
284
|
-
showError('This IFC file appears to be corrupted');
|
|
285
|
-
} else {
|
|
286
|
-
// Generic error handling
|
|
287
|
-
showError('Failed to parse IFC file');
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
```
|
|
171
|
+
## Development
|
|
291
172
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
let lastUpdate = 0;
|
|
296
|
-
|
|
297
|
-
await api.parseStreaming(ifcData, (event) => {
|
|
298
|
-
if (event.type === 'progress') {
|
|
299
|
-
// Throttle UI updates to avoid jank
|
|
300
|
-
const now = Date.now();
|
|
301
|
-
if (now - lastUpdate > 100) { // Update every 100ms
|
|
302
|
-
updateProgressBar(event.percent);
|
|
303
|
-
lastUpdate = now;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
## 🔧 Advanced Features
|
|
173
|
+
```bash
|
|
174
|
+
# Watch mode for all packages
|
|
175
|
+
pnpm -r dev
|
|
310
176
|
|
|
311
|
-
|
|
177
|
+
# Build specific package
|
|
178
|
+
cd packages/parser && pnpm build
|
|
312
179
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
const plane = { point: [0, 0, 0], normal: [0, 0, 1] };
|
|
316
|
-
const clipped = await api.clipMesh(mesh, plane);
|
|
317
|
-
```
|
|
180
|
+
# Run tests
|
|
181
|
+
pnpm test
|
|
318
182
|
|
|
319
|
-
|
|
183
|
+
# Build Rust/WASM
|
|
184
|
+
cd rust && cargo build --release --target wasm32-unknown-unknown
|
|
320
185
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
skipTypes: ['IFCOWNERHISTORY', 'IFCPERSON'],
|
|
324
|
-
onlyTypes: ['IFCWALL', 'IFCSLAB', 'IFCBEAM'],
|
|
325
|
-
progressInterval: 100, // Report progress every 100 entities
|
|
326
|
-
};
|
|
186
|
+
# Generate Rustdoc
|
|
187
|
+
cd rust && cargo doc --no-deps --open
|
|
327
188
|
|
|
328
|
-
|
|
189
|
+
# Build documentation site
|
|
190
|
+
cd docs && mkdocs serve
|
|
329
191
|
```
|
|
330
192
|
|
|
331
|
-
##
|
|
193
|
+
## Packages
|
|
332
194
|
|
|
333
|
-
|
|
195
|
+
| Package | Description | Status |
|
|
196
|
+
|---------|-------------|--------|
|
|
197
|
+
| `@ifc-lite/parser` | STEP tokenizer & entity extraction | ✅ Stable |
|
|
198
|
+
| `@ifc-lite/geometry` | Geometry processing bridge | ✅ Stable |
|
|
199
|
+
| `@ifc-lite/renderer` | WebGPU rendering pipeline | ✅ Stable |
|
|
200
|
+
| `@ifc-lite/query` | Fluent & SQL query system | 🚧 Beta |
|
|
201
|
+
| `@ifc-lite/data` | Columnar data structures | ✅ Stable |
|
|
202
|
+
| `@ifc-lite/spatial` | Spatial indexing & culling | 🚧 Beta |
|
|
203
|
+
| `@ifc-lite/export` | Export (glTF, Parquet, etc.) | 🚧 Beta |
|
|
334
204
|
|
|
335
|
-
|
|
336
|
-
|-----------|----------|---------|-------------|
|
|
337
|
-
| Bundle size | 86 KB | 8.2 MB | **95x smaller** |
|
|
338
|
-
| Initial parse | 850 ms | 1200 ms | **1.4x faster** |
|
|
339
|
-
| Entity queries | <1 ms | 100 ms | **100x faster** |
|
|
340
|
-
| Memory usage | 45 MB | 120 MB | **2.7x less** |
|
|
205
|
+
## Rust Crates
|
|
341
206
|
|
|
342
|
-
|
|
207
|
+
| Crate | Description | Status |
|
|
208
|
+
|-------|-------------|--------|
|
|
209
|
+
| `ifc-lite-core` | STEP/IFC parsing | ✅ Stable |
|
|
210
|
+
| `ifc-lite-geometry` | Mesh triangulation | ✅ Stable |
|
|
211
|
+
| `ifc-lite-wasm` | WASM bindings | ✅ Stable |
|
|
343
212
|
|
|
344
|
-
|
|
213
|
+
## Contributing
|
|
345
214
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
**Vite:**
|
|
349
|
-
```javascript
|
|
350
|
-
// vite.config.js
|
|
351
|
-
export default {
|
|
352
|
-
optimizeDeps: {
|
|
353
|
-
exclude: ['@ifc-lite/wasm']
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
```
|
|
215
|
+
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
357
216
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
module.exports = {
|
|
362
|
-
experiments: {
|
|
363
|
-
asyncWebAssembly: true
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
### "Memory access out of bounds"
|
|
369
|
-
|
|
370
|
-
This usually means the WASM memory has been deallocated. Make sure to:
|
|
371
|
-
1. Keep a reference to the API instance
|
|
372
|
-
2. Don't access meshes after they've been freed
|
|
373
|
-
3. Create TypedArray views before the next parse operation
|
|
217
|
+
```bash
|
|
218
|
+
# Fork and clone
|
|
219
|
+
git clone https://github.com/YOUR_USERNAME/ifc-lite.git
|
|
374
220
|
|
|
375
|
-
|
|
221
|
+
# Create a branch
|
|
222
|
+
git checkout -b feature/my-feature
|
|
376
223
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
const ifcApi = new IfcAPI();
|
|
380
|
-
await ifcApi.Init();
|
|
381
|
-
const modelID = ifcApi.OpenModel(buffer);
|
|
382
|
-
const walls = ifcApi.GetLineIDsWithType(modelID, IFCWALL);
|
|
224
|
+
# Make changes and test
|
|
225
|
+
pnpm test
|
|
383
226
|
|
|
384
|
-
|
|
385
|
-
const api = new IfcAPI();
|
|
386
|
-
const result = await api.parse(buffer);
|
|
387
|
-
// Walls are already counted in result.entityTypes.IFCWALL
|
|
227
|
+
# Submit a pull request
|
|
388
228
|
```
|
|
389
229
|
|
|
390
|
-
##
|
|
230
|
+
## License
|
|
391
231
|
|
|
392
|
-
|
|
232
|
+
This project is licensed under the [Mozilla Public License 2.0](LICENSE).
|
|
393
233
|
|
|
394
|
-
##
|
|
234
|
+
## Acknowledgments
|
|
395
235
|
|
|
396
|
-
|
|
236
|
+
- Built with [nom](https://github.com/rust-bakery/nom) for parsing
|
|
237
|
+
- [earcutr](https://github.com/nickel-org/earcutr) for polygon triangulation
|
|
238
|
+
- [nalgebra](https://nalgebra.org/) for linear algebra
|
|
239
|
+
- [wasm-bindgen](https://rustwasm.github.io/wasm-bindgen/) for Rust/JS interop
|
|
397
240
|
|
|
398
|
-
|
|
241
|
+
---
|
|
399
242
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
243
|
+
<p align="center">
|
|
244
|
+
Made with ❤️ for the AEC industry
|
|
245
|
+
</p>
|
package/package.json
CHANGED
|
@@ -1,44 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ifc-lite/wasm",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "WebAssembly bindings for IFC-Lite",
|
|
5
3
|
"type": "module",
|
|
6
|
-
"main": "ifc_lite_wasm.js",
|
|
7
|
-
"types": "ifc_lite_wasm.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./ifc_lite_wasm.d.ts",
|
|
11
|
-
"import": "./ifc_lite_wasm.js"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
4
|
"collaborators": [
|
|
15
5
|
"IFC-Lite Contributors"
|
|
16
6
|
],
|
|
7
|
+
"description": "WebAssembly bindings for IFC-Lite",
|
|
8
|
+
"version": "1.1.1",
|
|
17
9
|
"license": "MPL-2.0",
|
|
18
10
|
"repository": {
|
|
19
11
|
"type": "git",
|
|
20
|
-
"url": "https://github.com/louistrue/ifc-lite
|
|
21
|
-
"directory": "packages/wasm"
|
|
12
|
+
"url": "https://github.com/louistrue/ifc-lite"
|
|
22
13
|
},
|
|
23
14
|
"files": [
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
15
|
+
"pkg/ifc-lite_bg.wasm",
|
|
16
|
+
"pkg/ifc-lite.js",
|
|
17
|
+
"pkg/ifc-lite.d.ts"
|
|
27
18
|
],
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
19
|
+
"main": "./pkg/ifc-lite.js",
|
|
20
|
+
"module": "./pkg/ifc-lite.js",
|
|
21
|
+
"types": "./pkg/ifc-lite.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"import": "./pkg/ifc-lite.js",
|
|
25
|
+
"types": "./pkg/ifc-lite.d.ts"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"sideEffects": false,
|
|
34
29
|
"keywords": [
|
|
35
30
|
"ifc",
|
|
36
31
|
"bim",
|
|
37
32
|
"wasm",
|
|
38
33
|
"webassembly",
|
|
39
34
|
"aec"
|
|
40
|
-
]
|
|
41
|
-
"publishConfig": {
|
|
42
|
-
"access": "public"
|
|
43
|
-
}
|
|
35
|
+
]
|
|
44
36
|
}
|