Module for filling a bounding box with as many of an object that will fit isnt filling the bounding box correctly

It fills mostly correctly, although doesn’t fill the bounding box fully leaving lots of space at the top when it should be generating higher

--!strict

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

export type ModelOrPart = BasePart | Model
export type FillData = {
	ShouldStack: boolean?,
	ObjectSize: Vector3,
	BoxCFrame: CFrame?,
	BoxSize: Vector3,
	Padding: Vector2?
}

local Module = {}

function Module.GenerateLayers(Layer: {CFrame}, LayerSize: Vector3, BoxSize: Vector3, ObjectSize: Vector3)
	local TotalLayersSize = LayerSize
	local Layers = {}

	table.insert(Layers, Layer)
	
	repeat
		local YPosition = Vector3.new(0, ObjectSize.Y * #Layers, 0)
		local NewLayer = {} :: {CFrame}

		for _, Position in Layer do
			local NewPosition = Position + YPosition
			table.insert(NewLayer, NewPosition)
		end
		TotalLayersSize += YPosition
		
		table.insert(Layers, NewLayer)
		RunService.Heartbeat:Wait()
	until TotalLayersSize.Y > BoxSize.Y
	-- Removing the last layer because it was out of bounds
	Layers[#Layers] = nil
	
	return Layers, TotalLayersSize
end

function Module.GenerateLayer(Row: {CFrame}, RowSize: Vector3, BoxSize: Vector3, ObjectSize: Vector3)
	local TotalLayerSize = Vector3.new(ObjectSize.X, ObjectSize.Y, RowSize.Z)
	local PreviousRowIndexs = {} :: {number}
	local Layer = {} :: {CFrame}

	-- Generating the first row in the layer
	for Index, Position in Row do
		table.insert(PreviousRowIndexs, Index)
		table.insert(Layer, Position)
	end

	repeat
		local NumberOfRows = #Layer/#Row 
		local XPosition = Vector3.new((ObjectSize.X * NumberOfRows) + ObjectSize.X, 0, 0)
		table.clear(PreviousRowIndexs)
		
		for Index, Position in Row do
			local NewPosition = Position + XPosition
			table.insert(Layer, NewPosition)
			-- Inserting the last index number (the index of the position we just added)
			-- to the list of previous row indexs
			table.insert(PreviousRowIndexs, #Layer)
		end

		NumberOfRows = #Layer/#Row 
		TotalLayerSize += Vector3.new(ObjectSize.X * NumberOfRows, 0, 0)
		RunService.Heartbeat:Wait()
	until TotalLayerSize.X > BoxSize.X
	-- Removing all of the previous row indexs from the layer, as they are outside of the box
	for _, Index in PreviousRowIndexs do
		table.remove(Layer, Index)
	end
	
	return Layer, TotalLayerSize
end

function Module.GenerateRow(BoxCFrame: CFrame, BoxSize: Vector3, ObjectSize: Vector3)
	local BoxBottomRight = CFrame.new(BoxCFrame.X + BoxSize.X/2, BoxCFrame.Y - BoxSize.Y/2, BoxCFrame.Z + BoxSize.Z/2)
	local TotalRowSize = ObjectSize
	local Row = {} :: {CFrame}
	
	-- Putting in the first object position for the row
	local BottomRightObjectPosition = CFrame.new(BoxBottomRight.X - ObjectSize.X/2, BoxBottomRight.Y + ObjectSize.Y/2, BoxBottomRight.Z - ObjectSize.Z/2)
	table.insert(Row, BottomRightObjectPosition)
	
	repeat
		local ObjectPosition = Row[#Row] - Vector3.new(0, 0, -ObjectSize.Z)
		table.insert(Row, ObjectPosition)
		TotalRowSize += ObjectSize
		
		RunService.Heartbeat:Wait()
	until TotalRowSize.Z > BoxSize.Z
	-- Removing the last index in the row, so that the row fits in the box
	-- And removing the size of one object from the total row size
	TotalRowSize = TotalRowSize - ObjectSize
	Row[#Row] = nil
	
	return Row, TotalRowSize
end

function Module.FillBoxWithObject(Props: FillData)
	return function()
		local BoxCFrame = Props.BoxCFrame or CFrame.new(0, 0, 0) :: CFrame
		local ShouldStack = Props.ShouldStack
		local ObjectSize = Props.ObjectSize
		local Padding = Props.Padding
		local BoxSize = Props.BoxSize
		local Result: any, Result2: any
		
		if Padding then
			local PaddingVector2 = Padding/2
			local PaddingVector3 = Vector3.new(PaddingVector2.X, 0, PaddingVector2.Y)

			ObjectSize = ObjectSize + PaddingVector3
			BoxSize = BoxSize - PaddingVector3
		end
		
		local Row, RowSize = Module.GenerateRow(BoxCFrame, BoxSize, ObjectSize)
		local Layer, LayerSize = Module.GenerateLayer(Row, RowSize, BoxSize, ObjectSize)
			
		if ShouldStack then
			local Layers, LayersSize = Module.GenerateLayers(Layer, LayerSize, BoxSize, ObjectSize)
			return Layers, LayersSize
		else
			local ResultTable = {}
			table.insert(ResultTable, Layer)

			return ResultTable, LayerSize
		end
	end
end

What is it actually trying to do?