BabylonJS/Babylon.js · error

Cannot add part, as the maximum part count (${maxPartCount})

Error message

Cannot add part, as the maximum part count (${maxPartCount}) has been reached

What it means

Gaussian splatting compounds use a per-part index attribute whose size is capped by the engine (GetGaussianSplattingMaxPartCount). addPart/addParts throws once `nextPartIndex` would exceed that maximum, because there are no remaining part slots to assign to the new source meshes.

Source

Thrown at packages/dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.ts:1200

        // --- Build part indices ---
        let nextPartIndex = this.partCount;
        let partIndicesA = this._partIndices;
        if (!partIndicesA) {
            // First addPart on a plain mesh: assign its splats to part 0
            partIndicesA = new Uint8Array(splatCountA);
            nextPartIndex = splatCountA > 0 ? 1 : 0;
        }

        this._partIndices = new Uint8Array(textureLength);
        this._partIndices.set(partIndicesA.subarray(0, splatCountA));

        const assignedPartIndices: number[] = [];
        const assignedSplatsDataOffsets: number[] = [];
        let dstOffset = splatCountA;
        const maxPartCount = GetGaussianSplattingMaxPartCount(this._scene.getEngine());
        for (const other of others) {
            if (nextPartIndex >= maxPartCount) {
                throw new Error(`Cannot add part, as the maximum part count (${maxPartCount}) has been reached`);
            }
            const newPartIndex = nextPartIndex++;
            assignedPartIndices.push(newPartIndex);
            assignedSplatsDataOffsets.push(dstOffset);
            this._partIndices.fill(newPartIndex, dstOffset, dstOffset + other._vertexCount);
            dstOffset += other._vertexCount;
        }

        // --- Process source data ---
        if (!incremental) {
            // Full rebuild path — only reached when the GPU texture must be reallocated
            // (either the texture height needs to grow to fit the new total, or this is
            // the very first addPart onto a mesh with no GPU textures yet). In the common
            // case where the texture height is unchanged, `incremental` is true and this
            // entire block is skipped. The `splatCountA > 0` guard avoids redundant work
            // on the first-ever addPart when the compound mesh starts empty.
            if (splatCountA > 0) {
                if (this._partProxies.length > 0) {

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Check the current part count against `GetGaussianSplattingMaxPartCount(engine)` before adding and batch/limit merges accordingly.
  2. Merge multiple sources into fewer addParts calls only up to the cap; split the compound into several meshes beyond that.
  3. Query the cap early and design streaming chunk size so total parts stay within it.
  4. On catch, stop appending and create a new compound mesh for subsequent parts.

Example fix

// before
while (chunks.length) {
    compound.addPart(chunks.pop()!); // eventually throws
}

// after
const max = GetGaussianSplattingMaxPartCount(engine);
while (chunks.length && compound.partCount < max) {
    compound.addPart(chunks.pop()!);
}
Defensive patterns

Strategy: validation

Validate before calling

const max = GetGaussianSplattingMaxPartCount(engine);
const free = max - compound.partCount;
if (others.length > free) {
    // split: add up to free parts, start a new compound for the rest
}

Type guard

function canAddParts(compound: GaussianSplattingMeshBase, count: number): boolean {
    return compound.partCount + count <= GetGaussianSplattingMaxPartCount(compound.getScene().getEngine());
}

Try / catch

try {
    compound.addParts(sources);
} catch (e) {
    if (e instanceof Error && e.message.includes("maximum part count")) {
        const max = GetGaussianSplattingMaxPartCount(engine);
        compound.addParts(sources.slice(0, max - compound.partCount));
        return createNewCompound(sources.slice(max - compound.partCount));
    }
    throw e;
}

Prevention

When it happens

Trigger: Repeatedly calling `addPart()`/`addParts()` on one compound mesh until the number of parts exceeds GetGaussianSplattingMaxPartCount(engine) (GPU-dependent, often small, e.g. 8/16); merging many small splat meshes into one compound.

Common situations: Streaming scenarios appending parts over time; merging dozens of chunk files; hardware with a low max part count (weaker GPUs/WebGL limits) while testing on a device with a higher cap.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/8abe71375c29581b. Report an issue: GitHub.