From 0fa6f8fcdd63b4b49d10e5e1cea295dde880dbae Mon Sep 17 00:00:00 2001
From: Emmett Lalish
Date: Tue, 9 May 2023 12:35:01 -0700
Subject: [PATCH 1/7] make-manifold working
---
bindings/wasm/examples/gltf-io.js | 107 ++++++++-----
bindings/wasm/examples/make-manifold.html | 140 ++++++++++++++++++
.../wasm/manifold-encapsulated-types.d.ts | 1 +
3 files changed, 212 insertions(+), 36 deletions(-)
create mode 100644 bindings/wasm/examples/make-manifold.html
diff --git a/bindings/wasm/examples/gltf-io.js b/bindings/wasm/examples/gltf-io.js
index faed21c33..6d936a56d 100644
--- a/bindings/wasm/examples/gltf-io.js
+++ b/bindings/wasm/examples/gltf-io.js
@@ -32,23 +32,17 @@ export function setupIO(io) {
return io.registerExtensions([EXTManifold]);
}
-export function readMesh(mesh, attributes, materials) {
- if (attributes.length < 1 || attributes[0] !== 'POSITION')
- throw new Error('First attribute must be "POSITION".');
-
- const primitives = mesh.listPrimitives();
- if (primitives.length === 0) {
- return {};
- }
-
- const numProp = attributes.map((def) => attributeDefs[def].components)
- .reduce((a, b) => a + b);
- const position = primitives[0].getAttribute('POSITION');
- const numVert = position.getCount()
- const vertProperties = new Float32Array(numProp * numVert);
+function readPrimitive(primitive, numProp, attributes) {
+ const position = primitive.getAttribute('POSITION');
+ const numVert = position.getCount();
+ const vertProperties = [];
let offset = 0;
for (const attribute of attributes) {
- const accessor = primitives[0].getAttribute(attribute);
+ if (attribute === 'SKIP') {
+ offset += attributeDefs[attribute].components;
+ continue;
+ }
+ const accessor = primitive.getAttribute(attribute);
const array = accessor.getArray();
const size = accessor.getElementSize();
for (let i = 0; i < numVert; ++i) {
@@ -58,37 +52,78 @@ export function readMesh(mesh, attributes, materials) {
}
offset += size;
}
+ return vertProperties;
+}
+
+export function readMesh(mesh, attributes, materials) {
+ const primitives = mesh.listPrimitives();
+ if (primitives.length === 0) {
+ return {};
+ }
+ if (attributes.length === 0) {
+ const attributeSet = new Set();
+ for (const primitive of primitives) {
+ const semantics = primitive.listSemantics();
+ for (const semantic of semantics) {
+ attributeSet.add(semantic);
+ }
+ }
+ for (const semantic in attributeDefs) {
+ if (attributeSet.has(semantic)) {
+ attributes.push(semantic);
+ attributeSet.delete(semantic);
+ }
+ }
+ for (const semantic of attributeSet.keys()) {
+ attributes.push(semantic);
+ }
+ }
+
+ if (attributes.length < 1 || attributes[0] !== 'POSITION')
+ throw new Error('First attribute must be "POSITION".');
+
+ const numProp = attributes.map((def) => attributeDefs[def].components)
+ .reduce((a, b) => a + b);
+
+ const manifoldPrimitive = mesh.getExtension('EXT_manifold');
+
+ const vertPropArray = [];
const triVertArray = [];
- const runIndexArray = [0];
- for (const primitive of primitives) {
- if (primitive.getAttribute('POSITION') === position) {
+ const runIndexArray = [];
+ const mergeFromVert = [];
+ const mergeToVert = [];
+ if (manifoldPrimitive != null) {
+ runIndexArray.push(0);
+ vertPropArray.push(...readPrimitive(primitives[0], numProp, attributes));
+ for (const primitive of primitives) {
triVertArray.push(...primitive.getIndices().getArray());
runIndexArray.push(triVertArray.length);
materials.push(primitive.getMaterial());
- } else {
- console.log('primitives do not share accessors!');
+ }
+ const mergeTriVert = manifoldPrimitive.getMergeIndices()?.getArray() ?? [];
+ const mergeTo = manifoldPrimitive.getMergeValues()?.getArray() ?? [];
+ const vert2merge = new Map();
+ for (const [i, idx] of mergeTriVert.entries()) {
+ vert2merge.set(triVertArray[idx], mergeTo[i]);
+ }
+ for (const [from, to] of vert2merge.entries()) {
+ mergeFromVert.push(from);
+ mergeToVert.push(to);
+ }
+ } else {
+ for (const primitive of primitives) {
+ const numVert = vertPropArray.length / numProp;
+ vertPropArray.push(...readPrimitive(primitive, numProp, attributes));
+ triVertArray.push(
+ ...primitive.getIndices().getArray().map((i) => i + numVert));
+ materials.push(primitive.getMaterial());
}
}
+ const vertProperties = new Float32Array(vertPropArray);
const triVerts = new Uint32Array(triVertArray);
const runIndex = new Uint32Array(runIndexArray);
- const manifoldPrimitive = mesh.getExtension('EXT_manifold');
- const mergeTriVert =
- manifoldPrimitive ? manifoldPrimitive.getMergeIndices().getArray() : [];
- const mergeTo =
- manifoldPrimitive ? manifoldPrimitive.getMergeValues().getArray() : [];
- const vert2merge = new Map();
- for (const [i, idx] of mergeTriVert.entries()) {
- vert2merge.set(triVerts[idx], mergeTo[i]);
- }
- const mergeFromVert = [];
- const mergeToVert = [];
- for (const [from, to] of vert2merge.entries()) {
- mergeFromVert.push(from);
- mergeToVert.push(to);
- }
-
return {
numProp,
triVerts,
diff --git a/bindings/wasm/examples/make-manifold.html b/bindings/wasm/examples/make-manifold.html
new file mode 100644
index 000000000..e382ff090
--- /dev/null
+++ b/bindings/wasm/examples/make-manifold.html
@@ -0,0 +1,140 @@
+
+
+
+
+ Make manifold glTF
+
+
+
+
+
+
+
+
Load a glTF/GLB model and our Manifold library will attempt to
+ merge it into a set of manifold objects. You can download the new GLB which will have our EXT_manifold extension, thus preserving the manifold
+ data without losing any mesh properties.
+
+
+
+ Drop a GLB here
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bindings/wasm/manifold-encapsulated-types.d.ts b/bindings/wasm/manifold-encapsulated-types.d.ts
index 351c20f27..b4afd92b8 100644
--- a/bindings/wasm/manifold-encapsulated-types.d.ts
+++ b/bindings/wasm/manifold-encapsulated-types.d.ts
@@ -435,6 +435,7 @@ export class Mesh {
get numTri(): number;
get numVert(): number;
get numRun(): number;
+ merge(): boolean;
verts(tri: number): SealedUint32Array<3>;
position(vert: number): SealedFloat32Array<3>;
extras(vert: number): Float32Array;
From d1b0e27406e28fb2938cda5db26f70922942e52b Mon Sep 17 00:00:00 2001
From: Emmett Lalish
Date: Tue, 9 May 2023 13:00:26 -0700
Subject: [PATCH 2/7] prettier
---
bindings/wasm/examples/make-manifold.html | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/bindings/wasm/examples/make-manifold.html b/bindings/wasm/examples/make-manifold.html
index e382ff090..52e326461 100644
--- a/bindings/wasm/examples/make-manifold.html
+++ b/bindings/wasm/examples/make-manifold.html
@@ -8,7 +8,6 @@
@@ -41,15 +49,16 @@
data without losing any mesh properties.