adobe / adobe/USD-Fileformat-plugins

False “Invalid mesh topology” warning on the final valid face in `computeSmoothNormals`

Open Beginner friendly
#79 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
396
Forks
42
PR merge metrics
No merged PRs in 30d

Description

Hi Everyone, I found an issue while building a cli tool around around what this repo offers.

## Description

When exporting a valid USD mesh to STL, glTF, or GLB using Adobe USD File Format Plugins 2026.07, the exporter emits the following warning:

```text
Invalid mesh topology: offset 4944 into indices for face 1235 is larger than total indices 4944
```

The source mesh topology is valid:

```text
Faces: 1236
Sum of faceVertexCounts: 4944
Number of faceVertexIndices: 4944
```

Therefore:

```text
sum(faceVertexCounts) == faceVertexIndices.size()
```

The warning occurs while processing the final face, where the calculated exclusive end offset is exactly equal to the total number of indices.

The export still completes successfully with exit code `0`, but the normal-generation loop appears to stop before processing the final face.

## Reproduction asset

The issue reproduces using the unmodified Utah Teapot USD asset from the ASWF USD Assets Working Group repository.

The asset is provided under the Public Domain/CC0 license.

* [[Commit-pinned UtahTeapot.usd](https://github.com/usd-wg/assets/blob/0cfdafe7ed4b9507a215553f614e63882907074e/full_assets/Teapot/geo/UtahTeapot.usd)](https://github.com/usd-wg/assets/blob/0cfdafe7ed4b9507a215553f614e63882907074e/full_assets/Teapot/geo/UtahTeapot.usd)
* [[Raw UtahTeapot.usd download](https://raw.githubusercontent.com/usd-wg/assets/0cfdafe7ed4b9507a215553f614e63882907074e/full_assets/Teapot/geo/UtahTeapot.usd)](https://raw.githubusercontent.com/usd-wg/assets/0cfdafe7ed4b9507a215553f614e63882907074e/full_assets/Teapot/geo/UtahTeapot.usd)
* [[Teapot asset directory](https://github.com/usd-wg/assets/tree/0cfdafe7ed4b9507a215553f614e63882907074e/full_assets/Teapot)](https://github.com/usd-wg/assets/tree/0cfdafe7ed4b9507a215553f614e63882907074e/full_assets/Teapot)
* [[Asset README and license information](https://github.com/usd-wg/assets/blob/0cfdafe7ed4b9507a215553f614e63882907074e/full_assets/Teapot/README.md)](https://github.com/usd-wg/assets/blob/0cfdafe7ed4b9507a215553f614e63882907074e/full_assets/Teapot/README.md)
* [[Upstream asset commit](https://github.com/usd-wg/assets/commit/0cfdafe7ed4b9507a215553f614e63882907074e)](https://github.com/usd-wg/assets/commit/0cfdafe7ed4b9507a215553f614e63882907074e)

No modifications to the upstream USD file are required to reproduce the warning.

## Steps to reproduce

Download the commit-pinned `UtahTeapot.usd` file and export it to STL:

```powershell
usdconvert.exe UtahTeapot.usd -o UtahTeapot.stl
```

The same warning can also be reproduced when exporting to glTF or GLB:

```powershell
usdconvert.exe UtahTeapot.usd -o UtahTeapot.gltf
usdconvert.exe UtahTeapot.usd -o UtahTeapot.glb
```

## Actual result

The export completes with exit code `0`, but emits:

```text
Warning: in computeSmoothNormals at line 762 of utils/src/geometry.cpp
-- Invalid mesh topology: offset 4944 into indices for face 1235 is larger than total indices 4944
```

The warning is produced for STL, glTF, and GLB exports.

FBX and OBJ exports of the same source mesh complete without this warning.

## Expected result

* The mesh should not be reported as having invalid topology.
* The final face should be included in smooth-normal generation.
* No topology warning should be emitted when the exclusive end offset is exactly equal to the total number of indices.

## Suspected cause

The current implementation in `utils/src/geometry.cpp` contains the following condition:

```cpp
if ((size_t)(faceVertexIndex + numFaceVertices) >= totalNumFaceVertices) {
TF_WARN(
"Invalid mesh topology: offset %d into indices for face %zu is larger than "
"total indices %zu",
faceVertexIndex + numFaceVertices,
faceIdx,
totalNumFaceVertices);
break;
}
```

For the final valid face:

```text
faceVertexIndex + numFaceVertices == totalNumFaceVertices
```

This equality is valid because the calculated value is the exclusive end offset.

The condition appears to reject a valid final face because it uses `>=`.

A possible correction would be:

```cpp
if ((size_t)(faceVertexIndex + numFaceVertices) > totalNumFaceVertices) {
```

The warning text also says the offset is “larger than” the total number of indices, although in this reproduction the two values are equal.

## Potential impact

Because the function calls `break`, normal generation stops before the final face is processed.

Although the export succeeds, the last face may receive incomplete or incorrect generated normal data.

## Environment

```text
OS: Windows 10 x64
Adobe USD File Format Plugins: 2026.07
OpenUSD: 25.11
Affected exports: STL, glTF, GLB
Source mesh faces: 1236
Sum of faceVertexCounts: 4944
faceVertexIndices count: 4944
```

## Suggested regression test

Add a valid mesh where the final face ends exactly at the end of the index array:

```cpp
sum(mesh.faces) == mesh.indices.size()
```

Verify that:

1. `computeSmoothNormals` processes every face.
2. No invalid-topology warning is emitted.
3. The generated normals include the final face.

## Existing-issue search

I searched the repository’s open and closed issues and pull requests for:

* the exact warning text
* `computeSmoothNormals`
* `faceVertexIndex`
* `faceVertexIndices`
* `totalNumFaceVertices`
* mesh topology and normal-generation issues
* related STL and glTF reports

I did not find an existing report for this final-face boundary condition.

Contributor guide

Open the contributing guide

Research direction

Start in utils/src/geometry.cpp at computeSmoothNormals and reproduce the warning with the commit-pinned UtahTeapot.usd asset using usdconvert.exe. Check the final-face boundary condition and add regression coverage for a mesh whose face counts end exactly at the index-array length. Done means all faces are processed without an invalid-topology warning.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-graphics
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.