public void FreeIndexRange(int startIndex, int range)
        {
            var lastIndex = startIndex + range;

            if (startIndex < 0 || lastIndex > indexToID.Length)
            {
                throw new ArgumentOutOfRangeException($"StartIndex {startIndex} with range {range}, must be between 0 and {indexToID.Length}");
            }

            if (range == 0)
            {
                return; // nothing to do
            }
            if (freeIDs.Capacity < freeIDs.Length + (lastIndex - startIndex + 1))
            {
                freeIDs.SetCapacity((int)((freeIDs.Length + (lastIndex - startIndex + 1)) * 1.5f));
            }
            for (int index = startIndex; index < lastIndex; index++)
            {
                var idInternal = indexToID[index] - 1;
                indexToID[index] = 0;

                //Debug.Assert(!freeIDs.Contains(idInternal)); // slow
                freeIDs.AddNoResize(idInternal);

                var idLookup = idToIndex[idInternal];
                idLookup.index        = -1;
                idToIndex[idInternal] = idLookup;
            }

            sectionManager.FreeRange(startIndex, range);
        }
        public void Execute(int index)
        {
            var count = input.BeginForEachIndex(index);

            if (count == 0)
            {
                return;
            }

            var brushIndexOrder = input.Read <IndexOrder>();
            var brushNodeOrder  = brushIndexOrder.nodeOrder;
            var vertexCount     = input.Read <int>();

            NativeCollectionHelpers.EnsureCapacityAndClear(ref brushVertices, vertexCount);
            for (int v = 0; v < vertexCount; v++)
            {
                var vertex = input.Read <float3>();
                brushVertices.AddNoResize(vertex);
            }


            var surfaceOuterCount = input.Read <int>();

            NativeCollectionHelpers.EnsureSizeAndClear(ref surfaceLoopIndices, surfaceOuterCount);
            for (int o = 0; o < surfaceOuterCount; o++)
            {
                UnsafeList <int> inner = default;
                var surfaceInnerCount  = input.Read <int>();
                if (surfaceInnerCount > 0)
                {
                    inner = new UnsafeList <int>(surfaceInnerCount, Allocator.Temp);
                    //inner.ResizeUninitialized(surfaceInnerCount);
                    for (int i = 0; i < surfaceInnerCount; i++)
                    {
                        inner.AddNoResize(input.Read <int>());
                    }
                }
                surfaceLoopIndices[o] = inner;
            }

            var surfaceLoopCount = input.Read <int>();

            NativeCollectionHelpers.EnsureMinimumSizeAndClear(ref surfaceLoopAllInfos, surfaceLoopCount);
            NativeCollectionHelpers.EnsureSizeAndClear(ref surfaceLoopAllEdges, surfaceLoopCount);
            for (int l = 0; l < surfaceLoopCount; l++)
            {
                surfaceLoopAllInfos[l] = input.Read <SurfaceInfo>();
                var edgeCount = input.Read <int>();
                if (edgeCount > 0)
                {
                    var edgesInner = new UnsafeList <Edge>(edgeCount, Allocator.Temp);
                    //edgesInner.ResizeUninitialized(edgeCount);
                    for (int e = 0; e < edgeCount; e++)
                    {
                        edgesInner.AddNoResize(input.Read <Edge>());
                    }
                    surfaceLoopAllEdges[l] = edgesInner;
                }
            }
            input.EndForEachIndex();



            if (!basePolygonCache[brushNodeOrder].IsCreated)
            {
                return;
            }

            var maxLoops   = 0;
            var maxIndices = 0;

            for (int s = 0; s < surfaceLoopIndices.Length; s++)
            {
                if (!surfaceLoopIndices[s].IsCreated)
                {
                    continue;
                }
                var length = surfaceLoopIndices[s].Length;
                maxIndices += length;
                maxLoops    = math.max(maxLoops, length);
            }


            ref var baseSurfaces                = ref basePolygonCache[brushNodeOrder].Value.surfaces;