feat(web): complete user-facing workflow command coverage
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

This commit is contained in:
mes123456
2026-09-06 05:48:41 +08:00
parent 187deb0986
commit 23c59c2c2e
20 changed files with 670 additions and 40 deletions

View File

@@ -1,3 +1,5 @@
import type { SculptBrush, SculptMeshAttributesIR, SculptStrokeIR } from "./sculpt";
export const PAINT_BUDGET = {
maxSamples: 100_000,
maxWeightEntries: 1_000_000,
@@ -96,6 +98,45 @@ export interface PaintBrushSpatialQueryIR {
export interface PaintColorPatchIR { indices: number[]; colors: number[] }
export function createSculptStroke(
meshId: string,
brush: SculptBrush,
radius: number,
strength: number,
pressure: number,
symmetry: [boolean, boolean, boolean],
mirrorObjectSpace: boolean,
): SculptStrokeIR {
return {
schemaVersion: 1,
meshId,
brush,
samples: [{ position: [0, 0, 0], normal: [0, 0, 1], radius, strength, pressure, time: 0 }],
symmetry,
mirrorObjectSpace,
};
}
export function createSculptMeshAttributes(
meshId: string,
vertexCount: number,
faceCount: number,
maskValue: number,
faceSet: number,
revision: number,
): SculptMeshAttributesIR {
return {
schemaVersion: 1,
meshId,
vertexCount,
faceCount,
mask: Array.from({ length: vertexCount }, () => maskValue),
faceSets: Array.from({ length: faceCount }, () => faceSet),
activeFaceSet: faceSet,
revision,
};
}
function parseBrushWeights(value: unknown, path = "brushWeights"): PaintBrushWeightIR[] {
if (!Array.isArray(value) || value.length > PAINT_BUDGET.maxWeightEntries) fail(path, "exceeds the brush patch budget", true);
if (value.length === 0) fail(path, "must contain at least one brush hit");