### Load OBJ Mesh with Dependencies Source: https://context7.com/opendronemap/obj2tiles/llms.txt Loads an OBJ file into an IMesh object, extracting associated dependencies like textures and materials. It also provides methods to get mesh properties and split points, and can write the processed mesh back to OBJ format. ```csharp using Obj2Tiles.Library.Geometry; // Load mesh with dependencies (textures, materials) var mesh = MeshUtils.LoadMesh("/path/to/model.obj", out string[] dependencies); Console.WriteLine($"Vertices: {mesh.VertexCount}"); Console.WriteLine($"Faces: {mesh.FacesCount}"); Console.WriteLine($"Bounds: {mesh.Bounds}"); Console.WriteLine($"Dependencies: {string.Join(", ", dependencies)}"); // Get split points for mesh partitioning var baricenter = mesh.GetVertexBaricenter(); // Centroid of all vertices var median = mesh.GetVertexMedian(); // Median position per axis // Check mesh type (textured vs non-textured) if (mesh is MeshT texturedMesh) { Console.WriteLine($"Texture coordinates: {texturedMesh.TextureVertices.Count}"); Console.WriteLine($"Materials: {texturedMesh.Materials.Count}"); } else if (mesh is Mesh simpleMesh) { Console.WriteLine($"Non-textured mesh with {simpleMesh.Faces.Count} faces"); // Check for vertex colors (extended OBJ: v x y z r g b) if (simpleMesh.VertexColors != null) { Console.WriteLine($"Vertex colors: {simpleMesh.VertexColors.Count}"); } } // Write mesh back to OBJ format mesh.WriteObj("/output/processed.obj", removeUnused: true); ``` -------------------------------- ### Build Obj2Tiles Source: https://github.com/opendronemap/obj2tiles/blob/master/README.md Clone the repository and build the Obj2Tiles project using .NET. ```bash git clone https://github.com/OpenDroneMap/Obj2Tiles.git cd Obj2Tiles dotnet build -c Release ``` -------------------------------- ### Initialize and manipulate Box3 geometry Source: https://context7.com/opendronemap/obj2tiles/llms.txt Demonstrates creating bounding boxes from coordinates or vertices, accessing dimensions, splitting boxes along axes, and converting to 3D Tiles format. ```csharp using Obj2Tiles.Library.Geometry; // Create bounding box var box = new Box3( minX: 0, minY: 0, minZ: 0, maxX: 100, maxY: 100, maxZ: 50 ); // Or from vertices var box2 = new Box3( min: new Vertex3(0, 0, 0), max: new Vertex3(100, 100, 50) ); // Properties Console.WriteLine($"Width: {box.Width}"); // 100 Console.WriteLine($"Height: {box.Height}"); // 100 Console.WriteLine($"Depth: {box.Depth}"); // 50 Console.WriteLine($"Center: {box.Center}"); // (50, 50, 25) // Split bounding box along axis var xSplit = box.Split(Axis.X); // Returns 2 Box3 at center var ySplit = box.Split(Axis.Y, 30.0); // Split at Y=30 // Convert to 3D Tiles bounding volume (Y/Z swap for Z-up convention) var boundingVolume = box.ToBoundingVolume(); // Returns: { Box: [cx, -cz, cy, halfW, 0, 0, 0, -halfD, 0, 0, 0, halfH] } ``` -------------------------------- ### Obj2Tiles Command Line Parameters Source: https://github.com/opendronemap/obj2tiles/blob/master/README.md This lists the available command-line parameters for the Obj2Tiles tool, including input/output specifications, stage control, LOD generation, splitting strategies, and geo-referencing options. ```bash Input (pos. 0) Required. Input OBJ file. Output (pos. 1) Required. Output folder. -s, --stage (Default: Tiling) Stage to stop at (Decimation, Splitting, Tiling) -l, --lods (Default: 3) How many levels of detail -d, --divisions (Default: 2) How many tiles divisions -z, --zsplit (Default: false) Splits along z-axis too -g, --split-strategy (Default: VertexBaricenter) Split point strategy: AbsoluteCenter, VertexBaricenter or VertexMedian -k, --keeptextures (Default: false) Keeps original textures --lat Latitude of the mesh (WGS84 decimal degrees) --lon Longitude of the mesh (WGS84 decimal degrees) --alt (Default: 0) Altitude of the mesh (meters above ellipsoid) -e, --error (Default: 100), baseError value for root node --scale (Default: 1), scale factor for local geometry (e.g. 1200.0/3937.0 for survey ft). Does NOT affect altitude or ECEF position. --local (Default: false) Local mode: no ECEF geo-referencing, uses identity matrix. Use this when you don't need globe placement. --y-up-to-z-up (Default: false) Converts Y-up to Z-up --use-system-temp (Default: false) Uses the system temp folder --keep-intermediate (Default: false) Keeps the intermediate files (do not cleanup) --help Display this help screen. --version Display version information. ``` -------------------------------- ### Create B3DM from GLB Source: https://context7.com/opendronemap/obj2tiles/llms.txt Wraps GLB data into a B3DM file structure suitable for 3D Tiles. ```csharp using Obj2Tiles.Tiles; // Read GLB file byte[] glbData = File.ReadAllBytes("/input/model.glb"); // Create B3DM wrapper var b3dm = new B3dm(glbData) { FeatureTableJson = "{\"BATCH_LENGTH\":0} ", // Padded for alignment BatchTableJson = "", FeatureTableBinary = Array.Empty(), BatchTableBinary = Array.Empty() }; // Write B3DM file byte[] b3dmBytes = b3dm.ToBytes(); File.WriteAllBytes("/output/model.b3dm", b3dmBytes); // B3DM structure: // - Header (28 bytes): magic "b3dm", version, lengths // - Feature Table JSON (padded to 8-byte boundary) // - Feature Table Binary // - Batch Table JSON // - Batch Table Binary // - GLB payload (padded to 8-byte boundary) ``` -------------------------------- ### Basic Obj2Tiles Usage Source: https://github.com/opendronemap/obj2tiles/blob/master/README.md Converts a model to 3D Tiles format using default settings and outputs to the specified directory. ```bash Obj2Tiles model.obj ./output ``` -------------------------------- ### B3dm.ToBytes Source: https://context7.com/opendronemap/obj2tiles/llms.txt Creates B3DM files for 3D Tiles from existing GLB data. ```APIDOC ## B3dm.ToBytes ### Description Wraps GLB data into a B3DM structure with optional feature and batch tables. ### Parameters - **glbData** (byte[]) - Required - Binary GLB data - **FeatureTableJson** (string) - Optional - JSON string for feature table - **BatchTableJson** (string) - Optional - JSON string for batch table ### Response - **b3dmBytes** (byte[]) - The resulting B3DM file binary data ``` -------------------------------- ### Basic OBJ to 3D Tiles Conversion Source: https://context7.com/opendronemap/obj2tiles/llms.txt Converts an OBJ file to 3D Tiles format using default settings for LODs and divisions. The output includes a tileset.json and recursively organized B3DM files. ```bash # Basic usage - converts OBJ to 3D Tiles with defaults Obj2Tiles model.obj ./output ``` -------------------------------- ### Obj2Tiles Full Pipeline with Geo-referencing Source: https://github.com/opendronemap/obj2tiles/blob/master/README.md Runs the complete pipeline, generating 8 LODs and 3 divisions per axis, with the model placed at specific WGS84 coordinates. ```bash Obj2Tiles --lods 8 --divisions 3 --lat 40.689434025350025 --lon -74.0444987716782 --alt 120 model.obj ./output ``` -------------------------------- ### Custom LODs and Divisions for OBJ to 3D Tiles Source: https://context7.com/opendronemap/obj2tiles/llms.txt Generates 3D Tiles with a specified number of Levels of Detail (LODs) and divisions per axis for finer tile partitioning. Adjust LODs for detail and divisions for tile count. ```bash # Generate 8 LODs with 3 divisions per axis (9 tiles at deepest level per LOD) Obj2Tiles --lods 8 --divisions 3 model.obj ./output ``` -------------------------------- ### Convert OBJ to glTF Source: https://context7.com/opendronemap/obj2tiles/llms.txt Converts OBJ files to glTF 2.0 format, including PBR material conversion and vertex color handling. ```csharp using SilentWave.Obj2Gltf; // Create converter with default parsers var converter = Converter.MakeDefault(); // Convert OBJ to glTF converter.Convert( objPath: "/input/model.obj", gltfPath: "/output/model.gltf", options: new GltfConverterOptions { RemoveDegenerateFaces = true, DeleteOriginals = false, ObjEncoding = null // Auto-detect encoding } ); // Material conversion: Blinn-Phong -> PBR Metallic-Roughness // - Diffuse color -> BaseColorFactor // - Specular intensity -> RoughnessFactor (inverted) // - Metallic factor defaults to 0.0 // - Textures (map_Kd, norm) -> BaseColorTexture, NormalTexture // Vertex colors (v x y z r g b) are exported as COLOR_0 attribute // with automatic sRGB -> linear RGB conversion per glTF spec ``` -------------------------------- ### Converter.Convert (OBJ to glTF) Source: https://context7.com/opendronemap/obj2tiles/llms.txt Converts OBJ files to glTF 2.0 format, including PBR material conversion. ```APIDOC ## Converter.Convert ### Description Converts OBJ files to glTF 2.0 format with support for Blinn-Phong to PBR Metallic-Roughness material conversion. ### Parameters - **objPath** (string) - Required - Path to input OBJ file - **gltfPath** (string) - Required - Path to output glTF file - **options** (GltfConverterOptions) - Required - Conversion settings including RemoveDegenerateFaces and DeleteOriginals ``` -------------------------------- ### Convert OBJ to B3DM Source: https://context7.com/opendronemap/obj2tiles/llms.txt Converts OBJ files to B3DM format and manages associated dependencies like materials and textures. ```csharp using Obj2Tiles; // Convert single OBJ to B3DM Utils.ConvertB3dm( objPath: "/input/model.obj", destPath: "/output/model.b3dm" ); // Pipeline: OBJ -> glTF -> GLB -> B3DM // Intermediate files created in same directory as input: // - model.gltf (glTF JSON) // - model.glb (Binary glTF) // Final output: model.b3dm // Get OBJ dependencies (materials, textures) var deps = Utils.GetObjDependencies("/input/model.obj"); foreach (var dep in deps) { Console.WriteLine($"Dependency: {dep}"); } // Copy dependencies to output folder Utils.CopyObjDependencies( input: "/input/model.obj", output: "/output/processed" ); ``` -------------------------------- ### Obj2Tiles Local Mode (No Geo-referencing) Source: https://github.com/opendronemap/obj2tiles/blob/master/README.md Converts a model to 3D Tiles format without geo-referencing, suitable for local viewers. The `--local` flag takes precedence over `--lat`/`--lon`. ```bash Obj2Tiles --local model.obj ./output ``` -------------------------------- ### Convert to B3DM tilesets with StagesFacade.Tile Source: https://context7.com/opendronemap/obj2tiles/llms.txt Converts split OBJ files into B3DM format and generates a tileset.json. Supports both geo-referenced and local coordinate modes. ```csharp using Obj2Tiles.Stages; using Obj2Tiles.Stages.Model; using Obj2Tiles.Library.Geometry; // Prepare bounds mapper from split stage output var boundsMapper = new Dictionary[] { new() { ["Mesh-XL-YL"] = new Box3(0, 0, 0, 50, 50, 30), ["Mesh-XL-YR"] = new Box3(0, 50, 0, 50, 100, 30), ["Mesh-XR-YL"] = new Box3(50, 0, 0, 100, 50, 30), ["Mesh-XR-YR"] = new Box3(50, 50, 0, 100, 100, 30) } }; // Generate tileset with geo-referencing var gpsCoords = new GpsCoords( latitude: 45.46424200394995, // Milan, Italy longitude: 9.190277486808588, altitude: 180, scale: 1.0, yUpToZUp: false ); StagesFacade.Tile( sourcePath: "/output/split", destPath: "/output/tiles", lods: 3, baseError: 100, // Geometric error for root node boundsMapper: boundsMapper, coords: gpsCoords, localMode: false // Use ECEF transform ); // Local mode (no geo-referencing, identity matrix) StagesFacade.Tile( sourcePath: "/output/split", destPath: "/output/local-tiles", lods: 3, baseError: 100, boundsMapper: boundsMapper, coords: null, localMode: true ); // Output: tileset.json + LOD-N/*.b3dm files ``` -------------------------------- ### Obj2Tiles Split Strategies Source: https://context7.com/opendronemap/obj2tiles/llms.txt Configures the spatial partitioning strategy for mesh subdivision. Options include VertexBaricenter, AbsoluteCenter, and VertexMedian, with an option for Z-axis splitting for volumetric data. ```bash # VertexBaricenter (default) - split at vertex centroid # Produces balanced tiles in vertex/face count Obj2Tiles --split-strategy VertexBaricenter model.obj ./output ``` ```bash # AbsoluteCenter - split at bounding box center # Produces spatially uniform grid, predictable but may be uneven Obj2Tiles --split-strategy AbsoluteCenter model.obj ./output ``` ```bash # VertexMedian - split at vertex median # Best balance for non-uniform geometry distributions Obj2Tiles --split-strategy VertexMedian model.obj ./output ``` ```bash # Enable Z-axis splitting for volumetric models (buildings, terrain) Obj2Tiles --zsplit --divisions 2 model.obj ./output # Creates 2^3 = 8 tiles per recursion level instead of 4 ``` -------------------------------- ### MeshUtils.LoadMesh Source: https://context7.com/opendronemap/obj2tiles/llms.txt Loads OBJ files into memory as IMesh objects. Supports textured and non-textured meshes with optional vertex colors. It also returns any associated dependencies like textures or materials. ```APIDOC ## LoadMesh ### Description Loads OBJ files into memory as IMesh objects, supporting textured and non-textured meshes with optional vertex colors. ### Method `MeshUtils.LoadMesh(string filePath, out string[] dependencies)` ### Endpoint N/A (Library function) ### Parameters #### Path Parameters - **filePath** (string) - Required - The path to the OBJ file to load. #### Query Parameters None #### Request Body None ### Request Example ```csharp var mesh = MeshUtils.LoadMesh("/path/to/model.obj", out string[] dependencies); ``` ### Response #### Success Response (IMesh) - **mesh** (IMesh) - The loaded mesh object. - **dependencies** (string[]) - An array of strings representing any loaded dependencies (e.g., textures, materials). #### Response Example ```json { "mesh": { "VertexCount": 1234, "FacesCount": 5678, "Bounds": { "Min": [-10.0, -10.0, -10.0], "Max": [10.0, 10.0, 10.0] } }, "dependencies": ["texture.png", "material.mtl"] } ``` ### Additional Information - The loaded mesh can be a `MeshT` (textured) or `Mesh` (non-textured). - Vertex colors are supported if present in the OBJ file (extended format: `v x y z r g b`). - The mesh can be written back to OBJ format using `mesh.WriteObj()`. ``` -------------------------------- ### Utils.ConvertB3dm Source: https://context7.com/opendronemap/obj2tiles/llms.txt Converts OBJ files to B3DM (Batched 3D Model) format via glTF/GLB intermediate steps. ```APIDOC ## Utils.ConvertB3dm ### Description Converts a single OBJ file into a B3DM file. The pipeline automatically generates intermediate glTF and GLB files. ### Parameters - **objPath** (string) - Required - Path to input OBJ file - **destPath** (string) - Required - Path to output B3DM file ``` -------------------------------- ### StagesFacade.Tile Source: https://context7.com/opendronemap/obj2tiles/llms.txt Converts split OBJ files to B3DM format and generates tileset.json for 3D Tiles viewers. ```APIDOC ## StagesFacade.Tile ### Description Converts split OBJ files to B3DM format and generates tileset.json for 3D Tiles viewers. ### Method (Not specified, likely a static method call) ### Endpoint (Not applicable, this is a library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```csharp using Obj2Tiles.Stages; using Obj2Tiles.Stages.Model; using Obj2Tiles.Library.Geometry; // Prepare bounds mapper from split stage output var boundsMapper = new Dictionary[] { new() { ["Mesh-XL-YL"] = new Box3(0, 0, 0, 50, 50, 30), ["Mesh-XL-YR"] = new Box3(0, 50, 0, 50, 100, 30), ["Mesh-XR-YL"] = new Box3(50, 0, 0, 100, 50, 30), ["Mesh-XR-YR"] = new Box3(50, 50, 0, 100, 100, 30) } }; // Generate tileset with geo-referencing var gpsCoords = new GpsCoords( latitude: 45.46424200394995, // Milan, Italy longitude: 9.190277486808588, altitude: 180, scale: 1.0, yUpToZUp: false ); StagesFacade.Tile( sourcePath: "/output/split", destPath: "/output/tiles", lods: 3, baseError: 100, // Geometric error for root node boundsMapper: boundsMapper, coords: gpsCoords, localMode: false // Use ECEF transform ); // Local mode (no geo-referencing, identity matrix) StagesFacade.Tile( sourcePath: "/output/split", destPath: "/output/local-tiles", lods: 3, baseError: 100, boundsMapper: boundsMapper, coords: null, localMode: true ); // Output: tileset.json + LOD-N/*.b3dm files ``` ### Response #### Success Response (200) Generates `tileset.json` and B3DM files in the specified destination path. #### Response Example (No specific JSON response example provided, but output includes `tileset.json` and `LOD-N/*.b3dm` files.) ``` -------------------------------- ### Recursive Mesh Splitting for Tiling Source: https://context7.com/opendronemap/obj2tiles/llms.txt Recursively splits meshes along specified axes for tile generation, supporting parallel processing. It allows for different splitting strategies, including absolute center, custom split point functions, and balanced splitting. ```csharp using System.Collections.Concurrent; using Obj2Tiles.Library.Geometry; var mesh = MeshUtils.LoadMesh("/path/to/model.obj"); var outputMeshes = new ConcurrentBag(); // XY split with bounding box center (AbsoluteCenter strategy) int edgeCuts = await MeshUtils.RecurseSplitXY( mesh: mesh, depth: 2, // 2 levels = 4^2 = 16 tiles max bounds: mesh.Bounds, meshes: outputMeshes ); Console.WriteLine($"Edge cuts: {edgeCuts}, Tiles: {outputMeshes.Count}"); // XY split with custom split point function (VertexBaricenter/Median) outputMeshes = new ConcurrentBag(); edgeCuts = await MeshUtils.RecurseSplitXY( mesh: mesh, depth: 2, getSplitPoint: m => m.GetVertexBaricenter(), meshes: outputMeshes ); // XYZ split for volumetric models (8 children per recursion) outputMeshes = new ConcurrentBag(); edgeCuts = await MeshUtils.RecurseSplitXYZ( mesh: mesh, depth: 2, // 2 levels = 8^2 = 64 tiles max getSplitPoint: m => m.GetVertexMedian(), meshes: outputMeshes ); // Balanced XY split (recomputes split point per sub-partition) outputMeshes = new ConcurrentBag(); edgeCuts = await MeshUtils.RecurseSplitXYBalanced( mesh: mesh, depth: 2, getSplitPoint: m => m.GetVertexMedian(), meshes: outputMeshes ); // Write all output tiles foreach (var tile in outputMeshes) { tile.WriteObj($"/output/tiles/{tile.Name}.obj"); Console.WriteLine($"Tile: {tile.Name}, Faces: {tile.FacesCount}"); } ``` -------------------------------- ### Split meshes with StagesFacade.Split Source: https://context7.com/opendronemap/obj2tiles/llms.txt Recursively splits meshes along axes with options for texture repacking. Supports both batch processing of multiple files and single-file operations. ```csharp using Obj2Tiles.Stages; using Obj2Tiles.Library.Geometry; // Split multiple LOD files (typically output from Decimate stage) string[] sourceFiles = [ "/output/decimation/model.obj", "/output/decimation/model_0.obj", "/output/decimation/model_1.obj" ]; var boundsMapper = await StagesFacade.Split( sourceFiles: sourceFiles, destFolder: "/output/split", divisions: 2, // 2^2 = 4 tiles per LOD zsplit: false, // XY split only keepOriginalTextures: false, // Repack textures splitPointStrategy: SplitPointStrategy.VertexBaricenter ); // boundsMapper is Dictionary[] - one dict per LOD // Keys are mesh names like "Mesh-XL-YL", "Mesh-XL-YR", etc. foreach (var (meshName, bounds) in boundsMapper[0]) { Console.WriteLine($"Tile: {meshName}, Bounds: {bounds}"); } // Single file split with custom options var singleBounds = await StagesFacade.Split( sourcePath: "/path/to/model.obj", destPath: "/output/tiles", divisions: 3, zSplit: true, // XYZ split (8 tiles) bounds: null, // Auto-compute bounds textureStrategy: TexturesStrategy.Repack, splitPointStrategy: SplitPointStrategy.VertexMedian ); ``` -------------------------------- ### MeshUtils.RecurseSplitXY / RecurseSplitXYZ / RecurseSplitXYBalanced Source: https://context7.com/opendronemap/obj2tiles/llms.txt Recursively splits meshes along specified axes for tile generation, supporting parallel processing. Different strategies for determining split points are available. ```APIDOC ## RecurseSplitXY / RecurseSplitXYZ / RecurseSplitXYBalanced ### Description Recursively splits meshes along axes for tile generation with parallel processing. Supports different strategies for determining split points. ### Method `Task RecurseSplitXY(IMesh mesh, int depth, BoundingBox bounds, ConcurrentBag meshes)` `Task RecurseSplitXY(IMesh mesh, int depth, Func getSplitPoint, ConcurrentBag meshes)` `Task RecurseSplitXYZ(IMesh mesh, int depth, Func getSplitPoint, ConcurrentBag meshes)` `Task RecurseSplitXYBalanced(IMesh mesh, int depth, Func getSplitPoint, ConcurrentBag meshes)` ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None #### Parameters for all `RecurseSplit` methods: - **mesh** (IMesh) - Required - The mesh to split. - **depth** (int) - Required - The recursion depth for splitting. For `RecurseSplitXY`, depth `d` results in `4^d` tiles. For `RecurseSplitXYZ`, depth `d` results in `8^d` tiles. - **meshes** (ConcurrentBag) - Required - A thread-safe collection to store the resulting tiles. #### Specific Parameters: - **bounds** (BoundingBox) - Required for `RecurseSplitXY` (non-function overload) - The bounding box to use for splitting. - **getSplitPoint** (Func) - Optional - A function that determines the split point for a given mesh. If not provided, a default strategy (e.g., `AbsoluteCenter`) is used. ### Request Example ```csharp var mesh = MeshUtils.LoadMesh("/path/to/model.obj"); var outputMeshes = new ConcurrentBag(); // XY split with bounding box center await MeshUtils.RecurseSplitXY(mesh: mesh, depth: 2, bounds: mesh.Bounds, meshes: outputMeshes); // XY split with custom split point function await MeshUtils.RecurseSplitXY(mesh: mesh, depth: 2, getSplitPoint: m => m.GetVertexBaricenter(), meshes: outputMeshes); // XYZ split await MeshUtils.RecurseSplitXYZ(mesh: mesh, depth: 2, getSplitPoint: m => m.GetVertexMedian(), meshes: outputMeshes); // Balanced XY split await MeshUtils.RecurseSplitXYBalanced(mesh: mesh, depth: 2, getSplitPoint: m => m.GetVertexMedian(), meshes: outputMeshes); ``` ### Response #### Success Response (int) - **Return Value** (int) - The total number of edge cuts performed during the splitting process. #### Response Example ```json { "edgeCuts": 16 } ``` ### Additional Information - `GetVertexBaricenter()` returns the centroid of all vertices. - `GetVertexMedian()` returns the median position per axis. - The `RecurseSplitXYBalanced` method recomputes the split point for each sub-partition, potentially leading to more balanced tiles. ``` -------------------------------- ### Convert glTF to GLB Source: https://context7.com/opendronemap/obj2tiles/llms.txt Converts glTF JSON files into a single binary GLB file with embedded resources. ```csharp using SilentWave.Obj2Gltf; var converter = Gltf2GlbConverter.Factory(); converter.Convert(new Gltf2GlbOptions( inputPath: "/input/model.gltf" ) { MinifyJson = true, // Compact JSON chunk DeleteOriginal = false // Keep source files }); // Output: /input/model.glb // Embeds all buffers and images into single binary file // GLB structure: // - Header (12 bytes): magic, version, length // - JSON chunk: scene description // - Binary chunk: geometry buffers + embedded images ``` -------------------------------- ### Obj2Tiles Pipeline Stage Control Source: https://context7.com/opendronemap/obj2tiles/llms.txt Allows stopping the conversion pipeline at intermediate stages (Decimation, Splitting) for debugging or custom workflows. Options to keep intermediate files or use system temp folder are also available. ```bash # Stop after decimation - generates LOD OBJ files only Obj2Tiles --stage Decimation --lods 5 model.obj ./output ``` ```bash # Stop after splitting - generates split OBJ files with repacked textures Obj2Tiles --stage Splitting --divisions 3 model.obj ./output ``` ```bash # Keep intermediate files for debugging Obj2Tiles --keep-intermediate model.obj ./output ``` ```bash # Use system temp folder instead of output/.temp Obj2Tiles --use-system-temp model.obj ./output ``` -------------------------------- ### StagesFacade.Split Source: https://context7.com/opendronemap/obj2tiles/llms.txt Recursively splits meshes along X, Y (and optionally Z) axes with texture repacking. ```APIDOC ## StagesFacade.Split ### Description Recursively splits meshes along X, Y (and optionally Z) axes with texture repacking. ### Method (Not specified, likely a static method call) ### Endpoint (Not applicable, this is a library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```csharp using Obj2Tiles.Stages; using Obj2Tiles.Library.Geometry; // Split multiple LOD files (typically output from Decimate stage) string[] sourceFiles = [ "/output/decimation/model.obj", "/output/decimation/model_0.obj", "/output/decimation/model_1.obj" ]; var boundsMapper = await StagesFacade.Split( sourceFiles: sourceFiles, destFolder: "/output/split", divisions: 2, // 2^2 = 4 tiles per LOD zsplit: false, // XY split only keepOriginalTextures: false, // Repack textures splitPointStrategy: SplitPointStrategy.VertexBaricenter ); // boundsMapper is Dictionary[] - one dict per LOD // Keys are mesh names like "Mesh-XL-YL", "Mesh-XL-YR", etc. foreach (var (meshName, bounds) in boundsMapper[0]) { Console.WriteLine($"Tile: {meshName}, Bounds: {bounds}"); } // Single file split with custom options var singleBounds = await StagesFacade.Split( sourcePath: "/path/to/model.obj", destPath: "/output/tiles", divisions: 3, zSplit: true, // XYZ split (8 tiles) bounds: null, // Auto-compute bounds textureStrategy: TexturesStrategy.Repack, splitPointStrategy: SplitPointStrategy.VertexMedian ); ``` ### Response #### Success Response (200) - **boundsMapper** (Dictionary[]) - An array of dictionaries, where each dictionary maps tile names to their bounding boxes for each LOD. #### Response Example ```json [ { "Mesh-XL-YL": {"min": {"x": 0, "y": 0, "z": 0}, "max": {"x": 50, "y": 50, "z": 30}}, "Mesh-XL-YR": {"min": {"x": 0, "y": 50, "z": 0}, "max": {"x": 50, "y": 100, "z": 30}}, "Mesh-XR-YL": {"min": {"x": 50, "y": 0, "z": 0}, "max": {"x": 100, "y": 50, "z": 30}}, "Mesh-XR-YR": {"min": {"x": 50, "y": 50, "z": 0}, "max": {"x": 100, "y": 100, "z": 30}} } ] ``` ``` -------------------------------- ### Obj2Tiles Splitting Stage Source: https://github.com/opendronemap/obj2tiles/blob/master/README.md Stops the pipeline at the splitting stage to generate a specified number of divisions per axis. ```bash Obj2Tiles --stage Splitting --divisions 3 model.obj ./output ``` -------------------------------- ### Generate ECEF Transformation Matrix Source: https://context7.com/opendronemap/obj2tiles/llms.txt Creates a 4x4 transformation matrix for geo-positioning models. The scale factor affects local geometry but does not impact the ECEF position. ```csharp using Obj2Tiles.Stages.Model; // Create GPS coordinates for model placement var coords = new GpsCoords( latitude: 45.46424200394995, // Decimal degrees longitude: 9.190277486808588, altitude: 180, // Meters above WGS84 ellipsoid scale: 1.0, // Geometry scale factor yUpToZUp: false // Apply 90deg rotation around X ); // Generate 4x4 transformation matrix (column-major order) double[] transform = coords.ToEcefTransform(); // Matrix structure (column-major for 3D Tiles): // [0] [4] [8] [12] <- rotation/scale columns + translation X // [1] [5] [9] [13] <- rotation/scale columns + translation Y // [2] [6] [10] [14] <- rotation/scale columns + translation Z // [3] [7] [11] [15] <- always [0, 0, 0, 1] Console.WriteLine($"ECEF Position: X={transform[12]:F2}, Y={transform[13]:F2}, Z={transform[14]:F2}"); // Scale only affects local geometry, NOT the ECEF position var scaledCoords = new GpsCoords(45.0, 9.0, 17.0, 100.0, false); var scaledTransform = scaledCoords.ToEcefTransform(); // Position stays at 17m altitude, not 1700m // Matrix multiplication helper double[] combined = GpsCoords.MultiplyMatrix(transform, rotationMatrix); double[] colMajor = GpsCoords.ConvertToColumnMajorOrder(rowMajorMatrix); ``` -------------------------------- ### Low-Level Mesh Splitting Source: https://context7.com/opendronemap/obj2tiles/llms.txt Performs a single mesh split along a specified axis at a given threshold, interpolating edges to create two new meshes. This can be chained for multi-axis partitioning. ```csharp using Obj2Tiles.Library.Geometry; var mesh = MeshUtils.LoadMesh("/path/to/model.obj"); // Split along X axis at x=50 var xUtils = new VertexUtilsX(); int edgeCuts = mesh.Split( utils: xUtils, q: 50.0, // Split threshold left: out IMesh leftMesh, right: out IMesh rightMesh ); Console.WriteLine($"Left: {leftMesh.FacesCount} faces, Right: {rightMesh.FacesCount} faces"); Console.WriteLine($"Edge intersections: {edgeCuts}"); // Chain splits for multi-axis partitioning var yUtils = new VertexUtilsY(); var zUtils = new VertexUtilsZ(); var center = mesh.Bounds.Center; // Split X mesh.Split(xUtils, center.X, out var left, out var right); // Split Y on each half left.Split(yUtils, center.Y, out var topLeft, out var bottomLeft); right.Split(yUtils, center.Y, out var topRight, out var bottomRight); // Result: 4 quadrant meshes // Mesh names automatically assigned: "Mesh-XL-YL", "Mesh-XL-YR", etc. ``` -------------------------------- ### Obj2Tiles Decimation Quality Formula Source: https://github.com/opendronemap/obj2tiles/blob/master/README.md This formula calculates the quality level for each LOD during the decimation stage. A lower quality value means more decimation. ```text quality[i] = 1 - ((i + 1) / lods) ``` -------------------------------- ### Decimate OBJ models with StagesFacade.Decimate Source: https://context7.com/opendronemap/obj2tiles/llms.txt Reduces mesh complexity to generate multiple LOD levels. The result includes paths to the generated OBJ files and the original mesh bounding box. ```csharp using Obj2Tiles.Stages; // Decimate model.obj into 5 LOD levels var result = await StagesFacade.Decimate( sourcePath: "/path/to/model.obj", destPath: "/output/decimation", lods: 5 ); // Result contains: // - result.DestFiles: string[] of output OBJ paths // ["/output/decimation/model.obj", // Original (100%) // "/output/decimation/model_0.obj", // 80% quality // "/output/decimation/model_1.obj", // 60% quality // "/output/decimation/model_2.obj", // 40% quality // "/output/decimation/model_3.obj"] // 20% quality // - result.Bounds: Box3 bounding box of the original mesh Console.WriteLine($"Generated {result.DestFiles.Length} LOD files"); Console.WriteLine($"Bounds: {result.Bounds}"); ``` -------------------------------- ### Gltf2GlbConverter.Convert Source: https://context7.com/opendronemap/obj2tiles/llms.txt Converts glTF JSON files to binary GLB format with embedded resources. ```APIDOC ## Gltf2GlbConverter.Convert ### Description Converts a glTF JSON file into a single binary GLB file, embedding buffers and images. ### Parameters - **options** (Gltf2GlbOptions) - Required - Configuration including inputPath, MinifyJson, and DeleteOriginal ``` -------------------------------- ### Geo-Referenced 3D Tiles Conversion Source: https://context7.com/opendronemap/obj2tiles/llms.txt Converts OBJ to 3D Tiles, placing the model at specific WGS84 coordinates (latitude, longitude, altitude). Supports scale factor for unit conversion and Y-up to Z-up axis transformation. ```bash # Place model at Statue of Liberty coordinates Obj2Tiles --lat 40.689434025350025 --lon -74.0444987716782 --alt 120 \ --lods 8 --divisions 3 model.obj ./output ``` ```bash # With scale factor (for survey feet to meters conversion) Obj2Tiles --lat 45.0 --lon 9.0 --alt 17 --scale 0.3048 model.obj ./output ``` ```bash # With Y-up to Z-up axis conversion (common for some OBJ exporters) Obj2Tiles --lat 45.0 --lon 9.0 --y-up-to-z-up model.obj ./output ``` ```bash # Local mode - no ECEF transform, identity matrix (for local viewers) Obj2Tiles --local model.obj ./output ``` -------------------------------- ### StagesFacade.Decimate Source: https://context7.com/opendronemap/obj2tiles/llms.txt Decimates a source OBJ file to generate multiple LOD versions using Fast Quadric Mesh Simplification. ```APIDOC ## StagesFacade.Decimate ### Description Decimates a source OBJ file to generate multiple LOD versions using Fast Quadric Mesh Simplification. ### Method (Not specified, likely a static method call) ### Endpoint (Not applicable, this is a library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```csharp using Obj2Tiles.Stages; // Decimate model.obj into 5 LOD levels var result = await StagesFacade.Decimate( sourcePath: "/path/to/model.obj", destPath: "/output/decimation", lods: 5 ); // Result contains: // - result.DestFiles: string[] of output OBJ paths // ["/output/decimation/model.obj", // Original (100%) // "/output/decimation/model_0.obj", // 80% quality // "/output/decimation/model_1.obj", // 60% quality // "/output/decimation/model_2.obj", // 40% quality // "/output/decimation/model_3.obj"] // 20% quality // - result.Bounds: Box3 bounding box of the original mesh Console.WriteLine($"Generated {result.DestFiles.Length} LOD files"); Console.WriteLine($"Bounds: {result.Bounds}"); ``` ### Response #### Success Response (200) - **DestFiles** (string[]) - Array of paths to the generated LOD OBJ files. - **Bounds** (Box3) - Bounding box of the original mesh. #### Response Example ```json { "DestFiles": [ "/output/decimation/model.obj", "/output/decimation/model_0.obj", "/output/decimation/model_1.obj", "/output/decimation/model_2.obj", "/output/decimation/model_3.obj" ], "Bounds": { "min": {"x": 0, "y": 0, "z": 0}, "max": {"x": 100, "y": 100, "z": 100} } } ``` ``` -------------------------------- ### Obj2Tiles Decimation Stage Source: https://github.com/opendronemap/obj2tiles/blob/master/README.md Stops the pipeline at the decimation stage to generate a specified number of Level of Details (LODs). ```bash Obj2Tiles --stage Decimation --lods 8 model.obj -o ./output ``` -------------------------------- ### GpsCoords.ToEcefTransform Source: https://context7.com/opendronemap/obj2tiles/llms.txt Generates an ECEF (Earth-Centered, Earth-Fixed) 4x4 transformation matrix for geo-positioning models. ```APIDOC ## GpsCoords.ToEcefTransform ### Description Generates a 4x4 transformation matrix (column-major order) for placing models in ECEF coordinates based on GPS parameters. ### Parameters - **latitude** (double) - Required - Decimal degrees - **longitude** (double) - Required - Decimal degrees - **altitude** (double) - Required - Meters above WGS84 ellipsoid - **scale** (double) - Required - Geometry scale factor - **yUpToZUp** (bool) - Required - Apply 90deg rotation around X ### Response - **transform** (double[]) - 4x4 transformation matrix in column-major order ``` -------------------------------- ### IMesh.Split Source: https://context7.com/opendronemap/obj2tiles/llms.txt Performs a low-level mesh splitting operation along a single axis, with support for edge interpolation. This is a fundamental operation used by the recursive splitting methods. ```APIDOC ## IMesh.Split ### Description Low-level mesh splitting along a single axis with edge interpolation. This method divides a mesh into two parts based on a threshold value along a specified axis. ### Method `int Split(IVertexUtils utils, double q, out IMesh left, out IMesh right)` ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None #### Parameters: - **utils** (IVertexUtils) - Required - An object implementing `IVertexUtils` (e.g., `VertexUtilsX`, `VertexUtilsY`, `VertexUtilsZ`) that defines the axis and interpolation logic. - **q** (double) - Required - The threshold value along the specified axis at which to split the mesh. - **left** (out IMesh) - Output - The resulting mesh containing vertices on the 'left' side of the split threshold. - **right** (out IMesh) - Output - The resulting mesh containing vertices on the 'right' side of the split threshold. ### Request Example ```csharp var mesh = MeshUtils.LoadMesh("/path/to/model.obj"); var xUtils = new VertexUtilsX(); // Split along X axis at x=50 int edgeCuts = mesh.Split(xUtils, 50.0, out IMesh leftMesh, out IMesh rightMesh); Console.WriteLine($"Left: {leftMesh.FacesCount} faces, Right: {rightMesh.FacesCount} faces"); Console.WriteLine($"Edge intersections: {edgeCuts}"); // Example of chaining splits for multi-axis partitioning var yUtils = new VertexUtilsY(); var zUtils = new VertexUtilsZ(); var center = mesh.Bounds.Center; mesh.Split(xUtils, center.X, out var left, out var right); left.Split(yUtils, center.Y, out var topLeft, out var bottomLeft); right.Split(yUtils, center.Y, out var topRight, out var bottomRight); ``` ### Response #### Success Response (int) - **Return Value** (int) - The number of edges that were intersected by the split plane. #### Response Example ```json { "edgeCuts": 5 } ``` ### Additional Information - The `IVertexUtils` interface provides methods for accessing vertex coordinates along a specific axis and for interpolating points on edges that cross the split plane. - Mesh names are automatically assigned for chained splits (e.g., "Mesh-XL-YL"). ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.