Skip to content

Commit

Permalink
Prevent simplify from leaving degenerate mesh primitives (#1066)
Browse files Browse the repository at this point in the history
* hotfix(simplify): Remove degenerate meshes.
  • Loading branch information
donmccurdy authored Aug 22, 2023
1 parent 88e2d23 commit 4dde394
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
14 changes: 12 additions & 2 deletions packages/functions/src/simplify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { weld } from './weld.js';
import type { MeshoptSimplifier } from 'meshoptimizer';
import { dedup } from './dedup.js';
import { prune } from './prune.js';

const NAME = 'simplify';

Expand Down Expand Up @@ -88,14 +89,23 @@ export function simplify(_options: SimplifyOptions): Transform {
for (const prim of mesh.listPrimitives()) {
if (prim.getMode() !== Primitive.Mode.TRIANGLES) {
logger.warn(
`${NAME}: Skipping primitive of mesh "${mesh.getName()}": Requires TRIANGLES draw mode.`
`${NAME}: Skipping primitive of mesh "${mesh.getName()}": Requires TRIANGLES draw mode.`,
);
continue;
}
simplifyPrimitive(document, prim, options);

if (prim.getIndices()!.getCount() === 0) prim.dispose();
}

if (mesh.listPrimitives().length === 0) mesh.dispose();
}

// Where simplification removes meshes, we may need to prune leaf nodes.
await document.transform(
prune({ keepLeaves: false, propertyTypes: [PropertyType.ACCESSOR, PropertyType.NODE] }),
);

// Where multiple primitive indices point into the same vertex streams, simplification
// may write duplicate streams. Find and remove the duplicates after processing.
if (!isTransformPending(context, NAME, 'dedup')) {
Expand Down Expand Up @@ -150,7 +160,7 @@ export function simplifyPrimitive(document: Document, prim: Primitive, _options:
3,
targetCount,
options.error,
options.lockBorder ? ['LockBorder'] : []
options.lockBorder ? ['LockBorder'] : [],
);

const [remap, unique] = simplifier.compactMesh(dstIndicesArray);
Expand Down
24 changes: 22 additions & 2 deletions packages/functions/test/simplify.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,26 @@ test('shared accessors', async (t) => {
t.deepEqual(srcBounds, dstBounds, 'src.bounds = dst.bounds');
});

test('degenerate', async (t) => {
const document = new Document().setLogger(logger);
const position = document
.createAccessor()
.setArray(new Float32Array([0, 0, 0, 0, 0.01, 0, 0, 0, 1]))
.setType('VEC3');
const prim = document.createPrimitive().setAttribute('POSITION', position);
const mesh = document.createMesh().addPrimitive(prim);
const node = document.createNode().setMesh(mesh);
const scene = document.createScene().addChild(node);

await document.transform(simplify({ simplifier: MeshoptSimplifier, ratio: 0.01, error: 0.1 }));

t.true(prim.isDisposed(), 'prim disposed');
t.true(mesh.isDisposed(), 'mesh disposed');
t.true(node.isDisposed(), 'node disposed');
t.false(scene.isDisposed(), 'scene kept');
t.is(getVertexCount(document), 0, '0 vertices');
});

/* UTILITIES */

/** Creates a rounding function for given decimal precision. */
Expand Down Expand Up @@ -123,8 +143,8 @@ function splitPrim(prim: Primitive, start: number, end: number) {
indices.setArray(
indicesArray.slice(
Math.floor((start * indices.getCount()) / 3) * 3,
Math.ceil((end * indices.getCount()) / 3) * 3
)
Math.ceil((end * indices.getCount()) / 3) * 3,
),
);
prim.setIndices(indices);
}

0 comments on commit 4dde394

Please sign in to comment.