Esempio n. 1
0
        /// <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));
            }
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }