コード例 #1
0
 Memory <byte> IBufferWriter <byte> .GetMemory(int minimumLength)
 {
     if (minimumLength < 1)
     {
         minimumLength = 1;
     }
     if (_buffer.Free.Count < minimumLength)
     {
         var doubleCount = _buffer.Free.Count * 2;
         int newSize     = minimumLength > doubleCount ? minimumLength : doubleCount;
         var newArray    = _pool.Rent(newSize + _buffer.Count);
         var oldArray    = _buffer.Resize(newArray);
         _pool.Return(oldArray);
     }
     return(_buffer.Free);
 }
コード例 #2
0
        public void Shrink()
        {
            var array = new ResizableArray <int>(8);

            array.Resize(8);
            Assert.AreEqual(8, array.Count);
        }
コード例 #3
0
        public void ResizeTests()
        {
            var array = new ResizableArray <int>(12);

            array.Resize(24);
            Assert.AreEqual(24, array.Count);
        }
コード例 #4
0
 public Memory <byte> GetMemory(int minimumLength = 0)
 {
     if (minimumLength < 1)
     {
         minimumLength = 1;
     }
     if (minimumLength > _buffer.FreeCount)
     {
         int    doubleCount = _buffer.FreeCount * 2;
         int    newSize     = minimumLength > doubleCount ? minimumLength : doubleCount;
         byte[] newArray    = _pool.Rent(newSize + _buffer.Count);
         byte[] oldArray    = _buffer.Resize(newArray);
         _pool.Return(oldArray);
     }
     return(_buffer.FreeMemory);
 }
コード例 #5
0
        public static Span <T> Flatten <T>(this ISpanSequence <T> sequence)
        {
            var      position = Position.First;
            Span <T> firstSpan;

            // if sequence length == 0
            if (!sequence.TryGet(ref position, out firstSpan, advance: true))
            {
                return(Span <T> .Empty);
            }
            Span <T> secondSpan;

            // if sequence length == 1
            if (!sequence.TryGet(ref position, out secondSpan, advance: true))
            {
                return(firstSpan);
            }

            // allocate and copy
            Span <T> result;

            // if we know the total size of the sequence
            if (sequence.TotalLength != null)
            {
                result = new T[sequence.TotalLength.Value];
                result.Set(firstSpan);
                result.Slice(firstSpan.Length).Set(secondSpan);
                int      copied = firstSpan.Length + secondSpan.Length;
                Span <T> nextSpan;
                while (sequence.TryGet(ref position, out nextSpan, advance: true))
                {
                    nextSpan.CopyTo(result.Slice(copied));
                    copied += nextSpan.Length;
                }
                return(result);
            }
            else
            {
                var capacity       = (firstSpan.Length + secondSpan.Length) * 2;
                var resizableArray = new ResizableArray <T>(capacity);
                firstSpan.CopyTo(ref resizableArray);
                secondSpan.CopyTo(ref resizableArray);
                Span <T> nextSpan;
                int      copied = firstSpan.Length + secondSpan.Length;
                while (sequence.TryGet(ref position, out nextSpan, advance: true))
                {
                    while (copied + nextSpan.Length > resizableArray.Capacity)
                    {
                        var newLength = resizableArray.Capacity * 2;
                        resizableArray.Resize(newLength);
                    }
                    nextSpan.CopyTo(ref resizableArray);
                    copied += nextSpan.Length;
                }
                return(resizableArray._array.Slice(0, copied));
            }
        }
コード例 #6
0
        public static ReadOnlySpan <byte> ToSpan <T>(this T sequence) where T : ISequence <ReadOnlyMemory <byte> >
        {
            SequencePosition      position = sequence.Start;
            ResizableArray <byte> array    = new ResizableArray <byte>(1024);

            while (sequence.TryGet(ref position, out ReadOnlyMemory <byte> buffer))
            {
                array.AddAll(buffer.Span);
            }
            array.Resize(array.Count);
            return(array.Span.Slice(0, array.Count));
        }
コード例 #7
0
 private ResizableArray <T> InitializeVertexAttribute <T>(T[] attributeValues)
 {
     if (attributeValues != null && attributeValues.Length == vertices.Length)
     {
         var newArray = new ResizableArray <T>(0);
         newArray.Resize(attributeValues.Length);
         var newArrayData = newArray.Data;
         Array.Copy(attributeValues, 0, newArrayData, 0, attributeValues.Length);
         return(newArray);
     }
     return(null);
 }
