예제 #1
0
 public void Remove(BoardNode board)
 {
     if (board == Head)
     {
         if (board == Tail)
         {
             Head  = null;
             Tail  = null;
             Count = 0;
         }
         else
         {
             Head      = Head.Next;
             Head.Prev = null;
             Count--;
         }
     }
     else
     {
         if (board == Tail)
         {
             Tail      = Tail.Prev;
             Tail.Next = null;
             Count--;
         }
         else
         {
             board.Prev.Next = board.Next;
             board.Next.Prev = board.Prev;
             Count--;
         }
     }
 }
예제 #2
0
 public BoardNode(BoardNode original)
 {
     ID              = original.ID;
     dWidth          = original.dWidth;
     dLength         = original.dLength;
     Length          = original.Length;
     Width           = original.Width;
     Area            = original.Area;
     AssociatedBoard = original.AssociatedBoard;
 }
예제 #3
0
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            for (BoardNode iBoard = Head; iBoard != null; iBoard = iBoard.Next)
            {
                sb.Append($"{iBoard.ID} [{iBoard.Length,7:0.0} x {iBoard.Width,5:0.0}] @ ({iBoard.dLength,7:0.0} , {iBoard.dWidth,5:0.0}) \r\n");
            }
            return(sb.ToString());
        }
예제 #4
0
        public BoardList OrderredByArea()
        {
            BoardList orderredList = new BoardList();

            for (BoardNode iBoard = Head; iBoard != null; iBoard = iBoard.Next)
            {
                orderredList.InsertItemSortedbyAreaAsc(new BoardNode(iBoard));
            }

            return(orderredList);
        }
예제 #5
0
 public BoardNode this[string id]
 {
     get
     {
         BoardNode i = Head;
         while (i != null && i.ID != id)
         {
             i = i.Next;
         }
         return(i);
     }
 }
예제 #6
0
 public BoardList(BoardList original)
 {
     Head  = new BoardNode(original.Head);
     Tail  = Head;
     Count = original.Count;
     for (BoardNode iBoard = original.Head.Next; iBoard != null; iBoard = iBoard.Next)
     {
         var newPart = new BoardNode(iBoard);
         newPart.Prev = Tail;
         Tail.Next    = newPart;
         Tail         = newPart;
     }
 }
예제 #7
0
        public void InsertItemSortedbyAreaAsc(BoardNode board)
        {
            if (Head == null)   // list is empty
            {
                board.Prev = null;
                board.Next = null;
                Head       = board;
                Tail       = board;
                Count      = 1;
                return;
            }

            BoardNode iBoard = Head;

            while (iBoard != null && iBoard.Area < board.Area)
            {
                iBoard = iBoard.Next;
            }

            if (iBoard == null)  //passed the end of the list
            {
                board.Prev = Tail;
                Tail.Next  = board;
                Tail       = board;
            }
            else
            {                       // not past the end
                if (iBoard == Head) // at the head
                {
                    board.Prev = null;
                    board.Next = Head;
                    Head.Prev  = board;
                    Head       = board;
                }
                else
                {
                    board.Prev       = iBoard.Prev;
                    board.Next       = iBoard;
                    iBoard.Prev.Next = board;
                    iBoard.Prev      = board;
                }
            }

            Count++;
        }
예제 #8
0
        public BoardList(params BoardNode[] boards)
        {
            if (boards == null || boards.Length == 0 || boards[0] == null)
            {
                return;
            }
            Head = boards[0];
            Tail = Head;
            int i = 0;

            Count = 1;
            while (++i < boards.Length && boards[i] != null)
            {
                boards[i].Prev = Tail;
                Tail           = Tail.Next = boards[i];
                Count++;
            }
        }
예제 #9
0
        public void Remove(string id)
        {
            BoardNode iBoard = Head;

            while (iBoard.ID != id)
            {
                iBoard = iBoard.Next;
            }
            if (iBoard == null)
            {
                return;
            }

            if (iBoard == Head)
            {
                if (iBoard == Tail)
                {
                    Head  = null;
                    Tail  = null;
                    Count = 0;
                }
                else
                {
                    Head      = Head.Next;
                    Head.Prev = null;
                    Count--;
                }
            }
            else
            {
                if (iBoard == Tail)
                {
                    Tail      = Tail.Prev;
                    Tail.Next = null;
                    Count--;
                }
                else
                {
                    iBoard.Prev.Next = iBoard.Next;
                    iBoard.Next.Prev = iBoard.Prev;
                    Count--;
                }
            }
        }
