Skip to content

Support multiple texture images per mesh (closes #2) - #21

Merged
csparker247 merged 3 commits into
developfrom
issue-2-multi-texture-reorder
Jul 9, 2026
Merged

Support multiple texture images per mesh (closes #2)#21
csparker247 merged 3 commits into
developfrom
issue-2-multi-texture-reorder

Conversation

@csparker247

@csparker247 csparker247 commented Jul 9, 2026

Copy link
Copy Markdown
Member

Summary

This PR adds support for meshes textured by multiple images, closing #2. Each UV chart in a multi-chart mesh (e.g., multi-material OBJ) is now independently textured. The reorder pipeline normalizes all inputs to 8-bit/3-channel internally and samples each face from its UV chart's image, skipping uncolored regions and warning for missing textures.

Changes

Core Library (core/)

  • ReorderUnorganizedTexture: Changed setTextureMat()setTextureMats(std::vector<cv::Mat>) to accept multiple textures indexed by UV chart; removed getTextureMat()
  • Input normalization: each image quantized to 8-bit and color-converted to 3-channel (BGR) on input
  • Implement chart-aware sampling: new resolve_chart_image_() method resolves a face's texture from its UV chart; returns nullptr if chart is out of range or image is empty
  • New report_missing_charts_() aggregates and warns once for all charts with no usable image
  • Update ComputeUVDensity() to scale UV regions by their chart's image dimensions, supporting varying sizes in multi-chart meshes
  • MeshIO: Change MeshReadResult to use std::vector<cv::Mat> textures and std::vector<std::filesystem::path> texturePaths (replacing scalar texture and texturePath)
  • ReadMesh() now loads every referenced texture into the vectors, preserving alignment so chart i ↔ textures[i]; materials with no map_Kd (empty path) and missing images are stored as empty cv::Mat/path to maintain indexing

Graph Layer (graph/)

  • MeshReadNode: Add images port exposing the full texture vector (canonical plural output); keep image port as a documented stopgap scalar convenience for single-image consumers (backed by a getter lambda returning images[0])—remove imagePath port
  • ReorderTextureNode: Rename imageIn input port → imagesIn (type: std::vector<cv::Mat>)
  • Wire the node's setter from setTextureMatsetTextureMats

Applications (apps/)

  • ReorderTexture: Remove the now-unneeded ColorConvertNode; connect reorder->imagesIn directly to reader->images
  • SeamFlattening, TextureDewarp: Update calls from setTextureMat()setTextureMats()

Tests (tests/)

Design Notes

  • Chart-to-image mapping: Face colors come from UV chart indices embedded in the mesh's UVMap coordinates. The mapping is inherent to the mesh file format and read transparently by ReadMesh.
  • Skip-and-warn: Faces whose chart has no image (out-of-range index or empty cv::Mat) remain uncolored in the output. A single aggregated warning names all affected chart indices; duplicates are deduplicated and sorted for clarity.
  • Input normalization: All textures are quantized and color-converted on input to ensure consistent downstream behavior. Higher bit depths and non-3-channel layouts are not yet preserved (see ReorderUnorganizedTexture: support non-8bpc / non-3-channel input textures #19).
  • Stopgap scalar convenience: The image output port on MeshReadNode is kept as a convenience for legacy single-texture consumers—it returns images[0] via a getter lambda. The plural images port is the canonical output and will become the only path once downstream code migrates.

Follow-ups

Testing

  • Full clean build succeeds (core, graph, all apps, all tests)
  • ctest: 6/6 suites pass, including the new ReorderMultiTexture.* cases
  • End-to-end run against a real multi-material mesh not yet performed — recommended before merge

Closes #2

🤖 Generated with Claude Code

csparker247 and others added 3 commits July 9, 2026 09:22
- Change ReorderUnorganizedTexture::setTextureMat → setTextureMats (vector-based)
- Normalize each input texture to 8-bit, 3-channel internally via QuantizeImage + ColorConvertImage
- Implement chart-aware texture sampling: each face samples from its UV chart's image
- Update MeshReadResult: single texture/texturePath → vectors textures/texturePaths
- ReadMesh now loads all referenced textures, preserving chart-index alignment
- Add resolve_chart_image_() helper to locate chart texture; report_missing_charts_() warns for unused charts
- Update ComputeUVDensity to handle multi-chart meshes with varying image dimensions
- Remove ColorConvertNode from ReorderTexture app (normalization now internal)
- Graph layer: MeshReadNode exposes images vector; ReorderTextureNode input port imageIn → imagesIn
- Add unit tests for multi-chart UV-mapped meshes (camera-path tests to avoid vtkOBBTree degenerate-mesh issue)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A material that declares no map_Kd arrives as an empty relative path.
Resolving it against the OBJ's parent directory would be wrong, so keep
the chart's texture/path slots empty instead, preserving the
chart i ↔ textures[i] alignment invariant. The reorder step already
no-ops on empty charts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the singular imagePath output port, which had no consumers, and
make the plural images port the canonical texture output. The scalar
image port is kept as a documented stopgap convenience for single-image
consumers (e.g. registration) and is now backed by a getter lambda over
imgs_ rather than a duplicated img_ member, so it always reflects
images[0]. The full plural-pipeline conversion of downstream consumers
is deferred to a future PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@csparker247
csparker247 merged commit fe6c715 into develop Jul 9, 2026
3 checks passed
@csparker247
csparker247 deleted the issue-2-multi-texture-reorder branch July 9, 2026 19:41
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.

Add support for multiple texture images

1 participant