コード例 #8
0
ファイル: BufferExtensions.cs プロジェクト: mjp41/corefxlab
        public static ReadOnlySpan <byte> ToSpan <T>(this T memorySequence) where T : ISequence <ReadOnlyMemory <byte> >
        {
            Position position = Position.First;
            ReadOnlyMemory <byte> memory;
            ResizableArray <byte> array = new ResizableArray <byte>(memorySequence.Length.GetValueOrDefault(1024));

            while (memorySequence.TryGet(ref position, out memory))
            {
                array.AddAll(memory.Span);
            }
            array.Resize(array.Count);
            return(array.Items.Slice(0, array.Count));
        }
コード例 #9
0
        void IOutput.Enlarge(int desiredBufferLength)
        {
            if (desiredBufferLength < 1)
            {
                desiredBufferLength = 1;
            }
            var doubleCount = _buffer.Free.Count * 2;
            int newSize     = desiredBufferLength > doubleCount ? desiredBufferLength : doubleCount;
            var newArray    = _pool.Rent(newSize + _buffer.Count);
            var oldArray    = _buffer.Resize(newArray);

            _pool.Return(oldArray);
        }
コード例 #10
0
        public static ReadOnlySpan <byte> ToSpan <T>(this T bufferSequence) where T : ISequence <ReadOnlyBuffer <byte> >
        {
            Position position = Position.First;
            ReadOnlyBuffer <byte> buffer;
            ResizableArray <byte> array = new ResizableArray <byte>(1024);

            while (bufferSequence.TryGet(ref position, out buffer))
            {
                array.AddAll(buffer.Span);
            }
            array.Resize(array.Count);
            return(array.Items.Slice(0, array.Count));
        }
コード例 #11
0
 public void Resize(int length, bool trimExess = false)
 {
     deltaVertices.Resize(length, trimExess);
     deltaNormals.Resize(length, trimExess);
     deltaTangents.Resize(length, trimExess);
 }
コード例 #12
0
        /// <summary>
        /// Initializes the algorithm with the original mesh.
        /// </summary>
        /// <param name="mesh">The mesh.</param>
        public override void Initialize(Mesh mesh)
        {
            if (mesh == null)
            {
                throw new ArgumentNullException("mesh");
            }

            int meshSubMeshCount  = mesh.SubMeshCount;
            int meshTriangleCount = mesh.TriangleCount;
            var meshVertices      = mesh.Vertices;
            var meshNormals       = mesh.Normals;
            var meshTangents      = mesh.Tangents;
            var meshUV1           = mesh.UV1;
            var meshUV2           = mesh.UV2;
            var meshUV3           = mesh.UV3;
            var meshUV4           = mesh.UV4;
            var meshColors        = mesh.Colors;
            var meshBoneWeights   = mesh.BoneWeights;

            subMeshCount = meshSubMeshCount;

            vertices.Resize(meshVertices.Length);
            var vertArr = vertices.Data;

            for (int i = 0; i < meshVertices.Length; i++)
            {
                vertArr[i] = new Vertex(meshVertices[i]);
            }

            if (keepLinkedVertices)
            {
                // Find links between vertices
                // TODO: Is it possible to optimize this further?
                int vertexCount = vertArr.Length;
                for (int i = 0; i < vertexCount; i++)
                {
                    bool hasLinked = false;
                    var  p0        = meshVertices[i];
                    for (int j = i + 1; j < vertexCount; j++)
                    {
                        if (hasLinked && vertArr[j].linked)
                        {
                            continue;
                        }

                        double xDiff = meshVertices[j].x - p0.x;
                        if ((xDiff * xDiff) > Vector3d.Epsilon)
                        {
                            continue;
                        }

                        double yDiff = meshVertices[j].y - p0.y;
                        if ((yDiff * yDiff) > Vector3d.Epsilon)
                        {
                            continue;
                        }

                        double zDiff = meshVertices[j].z - p0.z;
                        if ((zDiff * zDiff) > Vector3d.Epsilon)
                        {
                            continue;
                        }

                        hasLinked         = true;
                        vertArr[i].linked = true;
                        vertArr[j].linked = true;
                    }
                }
            }

            triangles.Resize(meshTriangleCount);
            var trisArr       = triangles.Data;
            int triangleIndex = 0;

            for (int subMeshIndex = 0; subMeshIndex < meshSubMeshCount; subMeshIndex++)
            {
                int[] subMeshIndices       = mesh.GetIndices(subMeshIndex);
                int   subMeshTriangleCount = subMeshIndices.Length / 3;
                for (int i = 0; i < subMeshTriangleCount; i++)
                {
                    int offset = i * 3;
                    int v0     = subMeshIndices[offset];
                    int v1     = subMeshIndices[offset + 1];
                    int v2     = subMeshIndices[offset + 2];
                    trisArr[triangleIndex++] = new Triangle(v0, v1, v2, subMeshIndex);
                }
            }

            vertNormals     = InitializeVertexAttribute(meshNormals);
            vertTangents    = InitializeVertexAttribute(meshTangents);
            vertUV1         = InitializeVertexAttribute(meshUV1);
            vertUV2         = InitializeVertexAttribute(meshUV2);
            vertUV3         = InitializeVertexAttribute(meshUV3);
            vertUV4         = InitializeVertexAttribute(meshUV4);
            vertColors      = InitializeVertexAttribute(meshColors);
            vertBoneWeights = InitializeVertexAttribute(meshBoneWeights);
        }
