### Writing Splat Files with SplatPLYSceneWriter Source: https://context7.com/scier/metalsplatter/llms.txt Exports SplatPoint arrays to PLY format with configurable spherical harmonics degree. Supports binary and ASCII output. Use `writtenData` to get data in memory. ```swift import SplatIO // Create writer for binary PLY output let writer = try SplatPLYSceneWriter(toFileAtPath: "/path/to/output.ply") // Start with configuration try await writer.start( sphericalHarmonicDegree: 3, // 0-3, higher = more view-dependent color data binary: true, // Binary is faster and smaller pointCount: points.count ) // Write points (can be batched) try await writer.write(points) // Finish and close try await writer.close() // Get written data directly (for in-memory processing) let outputData = await writer.writtenData ``` -------------------------------- ### SplatConverter Command-Line Tool Source: https://context7.com/scier/metalsplatter/llms.txt Command-line utility for converting between splat formats (PLY, .splat, SPZ). Supports subset selection, ASCII/binary output, and verbose descriptions. ```bash # Basic conversion SplatConverter input.ply -o output.splat # Convert to ASCII PLY SplatConverter scene.spz -o scene_ascii.ply -f ply-ascii # Convert to SPZ compressed format SplatConverter scene.ply -o scene.spz -f spz # Convert subset of points SplatConverter large_scene.ply -o subset.ply --start 1000 --count 5000 # Describe points (for debugging) SplatConverter scene.ply --describe --start 0 --count 10 # Verbose output with timing SplatConverter input.spz -o output.ply -v # Output: Read 1500000 points from input.spz in 2.34 seconds (641025 points/s) # Output: Wrote 1500000 points to output.ply in 3.12 seconds (480769 points/s) ``` -------------------------------- ### Initialize SplatRenderer in Swift Source: https://context7.com/scier/metalsplatter/llms.txt Initializes the core SplatRenderer with Metal device and configuration. Supports stereo rendering and high-quality depth output. Optional callbacks can be set for sort monitoring. ```swift import MetalSplatter import Metal // Initialize the renderer with configuration let device = MTLCreateSystemDefaultDevice()! let renderer = try SplatRenderer( device: device, colorFormat: .bgra8Unorm, depthFormat: .depth32Float, sampleCount: 1, maxViewCount: 2, // 2 for stereo on visionOS maxSimultaneousRenders: 3, highQualityDepth: true, // Better depth for Vision Pro reprojection clearColor: MTLClearColor(red: 0, green: 0, blue: 0, alpha: 0) ) // Set optional callbacks for sort monitoring renderer.onSortStart = { print("Sort started") } renderer.onSortComplete = { duration in print("Sort completed in \(duration) seconds") } ``` -------------------------------- ### Write PLY Files with PLYWriter Source: https://context7.com/scier/metalsplatter/llms.txt Creates PLY files in ASCII or binary format. Write the header first, then stream elements in batches for efficient memory usage. ```swift import PLYIO // Create PLY writer let writer = try PLYWriter(to: .file(URL(fileURLWithPath: "/path/to/output.ply"))) // Define header let properties: [PLYHeader.Property] = [ .init(name: "x", type: .primitive(.float32)), .init(name: "y", type: .primitive(.float32)), .init(name: "z", type: .primitive(.float32)), .init(name: "red", type: .primitive(.uint8)), .init(name: "green", type: .primitive(.uint8)), .init(name: "blue", type: .primitive(.uint8)) ] let element = PLYHeader.Element(name: "vertex", count: 1000, properties: properties) let header = PLYHeader(format: .binaryLittleEndian, version: "1.0", elements: [element]) // Write header try await writer.write(header) // Write elements in batches for batch in pointBatches { let elements = batch.map { point -> PLYElement in PLYElement(properties: [ .float32(point.x), .float32(point.y), .float32(point.z), .uint8(point.r), .uint8(point.g), .uint8(point.b) ]) } try await writer.write(elements) } try await writer.close() ``` -------------------------------- ### Writing PLY Files Source: https://context7.com/scier/metalsplatter/llms.txt Creates PLY files in ASCII or binary format, supporting batched element writing. ```APIDOC ## Writing PLY Files ### Description PLYWriter creates PLY files in ASCII or binary format. Write the header first, then stream elements in batches for efficient memory usage. ### Parameters - **header** (PLYHeader) - Required - The header definition for the PLY file. - **elements** (Array) - Required - A batch of PLYElement objects to write. ``` -------------------------------- ### Load Splat Files with AutodetectSceneReader in Swift Source: https://context7.com/scier/metalsplatter/llms.txt Loads splat files (PLY, .splat, SPZ) using AutodetectSceneReader, which automatically detects the format. It streams points in batches for memory efficiency or can load all points at once. ```swift import SplatIO // Load splat file with automatic format detection let url = URL(fileURLWithPath: "/path/to/scene.ply") let reader = try AutodetectSceneReader(url) // Stream points in batches var allPoints: [SplatPoint] = [] for try await batch in try await reader.read() { allPoints.append(contentsOf: batch) print("Loaded \(batch.count) points, total: \(allPoints.count)") } // Alternatively, use readAll() for convenience let points = try await reader.readAll() print("Loaded \(points.count) splat points") ``` -------------------------------- ### Reading PLY Files Source: https://context7.com/scier/metalsplatter/llms.txt Provides low-level PLY file parsing supporting ASCII and binary formats using an async stream. ```APIDOC ## Reading PLY Files ### Description PLYReader provides low-level PLY file parsing supporting ASCII and binary formats (little/big endian). It returns an async stream of element series for memory-efficient processing. ### Response - **header** (PLYHeader) - The parsed PLY file header. - **elementsStream** (AsyncStream) - An async stream of element series for processing. ``` -------------------------------- ### Create and Add SplatChunks in Swift Source: https://context7.com/scier/metalsplatter/llms.txt Creates a SplatChunk from loaded points and adds it to the renderer. Chunks can be enabled/disabled and managed independently. Sorting and enabling can be synchronized with renderer events. ```swift import MetalSplatter import SplatIO import Metal // Create chunk from loaded points let device = MTLCreateSystemDefaultDevice()! let points = try await AutodetectSceneReader(url).readAll() let chunk = try SplatChunk(device: device, from: points) // Add chunk to renderer (disabled initially to avoid visual glitches) let chunkID = await renderer.addChunk(chunk, sortByLocality: true, enabled: false) // Wait for sort completion, then enable renderer.afterNextSort { Task { await renderer.setChunkEnabled(chunkID, enabled: true) } } // Later: remove chunk when done await renderer.removeChunk(chunkID) // Or remove all chunks await renderer.removeAllChunks() ``` -------------------------------- ### Rendering a Frame Source: https://context7.com/scier/metalsplatter/llms.txt Encodes splat rendering commands to a command buffer, supporting stereo viewports and configurable textures. ```APIDOC ## Rendering a Frame ### Description The render method encodes splat rendering commands to a command buffer. It supports multiple viewports for stereo rendering, configurable color/depth textures, and rasterization rate maps. ### Parameters - **viewports** (Array) - Required - List of SplatRenderer.ViewportDescriptor objects. - **colorTexture** (MTLTexture) - Required - The target color texture. - **colorStoreAction** (MTLStoreAction) - Required - The store action for the color texture. - **depthTexture** (MTLTexture) - Optional - The depth texture for rendering. - **rasterizationRateMap** (MTLRasterizationRateMap) - Optional - Optional rate map. - **renderTargetArrayLength** (Int) - Required - Length of the render target array. - **accessTimeout** (Double) - Required - Max wait time for exclusive access. - **sortTimeout** (Double) - Required - Max wait time for valid sort. - **to** (MTLCommandBuffer) - Required - The command buffer to encode into. ### Response - **success** (Bool) - Returns true if rendering succeeded, false if skipped. ``` -------------------------------- ### Read PLY Files with PLYReader Source: https://context7.com/scier/metalsplatter/llms.txt Provides low-level PLY file parsing supporting ASCII and binary formats. Returns an async stream of element series for memory-efficient processing of large files. ```swift import PLYIO // Read PLY file let reader = try PLYReader(URL(fileURLWithPath: "/path/to/model.ply")) let (header, elementsStream) = try await reader.read() print("Format: \(header.format)") print("Elements: \(header.elements.count)") for element in header.elements { print(" \(element.name): \(element.count) items, \(element.properties.count) properties") } // Process elements for try await series in elementsStream { let elementName = series.elementHeader.name for element in series.elements { // Access properties by index if case .float32(let x) = element.properties[0], case .float32(let y) = element.properties[1], case .float32(let z) = element.properties[2] { print("Position: (\(x), \(y), \(z))") } } } ``` -------------------------------- ### Render Frame with MetalSplatter Source: https://context7.com/scier/metalsplatter/llms.txt Encodes splat rendering commands to a command buffer. Supports multiple viewports, configurable textures, and rasterization rate maps. Returns true on success, false if skipped. ```swift import MetalSplatter import Metal // Create viewport descriptor let viewport = SplatRenderer.ViewportDescriptor( viewport: MTLViewport(originX: 0, originY: 0, width: Double(drawableSize.width), height: Double(drawableSize.height), znear: 0.001, zfar: 1000.0), projectionMatrix: projectionMatrix, viewMatrix: viewMatrix, screenSize: SIMD2(Int(drawableSize.width), Int(drawableSize.height)) ) // Render to command buffer let commandBuffer = commandQueue.makeCommandBuffer()! let success = try renderer.render( viewports: [viewport], // Multiple viewports for stereo colorTexture: drawable.texture, colorStoreAction: .store, depthTexture: depthTexture, rasterizationRateMap: nil, renderTargetArrayLength: 1, accessTimeout: 0.1, // Max wait for exclusive access sortTimeout: 0.1, // Max wait for valid sort to: commandBuffer ) if success { commandBuffer.present(drawable) commandBuffer.commit() } else { // Skip frame - no valid sorted indices or timeout commandBuffer.commit() } ``` -------------------------------- ### Reading Specific Splat Formats Source: https://context7.com/scier/metalsplatter/llms.txt Use dedicated readers for PLY, .splat, and SPZ formats. Supports reading from URLs or Data objects. ```swift import SplatIO // Read PLY splat file explicitly let plyReader = try SplatPLYSceneReader(URL(fileURLWithPath: "scene.ply")) for try await batch in try await plyReader.read() { processBatch(batch) } // Read .splat file (antimatter15 format) let dotSplatReader = try DotSplatSceneReader(URL(fileURLWithPath: "scene.splat")) for try await batch in try dotSplatReader.read() { processBatch(batch) } // Read SPZ compressed file let spzReader = try SPZSceneReader(URL(fileURLWithPath: "scene.spz")) for try await batch in try spzReader.read() { processBatch(batch) } // Read from Data instead of URL let data = try Data(contentsOf: url) let memoryReader = try SplatPLYSceneReader(data) let points = try await memoryReader.readAll() ``` -------------------------------- ### SplatPoint Data Structure Source: https://context7.com/scier/metalsplatter/llms.txt Represents a single Gaussian splat with position, color, opacity, scale, and rotation. Color supports sRGB or spherical harmonics. Access properties in different formats. ```swift import SplatIO import simd // Create a splat point let point = SplatPoint( position: SIMD3(1.0, 2.0, 3.0), color: .sRGBUInt8(SIMD3(255, 128, 64)), opacity: .linearFloat(0.95), scale: .linearFloat(SIMD3(0.01, 0.01, 0.02)), rotation: simd_quatf(angle: .pi / 4, axis: SIMD3(0, 1, 0)) ) // Access color in different formats let srgbFloat = point.color.asSRGBFloat // SIMD3 0-1 let srgbUInt8 = point.color.asSRGBUInt8 // SIMD3 0-255 let shCoeffs = point.color.asSphericalHarmonicFloat // [SIMD3] // Access opacity in different formats let logitOpacity = point.opacity.asLogitFloat // For PLY storage let linearOpacity = point.opacity.asLinearFloat // 0-1 range // Access scale in different formats let exponentScale = point.scale.asExponent // For PLY storage let linearScale = point.scale.asLinearFloat // Actual size // Spherical harmonics degree let shDegree = point.color.shDegree // .sh0, .sh1, .sh2, or .sh3 let higherOrderSH = point.color.higherOrderSHCoefficients // [Float] ``` -------------------------------- ### Exclusive Chunk Access with MetalSplatter Source: https://context7.com/scier/metalsplatter/llms.txt Provides exclusive access for modifying multiple chunks atomically. Waits for in-flight renders to complete and prevents new renders until the body completes. ```swift // Perform multiple chunk operations atomically await renderer.withChunkAccess { // Remove old chunks await renderer.removeAllChunks() // Add new chunks in a batch for points in sceneChunks { let chunk = try SplatChunk(device: device, from: points) await renderer.addChunk(chunk, enabled: true) } } // Check renderer readiness before acquiring drawable if renderer.isReadyToRender { let drawable = metalLayer.nextDrawable() // ... proceed with rendering } ``` -------------------------------- ### Exclusive Chunk Access Source: https://context7.com/scier/metalsplatter/llms.txt Provides exclusive access for modifying multiple chunks atomically, preventing new renders until the operation completes. ```APIDOC ## Exclusive Chunk Access ### Description The withChunkAccess method provides exclusive access for modifying multiple chunks atomically. It waits for in-flight renders to complete and prevents new renders until the body completes. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.