Skip to content

Fix reading OBJ meshes from UTF-8 paths on Windows - #7524

Open
Fstarnb wants to merge 2 commits into
isl-org:mainfrom
Fstarnb:fix/obj-utf8-path-windows
Open

Fix reading OBJ meshes from UTF-8 paths on Windows#7524
Fstarnb wants to merge 2 commits into
isl-org:mainfrom
Fstarnb:fix/obj-utf8-path-windows

Conversation

@Fstarnb

@Fstarnb Fstarnb commented Jul 18, 2026

Copy link
Copy Markdown

Description

ReadTriangleMeshFromOBJ used tinyobj::LoadObj(filename, ...), which opens the path with narrow fopen/ifstream. On Windows that breaks when the path contains non-ASCII characters (e.g. Korean), while ASCII PLY paths work because other loaders use utility::filesystem::FOpen / FReadToBuffer (UTF-8 → wide open).

This change:

  1. Loads the .obj bytes through FReadToBuffer
  2. Parses via tinyobj::LoadObj stream overload
  3. Resolves .mtl files with a small MaterialReader that also uses FReadToBuffer + MaterialStreamReader

Related Issue

Fixes #7336

Checklist

@update-docs

update-docs Bot commented Jul 18, 2026

Copy link
Copy Markdown

Thanks for submitting this pull request! The maintainers of this repository would appreciate if you could update the CHANGELOG.md based on your changes.

@ssheorey

ssheorey commented Jul 23, 2026

Copy link
Copy Markdown
Member

Hi @Fstarnb, thanks for submitting this fix. Have you checked if the latest (main branch) of tinyobjloader fixes this? Its easier to update versions than have special workarounds in Open3D.

Alternately, will adding "/utf-8" to MSVC compile options fix this?

Fstarnb added a commit to Fstarnb/Open3D that referenced this pull request Jul 28, 2026
Document the FileOBJ stream/FReadToBuffer change for issue isl-org#7336 / PR isl-org#7524.
@Fstarnb

Fstarnb commented Jul 28, 2026

Copy link
Copy Markdown
Author

@ssheorey Thanks for the review questions — I checked both options carefully.

1. Does latest tinyobjloader main already fix this?

Yes on main, no on the pin Open3D uses.

Open3D currently vendors tinyobjloader v2.0.0rc8 (3rdparty/tinyobjloader/tinyobjloader.cmake). That release opens paths with a narrow std::ifstream ifs(filename) / equivalent — no MultiByteToWideChar / wide path handling — so UTF-8 paths on Windows fail exactly as in #7336.

On tinyobjloader main (post-rc8), the filename LoadObj path was updated to open via LongPathW(UTF8ToWchar(filename)) (and the same for material file readers). So upstream has fixed the classic filename API.

I did not bump the third-party pin in this PR because:

  • There is still no newer tagged release after v2.0.0rc8 (only that tag).
  • Main has since grown a large pure-C11 loader and other surface area; pinning an untagged main commit is a wider dependency risk than this one IO path.
  • Open3D already has the right primitive for this: utility::filesystem::FOpen / FReadToBuffer (UTF-8 → _wfopen on Windows), which other mesh loaders already use. Routing OBJ/MTL through that keeps path semantics consistent with the rest of Open3D IO even if tinyobj is upgraded later.

If you prefer a dedicated follow-up to bump tinyobjloader once there is a tagged release (or a pinned commit you trust), happy to do that separately. This PR stays a minimal, pin-safe fix for #7336.

2. Would MSVC /utf-8 fix it?

No. /utf-8 only sets the source/execution charset for the compiler (how string literals and source files are decoded). It does not change the CRT/MSVC behavior of narrow fopen / std::ifstream with a runtime path string: on a typical Windows ANSI/ACP code page those still go through the narrow API and break on characters outside that code page (e.g. Korean in the reporter’s path).

Open3D already learned this elsewhere: other loaders go through FOpenMultiByteToWideChar(CP_UTF8, …)_wfopen. That is the same mechanism this PR uses, just via FReadToBuffer + tinyobj’s stream overloads (LoadObj(istream*) + MaterialStreamReader), which exist on the current v2.0.0rc8 pin.

3. CHANGELOG

Also pushed a CHANGELOG.md entry for this fix (bot request).

Happy to adjust further if you’d rather see a tinyobj pin bump instead of the stream wrapper — just say which direction you prefer.

Fstarnb added 2 commits July 28, 2026 13:46
Read OBJ/MTL via filesystem::FReadToBuffer (UTF-8 aware FOpen) and
tinyobj stream APIs instead of narrow fopen paths. Fixes isl-org#7336.
Document the FileOBJ stream/FReadToBuffer change for issue isl-org#7336 / PR isl-org#7524.
@Fstarnb
Fstarnb force-pushed the fix/obj-utf8-path-windows branch from d040636 to 7726e7b Compare July 28, 2026 05:46
@Fstarnb

Fstarnb commented Jul 28, 2026

Copy link
Copy Markdown
Author

Follow-up: rebased onto current main and resolved a CHANGELOG.md conflict with the recent SYCL/SPZ entries so the PR is mergeable again. Code change in FileOBJ.cpp is unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug report: Cannot load .obj file when path contains Korean characters

2 participants