/*-------------------------------------------------------------*/ private void btnLdStackConfig_Click(object sender, EventArgs e) { try { using (OpenFileDialog openDialog = new OpenFileDialog()) { openDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); openDialog.Filter = "csv files (.CSV)|*.csv|Text Files (.txt)|*.txt|All Files (*.*)|*.*"; openDialog.Title = "Please select a pnp machine file..."; if (openDialog.ShowDialog() == DialogResult.OK) { //HOW IT WORKS: //1)get the reel list of the displayed layer StackList oldStackList = (StackList)tcPhaseDisplayer.SelectedTab.Controls["stackList"]; List <Reel> stackReelList = oldStackList.GetTotalList(); //2) Make a new phase string[] stackConfig = pnpMachine.LoadStackConfiguration(openDialog.FileName); //StackList newStackList = new StackList(pnpMachine, openDialog.FileName, stackReelList); StackList newStackList = new StackList(pnpMachine, stackConfig, stackReelList); newStackList.Name = "stackList"; newStackList.updateAllListsEvent += UpdateAllListsEvent; stacklisters.Add(newStackList); //3) Try to add all components to the new stackList foreach (Reel stackReel in stackReelList) { newStackList.AddReelWithUpdate(stackReel); } //4) int phaseCounter = 0; tcPhaseDisplayer.TabPages.Clear(); stacklisters = stacklisters.OrderBy(stacklist_ => stacklist_.Layer).ToList(); //http://stackoverflow.com/questions/3309188/how-to-sort-a-listt-by-a-property-in-the-object while (phaseCounter < stacklisters.Count) { StackList curStackList = stacklisters[phaseCounter]; if (curStackList.ContainsReels) { phaseCounter++; curStackList.PhaseNumber = phaseCounter; GenerateTabPage(curStackList); } else { curStackList.updateAllListsEvent -= UpdateAllListsEvent; stacklisters.Remove(curStackList); curStackList.Dispose(); } } } } } catch (Exception exc) { MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Generates a new phase /// </summary> /// <returns>Returns the associated stacklist user control</returns> private StackList GenerateNewPhase() { StackList newControl = new StackList(pnpMachine, stacklisters.Count + 1); newControl.Name = "stackList"; newControl.updateAllListsEvent += UpdateAllListsEvent; stacklisters.Add(newControl); return(newControl); }
/// <summary> /// Initializes and configure a new TabPage for the tcPhaseDisplayer /// </summary> /// <returns>New TabPage for the tcPhaseDisplayer</returns> private void GenerateTabPage(StackList newControl) { TabPage newPage = new TabPage(); int phase = newControl.PhaseNumber; newPage.Padding = new System.Windows.Forms.Padding(0); newPage.Name = "tpPhase" + phase.ToString(); newPage.Text = "phase " + phase.ToString(); newPage.UseVisualStyleBackColor = true; newPage.Controls.Add(newControl); tcPhaseDisplayer.Controls.Add(newPage); //This must happen BEFORE the imagekey is changed newPage.ImageKey = newControl.Layer.ToString(); }
/// <summary> /// Save a pick and place project /// </summary> /// <param name="project">Project to save</param> public static void SaveProject(PnpProject project) { using (StreamWriter writer = new StreamWriter(project.Path)) { //part 1: project information writer.WriteLine("ProjectName=" + project.ProjectName); writer.WriteLine("ProjectFolder=" + project.ProjectFolder); writer.WriteLine(); //part 2: machine information writer.WriteLine("#Machine information:"); string equippedNozzles = ""; int numberOfNozzles = project.Machine.EquippedNozzles.Length; for (int i = 0; i < numberOfNozzles; i++) { equippedNozzles += project.Machine.EquippedNozzles[i].ToString(); if (i != numberOfNozzles - 1) { equippedNozzles += ","; } } writer.WriteLine("MachineType={0},speed={1},equipped nozzles={2}{3}", new object[] { project.Machine.GetType(), project.Machine.DefaultSpeed, equippedNozzles, Environment.NewLine }); //Part 3: Offset and panelization writer.WriteLine("#Offset and panelization:"); writer.WriteLine("originOffsetX={1},originOffsetY={2}{0}boardsX={3},boardsY={4}{0}distanceX={5},distanceY={6}{0}boardDimX={7},boardDimY={8}{0}", new object[] { Environment.NewLine, project.HorizontalOriginOffset, project.VerticalOriginOffset, project.BoardsX, project.BoardsY, project.DistanceX, project.DistanceY, project.BoardWidth, project.BoardLength }); //part 4: components writer.WriteLine("#Included components/reels:"); writer.WriteLine(SaveStringComponents(project.IncludedReels, true)); writer.WriteLine(); writer.WriteLine("#Excluded components/reels:"); writer.WriteLine(SaveStringComponents(project.ExcludedReels, false)); writer.WriteLine(); //part 5: stackConfiguration writer.WriteLine("#Stack setup(s):"); for (int i = 0; i < project.StackListers.Count; i++) { StackList stackList_ = project.StackListers[i]; writer.WriteLine("Phase=" + stackList_.PhaseNumber.ToString()); writer.WriteLine(stackList_.GetSaveString()); } } }
/// <summary> /// Save specific phase at the given location /// </summary> /// <param name="path">The complete file path to write to</param> /// <param name="phase">Phase to save</param> private void ExportData(string path, StackList phase) { float originOffsetX = (float)bscOrigin.ValueX; float originOffsetY = (float)bscOrigin.ValueY; float boardWidth = (float)bscDimensions.ValueX; float boardLength = (float)bscDimensions.ValueY; BoardSettings boardSettings = new BoardSettings(originOffsetX, originOffsetY, boardWidth, boardLength); boardSettings.BoardsX = Convert.ToInt32(bscNumberOfBoards.ValueX); boardSettings.BoardsY = Convert.ToInt32(bscNumberOfBoards.ValueY); boardSettings.DistanceX = (float)bscDistBetwBoards.ValueX; boardSettings.DistanceY = (float)bscDistBetwBoards.ValueY; pnpMachine.ExportToFile(path, boardSettings, phase); }
/*-------------------------------------------------------------*/ private void btnExport_Click(object sender, EventArgs e) { string fileName = Path.Combine(folder, projectName + ".csv"); StackList stackListToExport = (StackList)tcPhaseDisplayer.SelectedTab.Controls["stackList"]; try { ExportData(fileName, stackListToExport); MessageBox.Show("File has been successfully exported"); } catch (Exception exc) { MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/*-------------------------------------------------------------*/ private void btnExportAll_Click(object sender, EventArgs e) { try { for (int i = 0; i < tcPhaseDisplayer.TabCount; i++) { string phase = tcPhaseDisplayer.TabPages[i].Text.Replace(' ', '_'); string fileName = Path.Combine(folder, projectName + "_" + phase + ".csv"); StackList stackListToExport = (StackList)tcPhaseDisplayer.TabPages[i].Controls["stackList"]; ExportData(fileName, stackListToExport); //ExportData(fileName, stacklisters[i]); } MessageBox.Show("Files have been successfully exported", "Succes", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception exc) { MessageBox.Show(exc.Message + Environment.NewLine + "Some files may have been exported", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Create stackList controls and fills them with the reels, one layer only /// </summary> /// <param name="reelsToFill">Reels to fill in the stackControls</param> private void FillStackListers(List <Reel> reelsToFill) { if (reelsToFill.Count == 0) { return; } GenerateNewPhase(); int reelIndex = 0; //foreach (Reel goodReel in reelsToFill) while (reelIndex < reelsToFill.Count) { Reel goodReel = reelsToFill[reelIndex]; List <StackList> matchingStackListers = stacklisters.FindAll(stacklister => ((stacklister.Layer == ReelLayer.Both) || (stacklister.Layer == goodReel.ReelLayer))); if (matchingStackListers.Count == 0) { matchingStackListers.Add(GenerateNewPhase()); } int index = 0; bool succes = false; do { succes = matchingStackListers[index].AddReel(goodReel); index++; //go to next (in case it failed) if ((index == matchingStackListers.Count) && (!succes)) { StackList newStackControl = GenerateNewPhase(); if (!newStackControl.AddReel(goodReel)) { //this reel can't be added //newStackControl.updateAllListsEvent -= updateAllListsEvent; //stacklisters.Remove(newStackControl); //newStackControl.Dispose(); reelIndex--; //go to previous : otherwise a reel could be skipped reelsToFill.Remove(goodReel); } succes = true; } } while (!succes); reelIndex++; } }
/// <summary> /// Load a pick and place project from the project.path /// </summary> /// <param name="project">Project to load data to</param> /// <exception cref="PickAndPlace.FileOperationsException">Thrown when data is missing or when a line could not be decoded</exception> public static void LoadProject(PnpProject project) { List <PnpComponent> includedComponents = new List <PnpComponent>(); List <PnpComponent> excludedComponents = new List <PnpComponent>(); //project.stackListers = new List<StackList>(); using (StreamReader reader = new StreamReader(project.Path)) { while (!reader.EndOfStream) { string curLine = reader.ReadLine(); //# is a line with comment if (curLine.StartsWith("#") || String.IsNullOrWhiteSpace(curLine)) { continue; } string[] splitedLine = curLine.Split(new char[] { ',', '=' }, StringSplitOptions.None); switch (splitedLine[0]) { case "ProjectName": project.ProjectName = splitedLine[1]; break; case "ProjectFolder": project.ProjectFolder = splitedLine[1]; break; case "MachineType": project.Machine = (IMachine)Assembly.GetExecutingAssembly().CreateInstance(splitedLine[1]); project.Machine.DefaultSpeed = Convert.ToInt32(splitedLine[3]); for (int i = 5; i < splitedLine.Length; i++) { Nozzle nozzle = PNPconverterTools.StringToNozzle(splitedLine[i]); project.Machine.SetNozzle(i - 5, nozzle); } break; case "originOffsetX": project.HorizontalOriginOffset = float.Parse(splitedLine[1]); project.VerticalOriginOffset = float.Parse(splitedLine[3]); break; case "boardsX": project.BoardsX = Convert.ToInt32(splitedLine[1]); project.BoardsY = Convert.ToInt32(splitedLine[3]); break; case "distanceX": project.DistanceX = float.Parse(splitedLine[1]); project.DistanceY = float.Parse(splitedLine[3]); break; case "boardDimX": project.BoardWidth = float.Parse(splitedLine[1]); project.BoardLength = float.Parse(splitedLine[3]); break; case "Designator": //load new component string designator = splitedLine[1]; string manufacturerPartNumber_ = splitedLine[3]; float x = float.Parse(splitedLine[5]); float y = float.Parse(splitedLine[7]); int rotation = Convert.ToInt32(splitedLine[9]); Layer layer_; if (splitedLine[11] == Layer.Bottom.ToString()) { layer_ = Layer.Bottom; } else { layer_ = Layer.Top; } Location location_ = new Location(x, y, rotation, layer_); string comment = splitedLine[13]; bool included = Convert.ToBoolean(splitedLine[15]); PnpComponent comp = new PnpComponent(designator, location_, comment, manufacturerPartNumber_); if (included) { includedComponents.Add(comp); } else { excludedComponents.Add(comp); } break; case "Phase": //last part of the file string remainingLines = reader.ReadToEnd(); string[] remainingLinesSplited = remainingLines.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); //1) make reels from the components: project.IncludedReels = ComponentsToReels(includedComponents, project.Machine.DefaultSpeed); project.ExcludedReels = ComponentsToReels(excludedComponents, project.Machine.DefaultSpeed); List <Reel> completeReelList = new List <Reel>(project.IncludedReels); completeReelList.AddRange(project.ExcludedReels); //the completeReelList contains all reels, however these reels where not splited List <Reel> topReels, bottomReels; Reel.SplitReelList(completeReelList, out topReels, out bottomReels); completeReelList.Clear(); completeReelList.AddRange(topReels); completeReelList.AddRange(bottomReels); //topReels and bottomReels contain all reels, also the excluded reels //they will be reused later //2) read each line StackList newStackList = new StackList(project.Machine, Convert.ToInt32(splitedLine[1])); newStackList.Name = "stackList"; project.StackListers.Add(newStackList); int index = -1; for (int i = 0; i < remainingLinesSplited.Length; i++) { splitedLine = remainingLinesSplited[i].Split(new char[] { '=', ',' }); if (splitedLine[0] != "Phase") { index++; //Stacks are saved in order (starting at reel 0 -> reel n) string designator_ = splitedLine[1]; if (String.IsNullOrWhiteSpace(designator_)) { continue; //empty stack } bool locked = Convert.ToBoolean(splitedLine[5]); //find the reel in the completeReelList Reel matchingReel = completeReelList.Find(reel => reel.GetDesignators().Contains(designator_)); matchingReel.Speed = Convert.ToInt32(splitedLine[3]); newStackList.AddReel(matchingReel, locked, index); project.ReelsInStackList.Add(matchingReel); } else { //make a new phase //Phase=X (X=phase number) newStackList = new StackList(project.Machine, Convert.ToInt32(splitedLine[1])); newStackList.Name = "stackList"; project.StackListers.Add(newStackList); index = -1; } } //Reusing topReels and bottomReels Reel.SplitReelList(project.ReelsInStackList, out topReels, out bottomReels); project.TopReels = topReels; project.BottomReels = bottomReels; break; default: throw new FileOperationsException(String.Format("Unable to read file: {0}{2}Problem with reading folowing line:{2}{1}", project.Path, curLine, Environment.NewLine)); } } } if (project.StackListers.Count == 0) { //no phases saved project.IncludedReels = ComponentsToReels(includedComponents, project.Machine.DefaultSpeed); project.ExcludedReels = ComponentsToReels(excludedComponents, project.Machine.DefaultSpeed); } if ((project.HorizontalOriginOffset == -1f) || (project.VerticalOriginOffset == -1f) || (project.BoardsX == -1) || (project.BoardsY == -1) || (project.DistanceX == -1f) || (project.DistanceY == -1f) || (project.BoardWidth == -1f) || (project.BoardLength == -1f) || (project.Machine == null)) { throw new FileOperationsException("Not all data was found in the file"); } }
public void ExportToFile(string path, BoardSettings boardSettings, StackList phaseStackList) { StringBuilder sbStackOffset = new StringBuilder(); StringBuilder sbFeederSpacing = new StringBuilder(); StringBuilder sbComponentLocations = new StringBuilder(); int operationNumber = 1; int curSpeed = -1; for (int index = 0; index < this.totalAmountOfReels_; index++) { //values for when there is no reel float offsetX = 0; float offsetY = 0; string comment = ""; float feedSpacingReel = 0; Reel reelWithIntel = phaseStackList.GetReel(index); if (reelWithIntel != null) { Footprint reelsFootprint = reelWithIntel.Footprint; //this makes reading the code easier if (reelWithIntel.Footprint.StackType != StackType.Tray18mm) { offsetX = reelsFootprint.OffsetStackX; offsetY = reelsFootprint.OffsetStackY; } else { offsetX = -9.4f + reelsFootprint.Width / 2 + reelsFootprint.OffsetStackX; offsetY = 8.5f - reelsFootprint.Length / 2 + reelsFootprint.OffsetStackY; } comment = reelsFootprint.ManufacturerPartNumber; feedSpacingReel = reelsFootprint.FeedRate; int speedValue = reelWithIntel.Speed / 10; //1) check if the speed changes if (speedValue != curSpeed) { curSpeed = speedValue; sbComponentLocations.AppendFormat("0,{0},0,0,0,0,0,0,{1}", speedValue, Environment.NewLine); } //set all components for (int i = 0; i < reelWithIntel.Components.Count; i++) { PnpComponent comp = reelWithIntel.Components[i]; float distance; int nozzleNumber = this.GetNozzleNumber(reelsFootprint.Nozzle); //This should never give -1 and if it does, the machine wil give an error int compRotation; if (comp.Location.Layer == Layer.Top) { distance = comp.Location.Y; compRotation = ATmMachine.ConvertAngle(comp.Location.Rotation + reelsFootprint.Rotation); } else { //botom distance = boardSettings.BoardLength - comp.Location.Y; compRotation = ATmMachine.ConvertAngle(180 - (comp.Location.Rotation + reelsFootprint.Rotation)); } //%,Head,Stack,X,Y,R,H,skip,Ref,Comment, sbComponentLocations.AppendFormat("{0},{1},{2},{3:0.###},{4:0.###},{5},{6:0.##},0,{7},{8}{9}", new object[] { operationNumber, nozzleNumber, index, comp.Location.X, distance, compRotation, reelsFootprint.Height, comp.Designator, reelsFootprint.ManufacturerPartNumber, Environment.NewLine }); operationNumber++; } } //%,StackOffsetCommand,Stack,X,Y,Comment sbStackOffset.AppendFormat("65535,1,{0},{1},{2},{3}{4}", new object[] { index, offsetX, offsetY, comment, Environment.NewLine }); sbFeederSpacing.AppendFormat("65535,2,{0},{1},{2}", index, feedSpacingReel, Environment.NewLine); } using (StreamWriter writer = new StreamWriter(path)) { //1) origin offset writer.WriteLine("%,OriginOffsetCommand,X,Y,,"); writer.WriteLine("65535,0,{0:0.##},{1:0.##},", boardSettings.HorizontalOriginOffset, boardSettings.VerticalOriginOffset); writer.WriteLine(); //2) stack offset writer.WriteLine("%,StackOffsetCommand,Stack,X,Y,Comment"); writer.WriteLine(sbStackOffset.ToString()); //3) Feeder spacing writer.WriteLine("%,FeederSpacingCommand,Stack,FeedSpacing,"); writer.WriteLine(sbFeederSpacing.ToString()); //4) Board setup writer.WriteLine("%,JointedBoardCommand,X,Y,"); for (int i = 0; i < boardSettings.BoardsX; i++) { for (int j = 0; j < boardSettings.BoardsY; j++) { if ((i != 0) || (j != 0)) { //skip the first board float Xcoord = i * (boardSettings.BoardWidth + boardSettings.DistanceX); float Ycoord = j * (boardSettings.BoardLength + boardSettings.DistanceY); writer.WriteLine("65535,3,{0:0.##},{1:0.##},", Xcoord, Ycoord); } } } writer.WriteLine(); //5) Component locations writer.WriteLine("%,Head,Stack,X,Y,R,H,Skip,Ref,Comment,"); writer.Write(sbComponentLocations.ToString()); } }
/// <summary> /// Checks all reels and fill the stacks automatic with the good reels /// </summary> /// <param name="showWarnings">True if warnings are shown, else false</param> private void AssignReels(bool showWarnings) { //1) Filter the reels List <Reel> acceptedReels = new List <Reel>(); acceptedReels = reelsToPlace.FindAll(curReel => pnpMachine.ReelCanBePlaced(curReel)); if (showWarnings) { //Show warnings to the user if (acceptedReels.Count == 0) { MessageBox.Show("No reels accepted", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } int numberRejected = reelsToPlace.Count - acceptedReels.Count; //Not all components are accepted if ((numberRejected != 0) && (MessageBox.Show(numberRejected.ToString() + " rejected" + Environment.NewLine + "Do you want to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)) { return; } } //2) clear the old tabPages ClearPhases(); //3) split the list: top and bottom List <Reel> topReels, bottomReels; Reel.SplitReelList(acceptedReels, out topReels, out bottomReels); FillStackListers(topReels); FillStackListers(bottomReels); int index = 0; while (index < stacklisters.Count) { if (stacklisters[index].Layer == ReelLayer.Top) { stacklisters[index].SetTotalList(topReels); } else if (stacklisters[index].Layer == ReelLayer.Bottom) { stacklisters[index].SetTotalList(bottomReels); } else if (!stacklisters[index].ContainsReels) { //Stacklayer == both -> empty stacklist //if, for some reasen (reasen = bug), the layer is both and it contains reels, it should not be removed StackList removedStackList = stacklisters[index]; //need pointer to control for dispose removedStackList.updateAllListsEvent -= UpdateAllListsEvent; stacklisters.RemoveAt(index); removedStackList.Dispose(); continue; } GenerateTabPage(stacklisters[index]); index++; //index > 0 } if (index != 0) { this.pnlExportButtons.Enabled = true; } }