/// <summary>Unmanaged buffer of iMeshIndexer wrapped into a Span you can write your vertices</summary> public static Span <T> getBuffer <T>(this iMeshIndexer indexer) where T : unmanaged { sMeshIndexerSetup setup = indexer.getSetup(); int expected = setup.bytesPerVertex; int actual = Marshal.SizeOf <T>(); if (expected != actual) { throw new ArgumentException($"Vertex size mismatch; indexer expects { expected } bytes / vertex, yet sizeof( { typeof( T ).FullName } ) is { actual }"); } unsafe { return(new Span <T>((void *)indexer.getPointer(), (int)setup.verticesPerBatch)); } }
static BoundingBox loadStlImpl(iMeshIndexer indexer, Stream stream, int trianglesCount, int trianglesPerBatch, float?minCosAngle) { Stopwatch sw; if (logTime) { sw = Stopwatch.StartNew(); } var bbox = loadStlTriangles(indexer, stream, trianglesCount, trianglesPerBatch); if (logTime) { ConsoleLogger.logDebug("Loading STL and indexing vertices: {0}", sw.Elapsed.print()); } if (minCosAngle.HasValue) { if (logTime) { sw.Restart(); } indexer.generateNormals(minCosAngle.Value); if (logTime) { ConsoleLogger.logDebug("Generating normals: {0}", sw.Elapsed.print()); } } if (logTime) { sw.Restart(); } indexer.optimizeMesh(eMeshOptimizerFlags.All); if (logTime) { ConsoleLogger.logDebug("Optimizing the mesh: {0}", sw.Elapsed.print()); } return(bbox); }
static BoundingBox loadStlTriangles(iMeshIndexer indexer, Stream stream, int trianglesCount, int trianglesPerBatch) { Memory <StlTriangle> buffer = new Memory <StlTriangle>(new StlTriangle[trianglesPerBatch]); BoundingBox? box = null; Span <Vector3> indexerBuffer = indexer.getBuffer <Vector3>(); while (trianglesCount > 0) { int batch = Math.Min(trianglesCount, trianglesPerBatch); // Read into the buffer, it's over an array in managed memory Memory <StlTriangle> slice = buffer.Slice(0, batch); stream.Read(MemoryMarshal.AsBytes(slice.Span)); // Copy the batch to native memory copyBatch(indexerBuffer, slice.Span); // Update the box. Using the data from native memory because it has better locality, we only consume 72% of the source data, the rest is normals and BS. BoundingBox bb = BoundingBox.compute(indexerBuffer.Slice(0, batch * 3)); if (box.HasValue) { box = BoundingBox.union(box.Value, bb); } else { box = bb; } // Index these vertices indexer.commitBatch((uint)batch * 3); trianglesCount -= batch; } return(box.Value); }