Repository navigation
Conversation
…ching sets of parameters.
… instead of double.Epsilon (which allows only zero difference)
… certain *.obj files
…60729-improve-output-merge # Conflicts: # Obj2Gltf/GltfConverterOptions.cs # Obj2Tiles.Library/Geometry/MeshT.cs # Obj2Tiles/Options.cs # Obj2Tiles/Program.cs # Obj2Tiles/Stages/SplitStage.cs # Obj2Tiles/Stages/TilingStage.cs # Obj2Tiles/Utils.cs # README.md
…separate value (one usually wants good quality there)
…separate value (one usually wants good quality there)
|
Woah. Geometric error estimation and .glb support, are two things I already planned to also look into, some time in the future! |
There was a problem hiding this comment.
Pull request overview
This PR extends Obj2Tiles’ pipeline (Decimation → Splitting → Tiling) with new output/quality controls and several geometry/MTL/texture-handling improvements, including support for emitting plain GLB tile content (3D Tiles 1.1) and more robust geometric-error estimation.
Changes:
- Add GLB tile output path (alongside legacy b3dm) plus CLI preset support and additional CLI knobs.
- Introduce per-tile metrics (
TileBounds) and new geometric error estimation modes/factors used by the tiling stage. - Improve splitting/texture/material handling (tile overlap + deterministic nudge, normal-map parsing/ignoring, texture subfolder fallback, texture quality controls) and performance tweaks (bin pack prune optimization).
Reviewed changes
Copilot reviewed 35 out of 35 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| TODO | Adds roadmap notes for future work |
| README.md | Documents new CLI options and defaults |
| Obj2Tiles/Utils.cs | Enhances dependency copying and adds GLB conversion |
| Obj2Tiles/Stages/TilingStage.cs | Adds GLB output and geometric-error estimation modes |
| Obj2Tiles/Stages/TileBounds.cs | Introduces per-tile bounds + edge metrics record |
| Obj2Tiles/Stages/SplitStage.cs | Propagates overlap/normal-map/quality options; returns TileBounds |
| Obj2Tiles/Stages/Model/ObjMesh.cs | Optimizes OBJ writing via attribute deduplication |
| Obj2Tiles/Stages/DecimationStage.cs | Adds decimation modes and normal-map ignore option |
| Obj2Tiles/Program.cs | Adds preset application and wires new options through pipeline |
| Obj2Tiles/Options.cs | Adds many new CLI options (preset, GLB, overlap, error modes, etc.) |
| Obj2Tiles.Test/ThreeTzArchiveTests.cs | Updates tests for TileBounds mapping |
| Obj2Tiles.Test/StagesTests.cs | Updates stage tests; adds dependency-copy fallback test |
| Obj2Tiles.Test/ObjParserGltfTests.cs | Adds tests for normal-map parsing and glTF validity |
| Obj2Tiles.sln.DotSettings.user | Updates Rider user settings file (likely accidental) |
| Obj2Tiles.Library/Materials/Material.cs | Adds texture-subfolder fallback and normal-map aliases/ignoring |
| Obj2Tiles.Library/Geometry/VertexUtils.cs | Canonicalizes edge endpoints to avoid split cracks |
| Obj2Tiles.Library/Geometry/Vertex3.cs | Fixes equality implementation and epsilon usage |
| Obj2Tiles.Library/Geometry/Vertex2.cs | Switches equality epsilon to Common.Epsilon |
| Obj2Tiles.Library/Geometry/MeshUtils.cs | Adds overlap splitting + deterministic nudge; MTL ignoreNormalMaps |
| Obj2Tiles.Library/Geometry/MeshT.cs | Adds Translate, edge metrics, UV island logic fixes, normal map PNG handling |
| Obj2Tiles.Library/Geometry/Mesh.cs | Adds Translate and edge metrics |
| Obj2Tiles.Library/Geometry/IMesh.cs | Extends interface with Translate and edge metrics |
| Obj2Tiles.Library/Geometry/Box3.cs | Adds Diagonal() helper |
| Obj2Tiles.Library/Common.cs | Replaces unusable epsilon with machine epsilon constant |
| Obj2Tiles.Library/Algos/MaxRectanglesBinPack.cs | Optimizes free-rectangle pruning performance |
| Obj2Tiles.Library.Test/MtlParsingTests.cs | Adds tests for normal-map aliases and texture-subfolder fallback |
| Obj2Gltf/WaveFront/MtlParser.cs | Adds bump/map_Bump support for normal maps |
| Obj2Gltf/GltfConverterOptions.cs | Adds UnlitMaterials option |
| Obj2Gltf/Gltf/Material.cs | Adds material Extensions dictionary support |
| Obj2Gltf/Converter.cs | Adds unlit material support; fixes normal-map-only TEXCOORD emission |
| MeshDecimatorCore/SimplificationOptions.cs | Updates defaults/docs for vertex link epsilon and UV seam/foldover docs |
| MeshDecimatorCore/Math/Vector4d.cs | Updates epsilon constant to machine epsilon |
| MeshDecimatorCore/Math/Vector3d.cs | Updates epsilon constant to machine epsilon |
| MeshDecimatorCore/Math/Vector2d.cs | Updates epsilon constant to machine epsilon |
| MeshDecimatorCore/Algorithms/FastQuadricMeshSimplification.cs | Adds verbose decimation statistics logging |
Comments suppressed due to low confidence (3)
Obj2Tiles/Stages/TilingStage.cs:412
- The XML docs state
ToplevelAverageEdgeLengthdefaults to--error-factor 0.5, butResolveErrorFactor()defaults edge-length modes to 1.0. Please update this docstring to match behavior.
Obj2Tiles/Stages/TilingStage.cs:418 - The XML docs state
ToplevelMaximumEdgeLengthdefaults to--error-factor 0.5, butResolveErrorFactor()defaults edge-length modes to 1.0. Please update this docstring to match behavior.
MeshDecimatorCore/SimplificationOptions.cs:49 - Doc comment typos: “An UV … EnableSmarkLink … boders” should be “A UV … EnableSmartLink … borders” for clarity and to match the actual property name.
/// An UV foldover edge is a border edge that is duplicated in two distinct
/// triangles with same UV coordinates (likely normal-related vertex duplication).
/// This is relevant only if EnableSmarkLink is set to true.
/// If EnableSmartLink is set to false the UV foldover edges are always treated as boders.
/// Default value: false
…60729-improve-output-merge # Conflicts: # Obj2Tiles/Options.cs # Obj2Tiles/Program.cs
|
I think we will soon need a separate documentation website! |
|
I am ready to merge it @pragmaware but, since it is a pretty large PR, do you have any benchmark for these changes? |
Hi, I've developed and tested these changes on various large and complex models I'm working on. Mostly drone photogrammetry, often quite messed up. Different creator software, different settings, different exports, different hands... You can view some of them at https://monumentidigitali.artcentrica.com . Keep in mind that this is a testing website and not all the models have been generated with the same Obj2Tiles version. I think that MANM and Vulci are the latest. Unfortuntately I'm not able to share the source models as they aren't mine and I don't have the permission to distribute them. |
…ion about the number of tiles generated in each LOD
…g) into PR OpenDroneMap#100 Conflicts in Options.cs, Program.cs and SplitStage.cs resolved by keeping both parameter sets (overlap, ignoreNormalMaps, fineTextureQuality and singleMaterialPerPart, globalBounds). MeshT: the single-material atlas path from OpenDroneMap#99 called the old one-argument GetEdgesMapper; it now shares the position canonicalization used by the repack path, so UV-island detection is consistent across both.
…tile size The bounding-box driven recursion used by --split-strategy GlobalBounding ignored --overlap entirely. It now shares SplitWithOverlap and the leaf nudge with the split-point driven recursions. The nudge that breaks z-fighting in the overlap band was capped at an absolute 0.0001 model units, which is below depth-buffer precision for tiles viewed at photogrammetry scales. It is now 1e-4 of the tile's bounding-box diagonal, still capped at 20% of the overlap so it cannot reopen the seam.
The --single-material-per-part atlas wrote the normal map with the diffuse extension/encoder (JPEG/WebP), contradicting the lossless normal-map rule used by every other texture path.
- Toplevel* error modes now cascade from the root by pure halving, as documented; the root already carries the texture-quality multiplier. With the default --lod-texture-scale 0.5 the extra per-LOD multiplier gave LOD tiles twice the root's error. - Every tile's geometric error is capped at its parent's, so renderers never refine straight through a LOD. - --error 0 keeps its previously documented meaning (auto) instead of producing a zero root error; negative/non-finite --error, non-positive --error-factor and negative --overlap are rejected. - --preset legacy no longer overrides an explicit --zsplit/-z or --octree. - --preset standard no longer forces --local when --lat/--lon are given, which silently discarded the georeferencing.
Covers the position-canonicalized island detection (shared UVs without shared geometry, duplicated exporter vertices, UV seams) and checks that the incremental PruneFreeList keeps the free list pairwise non-containing and disjoint from used rectangles after every placement.
- FindTextureSubfolder was duplicated in Utils and Material; it now lives once in Obj2Tiles.Library.Common. - README documents --preset, --decimation-mode, --no-zsplit/--no-octree, --overlap, --ignore-normal-maps, --glb/--b3dm, --unlit, the normal-map MTL keywords, --error 0 = auto and the parent cap on geometric error. - Help texts updated for the scaled overlap nudge and preset precedence. - Removed the TODO file and redundant usings.
Summary of this PR
Maintainer additions
ImpactFixes several silent-wrong-output cases (bad GE cascades, VerificationBuild clean (0 warnings), 309 tests passing, CI green, and an 11-config end-to-end sweep with 0 child>parent geometric-error violations in every tileset. |
Upstream (PR OpenDroneMap#100) clamps each tile's estimated error to its parent's, so a saturated estimate legitimately equals the parent value. The regression guard stays: strictly-greater-than-parent and non-finite errors still fail the gate.
This PR contains several improvements including texture packing speed-ups, geometric error estimation, tile overlap, glb support, setting presets and some bug fixes. Look at the individual commits for more information.
I am aware of the fact that this is complicated to evaluate and merge. It's the result of a work I'm doing on a real project and unfortunately I didn't have time to make smaller PRs. You can merge it as it is, cherry-pick some commits, use some as inspiration or ignore everything altogether...
However, the bugfixes are certainly useful. Also the direct *.glb support is interesting because it then allows to run the draco encoder on each tile significantly reducing the output size.