コード例 #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
        }