コード例 #13
0
        /// <summary>
        /// Remove vertices and mark deleted triangles
        /// </summary>
        private void RemoveVertexPass(int startTrisCount, int targetTrisCount, double threshold, ResizableArray <bool> deleted0, ResizableArray <bool> deleted1, ref int deletedTris)
        {
            var triangles     = this.triangles.Data;
            int triangleCount = this.triangles.Length;
            var vertices      = this.vertices.Data;

            int maxVertexCount = this.maxVertexCount;

            if (maxVertexCount <= 0)
            {
                maxVertexCount = int.MaxValue;
            }

            Vertex   v0, v1;
            Vector3d p;

            for (int i = 0; i < triangleCount; i++)
            {
                var t = triangles[i];
                if (t.dirty || t.deleted || t.err3 > threshold)
                {
                    continue;
                }

                t.GetErrors(errArr);
                for (int j = 0; j < 3; j++)
                {
                    if (errArr[j] > threshold)
                    {
                        continue;
                    }

                    int i0 = t[j];
                    int i1 = t[(j + 1) % 3];
                    v0 = vertices[i0];
                    v1 = vertices[i1];

                    // Border check
                    if (v0.border != v1.border)
                    {
                        continue;
                    }

                    // Keep linked vertices
                    if (keepLinkedVertices && (v0.linked || v1.linked))
                    {
                        continue;
                    }

                    // If borders should be kept
                    if (keepBorders && (v0.border || v1.border))
                    {
                        continue;
                    }

                    // Compute vertex to collapse to
                    CalculateError(i0, i1, out p);
                    deleted0.Resize(v0.tcount); // normals temporarily
                    deleted1.Resize(v1.tcount); // normals temporarily

                    // Don't remove if flipped
                    if (Flipped(p, i0, i1, ref v0, deleted0))
                    {
                        continue;
                    }
                    if (Flipped(p, i1, i0, ref v1, deleted1))
                    {
                        continue;
                    }

                    // Not flipped, so remove edge
                    v0.p         = p;
                    v0.q        += v1.q;
                    vertices[i0] = v0;
                    MergeVertices(i0, i1);

                    int tstart = refs.Length;
                    UpdateTriangles(i0, ref v0, deleted0, ref deletedTris);
                    UpdateTriangles(i0, ref v1, deleted1, ref deletedTris);

                    int tcount = refs.Length - tstart;
                    if (tcount <= v0.tcount)
                    {
                        // save ram
                        if (tcount > 0)
                        {
                            var refsArr = refs.Data;
                            Array.Copy(refsArr, tstart, refsArr, v0.tstart, tcount);
                        }
                    }
                    else
                    {
                        // append
                        vertices[i0].tstart = tstart;
                    }

                    vertices[i0].tcount = tcount;
                    --remainingVertices;
                    break;
                }

                // Check if we are already done
                if ((startTrisCount - deletedTris) <= targetTrisCount && remainingVertices < maxVertexCount)
                {
                    break;
                }
            }
        }