예제 #10
0
 public void Append(BoardNode board)
 {
     if (Head == null)
     {
         board.Next = null;
         board.Prev = null;
         Head       = board;
         Tail       = board;
         Count      = 1;
     }
     else
     {
         board.Next = null;
         board.Prev = Tail;
         Tail.Next  = board;
         Tail       = board;
         Count++;
     }
 }
예제 #11
0
        static void Main(string[] args)
        {
            #region // Gather the inputs to the solution ...
            double boardMargins_length = 0;
            double boardMargins_Width  = 0;
            double PartPadding_Length  = 0;
            double PartPadding_Width   = 0;
            double SawKerf             = 3.2;


            BoardList boards = new BoardList(
                //new BoardNode("A", 2100, 193),
                //new BoardNode("B", 2100, 150),
                //new BoardNode("C", 2100, 143),
                //new BoardNode("D", 2100, 170),
                //new BoardNode("E", 2100, 185),
                new BoardNode("F", 2100, 210),
                //new BoardNode("G", 2100, 135),
                //new BoardNode("H", 2100, 225),
                null
                );

            PartList parts = new PartList(
                new PartNode("001", 1721.7, 100.0),
                new PartNode("002", 284.5, 100.0),
                new PartNode("003", 1721.7, 100.0),
                new PartNode("004", 284.5, 100.0),
                new PartNode("005", 955.0, 69.3),
                new PartNode("006", 955.0, 60.0),
                new PartNode("007", 955.0, 69.6),
                new PartNode("008", 955.0, 80.0),
                new PartNode("009", 955.0, 60.0),
                new PartNode("010", 955.0, 60.0),
                new PartNode("011", 310.0, 100.0),
                new PartNode("012", 310.0, 100.0),
                new PartNode("013", 310.0, 36.0),
                new PartNode("014", 310.0, 36.0),
                new PartNode("015", 354.5, 36.0),
                new PartNode("016", 354.5, 36.0),
                new PartNode("017", 299.0, 20.0),
                new PartNode("018", 299.0, 20.0),
                new PartNode("019", 299.0, 20.0),
                new PartNode("020", 299.0, 20.0),
                new PartNode("021", 327.5, 20.0),
                new PartNode("022", 327.5, 20.0),
                //new PartNode("023", 955.0, 80.0),
                //new PartNode("024", 310.0, 100.0),
                //new PartNode("025", 310.0, 100.0),
                //new PartNode("026", 310.0, 36.0),
                //new PartNode("027", 310.0, 36.0),
                //new PartNode("028", 354.5, 36.0),
                //new PartNode("029", 354.5, 36.0),
                //new PartNode("030", 299.0, 20.0),
                //new PartNode("031", 327.5, 20.0),
                //new PartNode("032", 327.5, 20.0),
                //new PartNode("033", 955.0, 80.0),
                //new PartNode("034", 310.0, 100.0),
                //new PartNode("035", 310.0, 100.0),
                //new PartNode("036", 310.0, 36.0),
                //new PartNode("037", 310.0, 36.0),
                //new PartNode("038", 354.5, 36.0),
                //new PartNode("039", 354.5, 36.0),
                //new PartNode("040", 299.0, 20.0),
                //new PartNode("041", 327.5, 20.0),
                //new PartNode("042", 327.5, 20.0),
                //new PartNode("043", 955.0, 80.0),
                //new PartNode("044", 310.0, 100.0),
                //new PartNode("045", 310.0, 100.0),
                //new PartNode("046", 310.0, 36.0),
                //new PartNode("047", 310.0, 36.0),
                //new PartNode("048", 354.5, 36.0),
                //new PartNode("049", 354.5, 36.0),
                //new PartNode("050", 299.0, 20.0),
                null
                );
            if (args[0].StartsWith("-clp:"))
            {
                string path = args[0].Replace("-clp:", "");
                if (System.IO.File.Exists(path))
                {
                    Import.FromCutlistPlusCSV(path, out parts, out boards);
                }
            }
            if (args[0].StartsWith("-csv:"))
            {
                string path = args[0].Replace("-csv:", "");
                if (System.IO.File.Exists(path))
                {
                    Import.FromCSV(path, out parts, out boards);
                }
            }
            #endregion

            //PartNode[] partsarray = parts.ToArray;
            //List<PartNode> partsList = new List<PartNode>(partsarray);
            //Stopwatch swt = new Stopwatch();
            //swt.Start();
            //for (int i = 0; i < 120000000; i++)
            //{
            //    //Array
            //    PartNode iPart;
            //    for (int j = 0; j < partsarray.Length; j++) { iPart = partsarray[j]; }

            //    //linked list
            //    //for (var iPart = parts.Head; iPart != null; iPart = iPart.Next) ;

            //    //List
            //    //foreach (var iPart in partsList) ;
            //    //PartNode iPart;
            //    //for (int j = 0; j < partsList.Count; j++) iPart = partsList[j];
            //}
            //swt.Stop();
            //Trace.WriteLine(swt.ElapsedMilliseconds);


            #region // Print starting parameters ...
            Trace.WriteLine($"Packing started @ {DateTime.Now} with the following:");
            Trace.WriteLine($"------------------------------------------------");
            Trace.WriteLine($"  Board margins (w x l) : {boardMargins_Width} mm x {boardMargins_length} mm");
            Trace.WriteLine($"  Part padding  (w x l) : {PartPadding_Width} mm x {PartPadding_Length} mm");
            Trace.WriteLine($"  Saw blade kerf        : {SawKerf} mm");
            Trace.WriteLine($"  {boards.Count} Boards:");
            for (BoardNode iBoard = boards.Head; iBoard != null; iBoard = iBoard.Next)
            {
                Trace.WriteLine($"{iBoard.ID,6} [{iBoard.Length,7:0.0} x {iBoard.Width,5:0.0}]");
            }
            Trace.WriteLine($"  {parts.Count} Parts:");
            for (PartNode iPart = parts.Head; iPart != null; iPart = iPart.Next)
            {
                Trace.WriteLine($"{iPart.ID,6} [{iPart.Length,7:0.0} x {iPart.Width,5:0.0}]");
            }
            #endregion

            #region // Find the solution ...
            Stopwatch sw = new Stopwatch();
            sw.Start();
            var solution = Packer.Pack(parts, boards,
                                       sawkerf: SawKerf,
                                       boardMarginLength: boardMargins_length,
                                       boardMarginWidth: boardMargins_Width,
                                       partPaddingLength: PartPadding_Length,
                                       partPaddingWidth: PartPadding_Width);
            sw.Stop();
            #endregion

            #region // Print the solution ...
            // calculate the total area of all used boards
            List <string> usedBoardIDs  = solution.ToArray.Select(t => t.Container).Distinct().ToList();
            double        UsedStockArea = boards.ToArray.Where(q => usedBoardIDs.Contains(q.ID)).Sum(t => t.Area);

            Trace.WriteLine("Solution:");
            Trace.WriteLine("----------------");
            if (solution.Count < parts.Count)
            {
                Trace.WriteLine("WARNING: All parts could not be placed!\r\n");
            }

            for (var iBoard = boards.Head; iBoard != null; iBoard = iBoard.Next)
            {
                if (iBoard.Solution == null)
                {
                    Trace.WriteLine($"   Board {iBoard.ID} [{iBoard.Length,6:0.0} x {iBoard.Width,5:0.0}] : not used.");
                }
                else
                {
                    Trace.WriteLine($"   Board {iBoard.ID} [{iBoard.Length,6:0.0} x {iBoard.Width,5:0.0}] ({(iBoard.Solution == null ? 0 : iBoard.Solution.TotalArea / iBoard.Area):00.0 %}) :\r\n{iBoard.Solution?.ToString()}");
                }
            }
            Trace.WriteLine("===========================================================");
            Trace.WriteLine("Solution summary");
            Trace.WriteLine("----------------");
            Trace.WriteLine($"   Processing time: {sw.ElapsedMilliseconds,5:0} ms");
            Trace.WriteLine($"   Boards         : {boards.Count,5:0}    ({boards.TotalArea / 1000000,6:0.000} m\u00b2)");
            Trace.WriteLine($"   Used boards    : {usedBoardIDs.Count,5:0}    ({UsedStockArea / 1000000,6:0.000} m\u00b2)");
            Trace.WriteLine($"   Parts          : {parts.Count,5:0}    ({parts.TotalArea / 1000000,6:0.000} m\u00b2)");
            Trace.WriteLine($"   Placed parts   : {solution.Count,5:0}    ({solution.TotalArea / 1000000,6:0.000} m\u00b2)");
            Trace.WriteLine($"   Waste          : {(UsedStockArea - solution.TotalArea) / UsedStockArea,7:0.0 %}  ({(UsedStockArea - solution.TotalArea) / 1000000,6:0.000} m\u00b2)");
            Trace.WriteLine($"   Coverage       : {solution.TotalArea / UsedStockArea,7:0.0 %}  ({(solution.TotalArea) / 1000000,6:0.000} m\u00b2)");
            #endregion

            #region // Draw solution to an image ...
            Bitmap bmp = Draw(boards, solution);
            bmp.Save("out.bmp");
            Console.WriteLine("Launch output image (Y/N):");
            string s = Console.ReadLine();
            if (s.ToLower() == "y")
            {
                Process.Start("out.bmp");
            }
            #endregion
        }