Skip to content

Conversation

@ssheorey
Copy link
Member

@ssheorey ssheorey commented Nov 7, 2025

Type

  • Bug fix (non-breaking change which fixes an issue): Fixes #
  • New feature (non-breaking change which adds functionality). Resolves #
  • Breaking change (fix or feature that would cause existing functionality to not work as expected) Resolves #

Motivation and Context

Normal maps are saved in tangent space. This PR adds functions to compute the tangent space of a mesh and convert a normal map between world space and tangent space.
Ambient occlusion allows meshes to be visualized properly without any color information. It can also be used for simple de-lighting.

Checklist:

  • I have run python util/check_style.py --apply to apply Open3D code style
    to my code.
  • This PR changes Open3D behavior or adds new functionality.
    • Both C++ (Doxygen) and Python (Sphinx / Google style) documentation is
      updated accordingly.
    • I have added or updated C++ and / or Python unit tests OR included test
      results
      (e.g. screenshots or numbers) here.
  • I will follow up and update the code if CI fails.
  • For fork PRs, I have selected Allow edits from maintainers.

Description

This PR adds support for tangent space computation and ambient occlusion rendering to triangle meshes. The key changes include implementing MikkTSpace for tangent space calculation, enabling normal map transformations between world and tangent space, and adding ambient occlusion texture generation using ray casting.

Key changes:

  • Integration of MikkTSpace library for computing tangent space vectors
  • New methods for ambient occlusion computation and normal map transformation
  • Addition of quasirandom sequence generation and cross product operations for tensor math

@update-docs
Copy link

update-docs bot commented Nov 7, 2025

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 requested a review from Copilot November 7, 2025 00:07
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for tangent space computation and ambient occlusion rendering to triangle meshes. The key changes include implementing MikkTSpace for tangent space calculation, enabling normal map transformations between world and tangent space, and adding ambient occlusion texture generation using ray casting.

Key changes:

  • Integration of MikkTSpace library for computing tangent space vectors
  • New methods for ambient occlusion computation and normal map transformation
  • Addition of quasirandom sequence generation and cross product operations for tensor math
  • Wayland compatibility fixes for GLFW window positioning

Reviewed Changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
cpp/open3d/t/geometry/TriangleMesh.cpp Implements ComputeTangentSpace(), TransformNormalMap(), and ComputeAmbientOcclusion() methods
cpp/open3d/t/geometry/kernel/mikktspace.h Adds MikkTSpace library header for tangent space computation
cpp/open3d/t/geometry/kernel/mikktspace.c Adds MikkTSpace library implementation (1899 lines)
cpp/open3d/core/Tensor.cpp Implements Quasirandom(), Cross(), and Norm() tensor operations
cpp/tests/t/geometry/TriangleMesh.cpp Adds comprehensive tests for tangent space and ambient occlusion
cpp/pybind/t/geometry/trianglemesh.cpp Exposes new mesh methods to Python bindings
cpp/open3d/visualization/visualizer/Visualizer.cpp Adds Wayland platform checks for window positioning
cpp/open3d/t/io/file_format/FileASSIMP.cpp Updates texture export to include ambient occlusion maps

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +330 to +331
// https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/
// for more details.
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The URL reference should be in a Doxygen comment format. These C++ style comments (//) will not appear in generated documentation. Use /// instead for Doxygen comments.

Suggested change
// https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/
// for more details.
/// https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/
/// for more details.

Copilot uses AI. Check for mistakes.
/// t[2, 0:4:2] = np.empty((2, 5), dtype=np.float32)
/// ```
///
/// Tensor Cross(const Tensor &b) const;
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line appears to be leftover documentation that doesn't belong here. It's placed in the middle of unrelated SetItem documentation and doesn't match the actual Cross() method signature (which takes const Tensor &other and int64_t axis=-1). This should be removed.

Suggested change
/// Tensor Cross(const Tensor &b) const;

Copilot uses AI. Check for mistakes.
Comment on lines +639 to +640
// (i.e. broadcastable) shape, and the size of the specified axis must be 3.
// If the axis is -1 (default), the last axis is used.
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent comment style in Doxygen documentation. Lines 639-640 use // instead of ///. All lines in a Doxygen comment block should use /// for proper documentation generation.

Suggested change
// (i.e. broadcastable) shape, and the size of the specified axis must be 3.
// If the axis is -1 (default), the last axis is used.
/// (i.e. broadcastable) shape, and the size of the specified axis must be 3.
/// If the axis is -1 (default), the last axis is used.

Copilot uses AI. Check for mistakes.
/// \param p The order of the norm. Default is 2.0 (L2 norm). Can be
/// positive infinity (L-infinity norm).
/// \return Tensor containing the computed norms. Dtype is
/// preserved for Float32 and Float64 for L2 norm, It is onverted to Float32
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'converted' from 'onverted'.

Suggested change
/// preserved for Float32 and Float64 for L2 norm, It is onverted to Float32
/// preserved for Float32 and Float64 for L2 norm, It is converted to Float32

Copilot uses AI. Check for mistakes.
utility::LogError(
"[Tensor::Cross] Dim axis={} of both tensors must have shape "
"3. Got {} and {} instead.",
axis, GetShape(3), other.GetShape(3));
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error message uses hardcoded index 3 instead of the axis parameter. Line 1149 should use GetShape(axis) and other.GetShape(axis) to match the actual dimension being checked.

Suggested change
axis, GetShape(3), other.GetShape(3));
axis, GetShape(axis), other.GetShape(axis));

Copilot uses AI. Check for mistakes.
Comment on lines +168 to +169
// bool visible = !(flags & FLAG_HIDDEN);
glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commented-out code for handling window visibility should either be removed or replaced with a TODO comment explaining why it was disabled. Leaving dead code without explanation reduces maintainability.

Copilot uses AI. Check for mistakes.
Comment on lines +195 to +199
//if (!visible) {
// glfwHideWindow(glfw_window);
//} else {
// glfwShowWindow(glfw_window);
//}
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Large block of commented-out code without explanation. If this code is no longer needed, it should be removed. If it's kept for reference, add a comment explaining why it's disabled.

Suggested change
//if (!visible) {
// glfwHideWindow(glfw_window);
//} else {
// glfwShowWindow(glfw_window);
//}

Copilot uses AI. Check for mistakes.
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.

2 participants