#usage "en: Export milling data for a board layout in SCRIPT, HPGL, ISEL, CNC\n" "

" "Author: support@cadsoft.de" , "de: Export von Fräsdaten aus einem Board in SCRIPT, HPGL, ISEL, CNC" "

" "Author: support@cadsoft.de" #require 6.0500 // ****************** History ************************************************* // place VIA with SIGNAL '~_REAL_OUTLINEMILL_~' in to break throgh for milling // this as outside contour. // THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED // 2002-05-08 - reverse milling // 2002-06-23 - Polygon:CHANGE THERMAL OFF // 2003-05-14 - With REFERENCE-Circle (Drill) to mirror for drilling machine // - Switch On/Off 2. isolate/cupper pouring // 2003-09-02 - Switch On/Off drills // 2004-04-24 - String ulp_path no longer necessary // 2004-07-21 - expand reference package menu // by select layer, switch mirror on/off // place VIAs with SIGNAL '~_REAL_OUTLINEMILL_~' // in to break throgh for milling as outside contour. // Language en/de // 2004-08-12 - ISEL Interface/Isel-Zwischenformat // Referenz: // | Übersicht des isel Zwischenformat zur Maschinensteuerung // | "isel ZF in deutsch.pdf" Stand 08.11.1999 // 2004-10-18 - Abfrage ob DRC fehlerfrei durchlaufen wurde. // - bei vorhandener .def-Datei werden diese Parameter als Defaultgeladen. // - Sichern der Einstellungen in def-Datei. // 2005-05-18 - ** output no shorter filling wires as MillToolFree diameter ** // - Hinweis auf den erfolgreichen (fehlerfreien) Design-Rule-Check // damit man im voraus abklären kann ob auch alles mit dem // benutztenFräser isoliert (gefräst) werden kann. // - Überprüfung der CLASS-Clerance mit dem Durchmesser des // Isolationsfräser Tool#1. // 2005-05-23 - UseRack: (switch), to can use also a Rack with HPGL and Nc-Machine-Code // for users to have a machine with automaticle tool change. // UseRack: Wenn mehr als die 3 Standarddurchmesser benutzt werden, // werden zusätzliche Tools (1/10mm gerundet) generiert für das Bohren // (auch in HPGL --> SPxx / Script) für Anwender die eine Fräsmaschine mit // automatischen Werkzeugwechsel besitzen. // - SP8 in HPGL bedeutet: Die Platine muß auf dem Frästisch umgedreht werden // ** nur HPGL ** www.cnc-papst.de * reiner_marcus@hotmail.com ** // 2005-06-16 - Isel-Zwischenformat Extension ".cnp" // 2005-06-23 - Drilling way optimised / Bohrwege Streckenoptimiert // - Beim RubOut wird der Fräser nicht angehoben, wenn sich die X-Koordinate // weniger als der Fräserradius ändert. // Schalter 'Lift_Off' wird nicht im Menu angezeigt, sondern ist fix im ULP. // - Zusätzlicher (plus) Layer zum fräsen von Texten in Kupferflächen (Polygon). // - Maschinen-Menu kann abgeschaltet werden für _nur_ Benutzer von HPGL // Schalter 'MachineMenuOn' // ** nur HPGL ** www.cnc-papst.de * reiner_marcus@hotmail.com ** // // 2005-09-28 *** für LPKF laut Hr. Böhm (agfeo) keine Formatbeschreibung zu erhalten // *** wird also wieder gecancelt *** // // 2005-09-30 - Device-Reinit bei Layer 45 Holes nicht offset 100 addieren. // - CNC // // 2005-11-21 - LPKF entfernt // // 2005-12-22 - Unit & Format bei [Masch. Nullpunkt] [Lade Beispiel] auf mm und 2.4 setzen // 2006-01-23 - Only Drills gibt jetzt nur die Drills aus // (ohne Meldung von fehlerhaften Parametern bzw. Layern) // 2006-01-25 - $ in temporären Namen in ~ (Tilde) geändert. // - Temporäre Files werden mit "wtD" geöffnet // - !Generatedrills; keine Abfrage der Bohrdurchmeser auf Gültigkeit // 2006-02-13 - Wegen Rechenungenauigkeit muß für Fräswege zwischen den Leiterbahnen und // einem evtl. vorhandenem Füll-Polygon die Spurbreite (Clearance/Isolate) // zu WIRE (Arc) um Inaccurateness breiter eingestellt werden, da es sonst // an gebogenen Leiterbahnsegmenten zu Fehlerhaften nicht berechneten Fräswegen // kommen kann. Also die gefräste Isolation nicht komplett geschlossen ist. // * Nur Isolationsfräsen: // Hier wird die Drehrichtung (Rotation) der berechneten Polygon-Kontur // zu der Kontur von Signal-Polygonen ermittelt, da sich die Kontur der Füllung // einmal rechts-drehend an den Leiterzug (WIRE/PAD/VIA-Struktur) und einmal // links-drehend an ein evtl. vorhandenes Polygon (Versorgungs-Polygon)um den // Leiterzug anschmiegt. // Dadurch würde die Isolation also der Fräsweg doppelt ausgegeben werden. // Bei inaktiven [] Rub out werden nur linksdrehende Polygonkonturen ausgegeben // um den Fräsaufwand zum reinen Isolieren zu minimieren. // Bei aktiven [] Rub out werden linksdrehende wie auch rechtsdrehende Polygon- // konturen ausgegeben, um der geätzten Version einer Leiterplatte so nah wie // Möglich zu kommen. * // // 2006-07-26 - Generate separated layer +100 +101 +102 for milling tools. // - check Polygons of Rank 6. // - Use Rank 1 of polygon to generate real outline contour // to milling out from holder. // - Correct Rank on all generated Polygons. // 2006-08-01 - Check if POLYGON placed. If Yes, check if CLASS-Clearance 0.005 mm > Tool#1 // but if problem with routet WIRE out of 0 45 90 Degree. // Es kann vorkommen, dass durch math. Rundung der Coordinaten das Polygon // nicht in die Isolationskanäle fliessen kann. // 2006-11-07 - Ausfräsen aus dem Träger (Dimensionlinie) berichtigt, war nur bei Script aktiv. // - dru Datei wird gelesen um den tatsächlichen Copper-Dimension Wert zu erhalten, // ist keine .dru gespeichert wird der defaultvalue benutzt und darauf hingewiesen. // 2006-12-11 - Maschinen-Menu aus/einschalten mit Checkbox. // // 2007-10-08 - Fräserbreiten ab 5 micron zulassen wg. Laser. // // 2008-11-12 - Layerzuordnung berichtigt, nicht das Flag, sondern die Layernummer benutzen. // - Delete von Polygon mit SHIFT und Via mit Ripup. // - Layerzuweisung vor Kontour fräsen. // // 2009-02-04 - Clear via airwire // 2009-02-05 - Correct mill tool for millout // 2009-03-31 - Correct koordinate delete special polygon and via # alf@cadsoft.de // corrected layer to millout (if only Layer 16 selected) // Holder spacing in script // Check if Dimension placed // // 2010-01-20 - Check DRC-Layer-Setup (1*16) // Check counts of outlines at layer Dimension // // 2010-01-25 - Use contour option positiv/negativ (rotation) // to switch on/off draw also polygon inside contours // // 2010-02-02 - Check and Set DRC-Layer-Setup and CLASS clearance to mill tool #1 + Inaccurateness // // 2010-04-08 - Milling always inner contour of pooring // CNC data finished // // 2010-08-06 - Info Durchbrüche als Dialog // Die gespeicherten Designregeln dürfen bis zu 30 Sekunden alt sein. // // 2010-10-28 - Prüfe die Designrules und benutze CLASSen, falls CLASSen benutzt sind, // sonst ändere die Design-Regeln. // // 2011-01-27 - Z-Achse in CNC-Device G00 / G01 Z.. // Referenzfahrt am Anfang // Z_down -> Actualmilldeep, zum hochfahren mit -1 multipliziert (pos. Vorzeichen) // // 2011-02-02 - Wenn 2. Milling (und Rubout) abgeschaltet waren, dann wurde auch das 1. mal nicht isoliert. // Milling [ ] innercontour BitMap waren getauscht. // Wählbare Auflösung 3.2 3.3 3.4 im CNC Menu. // Programmierter Halt für umdrehen der Platine. // // 2011-02-03 - Auflösung in mit und ohne Kommastelle. // Mill_z_safety, Drill_z_deep, Z_down, Z_dimension als Option bei RUN ... // // 2011-02-09 - Generiere ein Refpackage mit 2 Circle und platziere dieses Package // an der berechneten linken unteren Ecke. // * Anfrage am 2010-10-13 * // ISEL-Device berichtigt: MOVE Z -> MOVEABS Z // Überprüfung der Erzeugungszeit der DRU-Datei auf 120 Sekunden erhöht. // Ist ein Refpackge platziert, darf die Dimension nicht gefräst werden, // sonst würde man in die Haltestifte fräsen! // Abfrage ob trotzdem gefräst werden soll. // // 2011-03-10 Nur Kontur fräsen // // 2011-06-17 Fehlermeldung bezüglich Mehrfachkonturen (Dimesion) um außerhalb der Dimension // stehende Texte oder Logos erweitert. // // 2011-09-28 Holderspacing corrected und Stegbreite 0.2mm, unabhängig vom Fräserdurchmesser // WIRE_BEND wieder auf 2 (diagonal stellen). // // 2011-10-04 Durchbrüche/Mehrfachkonturen berichtigt, Info Durchbrüche erweitert. // // 2011-10-20 Hinweis auf "Only milling Dimension". // Brichtigt: Bohrungen fräsen von Holes größer maximal vorkommenden Fräserdurchmesser. // Milling und Z-Achsen menu auf Tabs getrennt. // // 2011-11-21 Isel-Format: Fräser Z-Achse wieder hoch. // // 2012-01-12 Auflösung mit 8 Nachkommastellen. Wird der erweiterten internen Auflösung gerecht, // da es sonst zu fehlenden Wires kommen kann. // // 2012-01-13 Dimension immer in Layer 103 zeichnen. // ScriptDrillFile wird nicht mehr automatisch eingelesen, // da sonst die Holes doppelt vorhanden sind und DRC-Fehler erzeugen. // Im Device SCRIPT wird je nach benutzten Layer die Außenkontur im Layer 103 bzw. 118 erzeugt. // // 2012-01-16 Überprüfung der CLASSen vor der Überprüfung der Design-Regeln. // Die Design-Regeln werden jetzt immer zuerst gespeichert. // // 2012-01-20 Menu Prüfe Einstellungen "OK" Button geändert [Change &Tool #1] // // 2012-01-25 MillOnlyContour : Nur aus Träger fräsen berichtigt. // Layer 103 bzw. 118 anlegen. // Jetzt mit Tool #1 an DRC-Clearance / CLASS-Clearance anpassen und nicht die Clearance ändern. // // 2012-02-09 Korrigietre DRC-Parameter (minDistWireWire) Überprüfung. // Wenn der Parameter minDistWireWire groß genug ist, dann // werden die CLASSen nicht mehr geprüft. // // 2012-03-09 Zum ändern der Breite des Fräs-Polygon wurde das B.area. benutzt, // was aber nicht einer der Koordinaten des "Fräs-Polygon" entsprach! // Dadurch wurde unter Umständen ein anderes Element gewählt. // Jetzt wird eine Wire-Koordinate des Fräs-Polygon selbst herangezogen. // // 2012-03-20 Behandlung der Bohrungen (HOLE) größer Max. drill diam berichtigt. // Die Fräswege werden in der Option Script im Layer 118 erzeugt und in die *_drl.scr geschrieben. // // 2013-03-05 Holder Spacing berichtigt. // Drills und Holes werden in die Scriptdatei geschrieben und im Layer 144 145 gezeichnet // ScriptDrillFile und *_drl.scr wird nicht mehr benötigt. // Bohrungen größer Maxdrill berichtigt, in Script + HPGL. // Fehlermeldung bez. der Vias des Signal '~_REAL_OUTLINEMILL_~' ohne Option Tool#2 blow up berichtigt. // GRID (last) zurück stellen. // Kommentarzeilen in HPGL entfernt (Markierung #HPGLxxxx), da GC-Prevue damit Probleme hat. // // 2013-04-18 Tool 9 eingerichtet, zum Fräs-Bohren von Drills größer Max_Drill_Diameter // Initialisierung bei HPGL nur einmal // 2013-04-19 Abfrage bez. des Ausfräsen aus dem Trägermateriel bei platzierten Fangzapfen // Menüpunkt und Parameter zum Referenzbohrungen bohren auskommentiert. // 2013-04-30 Versatz/Offset berichtigt, beim fräsen von nur Bottom-Seite und platzierten Referen-Package // HPGL wird nun in zwei Dateien geschrieben, da die Fräse der FU-Berlin die Tools // zu einem optimierten Fräsweg zusammen fasst. // 2014-10-06 HPGL_TOP_ext = "_top.plt" Namenserweiterung bei HPGL für Daten des Top layer // Am Ende wird eine Nachricht ausgegeben, in welche Datei die Fräsdaten geschrieben wurden, // wichtig bei HPGL da auf Wunsch der FU Berlin nun je Seite (Top/Bottom) eine Datei erzeugt wird. // 2014-11-26 InfoREFPack in englisch // // 2015-03-24 RIPUP der VIA '~_REAL_OUTLINEMILL_~' innerhalb eines Innendurchbruch erst am Ende löschen // Devices SCRIPT wird am Ende wieder eingelesen // /* ** to do : Scalierung bei HPGL vorwahl 2/5/10 ** */ string Version = "Version 6.2.2"; // 2015-03-24 alf@cadsoft.de string Header = "Outlines generator for PCB milling."; int test = 0; // Flag zum debuggen int test2 = 0; // 2. Flag zum debuggen /* **************************************************** Complete the following steps to add a new output device definition: 1. Add a new member to the 'enum { devScript = 1, ...' 2. Add the new (unique!) device name to 'DeviceNames[]' 3. Add the necessary 'case dev...' branches to 'DeviceInit()', 'DeviceReInit()', 'DeviceDraw()', 'CircleDraw()', 'ArcDraw()' and 'DeviceEnd()' 4. Add also new Tool values to 'toolFiles()' and 'ValueInit()' ***************************************************** */ // Actually draw a line on the output device. // 'state' is defined as // 0 = this is the first line of a partial polygon // 1 = this is a "middle" line (neither the first nor the last one) // 2 = this is the last line of a partial polygon // 3 = this is a drill coordinate // 4 = this is one line (polygon fillings) /* ********************************************************************************* 2006-02-08 Achtung bei Kupferflächen die durch ein POLYGON gefüllt sind! Durch die Rechenungenauigkeit (max. Auflösung der Eagle-Einheit) muß man die CLASS-Clearance um den Betrag breiter angegeben werden, da sonst um gekrümmte Leiterbahnen (Arc) teilweise keine Polygon-Kontur berechnet wird. Aber nur wenn das Isolate kleiner der Fräserbreite + dem Ungenauigkeitsfaktor ist. ************************************************************************************ */ real Inaccurateness = 0.005; // 2006-02-08 string DRC_CopperDimension = "mdCopperDimension"; // der Parameter in der .dru enum { false = -1 }; enum { First_line, Middle_line, Last_line, Drill_coord, One_line } ; string INFOhelp = usage; string INFOhelpBut = "Help"; string CANCEL = "-Cancel"; string BACK = "-Back"; string ACCEPT = "Accept"; string YES = "YES"; string NO = "NO"; string ON = "ON"; string OFF = "OFF"; string BREAK = "<--"; string NEXT = "Further"; string DRCCHECK = "Check CLASS"; string DRC_checked = "Befor milling the PCB, start the DRC (Design Rule Check) " + "with the milling diameter (isolate) in CLASS clearance.
" + "All Clearance ERROR define a not isolated wire track!
"; int Class_used[]; string SClass[]; // 2010-02-02 string INFOpolyClass; sprintf(INFOpolyClass, "If used a filling Polygon on Board, please check Clearance of Design-Rules/Classes if %.8f mm greater
" + "as Milling Tool #1, damit bei Leiterbahnen die nicht im 0°45°oder 90°Winkel also mit beliebigen Winkel
" + "verlegt sind, eventuelle Füllprobleme wegen Rechenungenauigkeit vermieden werden.
", Inaccurateness); string SavePar = "&Save parameter"; string Machine_Menu_Info = "Switch On Off the Mashine Menu for Z-Axis mashines!
" + "If accept to change this the ULP save the aktual Parameter und restart!
"; string Z_Machine_Menu = "Z Axis Menu"; string INFOinside = "Info Break through"; string INFOinnerContour = "If inside the board one or more breakthruogh you can place a VIA with SIGNAL name
" + "'~_REAL_OUTLINEMILL_~' to milling this.
"; string PlaceVIA = "place VIA"; string DRCinfo = "Distance info:
Distance Copper/Dimension (see DRC) this is the distance between
" "the polygon and outline of the board.
" "Do not use value 0 for Copper/Dimension in Design-Rules-Distance (DRC).
"; "
"; string Ref_pac = "_REFERENCE_HOLE_"; // *** special package for mirror milling data *** string InfoREFERENCE = "Generate a special package with
" + "REFERENCE circles in Layer 45 Holes.
" + "Place it in the layout for milling and
" + "mirroring (bottom side) with offset and
" + "start this ULP again.
" + "The position of the circles are defined
" + "in the NC drill data file which comes
" + "from the NC machine (eg. Excellon).

"; string InfoREFPack = "There is placed a reference package in order to take the catching pins of the " + "milling machine for calculating the axis of reflection. " + "In this case milling the board out of the carrier should be switched off!
" + "However, if you prefer to have the board contour milled out, please check the distance " "between the circles and layer Dimension!"; string A_refpack = "A reference package is placed!"; string InfoRefHole = "Drill referenz holes (fixing bolt) "; string InfoRefOff = "Drill reference holes OFF."; string InfoRefOn = "Drill reference holes ON."; string DrBrowse = "Browse"; string REFdialog = " - generate refernece and place on Board"; string LoadRefFile = "&Load ref. File"; string Example_Ref = "Load Example"; string DRILLref = "Select drill reference file (Holes)"; string PLACErefpac1 = "After reference package placing start the
"; string PLACErefpac2 = "
to set the USEed libraries back."; string SHOWRackFile = "Show rack file"; string SAVE_file = "Save Outlines file"; string REFinfo2 = "Press button Zero reference to generate a reference Package from a NC-Drill file
" + "to place reference safety grip (circles) on PCB for exact mirroring the bottom side
" + "of PCB on milling machine.
"; string ZeroRef = "Zero refere&nce"; string No_reftext = "!No reference file loaded."; string Script_Used = "SCRIPT used!
Return the millings as WIRE to Board-Editor.
"; string OnlyDrillHpgl = "Generate only drill file."; string INFOtext1_on = "Milling top side."; string INFOtext16_on = "Milling bottom side (mirror)."; string INFOtext1_off = "Milling top side."; string INFOtext16_off = "Milling bottom side (mirror)."; string TextInfoPlus = "Plus milling layer (to milling text inverting in a ploygon).
" + "Only can use with Top or Bottom layer."; string TOOLdiamIso = "Tool diameter for isolate.
"; string OVERlapIso = "Overlap isolate - blow up in percent (%)."; string OVERlapRubOut = "Overlap rub-out diameter in percent %."; string TOOLdiamBlow = "Tool diameter for Blow-Up/Rub-Out
If value set to 0, no Blow-Up (second isolate)
and Rub-Out (free milling) is generated.
"; string TOOLdiamRub = "Rub-Out is off!
Tool diameter for sec. isolate
If value set, Blow-Up (second isolate) is generated.
"; string MILLfreeYes = "You must set value to Blow-Up."; string MILLfreeNo = "No blow up and Rub-Out is generated while value is set to 0."; string INFOmirror0 = "Layer 16 (Bottom) not mirrored."; string INFOmirror1 = "Layer 16 (Bottom) is mirrored."; string GENdrilON = "Generate drill data."; string GENdrilOFF = "Drills (PAD, VIA, HOLE) are disabled.
"; string PADdrildiam = "
PAD drill diameter"; string VIAdrilldiam = "VIA drill diameter."; string HOLEdrildiam = "HOLE drill diameter."; string USErackON = "Use drill rack (1/10mm) see also Tool Assignment."; string USErackOFF = "Use only 3 drills (Pad, Via, Hole)."; string DrillLabel = "HPGL file include drills"; string DIMmiltoolOFF = "Mill diameter for cut out.
Cut out OFF.
"; string DIMmiltoolON = "Mill diameter for cut out.
Cut out ON.
"; string INFOspacing = "This value determins the minimum length of a edge where a spacer will be set.

" + "Spacers will be set on vertical & horizontal and in HPGL-Format only.

" + "The width of the spacer depends on the diameter of Mill Board/Dim.
" + "The value 0 switch off this functioon."; string INFOresolution = "Integer digits, fractional digits."; // 2011-02-02 string INFOdeep = "Drilling deep value."; string INFOzsafety = "This is the value of lift up the milling tool to change the tool."; string INFOzAxisUp = "This is the value of lift up the milling tool to move fast (safty)."; string INFOzAxisDown = "This is the value of push down the milling tool in to the PCB."; string INFOvdrill = "Drilling velocity mm/s."; string INFOvelocity = "Milling velocity mm/s."; string INFOfastVel = "Move velocity (no milling) mm/s."; string INFOrpm = "Spindle rotation per minute."; string INFOmaxdrill = "The maximum used drill diamter."; string DIMdown = "The z parameter for milling Board-Dimension."; string PARKinfo = "The park position of milling tool to mirror the board."; string SaveInfo = "Menu parameter saved!<\nobr>"; string FaultDRCdist1 = "!The value for Copper/Dimension is greater than the Mill Board/&Dim diameter.

" + "Check/change Distance Copper/Dimension in Design Rules DRC

" + "or accept a distance of "; string FaultDRCdist2 = "mm to board dimension."; string Error5 = "The CLASS clearance is lower at milling diameter (tool #1)!
" + "Befor milling the PCB, start the DRC (Design Rule Check)
" + "with the milling diameter (isolate) in CLASS clearance.
" + "All Clearance ERROR define a not isolated wire track!
"; // 2005-12-22 alf@cadsoft.de string INFOInaccurat = "Due to possible arithmetic imprecision you have to increase " + "the value for the track width the cutter uses for milling between " + "traces and possible copper planes - Clearance/Isolate to Wire " + "(Arc) - by %.3f mm. Otherwise it could happen that curved wires " + "won't be milled correctly. The isolating area won't be a closed " + "one, then."; string Mill_mInner_contour = "Process inner milling contours as well, for example, the isolation " "of thermal reliefs inside polygons."; string MissingDimension = "!Missing Dimension.\nFirst place dimension outline in layer 20."; string RefDrillDiameter = "Drill diameter "; string RefDrillDeep = " Deep "; string Get_Board_Zero = "Set board &zero"; // 2010-10-13 string Info_Board_Zero = "Generate a package with two circle
and placed this package at the
left bottom corner, to mark the
machine zero.
"; // 2011-02-07 /***** deutche Sprache *****/ if (language() == "de") { INFOhelp = usage; INFOhelpBut = "Hilfe"; CANCEL = "-Abbruch"; BACK = "-Zurück"; ACCEPT = "Akzeptieren"; YES = "JA"; NO = "NEIN"; ON = "EIN"; OFF = "AUS"; BREAK = "<--"; NEXT = "Weiter"; DRCCHECK = "Prüfe &CLASS"; sprintf(DRC_checked, "Bevor Sie die Fräsdatengenerierung starten, müssen Sie zuerst das Layout mit dem " + "DRC (Design Rule Check) überprüfen. " + "Stellen Sie die Clearance der benutzten CLASS(en) um mindestens %.3f mm größer dem Fräserdurchmesser ein.
" + "Jeder Clearance-ERROR bedeutet eine nicht isolierte Leiterbahn!
", Inaccurateness); sprintf(INFOpolyClass, "Ist ein füllendes Polygon im Board plaziert, dann muß die Clearance der Design-Rules/Class um %.3f mm größer
" + "als der Fräserdurchmesser sein. Damit bei Leiterbahnen die nicht im 0° 45° oder 90° Winkel also mit
" + "beliebigen Winkel verlegt sind, eventuelle Füllprobleme wegen Rechenungenauigkeit vermieden werden.", Inaccurateness); SavePar = "Parameter &sichern"; Machine_Menu_Info = "Ein/Ausschalten der Maschinenparamter für die Z-Achse.
Nach Ändernung des Paramter werden die aktuellen Einstellungen
gespeichert und das ULP neu gestartet.
"; Z_Machine_Menu = "Z-Achsen Menü"; Script_Used = "SCRIPT-Ausgabe!
Die Fräsbahnen (Daten) werden als WIRE in das Board geladen.
"; INFOinside = "Info Durchbrüche"; INFOinnerContour = "

Damit Durchbrüche innerhalb der Platine ebenfalls ausgefräst werden,
" + "muß in jedem Durchbruch eine VIA mit dem SIGNAL Namen
" + "'~_REAL_OUTLINEMILL_~' platziert werden.
" + "Ein Durchbruch darf kein HOLE sein, daß bedeutet,bei kreisrunden
" "Durchbrüchen muß ein CIRCLE im Layer Dimension gezeichnet werden.
"; // 2011-10-04 DRCinfo = "Distance info:

" + // geändert 2010-08-04 "Distance Copper/Dimension (siehe auch DRC) das ist die Distanz
" + // der Wert wird jetz aus den Design-Reglen gelesen, "zwischen dem Polygon (Kupfer) und der Kontur (Layer 20 Dimension) des Board.

"+ // daher wird der Hinweiß nicht merh beötigt. "" + "Dieser Wert wird aus den Design-Rules gelesen!
" + "Benutzen Sie nicht den Wert 0 für Copper/Dimension
" + "in den Design-Rules - Distance.
" + ""; InfoREFERENCE = "Generiert ein spezielles Package mit Referenzkreisen (Circle) im Layer 45 Holes.
" + "Platzieren Sie das Package im Layout für fräsen und spiegeln (Bottom Seite)
" + "mit Offset und starten das ULP erneut.
" + "Als Dateneingabe für die Koordinaten dieser Kreise kann das NC-Drill-File
" + "von der NC-Maschine (Excellon) benutzt werden.
" + "Es kann auch jedes Package mit der Bezeichnung   " + Ref_pac + "
" + "als Referenz für den Maschinennullpunkt und die Spiegellinie benutzt werden." + "

" + "Achtung: Die Referenzfangzapfen dürfen nicht über das Maß von Leiterplattenstärke " "minus Frästiefe hinausschauen, sonst werden diese Fangzapfen angefräst, was zum abbrechen des Fräser " "führen kann." + ""; // 2011-02-09 REFinfo2 = "Klicken Sie auf Masch. Nullpunkt zum generieren " + "eines Referenzpackage aus
" + "NC-Drill Daten um Referenzfangzapfen (Circle) im Board zu platzieren für
" + "die exakte Berechnung der Fräsdaten bezogen auf den Nullpunkt der
" + "NC-Anlage und für die Spiegelung der Unterseite.
"; InfoREFPack = "Es ist ein Referenzpackage platziert, um die Fangzapfen der Fräsmaschine zur Berechnung der " + "Spiegelachse heranzuziehen. Dadurch darf das Ausfräsen aus dem Träger an der Dimension unter Umständen nicht " + "eingeschaltet werden!
Wollen Sie die Platine trotzdem aus dem Träger fräsen, überprüfen Sie die " + "Abstände der Circle zum Layer Dimension!"; // englisch!? ZeroRef = "Masch. &Nullpunkt"; No_reftext = "!Keine Referenzdatei geladen."; DrBrowse = "Durchsuchen"; LoadRefFile = "&Lade ref. Datei"; Example_Ref = "Lade Beispiel"; REFdialog = " - Generiere Referenz-Package und platziere auf Board"; DRILLref = " Wähle Drill reference Datei (Holes)"; A_refpack = "Ein Referenzpackage ist platziert!"; InfoRefHole = " Fangzapfen bohren "; InfoRefOff = "Bohren der Fangzapfen AUS."; InfoRefOn = "Bohren der Fangzapfen EIN."; PLACErefpac1 = "Starten Sie nach der Platzierung des Referenzpackage das Script
"; PLACErefpac2 = "
um die erzeugte LBR aus der USE-Liste zu löschen."; SHOWRackFile = "Bohrer definition"; SAVE_file = "Outline Datei sichern"; DrillLabel = "
Drills in HPGL Datei enthalten"; OnlyDrillHpgl = "Nur Bohrdaten erzeugen!."; INFOtext1_on = "Top Layer (Oberseite) wird gefräst."; INFOtext16_on = "Bottom Layer (Unterseite) wird gefräst (gespiegelt) "; INFOtext1_off = "Top Layer (Oberseite) AUS."; INFOtext16_off = "Bottom Layer (Unterseite) AUS."; TextInfoPlus = "Zusätzlicher Layer zum fräsen von Texten für Frontplatten.
" + "(bzw. Texte in einem Polygon invertiert zu fräsen.)
" + "Kann nur in Verbindung mit einem Top- oder Bottom-Layer benutzt werden."; TOOLdiamIso = "Werkzeugdurchmesser zum Isolationsfräsen.
"; OVERlapIso = "Überlappung von 1. Isolation zu 2. Isolation/Freifräsung in Prozent (%)."; OVERlapRubOut = "Überlappung innerhalb der Freifräsung in Prozent %."; TOOLdiamBlow = "Werkzeugdurchmesser für erweiterte Isolation und Freifräsung.
" + "Wird der Wert auf 0 gesetzt wird keine erweiterte Isolation
" + "und Freifräsung generiert.
"; TOOLdiamRub = "Freifräsung (Rub-Out) ist ausgeschaltet!
" + "Es werden nur die Fräswege für eine 2. Isoilation generiert.

" + "Wird der Wert auf 0 gesetzt wird keine erweiterte Isolation
" + "und Freifräsung generiert."; MILLfreeYes = "Es muß ein Wert in Blow-Up (Freifräsung) gesetzt sein."; MILLfreeNo = "Es wird kein 2. Isolationsfräsen plus Freifräsen generiert,
da der Wert auf 0 gesetzt ist.
"; INFOmirror0 = "Layer 16 (Bottom) wird NICHT gespiegelt."; INFOmirror1 = "Layer 16 (Bottom) wird gespiegelt."; GENdrilON = "Bohrdaten generierung aktiv."; GENdrilOFF = "Bohrdaten generierung (PAD, VIA, HOLE) ausgeschaltet.
"; PADdrildiam = "
PAD Bohrdurchmesser.

" + "Wenn kein Rack benutzt wird, dann werden alle PADs
" + "mit diesem Durchmesser gebohrt.
" + "Wenn [] Use Rack aktiviert ist, dann werden die PADs
" + "in 1/10 mm Abstufung gebohrt.
Siehe Tool Assignment.
"; VIAdrilldiam = "VIA Bohrdurchmesser.

" + "Wenn kein Rack benutzt wird, dann werden alle VIAs
" + "mit diesem Durchmesser gebohrt.
" + "Wenn [] Use Rack aktiviert ist, dann werden die VIAs
" + "in 1/10 mm Abstufung gebohrt.
Siehe Tool Assignment.
"; HOLEdrildiam = "HOLE Bohrdurchmesser.

" + "Wenn kein Rack benutzt wird, dann werden alle HOLEs
" "mit diesem Durchmesser gebohrt.
" + "Wenn [] Use Rack aktiviert ist, dann werden die HOLEs
" + "in 1/10 mm Abstufung gebohrt.
Siehe Tool Assignment.
"; USErackON = "Benutze Bohrertabelle (1/10mm), siehe auch Tool Assignment.
" + "Die Bohrungen werden auf 1/10 mm gerundet gebohrt.
"; USErackOFF = "Benutze nur 3 Bohrer für Pad, Via, Hole.

" + "Alle PADs, VIAs und HOLEs werden mit den im Menu
" + "angegeben Werten gebohrt.
"; DIMmiltoolOFF = "Fräserdurchmeser zum ausfräsen aus dem Träger.
Ausfräsen AUS.
"; DIMmiltoolON = "Fräserdurchmeser zum ausfräsen aus dem Träger.
Ausfräsen EIN.
"; INFOspacing = "Dieser Wert definiert die Mindestkantenlänge der Platine damit
" + "ein Haltesteg (Spacer) erzeugt wird.
" + "Haltestege werden nur an horizontalen oder vertikalen Kanten erzeugt.
" + "Die Breite der Stege ist abhängig vom Durchmesser des Fräser
" + "(Mill Board/Dim).
Der Wert 0 schaltet die Funktion ab.
"; INFOresolution = "Auflösung, Vor- Nachkommastellen der Koordinaten."; // 2011-02-02 INFOdeep = "Bohrtiefe in/durch die Platine."; INFOzsafety = "Der Wert um den der Fräser in der Z-Achse über das Werkstück
" + "gefahren wird, z.B. für Werkzeugwechsel (Rueckzugsebene).
"; INFOzAxisUp = "Der Wert um den der Fräser in der Z-Achse über das Werkstück
" + "gefahren wird, für Schnellvorschub (Sicherheitsabstand).
"; INFOzAxisDown = "Die Frästiefe der Z-Achse."; INFOvdrill = "Bohrgeschwindigkeit mm/s."; INFOvelocity = "Fräsgeschwindgkeit mm/sec."; INFOfastVel = "Schnellvorschub (Geschwindigkeit) mm/s"; INFOrpm = "Spindlumdrehungen pro Minute"; INFOmaxdrill = "Der maximal nutzbare Bohrerdurchmesser.
" + "Grössere Bohrungen werden gefräst!
" + "Siehe auch Tool Assignment.
"; DIMdown = "Z-Parameter für ausfräsen der Boardkontur."; PARKinfo = "Die Parkposition des Fräskopf zum umdrehen der Leiterplatte."; SaveInfo = "Einstellungen gespeichert!<\nobr>"; FaultDRCdist1 = "!Der Wert von Copper/Dimension ist größer als der Radius von Mill Board/Dim.
" + "Überprüfen Sie den Wert von Distance Copper/Dimension in den Design Rules (DRC)
" + "oder akzeptieren Sie die Distanz von "; FaultDRCdist2 = " mm zur Boardaussenkannte.
"; PlaceVIA = "platziere VIA"; Error5 = "Die CLASS-Clearance ist kleiner als der Fäserdurchmesser von Tool #1!
" + "Dadurch kann nicht alles isoliert (gefräst) werden.
" + "Stellen Sie die CLASS-Clearance auf den Fräserdurchmesser und starten Sie den DRC.
" + "Jeder Clearance-Error bedeutet eine nicht isolierte Leiterbahn!
"; sprintf(INFOInaccurat, "Wegen Rechenungenauigkeiten muß für Fräswege zwischen den Leiterbahnen und " + // 2006-02-15 "einem evtl. vorhandenem Füll-Polygon die Spurbreite (Clearance/Isolate) zu WIRE (Arc) um " + "%.3f mm breiter eingestellt werden, da es sonst an gebogenen Leiterbahnsegmenten " + "zu Fehlerhaften nicht berechneten Fräswegen kommen kann. Also die gefräste Isolation nicht " + "komplett geschlossen ist. ", Inaccurateness); Mill_mInner_contour = "Auch Innenkonturen fräsen (z.B. die Isolation von Termal-Stegen von Polygonen). " + // 2010-01-25 "Daruch kann es vorkommen, daß wenn ein (Masse) Polygon im Layout vorhanden ist, " + "die Isolation doppelt, mit entsprechendem Versatz gefräst wird.
" + "Die Ursache ist, daß sich eine Kontur an den Leiterbahnzug anlegt, und eine entgegengesetzt " + "verlaufende Kontur an die berechnete Kontur des (Masse) Polygon.
" + "Soll ein evtl. zweifaches Freifräsen wegen diesem Umstand verhindert werden, so schalten " + "Sie die Option
Milling [] inner contour
einfach ab."; MissingDimension = "!Keine Dimension.\nPlatzierern Sie zuerst die Aussendimension in Layer 20."; RefDrillDiameter = "Bohrduchmesser "; RefDrillDeep = "Tiefe "; Get_Board_Zero = "Setze Maschinen-&Nullpunkt an linke unter Ecke"; // 2010-10-13 Info_Board_Zero = "Erzeugt ein Package mit zwei Kreisen und platziert
es an der linken untere Ecke des Board als
Manschinen-Nullpunkt.
"; // 2011-02-07 } // *** ende language de *** // ########################### // The various output devices // ########################### enum { none, devScript, devHPGL, devISEL, devCNC }; int Defaultdevice = devScript; // set default device int SelectedDevice = Defaultdevice; // overwritten by load_menu_values() int LastSelectedDevice; string HPGL_TOP_ext = "_top.plt"; // Namenserweierung bei HPGL für Daten des Top-Layer 2014-10-06 string Device; string Layer1, Layer16; int SelectedLayer1 = 0; int SelectedLayer16 = 0; int SelectedPlusLayerTop = 0; // 2005-06-08 int SelectedPlusLayerBot = 0; // to milling a Text inverse in a copper polygon int Mirror_On = 1; // flag can switch mirror off for Layer 16 int ToMillLayer1 = 0; int ToMillLayer16 = 0; int OutlineMillSignalLayer; // 2004-10-05 string DeviceNames[] = { "Select a device", "SCRIPT", "HPGL", "ISEL", "CNC" }; string DeviceExt[] = { ".~~~" , ".scr", ".plt", ".ncp", ".ncd" }; string DefaultSuffix = DeviceExt[SelectedDevice]; string Ftop = ""; // Fräsdaten für HPGL in zwei Dateien schreiben. 2013-04-30 // Die Fräse der FU Berlin optimiert die Fräs- und Bohrwege, // so daß alle Bohrungen und Fräswege mit dem selben Werkzeug zusammengefasst werden. real GridDistance; int GridUnit; int GridUnitdist; string Gridunit[]; Gridunit[GRID_UNIT_MIC] = "mic"; Gridunit[GRID_UNIT_MM] = "MM"; Gridunit[GRID_UNIT_MIL] = "mil"; Gridunit[GRID_UNIT_INCH] = "INCH"; int InitDone = 0; // nur einmal Initialisieren, siehe DeviceInit() // * set default device and values * // Parmameters // *** The milling tool diameter *** real MillToolOutl = 0.2; real MillToolIsolate = 0.0; // das Isolate des Polygon zum Isolationsfräsen real minClearance = 0.15; // to check can filled the complete aray with the // special polygon width int OverlapOutlPercent = 20; // percent, to avoid fine copper lines while milling out the area real MillToolFree = 0.8; // Blow up & free pouring int Millfreeyes = 1; // free pouring on/off int MInner_contour = 1; // milling positiv/negativ polygon contour 2010-01-25 int Lift_Off = 1; // ** do not lift up the tool for Rubout of polygon filling ** // ** if change the direction and X-coordinate < tool radius ** int OverlapRubOutPercent = 20; // percent, to avoid fine copper lines while milling out the area real DrillPad = 0.8; real DrillVia = 0.8; real DrillHole = 0.8; int Onlydrill = 0; // output only drill on HPGL int Generatedrills = 1; // aktivate drills only in one export file // while drills crashed in 2. run. real Max_Drill_Diameter = 2.0; // the maximum of drill diameter in mm of T-Code table for ISEL and CNC // editierbar gemacht 2004-12-01 real DimensionMillTool = 2.0; // milling board outline from holder int Dim_on_off = 1; // 2006-01-25 int MillOnlyContour = 0; // 2011-03-10 nur Kontur fräsen enum { Res32, Res33, Res34, Res3_2, Res3_3, Res3_4 }; // CNC-Resolution ohne und mit Komma 2011-02-03 int CNCmillResolution = Res3_2; // Auflösung der Koorinaten Vor- Nachkommastellen 2011-02-02 real Drill_z_deep = -3.8; // drill deep for drilling pads, via, holes real Mill_z_safety = 2.0; // safety distance to pcb for change tool real Z_down = -2.0; // milling z-axis down for milling real Actualmilldeep; // 2011-01-27 in den Funktionen wird nur die aktuelle Frästiefe benutzt int Spindle_rpm = 15000; // spindel rotation per minute real Tool_vel = 2; // velocity to milling real Fast_vel = 5; // velocity to move tool real Drill_Vel = 0.5; // drill velocity to drilling in to pcb real ParkZposition = 80.0; // 80mm Park poistion to turn pcb for 2.nd side milling real ParkXposition = 10.0; // 10mm Park poistion to turn pcb for 2.nd side milling real ParkYposition = 10.0; // 10mm Park poistion to turn pcb for 2.nd side milling real Z_dimension = -3.8; // 3.8mm Z-Down for milling dimension (contur) real DistanceDimension; real Distance_Copper_Dimension = 0.0001; // default value real Holder_Spacing = 10.0; // in mm, the distance to make a holder spacing for outline milling. // Class check string Clearance_check; // Design-Rules-Chek 2010-10-28 int UseClass = 0; int MinDistCLass = 0; string drufile = ""; string DRUvalues[]; int DRUlcnt = 0; int DRC_changed = 0; string DRC_changed_message = ""; // Design Rule Ceck - Values from .dru 2010-01-26 real mtCopper[]; real mtIsolate[]; real minDistWireWire; real minDistWirePad; real minDistWireVia; real minDistPadPad; real minDistPadVia; real minDistViaVia; real minDistSmdPad; real minDistSmdVia; real minDistSmdSmd; real MOI = 0.0; // round((MillToolOutl + Inaccurateness) *1000) / 1000; // Problem bei vergleich von Realzahlen real MDW = 0.0; // round(minDistWireWire * 1000) / 1000; string LayerStack; string DelPoly; // 2012-01-13 to delete vitual polygon and via outside off bord // The HPGL PEN list enum { PadDrill = 1, ViaDrill, Contour, BlowUp_RubOut, HoleDrill, DimensionLine, DrillRef, MirrorPCB, nrMaxDrillDiameter } // HPGL Pen select "SP.." /*** MirrorPCB = TOOL (PEN) #8 is reseved for switch PCB on milling machin for milling second side ***/ /*** nrMaxDrillDiameter == TOOL (PEN) 9 is reseved for milling drill biger then max drill diameter ***/ string PenList[]; PenList[PadDrill] = "PadDrill"; PenList[ViaDrill] = "ViaDrill"; PenList[Contour] = "Contour"; PenList[BlowUp_RubOut] = "Blow-Up/Rub-Out"; PenList[HoleDrill] = "HoleDrill"; PenList[DimensionLine] = "DimensionLine"; PenList[DrillRef] = "DrillRef"; PenList[MirrorPCB] = "MirrorPCB"; PenList[nrMaxDrillDiameter] = "max.Drill-Diameter"; // 2013-04-18 string sToolValue[]; // Tool diameter as String enum { HPGLsolution = 1016 } // Inch/1016 = 0.025 mm enum { ISELsolution = 1000 } // mm/1000 Isel format real Mirror = 1.0; int Mill_OffsetX = 0; int MillMirr_Offset = 0; int Ref_null_offsetY = 0; int Ref_offsetX[]; int Ref_offsetY[]; int Ref_cnto = 0; real RefHoleCircle = 3.0; // Der Durchmesser für den Circle der im Referenz-Package für den Maschinennullpunkt // benutzt wird. string Mirror_axis; real Drill_mirrorPCB = -1; // for message to mirror the PCB by personal int MachineMenuOn = 1; // 2011-10-20 maschine menu in seperate Tab // * for www.cnc-papst.de * 2005-06-23 int DrillRefOn = 0; // drill first the referenz holes to fix the pcb on machine real DrillRefDiameter = 3.0; // the diameter of referenz holes real DrillRefDeep = -6; // the deep of referen holes // to swap for menu real MDrillPad = DrillPad; real MDrillVia = DrillVia; real MDrillHole = DrillHole; real MDimensionMillTool = DimensionMillTool; real MHolder_Spacing = Holder_Spacing; real MMillToolOutl = MillToolOutl; real MOverlapOutlPercent = OverlapOutlPercent; real MMillToolFree = MillToolFree; real MOverlapRubOutPercent = OverlapRubOutPercent; int Mmillfreeyes = Millfreeyes; real Mz_down = Z_down; real Mdrill_z_deep = Drill_z_deep; // drill deep for drilling pads, via, holes real Mmill_z_safety = Mill_z_safety; // safety distance to pcb for change tool int Mspindle_rpm = Spindle_rpm; // spindel rotation per minute real Mtool_vel = Tool_vel; real Mfast_vel = Fast_vel; real MDrill_Vel = Drill_Vel; real MparkXposition = ParkXposition; real MparkYposition = ParkYposition; real MparkZposition = ParkZposition; real Mz_dimension = Z_dimension; int Mdim_on_off = Dim_on_off; int MCNCmillResolution = CNCmillResolution; real CNCsolution = 100; // mm/100 CNC format (default) int MdrillRefOn = 0; real MdrillRefDiameter = 3.0; real MdrillRefDeep = -6.0; string TrueOutline_coordinate; // The generatet polygon outlines for the milling polygon 2009-03-31 // get polygon coordinate from actual design. string ReservedOutlineSignalName = "_OUTLINES_"; // reserved Signal name for special polygon string OutlineMillSignal = "~_REAL_OUTLINEMILL_~"; // used Signal name for calculate the real outline string PassDimensionPoly = "PASSDIMESION"; // the true output line, defined by Layer 20 Dimension string Pass2 = "PASS_2"; string PassPour = "PASS_POUR"; string PassOutmill = "PASS_OUTLINE"; string InPassDimensionPoly; string InPass2; string InPassPour; string InPassOutmill; int menu = 0; int cntcontvia = 0; // 2011-10-04 string Showpic[]; string info; // 2011-10-20 first tab string Infotext; string zinfo; // 2011-10-20 second tab string zInfotext; string Path; string Xfile, MillFileName; string Fillstyle16 = "CloseDot"; string Fillstyle1 = "Interleave"; // fill style for layer to return the millings // as wire in to the board layer (if Device == SCRIPT) string Machineparameter = ""; // ------------- use a rack for drilling extend the tool list --------------------- int UseRack = 0; // Use drills with 1/10 mm as in generated Rack // or use only 3 drills 2005-05-23 real Drill_tools[]; // 2005-05-24 string Drill_comment[]; int Cnt_tools = MirrorPCB+2; // the last milling tool string Tool_Rack_string; string Drilltoolsplus; int Nc_drill[]; int Nc_drilld[]; real Nc_drilldround[]; int Nc_drillx[]; int Nc_drilly[]; int Cnt_ncdrill = 0; int Dindex[]; int index[]; //int Mark = -1; int Cntpcw; // the counter of contour wire 2006-02-08 int Pcwx[], Pcwy[]; // the polygon countour coordinates to calcultae int maxX = INT_MIN; // 2010-10-13 int minX = INT_MAX; int maxY = INT_MIN; int minY = INT_MAX; /* ------------------------------------------------------------------------------- ? weiterer Isolationswert (noch eine Fräserbreite) zwischen Isolation und Blow up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CNC-Programmierung: datron.de: Vom CAT3D Konverter unterstützte Befehle der DIN 66025 (ISO) G 00 Positionierung / Eilgang G 01 Linearinterpolation G 02 Kreisinterpolation UZ Schraubenlinieninterpolation UZ G 03 Kreisinterpolation GUZ Schraubenlinieninterpolation GUZ G 20 Maßangaben Zoll G 21 Maßangabe metrisch G 40 Werkzeugradiuskorrektur, Löschung G 41 Werkzeugradiuskorrektur, links G 42 Werkzeugradiuskorrektur, rechts G 90 Absolute Maßangabe G 91 Inkrementale Maßangabe Weitere ISO-Code Befehle, die vom CATPC berücksichtigt werden: N Satznummer wird ignoriert F Vorschub T Werkzeugwechsel ENGELHARDT GmbH - BedienPCNC.pdf G00 POSITIONIEREN IM EILGANG G01 LINEARINTERPOLATION G36 WERKZEUGWECHSEL G74 REFERENZPUNKT FAHREN M00 PROGRAMMIERTER HALT M01 PROGRAMMIERTER HALT MIT AKUSTISCHEM SIGNAL ------------------------------------------------------------------------------- */ /************* Functions ******************/ int viewtest(string nachricht, string cmd) { dlgDialog("Debug/Test") { dlgLabel(nachricht); dlgHBoxLayout dlgSpacing(900); dlgHBoxLayout { dlgTextEdit(cmd); dlgVBoxLayout dlgSpacing(250); } dlgHBoxLayout { dlgPushButton("OK") dlgAccept(); dlgSpacing(400); dlgPushButton(CANCEL) { dlgReject(); return -1; } } }; return 0; } string filenametop(string s) { // wenn Device HPGL, dann extra Dateiname für Toplayer if (SelectedDevice == devHPGL) { return filesetext(s, HPGL_TOP_ext); // 2014-10-06 } return s; } // wait in seconds void wait(int sec) { int t = time(); while(t+sec > time() ); return; } void Warning(string Message, string Details) { dlgMessageBox("Warning: " + Message + " " + Details, "OK"); return; } void Fatal(string Message, string Details) { dlgMessageBox("ERROR: " + Message + "


\n" + Details); exit(1); } int Error(string Message, string Details, string butt_ok, string butt_esc) { if (butt_esc) return dlgMessageBox("!ERROR: " + Message + "

" + Details, butt_ok, butt_esc); return dlgMessageBox("!ERROR: " + Message + "

" + Details, butt_ok); } if (!board) Fatal("No board!", "This program can only work in the board editor."); void dirtest(void) { string a[]; int n = fileglob(a, "*.*"); if (n) { dlgMessageBox("Working directory:\n" + filedir(a[0]), "OK"); } return; } string vunit(int val, int unit) { string s; if (unit) sprintf(s, "%.8f", u2mm(val)); else sprintf(s, "%.8f",u2inch(val)); return s; } string getval(string line, real exf, real refholediameter) { int Y = strchr(line, 'Y'); string s; sprintf(s, "(%.8f %.8f) (%.8f %.8f);\n", strtol(strsub(line, 1)) * exf, strtol(strsub(line, Y+1)) * exf, strtol(strsub(line, 1)) * exf + refholediameter/2 * exf, strtol(strsub(line,Y+1)) * exf ); return s; } // get Design Rules Layer-Setup string get_DesignRules(string bfile) { // read Copper Dimension from boardname.dru 2010-02-08 drufile = filesetext(bfile, ".dru"); string f[]; int fcnt = fileglob(f, drufile); string h; if (fcnt) { DRUlcnt = fileread(DRUvalues, drufile); // get Design Rules min. distance (clearance) string s[]; int n; for (int line = 0; line < DRUlcnt; line++) { n = strsplit(s, DRUvalues[line], ' '); if (s[0] == "layerSetup") { LayerStack = s[2]; if (LayerStack != "(1*16)") { if (language() == "de") { sprintf(h, "%s

Layer-Setup = %s, muss (1*16) sein.

Soll das Layer-Setup geändert werden?
", drufile, LayerStack); } else { sprintf(h, "%s

Layer Setup = %d, must be (1*16).

Change layer setup now?
", drufile, LayerStack); } DRC_changed_message += h; sprintf(DRUvalues[1], "%s %s (1*16)", s[0], s[1]); // set Layer Setup to default DRC_changed++; } } else if (s[0] == "mdCopperDimension") { if (strstr(s[2], "mm") > 0) Distance_Copper_Dimension = strtod(s[2]); else Distance_Copper_Dimension = strtod(s[2])*0.0254; } else if (s[0] == "mdWireWire") { if (strstr(s[2], "mm") > 0) minDistWireWire = strtod(s[2]); else if (strstr(s[2], "mil") > 0) minDistWireWire = strtod(s[2])*0.0254; MDW = round(minDistWireWire*1000) / 1000; if (MOI > MDW) { // 2012-02-09 sprintf(h, "Clearance: Wire to Wire %.8f < %.8f mm\n", minDistWireWire, MOI ); DRC_changed_message += h; sprintf(DRUvalues[line], "%s %s %.8fmm", s[0], s[1], MillToolOutl + Inaccurateness); DRC_changed++; } } else if (s[0] == "mdWirePad") { if (strstr(s[2], "mm") > 0) minDistWirePad = strtod(s[2]); else minDistWirePad = strtod(s[2])*0.0254; if (MOI > round(minDistWirePad*1000) / 1000) { sprintf(h, "Clearance: Wire to Pad %.8f < %.8f mm\n", minDistWirePad, MOI ); DRC_changed_message += h; sprintf(DRUvalues[line], "%s %s %.8fmm", s[0], s[1], MOI); DRC_changed++; } } else if (s[0] == "mdWireVia") { if (strstr(s[2], "mm") > 0) minDistWireVia = strtod(s[2]); else minDistWireVia = strtod(s[2])*0.0254; if (MOI > round(minDistWireVia*1000) / 1000) { sprintf(h, "Clearance: Wire to Via %.8f < %.8f mm\n", minDistWireVia, MOI ); DRC_changed_message += h; sprintf(DRUvalues[line], "%s %s %.8fmm", s[0], s[1], MOI); DRC_changed++; } } else if (s[0] == "mdPadPad") { if (strstr(s[2], "mm") > 0) minDistPadPad = strtod(s[2]); else minDistPadPad = strtod(s[2])*0.0254; if (MOI > round(minDistPadPad*1000) / 1000) { sprintf(h, "Clearance: Pad to Pad %.8f < %.8f mm\n", minDistPadPad, MOI ); DRC_changed_message += h; sprintf(DRUvalues[line], "%s %s %.8fmm", s[0], s[1], MOI); DRC_changed++; } } else if (s[0] == "mdPadVia") { if (strstr(s[2], "mm") > 0) minDistPadVia = strtod(s[2]); else minDistPadVia = strtod(s[2])*0.0254; if (MOI > round(minDistPadVia*1000) / 1000) { sprintf(h, "Clearance: Pad to Via %.8f < %.8f mm\n", minDistPadVia, MOI ); DRC_changed_message += h; sprintf(DRUvalues[line], "%s %s %.8fmm", s[0], s[1], MOI); DRC_changed++; } } else if (s[0] == "mdViaVia") { if (strstr(s[2], "mm") > 0) minDistViaVia = strtod(s[2]); else minDistViaVia = strtod(s[2])*0.0254; if (MOI > round(minDistViaVia*1000) / 1000) { sprintf(h, "Clearance: Via to Via %.8f < %.8f mm\n", minDistViaVia, MOI ); DRC_changed_message += h; sprintf(DRUvalues[line], "%s %s %.8fmm", s[0], s[1], MOI); DRC_changed++; } } } } else { string message; if (language() == "de") message = "Keine Design-Rules-Datei gefunden:
" + drufile + "

Möchten Sie diese Datei jetzt erzeugen und speichern?
"; else message = "No Design Rules file found:
" + drufile + "

Do you want to create and save this file now?
"; dlgDialog("Mill Outlines Design Rules") { dlgLabel(message); dlgStretch(1); dlgHBoxLayout { dlgPushButton("+"+YES) { dlgAccept(); exit("SET Interface.PreferredUnit 2;\nDRC SAVE '" + drufile + "';\nRUN '" + argv[0] + "'"); // 2010-02-08 setze Einheiten auf metrisch } dlgPushButton(CANCEL) { dlgReject(); exit(0); } dlgStretch(1); } }; } return drufile; } string checkClassClear(UL_BOARD B) { // check CLASS Clearance string classchanged = ""; Clearance_check = ""; real ClassClearance; int CheckDrcWirWire = 0; //real MOI = round((MillToolOutl + Inaccurateness) *1000) / 1000; // Problem bei vergleich von Realzahlen //real MDW = round(minDistWireWire * 1000) / 1000; if (MDW >= MOI) return ""; // 2012-02-09 // 2011-03-10 nur wenn DRC-Clearance kleiner MillToolOutl, dann prüfe CLASSen else CheckDrcWirWire = 1; B.classes(CL) { if (Class_used[CL.number]) { // nur benutzte Classen prüfen 2010-02-05 UseClass = 1; string s; int n; for (n = 0; n <= CL.number; n++) { ClassClearance = u2mm(CL.clearance[n]); if (ClassClearance < MillToolOutl + Inaccurateness) { // *** 2009-02-05 *** MinDistCLass = n+1; ClassClearance = MillToolOutl + Inaccurateness; sprintf(s, "CLASS %d '%s' %.8fmm %.8fmm %.8fmm %d:%.8fmm;\n", CL.number, CL.name, u2mm(CL.width), u2mm(CL.clearance), u2mm(CL.drill), n, ClassClearance ); SClass[CL.number] += s; classchanged += s; } } } } if (classchanged) { string drc_clearance_wire_wire; if (language() == "de") { sprintf(Clearance_check, "Setze Netzklassen-Clearance:
"+ "Durchmesser Tool #1 = %.8f mm plus Rechenungenauigkeit = %.3f
"+ "Setze Class Clearance auf %.8f mm oder Fräserdurchmesser <= kleinster CLASS Clearance - %.3f.

" + "Starten Sie anschließend den DRC und überprüfen Sie die Abstände.", MillToolOutl, Inaccurateness, MillToolOutl + Inaccurateness, Inaccurateness ); sprintf(drc_clearance_wire_wire, "Prüfen Sie auch im DRC Clearance Wire/Wire: %.8f, oder ändern Sie die CLASS(en).", minDistWireWire); // 2011-03-10 } else { sprintf(Clearance_check, "Set Clearance of Net Classes:
"+ "Diameter of tool #1 = %.8f mm plus Inaccurateness = %.8f
"+ "Set Clearance to %.8f mm or use a milling tool <= lowest clearance value - %.3f.

" + "Be sure to start the DRC to have the clearances checked then.", MillToolOutl, Inaccurateness, MillToolOutl + Inaccurateness, Inaccurateness ); sprintf(drc_clearance_wire_wire, "Please check also DRC Clearance Wire/Wire: %.8f, or change CLASS(s).", minDistWireWire); // 2011-03-10 } dlgDialog("Change CLASS") { dlgLabel(drc_clearance_wire_wire); dlgTextView(classchanged); dlgLabel(Clearance_check); dlgHBoxLayout { dlgPushButton("Set &CLASS") dlgAccept(); if (CheckDrcWirWire) dlgPushButton("Check DRC clearance") { dlgAccept(); exit("DRC"); } // 2012-02-09 dlgPushButton("Change &Tool #1") { dlgReject(); return ""; } // 2010-02-08 no classes change dlgStretch(1); } }; } return classchanged; } // *************************** void resetMaxMin(void) { // 2010-10-13 maxX = INT_MIN; minX = INT_MAX; maxY = INT_MIN; minY = INT_MAX; return; } void checkmaxmin(int x1, int x2, int y1, int y2, int width) { int w = 0; if (width) w = width/2; // 2010-10-13 if (x1 > maxX) maxX = x1+w; if (x2 > maxX) maxX = x2+w; if (y1 > maxY) maxY = y1+w; if (y2 > maxY) maxY = y2+w; if (x1 < minX) minX = x1-w; if (x2 < minX) minX = x2-w; if (y1 < minY) minY = y1-w; if (y2 < minY) minY = y2-w; return; } void checkarc( int x1, int x2, int y1, int y2, int xc, int yc, real angle1, real angle2, real radius, int width) { // 2010-10-13 checkmaxmin( x1, x2, y1, y2, width ); if ( angle2 > angle1 + 270.0) { if ( angle1 < 90 ) checkmaxmin( x1 , xc - radius, yc + radius, yc - radius, width ); else if( angle1 < 180 ) checkmaxmin( xc - radius, xc + radius, y1 , yc - radius, width ); else if( angle1 < 270 ) checkmaxmin( x1 , xc + radius, yc - radius, yc + radius, width ); else if( angle1 < 360 ) checkmaxmin( xc + radius, xc - radius, y1 , yc + radius, width ); } else if( angle2 > angle1 + 180.0) { if ( angle1 < 90 ) checkmaxmin( x1 , xc - radius, yc + radius, y2 , width ); else if( angle1 < 180 ) checkmaxmin( x1 , xc - radius, yc - radius, y2 , width ); else if( angle1 < 270 ) checkmaxmin( x1 , xc + radius, yc - radius, y2 , width ); else if( angle1 < 360 ) checkmaxmin( x1 , xc + radius, yc + radius, y2 , width ); } else if( angle2 > angle1 + 90.0 ) { if ( angle1 < 90 ) checkmaxmin( x1 , x2 , yc + radius, y2 , width ); else if( angle1 < 180 ) checkmaxmin( x1 , xc - radius, y1 , y2 , width ); else if( angle1 < 270 ) checkmaxmin( x1 , x2 , yc - radius, y2 , width ); else if( angle1 < 360 ) checkmaxmin( x1 , xc + radius, y1 , y2 , width ); } else { if ( angle1 < 90 && angle2 > 90 ) checkmaxmin( x1 , x2 , yc + radius, y2 , width ); else if( angle1 < 180 && angle2 > 180 ) checkmaxmin( x1 , xc - radius, y1 , y2 , width ); else if( angle1 < 270 && angle2 > 270 ) checkmaxmin( x1 , x2 , yc - radius, y2 , width ); else if( angle1 < 360 && angle2 > 360 ) checkmaxmin( x1 , xc + radius, y1 , y2 , width ); } return; } // calculate Wire length WL real WireLength( real x1, real y1, real x2, real y2) { real WL = sqrt(pow(x2-x1,2) + pow(y2-y1,2)); return WL; } void get_null(void) { // 2010-10-13 resetMaxMin(); board(B) { B.wires(W) { if (W.layer == 20) { if (W.arc) checkarc(W.arc.x1, W.arc.x2, W.arc.y1, W.arc.y2, W.arc.xc, W.arc.yc, W.arc.angle1, W.arc.angle2, W.arc.radius, W.width); else checkmaxmin( W.x1, W.x2, W.y1, W.y2, W.width ); } } status("Circles"); B.circles(C) { if (C.layer == 20) checkmaxmin( C.x - C.radius, C.x + C.radius, C.y - C.radius, C.y + C.radius, C.width ); } B.elements(E) { // *** Dimension in Packages *** status("Element:"+E.name); E.package.wires(W) { if (W.layer == 20) checkmaxmin( W.x1, W.x2, W.y1, W.y2, W.width ); } E.package.circles(C) { if (C.layer == 20) checkmaxmin( C.x - C.radius, C.x + C.radius, C.y - C.radius, C.y + C.radius, C.width ); } } } return; } string make_zerro_ref_pac(string used_scr, string usedlibraries) { // 2011-02-07 string s; string cmd; get_null(); // Nullpunkt des Board an der linken unteren Kante ermitteln real null_offx = u2mm(minX); real null_offy = u2mm(minY); real board_length = WireLength( null_offx, 0.0, u2mm(maxX), 0.0); real board_high = WireLength( 0.0, null_offy, 0.0, u2mm(maxY)); output(used_scr, "wt") { printf("%s", usedlibraries); } /*** Generate a REFERENCE-Package for machine zero point ***/ // 2011-02-04 string lbrname; string bname; board(B) { bname = B.name; lbrname = filesetext(B.name, "~~~ref_tmp.lbr"); } sprintf( cmd, "OPEN '%s';\n", lbrname ); cmd += "SET CONFIRM YES;\nEdit '" + Ref_pac + ".PAC';\nCHANGE LAYER 45;\nGRID mm; #1325\n"; // 2011-02-10 cmd += "GROUP ALL;\nDELETE (>0 0);\n"; // DELETE evtl. vorhandene Circle um mehrfach platzierung zu vermeiden, // falls diese Option schon mal durchgeführt wurde. 2011-02-09 sprintf(s, "CIRCLE 0 (%.8f %.8f) (%.8f %.8f);\n", RefHoleCircle/2 *-1, board_high / 2, // 2011-02-04 Circle mit 3mm Durchmesser 0.0, board_high / 2 ); cmd += s; sprintf(s, "CIRCLE 0 (%.8f %.8f) (%.8f %.8f);\n", board_length + RefHoleCircle/2, board_high / 2, board_length, board_high / 2 ); cmd += s; cmd += "WIN FIT;\nWRITE;\n"; /* ***************** Generate a REFERENCE-Package for machine zero point ***********************/ cmd += "SET CONFIRM OFF;\n"; // Schalte Automatische Bestätigung wieder aus. 2011-02-10 /* *** open the board again and place the REF-Package *** */ // cmd += "CLOSE;\n"; // close the lbr, go back to board erzeugt einen Absturz bei Stringrückgabe. cmd += "EDIT '" + bname + "';\n"; cmd += "DISPLAY 45;\n"; cmd += "GRId mm;\n"; cmd += "WIN FIT;\n", cmd += "USE -*; USE '" + lbrname + "';\n"; sprintf(s, "ADD %s '_REFERENCE_HOLE_' (%.8fmm %.8fmm);\n", Ref_pac , null_offx, null_offy); cmd += s; sprintf(s, "RUN '%s';\n", argv[0]); // 2011-02-07 cmd += s; dlgDialog(Get_Board_Zero) { dlgLabel(Showpic[33]); dlgLabel(Info_Board_Zero); dlgHBoxLayout dlgSpacing(500); dlgHBoxLayout { dlgVBoxLayout dlgSpacing(250); dlgTextView(cmd); } dlgHBoxLayout { dlgPushButton("+OK") dlgAccept(); dlgPushButton(BACK) { dlgReject(); return ""; } dlgStretch(1); } }; if (test) if (viewtest("setZeroReference():\n", cmd) != 0) exit(-1376); exit(cmd); // das erzeugt einen Absturz wegen CLOSE in der Kommandozeile 2011-02-10 return cmd; } void setZeroReference(void) { int refunit = 0; int format = 0; enum { inch, millimeter }; // 2005-12-22 enum { format23, format24 }; string ReferenceUnit[] = { "INCH", "MM", "INCH", "MM" }; real exf[] = { 0.001, 0.0001, 0.001, 0.0001 }; // Drillformat 2.3 2.4 2.3 2.4 // Unit Inch Inch MM MM real refhdiameter[] = { 118, 1180, 3000, 30000 }; string cmd; string reference_file; string ref[]; string ref_text; int l; int select; string used_scr; string usedlibraries; board(B) { usedlibraries = "USE -*;\n"; int u = 0; do { if (used_libraries[u]) { usedlibraries += "USE '" + used_libraries[u] + "';\n"; u++; } } while(used_libraries[u]); used_scr = filedir(B.name) + "used-lbrs-" + filesetext(filename(B.name), ".scr"); } // *** Reference Menue Dialog *** int Result = dlgDialog(filename(argv[0]) + REFdialog) { dlgHBoxLayout { dlgLabel(Showpic[17]); dlgLabel(InfoREFERENCE); dlgStretch(1); } dlgLabel("Reference file"); dlgHBoxLayout { dlgVBoxLayout { dlgHBoxLayout dlgSpacing(200); dlgTextEdit(ref_text); } dlgVBoxLayout { dlgHBoxLayout { dlgPushButton(LoadRefFile) { reference_file = dlgFileOpen( DRILLref, "", "*.ncd\n*.*"); if (!reference_file) return; ref_text = ""; l = fileread(ref_text, reference_file); } dlgPushButton(Example_Ref) { ref_text = "Example:\nEXCELLON in mm 2.4\n%\nT25\nX500000Y900000\nX2500000Y900000\nM30"; refunit = millimeter; // 2005-12-22 set the unit to mm for example format = format24; } dlgStretch(1); } dlgSpacing(10); dlgHBoxLayout { dlgGroup("Unit") { dlgHBoxLayout { dlgRadioButton("INCH", refunit); dlgRadioButton("MM", refunit); dlgStretch(1); } } dlgStretch(1); } dlgHBoxLayout { dlgGroup("Format") { dlgHBoxLayout { dlgRadioButton("2.3", format); dlgRadioButton("2.4", format); dlgStretch(1); } } dlgStretch(1); } dlgSpacing(8); dlgHBoxLayout { dlgPushButton(Get_Board_Zero) { // 2011-02-07 ref_text = make_zerro_ref_pac(used_scr, usedlibraries); } dlgStretch(1); } dlgLabel(Info_Board_Zero); } dlgStretch(1); } dlgLabel(PLACErefpac1 + used_scr + PLACErefpac2); dlgHBoxLayout { dlgPushButton("+OK") { if (ref_text) dlgAccept(); else dlgMessageBox(No_reftext, "Ok"); } dlgPushButton(CANCEL) dlgReject(); dlgStretch(1); } }; if (Result) { board(B) { int unit_format = refunit * 2 + format; output(used_scr, "wt") { printf("%s", usedlibraries); } /* ***************** Generate a REFERENCE-Package for machine zero point ***********************/ l = strsplit(ref, ref_text, '\n'); string lbrname; lbrname = filesetext(B.name, "~~~ref_tmp.lbr"); sprintf( cmd, "OPEN '%s';\n", lbrname ); cmd += "Edit '" + Ref_pac + ".PAC';\ncHANGE LAYER 45;\nGRiD " + ReferenceUnit[refunit] + ";\n"; for (int n = 0; n <= l; n++) { string s = ref[n]; if(s[0] == 'X') cmd += "CIRCLE 0 " + getval(ref[n], exf[unit_format], refhdiameter[unit_format]); } cmd += "WRITE;\n"; /* *** Generate a REFERENCE-Package for machine zero point ***/ /* *** open the board again and place the REF-Package *** */ cmd += "EDIT '" + B.name + "';\n"; cmd += "DISPLAY 45;\n"; cmd += "GrID " + ReferenceUnit[refunit] + ";\n"; cmd += "WIN FIT; WIN (" + vunit((B.area.x1 + B.area.x2 )/2, refunit) + " " + vunit((B.area.y1 + B.area.y2 )/2, refunit) + ") (" + vunit((B.area.x1 + B.area.x2 )/2 + 1000, refunit) + " " + vunit((B.area.y1 + B.area.y2 )/2 + 1000, refunit) + ") (" + vunit((B.area.x1 + B.area.x2 )/2 + 150 , refunit) + " " + vunit((B.area.y1 + B.area.y2 )/2 + 150 , refunit) + ");\n", cmd += "USE -*; USE '" + lbrname + "';\n"; cmd += "ADD " + Ref_pac + " '_REFERENCE_HOLE_' \n"; if (test) if (viewtest("setZeroReference():\n", cmd) != 0) exit(-1513); exit(cmd); } } return; } void set_tool_rack(void) { // ** generate tool list ** string tool_type; switch (SelectedDevice) { case devScript: tool_type = ""; break; case devHPGL : tool_type = "Pen #"; break; case devISEL : tool_type = "T"; break; case devCNC : tool_type = "T"; break; } //enum { PadDrill = 1, ViaDrill, Contour, BlowUp_RubOut, HoleDrill, DimensionLine, DrillRef, MirrorPCB, nrMaxDrillDiameter } // HPGL Pen select "SP.." Drill_tools[PadDrill] = DrillPad; Drill_comment[PadDrill] = "PadDrill"; Drill_tools[ViaDrill] = DrillVia; Drill_comment[ViaDrill] = "ViaDrill"; Drill_tools[Contour] = MillToolOutl; Drill_comment[Contour] = "Contour #1"; Drill_tools[BlowUp_RubOut] = MillToolFree; Drill_comment[BlowUp_RubOut] = "Blow-Up/Rub-Out #2"; Drill_tools[HoleDrill] = DrillHole; Drill_comment[HoleDrill] = "HoleDrill"; Drill_tools[DimensionLine] = DimensionMillTool; Drill_comment[DimensionLine] = "DimensionLine"; Drill_tools[DrillRef] = DrillRefDiameter; Drill_comment[DrillRef] = "RefDiameter holder"; Drill_tools[MirrorPCB] = Drill_mirrorPCB; Drill_comment[MirrorPCB] = "MirrorPCB"; Drill_tools[nrMaxDrillDiameter] = Max_Drill_Diameter; Drill_comment[nrMaxDrillDiameter] = "Milling Drill Diameter"; // 2013-04-18 Tool_Rack_string = ""; string t; if (UseRack) { for (int n = 1; n < Cnt_tools; n++) { // erzeuge Rackliste if (n > nrMaxDrillDiameter && Drill_tools[n] > Max_Drill_Diameter) Drill_comment[n] = " > Max_Drill_Diameter"; sprintf(t, "%s%02d % 4.2f mm : %s\n", tool_type, n, Drill_tools[n], Drill_comment[n]); Tool_Rack_string += t; } } else { for (int n = 1; n < MirrorPCB+1; n++) { sprintf(t, "nur 3 bohrer %s%02d % 4.2f mm : %s\n", tool_type, n, Drill_tools[n], Drill_comment[n]); Tool_Rack_string += t; } } return; } // *** Tools in EXCELLON and GERBER (mm) void toolFiles(void) { board(B) { output(filesetext(B.name, ".pen"), "wt") { printf(";PEN definition file generated by %s %s %s %s\n", EAGLE_SIGNATURE, filename(argv[0]), Header, Version ); printf("%s", Tool_Rack_string); } output(filesetext(B.name, ".rac"), "wt") { printf(";RACK file generated by %s %s %s %s\n", EAGLE_SIGNATURE, filename(argv[0]), Header, Version ); printf(";remove the above line to prevent this file from being overwritten!\n"); printf("T01 % 2.1f mm\n", DrillPad); printf("T02 % 2.1f mm\n", DrillVia); printf("T03 % 2.1f mm\n", MillToolOutl); printf("T04 % 2.1f mm\n", MillToolFree); printf("T05 % 2.1f mm\n", DrillHole); printf("T06 % 2.1f mm\n", DimensionMillTool); printf("T07 % 2.1f mm\n", DrillRefDiameter); printf("T08 % 2.1f mm\n", 0.001); // 2005-05-25 if (UseRack) { for (int n = MirrorPCB+1; n < Cnt_tools; n++) { printf("T%02d % 2.1f mm\n", n, Drill_tools[n]); } } } output(filesetext(B.name, ".whl"), "wt") { printf(";WHEEL (Aperture) file generated by %s %s %s %s\n", EAGLE_SIGNATURE, filename(argv[0]), Header, Version ); printf(";remove the above line to prevent this file from being overwritten!\n"); printf("D11 round %6.4fmm\n", DrillPad); printf("D12 round %6.4fmm\n", DrillVia); printf("D13 round %6.4fmm\n", MillToolOutl); printf("D14 round %6.4fmm\n", MillToolFree); printf("D15 round %6.4fmm\n", DrillHole); printf("D16 round %6.4fmm\n", DimensionMillTool); printf("D17 round %6.4fmm\n", DrillRefDiameter); printf("D18 round %6.4fmm\n", 0.001); // 2005-05-25 if (UseRack) { for (int n = MirrorPCB+1; n < Cnt_tools; n++) { printf("D%2d round %6.4fmm\n", n+10, Drill_tools[n]); } } } } return; } void showHPGLinfo(void) { string text; int nChars = fileread(text, filesetext(MillFileName, ".pli")); dlgDialog("Show plot Info") { dlgTextView(text); dlgHBoxLayout { dlgPushButton("+OK") dlgAccept(); dlgStretch(1); dlgSpacing(200); } }; return; } void showISELinfo(void) { string text; int nChars = fileread(text, filesetext(MillFileName, ".isi")); dlgDialog("Show ISEL Info") { dlgTextView(text); dlgHBoxLayout { dlgPushButton("+OK") dlgAccept(); dlgStretch(1); dlgSpacing(200); } }; return; } void showCNCinfo(void) { string text; int nChars = fileread(text, filesetext(MillFileName, ".nci")); dlgDialog("Show CNC Info") { dlgTextView(text); dlgHBoxLayout { dlgPushButton("+OK") dlgAccept(); dlgStretch(1); dlgSpacing(200); } }; return; } void ValueInit(void) { sprintf( sToolValue[PadDrill], "%.8f", DrillPad); sprintf( sToolValue[ViaDrill], "%.8f", DrillVia); sprintf( sToolValue[Contour], "%.8f", MillToolOutl); sprintf( sToolValue[BlowUp_RubOut], "%.8f", MillToolFree); sprintf( sToolValue[HoleDrill], "%.8f", DrillHole); sprintf( sToolValue[DimensionLine], "%.8f", DimensionMillTool); sprintf( sToolValue[DrillRef], "%.8f", DrillRefDiameter); sprintf( sToolValue[MirrorPCB], "Message"); // 2005-05-23 return; } int get_tool(real drill) { int tool = 0; if (drill > Max_Drill_Diameter && UseRack) { drill = Max_Drill_Diameter; // 2013-02-20 preset to Max_Drill_Diameter return nrMaxDrillDiameter; } if (UseRack) tool = nrMaxDrillDiameter+1; // wenn Rack benutzt, suche ab benutzerdefinierten Tools for (int n = tool; n < Cnt_tools; n++) { if(Drill_tools[n] == drill) return n; } return -1; } void firstlinewire(int x1, int y1, int x2, int y2) { // 2013-04-25 printf(";wIRE (%.8f %.8f) (%.8f %.8f) #1668 %.1f mx%d mo%d\n", // 2006-01-25 Mirror * u2mm(x1 + Mill_OffsetX) + u2mm(MillMirr_Offset), u2mm(y1 + Ref_null_offsetY), Mirror * u2mm(x2 + Mill_OffsetX) + u2mm(MillMirr_Offset), u2mm(y2 + Ref_null_offsetY), Mirror, Mill_OffsetX, MillMirr_Offset ); return; } void middlelinewire(int x2, int y2) { printf("(%.8f %.8f) #1677 %.1f mx%d mo%d\n", Mirror * u2mm(x2 + Mill_OffsetX) + u2mm(MillMirr_Offset), u2mm(y2 + Ref_null_offsetY), Mirror, Mill_OffsetX, MillMirr_Offset ); return; } void lastlinewire(int x2, int y2) { printf("(%.8f %.8f); #1685 %.1f mx%d mo%d\n", // ** OK ** 2012-01-13 Mirror * u2mm(x2 + Mill_OffsetX) + u2mm(MillMirr_Offset), u2mm(y2 + Ref_null_offsetY), Mirror, Mill_OffsetX, MillMirr_Offset ); return; } void onelinewire(int x1, int y1, int x2, int y2) { printf(";WiRE (%.8f %.8f) (%.8f %.8f) #1693 %.1f mx%d mo%d\n", Mirror * u2mm(x1 + Mill_OffsetX) + u2mm(MillMirr_Offset), u2mm(y1 + Ref_null_offsetY), Mirror * u2mm(x2 + Mill_OffsetX) + u2mm(MillMirr_Offset), u2mm(y2 + Ref_null_offsetY), Mirror, Mill_OffsetX, MillMirr_Offset ); return; } // *** SCRIPT output HOLDER spacing*** 2009-03-31 void lineprintScript( int x1, int y1, int x2, int y2) { printf("WIRE (%.8f %.8f) (%.f %.8f); #1704 %.1f mx%d mo%d\n", Mirror * u2mm(x1 + Mill_OffsetX) + u2mm(MillMirr_Offset), //stopstop u2mm(y1 + Ref_null_offsetY), Mirror * u2mm(x2 + Mill_OffsetX) + u2mm(MillMirr_Offset), u2mm(y2 + Ref_null_offsetY), Mirror, Mill_OffsetX, MillMirr_Offset ); return; } // *** HPGL output HOLDER spacing*** 2009-03-31 void startlineprintHpgl( int x1, int y1, int x2, int y2) { printf("\nPA%.0f,%.0f;PD;\nPA%.0f,%.0f;", Mirror * u2inch(x1 + Mill_OffsetX)*HPGLsolution + u2inch(MillMirr_Offset)*HPGLsolution, u2inch(y1 + Ref_null_offsetY)*HPGLsolution, Mirror * u2inch(x2 + Mill_OffsetX)*HPGLsolution + u2inch(MillMirr_Offset)*HPGLsolution, u2inch(y2 + Ref_null_offsetY)*HPGLsolution ); return; } void nextlineprintHpgl( int x2, int y2) { printf("\nPA%.0f,%.0f;", Mirror * u2inch(x2 + Mill_OffsetX)*HPGLsolution + u2inch(MillMirr_Offset)*HPGLsolution, u2inch(y2 + Ref_null_offsetY)*HPGLsolution ); return; } void endlineprintHpgl( int x2, int y2) { printf("\nPA%.0f,%.0f;PU;", Mirror * u2inch(x2 + Mill_OffsetX)*HPGLsolution + u2inch(MillMirr_Offset)*HPGLsolution, u2inch(y2 + Ref_null_offsetY)*HPGLsolution ); return; } void fullineprintHpgl( int x1, int y1, int x2, int y2) { printf("\nPA%.0f,%.0f;PD;\nPA%.0f,%.0f;PU;", Mirror * u2inch(x1 + Mill_OffsetX)*HPGLsolution + u2inch(MillMirr_Offset)*HPGLsolution, u2inch(y1 + Ref_null_offsetY)*HPGLsolution, Mirror * u2inch(x2 + Mill_OffsetX)*HPGLsolution + u2inch(MillMirr_Offset)*HPGLsolution, u2inch(y2 + Ref_null_offsetY)*HPGLsolution ); return; } // *** ISEL output *** void startlineIsel( int x1, int y1, int x2, int y2) { printf("FASTABS X%.0f Y%.0f ; Start line\nMOVEABS Z%.0f\nMOVEABS X%.0f Y%.0f\n", Mirror * u2mm(x1 + Mill_OffsetX)*ISELsolution + u2mm(MillMirr_Offset)*ISELsolution, u2mm(y1 + Ref_null_offsetY)*ISELsolution, Actualmilldeep*ISELsolution , Mirror * u2mm(x2 + Mill_OffsetX)*ISELsolution + u2mm(MillMirr_Offset)*ISELsolution, u2mm(y2 + Ref_null_offsetY)*ISELsolution ); return; } void nextlineIsel( int x2, int y2) { printf("MOVEABS X%.0f Y%.0f\n", Mirror * u2mm(x2 + Mill_OffsetX)*ISELsolution + u2mm(MillMirr_Offset)*ISELsolution, u2mm(y2 + Ref_null_offsetY)*ISELsolution ); return; } void endlineIsel( int x2, int y2) { printf("MOVEABS X%.0f Y%.0f\nMOVEABS Z%.0f\n", Mirror * u2mm(x2 + Mill_OffsetX)*ISELsolution + u2mm(MillMirr_Offset)*ISELsolution, u2mm(y2 + Ref_null_offsetY)*ISELsolution, Actualmilldeep * -1 * ISELsolution // 2011-11-21 Fräser Z-Achse wieder hoch ); return; } void fullineIsel( int x1, int y1, int x2, int y2) { printf("FASTABS X%.0f Y%.0f\nMOVEABS Z%.0f\nMOVEABS X%.0f Y%.0f\n", Mirror * u2mm(x1 + Mill_OffsetX)*ISELsolution + u2mm(MillMirr_Offset)*ISELsolution, u2mm(y1 + Ref_null_offsetY)*ISELsolution, Actualmilldeep*ISELsolution, Mirror * u2mm(x2 + Mill_OffsetX)*ISELsolution + u2mm(MillMirr_Offset)*ISELsolution, u2mm(y2 + Ref_null_offsetY)*ISELsolution ); printf("MOVEABS X%.0f Y%.0f\nMOVEABS Z%.0f\n", Mirror * u2mm(x2 + Mill_OffsetX)*ISELsolution + u2mm(MillMirr_Offset)*ISELsolution, u2mm(y2 + Ref_null_offsetY)*ISELsolution, Actualmilldeep * -1 * ISELsolution ); return; } // *** CNC output *** // **************************************************** // *** Source cnc750a.pdf *** 2005-05-16 alf@cadsoft.de // **************************************************** void startlineCnc( int x1, int y1, int x2, int y2) { switch(CNCmillResolution) { // 2011-02-02 case Res32 : CNCsolution = 100; printf("G00 X%05.0f Y%05.0f\nG01 Z%05.0f\nG01 X%05.0f Y%05.0f\n", // Format 3 2 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen 2011-01-27 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; case Res33 : CNCsolution = 1000; printf("G00 X%06.0f Y%06.0f\nG01 Z%06.0f\nG01 X%06.0f Y%06.0f\n", // Format 3 3 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen 2011-01-27 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; case Res34 : CNCsolution = 10000; printf("G00 X%07.0f Y%07.0f\nG01 Z%07.0f\nG01 X%07.0f Y%07.0f\n", // Format 3 4 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen 2011-01-27 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; case Res3_2 : CNCsolution = 1; // 2011-02-03 printf("G00 X%05.2f Y%05.2f\nG01 Z%05.2f\nG01 X%05.2f Y%05.2f\n", // Format 3.2 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen 2011-01-27 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; case Res3_3 : CNCsolution = 1; printf("G00 X%06.3f Y%06.3f\nG01 Z%06.3f\nG01 X%06.3f Y%06.3f\n", // Format 3.3 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen 2011-01-27 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; case Res3_4 : CNCsolution = 1; printf("G00 X%07.4f Y%07.4f\nG01 Z%07.4f\nG01 X%07.4f Y%07.4f\n", // Format 3.4 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen 2011-01-27 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; } return; } void nextlineCnc( int x2, int y2) { switch(CNCmillResolution) { // 2011-02-02 case Res32 : CNCsolution = 100; printf("G01 X%05.0f Y%05.0f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; case Res33 : CNCsolution = 1000; printf("G01 X%06.0f Y%06.0f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; case Res34 : CNCsolution = 10000; printf("G01 X%07.0f Y%07.0f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; case Res3_2 : CNCsolution = 1; printf("G01 X%05.2f Y%05.2f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; case Res3_3 : CNCsolution = 1; printf("G01 X%06.3f Y%06.3f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; case Res3_4 : CNCsolution = 1; printf("G01 X%07.4f Y%07.4f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); break; } return; } void endlineCnc( int x2, int y2) { switch(CNCmillResolution) { // 2011-02-02 case Res32 : CNCsolution = 100; printf("G01 X%05.0f Y%05.0f\nG00 Z%05.0f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch ); break; case Res33 : CNCsolution = 1000; printf("G01 X%06.0f Y%06.0f\nG00 Z%06.0f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch ); break; case Res34 : CNCsolution = 10000; printf("G01 X%07.0f Y%07.0f\nG00 Z%07.0f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch ); break; case Res3_2 : CNCsolution = 1; printf("G01 X%05.2f Y%05.2f\nG00 Z%05.2f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch ); break; case Res3_3 : CNCsolution = 1; printf("G01 X%06.3f Y%06.3f\nG00 Z%06.3f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch ); break; case Res3_4 : CNCsolution = 1; printf("G01 X%07.4f Y%07.4f\nG00 Z%07.4f\n", Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch ); break; } return; } void fullineCnc( int x1, int y1, int x2, int y2) { switch(CNCmillResolution) { // 2011-02-02 case Res32 : CNCsolution = 100; printf("G00 X%05.0f Y%05.0f\nG01 Z%05.0f\nG01 X%05.0f Y%05.0f\nG00 Z%05.0f\n", // Format 3.2 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch 2011-01-27 ); break; case Res33 : CNCsolution = 1000; printf("G00 X%06.0f Y%06.0f\nG01 Z%06.0f\nG01 X%06.0f Y%06.0f\nG00 Z%06.0f\n", // Format 3.3 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch 2011-01-27 ); break; case Res34 : CNCsolution = 10000; printf("G00 X%07.0f Y%07.0f\nG01 Z%07.0f\nG01 X%07.0f Y%07.0f\nG00 Z%07.0f\n", // Format 3.4 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch 2011-01-27 ); break; case Res3_2 : CNCsolution = 1; printf("G00 X%05.2f Y%05.2f\nG01 Z%05.2f\nG01 X%05.2f Y%05.2f\nG00 Z%05.2f\n", // Format 3.2 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch 2011-01-27 ); break; case Res3_3 : CNCsolution = 1; printf("G00 X%06.3f Y%06.3f\nG01 Z%06.3f\nG01 X%06.3f Y%06.3f\nG00 Z%06.3f\n", // Format 3.3 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch 2011-01-27 ); break; case Res3_4 : CNCsolution = 1; printf("G00 X%07.4f Y%07.4f\nG01 Z%07.4f\nG01 X%07.4f Y%07.4f\nG00 Z%07.4f\n", // Format 3.4 Mirror * u2mm(x1 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y1 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*CNCsolution, // Z-Achse eintauchen Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution // Z-Achse wieder hoch 2011-01-27 ); break; } return; } // if the wire longer as longdistance and vertical or horizontal // then make a holder spacing void checkBridge(int x1, int y1, int x2, int y2, int state) { real WL = WireLength(u2mm(x2),u2mm(y2),u2mm(x1),u2mm(y1)); if (Holder_Spacing && (WL >= Holder_Spacing) && (x1 == x2 || y1 == y2) ) { // 2011-09-28 int bridgewidth = mm2u(DimensionMillTool); // 2013-03-05 an neue Eagle-Einheit angepasst real bridglength = 2.25; // 2011-09-28 Stegbreite int xa, xb, ya, yb; if (x2 > x1 && x2 >= 0) { xa = x2 - (bridglength * bridgewidth); xb = x2 - bridgewidth; } else if (x2 < x1 && x2 >= 0) { xa = x2 + (bridglength * bridgewidth); xb = x2 + bridgewidth; } else if (x2 > x1 && x2 < 0) { xa = x2 - (bridglength * bridgewidth); xb = x2 - bridgewidth; } else if (x2 < x1 && x2 < 0) { xa = x2 + (bridglength * bridgewidth); xb = x2 + bridgewidth; } else if (y2 > y1 && y2 >= 0 ) { ya = y2 - (bridglength * bridgewidth); yb = y2 - bridgewidth; } else if (y2 < y1 && y2 >= 0) { ya = y2 + (bridglength * bridgewidth); yb = y2 + bridgewidth; } else if (y2 > y1 && y2 < 0 ) { ya = y2 - (bridglength * bridgewidth); yb = y2 - bridgewidth; } else if (y2 < y1 && y2 < 0) { ya = y2 + (bridglength * bridgewidth); yb = y2 + bridgewidth; } switch (SelectedDevice) { case (devScript) : // holder spacing for SCRIPT 2009-03-31 if (x1 == x2) { // vertical lineprintScript(x1, y1, x1, ya); lineprintScript(x1, yb, x1, y2); } else { // horizontal lineprintScript(x1, y1, xa, y1); lineprintScript(xb, y1, x2, y2); } break; case (devHPGL) : switch (state) { case First_line : startlineprintHpgl(x1, y1, x2, y2); break; case Middle_line : if (x1 == x2) { endlineprintHpgl(x1, ya); startlineprintHpgl(x1, yb, x1, y2); } else { endlineprintHpgl(xa, y1); startlineprintHpgl(xb, y1, x2, y2); } break; case Last_line : endlineprintHpgl(x2, y2); break; } break; case (devISEL) : switch (state) { case First_line : startlineIsel(x1, y1, x2, y2); break; case Middle_line : if (x1 == x2) { endlineIsel(x1, ya); startlineIsel(x1, yb, x1, y2); } else { endlineIsel(xa, y1); startlineIsel(xb, y1, x2, y2); } break; case Last_line : endlineIsel(x2, y2); break; } break; case (devCNC) : switch (state) { case First_line : startlineCnc(x1, y1, x2, y2); break; case Middle_line : if (x1 == x2) { endlineCnc(x1, ya); startlineCnc(x1, yb, x1, y2); } else { endlineCnc(xa, y1); startlineCnc(xb, y1, x2, y2); } break; case Last_line : endlineCnc(x2, y2); break; } break; } return; } else { switch (SelectedDevice) { case (devScript) : // to short for holder spacing for Script 2009-03-31 switch (state) { case First_line : lineprintScript(x1, y1, x2, y2); break; case Middle_line : lineprintScript(x1, y1, x2, y2); break; case Last_line : lineprintScript(x1, y1, x2, y2); break; } break; case (devHPGL) : switch (state) { case First_line : startlineprintHpgl(x1, y1, x2, y2); break; case Middle_line : nextlineprintHpgl(x2, y2); break; case Last_line : endlineprintHpgl(x2, y2); break; } break; case (devISEL) : switch (state) { case First_line : startlineIsel(x1, y1, x2, y2); break; case Middle_line : nextlineIsel(x2, y2); break; case Last_line : endlineIsel(x2, y2); break; } break; case (devCNC) : switch (state) { case First_line : startlineCnc(x1, y1, x2, y2); break; case Middle_line : nextlineCnc(x2, y2); break; case Last_line : endlineCnc(x2, y2); break; } break; } return; } } // 2012-03-20 Bohrungen größer max drill werden gefräst void CircleDraw(int centerx, int centery, int diam, real drilldiamround, int drilltool) { int tool_diameter = mm2u(Max_Drill_Diameter); // 2012-03-20 switch (SelectedDevice) { case devScript: // 2012-03-20 die Fräswege der goßen Bohrungen werden in das drl-script geschrieben! printf("CIRCLE %.8f (%.9f %.9f) (%.9f %.9f); #2185 %.1f mx%d xo%d\n", Max_Drill_Diameter, Mirror * u2mm(centerx + Mill_OffsetX) + u2mm(MillMirr_Offset), u2mm(centery + Ref_null_offsetY), Mirror * u2mm(centerx + Mill_OffsetX) + u2mm(MillMirr_Offset) + u2mm(diam)/2 - u2mm(tool_diameter)/2, // 2012-03-20 u2mm(centery + Ref_null_offsetY), Mirror, Mill_OffsetX, MillMirr_Offset ); break; case devHPGL: int hpMax_Drill_Diameter = mm2u(Max_Drill_Diameter); // 2013-03-05 // AR Arc Relative // 1. Start point arc, // 2. Center point arc = Radius-Koordinate Relativ zur letzten Koordinate // 3. angel /* vvvv Die Zeilen aktivieren, wenn die Fräse AR benötigt vvvv printf("\nPA%.0f,%.0f;PD;AR%.0f,%.0f,360;PU;", (Mirror * u2inch(centerx + Mill_OffsetX) + u2inch(MillMirr_Offset)) * HPGLsolution, // 2013-04-18 (u2inch(centery + Ref_null_offsetY) - (u2inch(diam/2) - u2inch(tool_diameter/2))) * HPGLsolution, 0.0, (u2inch(diam/2) - u2inch(tool_diameter/2)) * HPGLsolution ); ^^^^ Die Zeilen aktivieren, wenn die Fräse AA benötigt ^^^^ */ // AA Arc Absolute // 1. Start point arc, // 2. Center point arc == Radius-Koordinate Absolute // 3. angel /* Die Zeilen deaktivieren, wenn die Fräse AR benötigt */ printf("\nPA%.0f,%.0f;PD;AA%.0f,%.0f,360;PU;", (Mirror * u2inch(centerx + Mill_OffsetX) + u2inch(MillMirr_Offset)) * HPGLsolution, // 2013-04-18 (u2inch(centery + Ref_null_offsetY) - (u2inch(diam/2) - u2inch(tool_diameter/2))) * HPGLsolution, (Mirror * u2inch(centerx + Mill_OffsetX) + u2inch(MillMirr_Offset)) * HPGLsolution, u2inch(centery + Ref_null_offsetY) * HPGLsolution ); /* Die Zeilen deaktivieren, wenn die Fräse AR benötigt */ break; case devISEL: // 1. festlegen der Interpolationsebene // 2. Startpunkt anfahren // 3. Kreis fräsen printf("PLANE XY\n"); printf("MOVEABS X%.0f Y%.0f\nMOVEABS Z-%.0f\n", Mirror * u2mm(centerx + Mill_OffsetX) * ISELsolution, u2mm(centery + Ref_null_offsetY) * ISELsolution, Drill_z_deep * ISELsolution ); printf("CWREL I%06.0f J00000 X000000 Y000000 A000000\n", u2mm(diam) / 2.0 * ISELsolution ); printf("MOVEABS Z%.0f\n", Mill_z_safety * ISELsolution ); break; case devCNC: // for CNC 1. Start point arc, // 2. Center point arc switch(CNCmillResolution) { case Res32 : CNCsolution = 100; printf("G00 X%05.0f Y%05.0f\nG01 Z%05.0f\n", // Format 3 2 Mirror * (u2mm((centerx + diam / 2 - tool_diameter / 2) + Mill_OffsetX))*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY) * CNCsolution, Actualmilldeep*CNCsolution ); printf("G03 X%05.0f Y%05.0f\nG00 Z%05.0f\n", // Format 3 2 Mirror * u2mm(centerx + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; case Res33 : CNCsolution = 1000; printf("G00 X%06.3f Y%06.3f\nG01 Z%06.3f\n", // Format 3 3 Mirror * (u2mm((centerx + diam / 2 - tool_diameter / 2) + Mill_OffsetX))*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY) * CNCsolution, Actualmilldeep*CNCsolution ); printf("G03 X%06.3f Y%06.3f\nG00 Z%06.3f\n", // Format 3 3 Mirror * u2mm(centerx + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; case Res34 : CNCsolution = 10000; printf("G00 X%07.0f Y%07.0f\nG01 Z%07.0f\n", // Format 3 4 Mirror * (u2mm((centerx + diam / 2 - tool_diameter / 2) + Mill_OffsetX))*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY) * CNCsolution, Actualmilldeep*CNCsolution ); printf("G03 X%07.0f Y%07.0f\nG00 Z%07.0f\n", // Format 3 4 Mirror * u2mm(centerx + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; case Res3_2 : CNCsolution = 1; printf("G00 X%05.2f Y%05.2f\nG01 Z%05.2f\n", // Format 3.2 Mirror * (u2mm((centerx + diam / 2 - tool_diameter / 2) + Mill_OffsetX))*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY) * CNCsolution, Actualmilldeep*CNCsolution ); printf("G03 X%05.2f Y%05.2f\nG00 Z%05.2f\n", // Format 3.2 Mirror * u2mm(centerx + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; case Res3_3 : CNCsolution = 1; printf("G00 X%06.3f Y%06.3f\nG01 Z%06.3f\n", // Format 3.3 Mirror * (u2mm((centerx + diam / 2 - tool_diameter / 2) + Mill_OffsetX))*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY) * CNCsolution, Actualmilldeep*CNCsolution ); printf("G03 X%06.3f Y%06.3f\nG00 Z%06.3f\n", // Format 3.3 Mirror * u2mm(centerx + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; case Res3_4 : CNCsolution = 1; printf("G00 X%07.4f Y%07.4f\nG01 Z%07.4f\n", // Format 3.4 Mirror * (u2mm((centerx + diam / 2 - tool_diameter / 2) + Mill_OffsetX))*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY) * CNCsolution, Actualmilldeep*CNCsolution ); printf("G03 X%07.4f Y%07.4f\nG00 Z%07.4f\n", // Format 3.4 Mirror * u2mm(centerx + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(centery + Ref_null_offsetY)*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; } break; } return; } // *** draw lines and drills/holes *** void DeviceDraw(int x1, int y1, int x2, int y2, int state) { // Actually draw a line on the output device. // 'state' is defined as // 0 = this is the first line of a partial polygon // 1 = this is a "normal" line (neither the first nor the last one) // 2 = this is the last line of a partial polygon // 3 = this is a drill coordinate // 2013-03-05 x1 = Diameter y1 = Diameter // 4 = this is one line real drilldiam = round(u2mm(x1)*10) / 10; // 2013-04-18 // real-vergleich ist Problematisch bei Nachkommastellen if (InPassPour && state == One_line) { // *** print no shorter horizontal fillings as MillToolFree *** if (y2 == y1) { // *** OK 2005-05-18 alf *** real check_legth = WireLength(u2mm(x2), u2mm(y2), u2mm(x1), u2mm(y1) ); if (abs(check_legth) < MillToolFree) return; } } switch (SelectedDevice) { case devScript: switch (state) { case First_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else firstlinewire(x1, y1, x2, y2); break; case Middle_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else middlelinewire(x2, y2); break; case Last_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else lastlinewire(x2, y2); break; case Drill_coord : if (drilldiam > Max_Drill_Diameter) { // 2013-03-05 printf("CIRCLE %.8f (%.8f %.8f) (%.8f %.8f); #2352 %.1f mx%d mo%d milling Drill/Hole\n", Max_Drill_Diameter, Mirror * u2mm(x2 + Mill_OffsetX) + u2mm(MillMirr_Offset), u2mm(y2 + Ref_null_offsetY), Mirror * u2mm(x2+ (x1/2) + Mill_OffsetX) + u2mm(MillMirr_Offset) - (Mirror * (Max_Drill_Diameter/2)), // 2013-03-05 x1 = Diameter u2mm(y2 + Ref_null_offsetY), Mirror, Mill_OffsetX, MillMirr_Offset ); } else { printf("CIRCLE 0 (%.8f %.8f) (%.8f %.8f); #2361 %.1f mx%d mo%d Drill/Hole\n", Mirror * u2mm(x2 + Mill_OffsetX) + u2mm(MillMirr_Offset), u2mm(y2 + Ref_null_offsetY), Mirror * u2mm(x2+ (x1/2) + Mill_OffsetX) + u2mm(MillMirr_Offset), // x1 = Diameter u2mm(y2 + Ref_null_offsetY), Mirror, Mill_OffsetX, MillMirr_Offset ); } break; case One_line : // polygon filling onelinewire(x1, y1, x2, y2); break; } break; case devHPGL: switch (state) { case First_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else startlineprintHpgl(x1, y1, x2, y2); break; case Middle_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else nextlineprintHpgl(x2, y2); break; case Last_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else endlineprintHpgl(x2, y2); break; case Drill_coord : /* Option mit nur 3 Bohrern ohne Use rack! if (drilldiam > Max_Drill_Diameter) { string dtool; sprintf(dtool, "#2403 Use rack?\nDrill %.1f > Max. Drill %.1f Tool %d", drilldiam, Max_Drill_Diameter, get_tool(drilldiam)); if (dlgMessageBox(dtool, "OK", "Abort milling") != 0) exit(-2404); CircleDraw( x1, y1, x2, y2, get_tool(drilldiam)); } */ printf("\nPA%.0f,%.0f;PD;", // Drill bohren 2013-04-18 (Mirror * u2inch(x2 + Mill_OffsetX) + u2inch(MillMirr_Offset)) * HPGLsolution, u2inch(y2 + Ref_null_offsetY)*HPGLsolution ); printf("\nPA%.0f,%.0f;PU;", (Mirror * u2inch(x2 + Mill_OffsetX) + u2inch(MillMirr_Offset)) * HPGLsolution, u2inch(y2 + Ref_null_offsetY) * HPGLsolution ); break; case One_line : // polygon filling fullineprintHpgl(x1, y1, x2, y2); break; } break; case devISEL: switch (state) { case First_line : printf("; Start LINE\n"); if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else startlineIsel(x1, y1, x2, y2); break; case Middle_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else nextlineIsel(x2, y2); break; case Last_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else endlineIsel(x2, y2); printf("; End line\n"); break; case Drill_coord : printf("; Zyklus Zentrierbohren begin\n"); printf("FASTABS X%.0f Y%.0f ; Positionieren\n", Mirror * u2mm(x2 + Mill_OffsetX)*ISELsolution + u2mm(MillMirr_Offset)*ISELsolution, u2mm(y2 + Ref_null_offsetY)*ISELsolution ); printf("MOVEABS Z%.0f\n", Drill_z_deep*ISELsolution); printf("FASTABS Z%.0f\n", Actualmilldeep*-1*ISELsolution); printf("; Zyklus Zentrierbohren end\n"); break; case One_line : printf("; polygon filling\n"); // polygon filling fullineIsel(x1, y1, x2, y2); break; } break; case devCNC: switch (state) { case First_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else startlineCnc(x1, y1, x2, y2); break; case Middle_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else nextlineCnc(x2, y2); break; case Last_line : if (InPassOutmill) checkBridge(x1, y1, x2, y2, state); else endlineCnc(x2, y2); break; case Drill_coord : switch(CNCmillResolution) { // 2011-02-02 case Res32 : CNCsolution = 100; printf("G00 X%05.0f Y%05.0f\n", // Format 2.4 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); printf("G01 Z%05.0f\nG00 Z%05.0f\n", // langsam Eintauchen, schnell hoch 2011-01-27 Actualmilldeep*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; case Res33 : CNCsolution = 1000; printf("G00 X%06.0f Y%06.0f\n", // Format 2.4 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); printf("G01 Z%06.0f\nG00 Z%06.0f\n", // langsam Eintauchen, schnell hoch 2011-01-27 Actualmilldeep*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; case Res34 : CNCsolution = 10000; printf("G00 X%07.0f Y%07.0f\n", // Format 2.4 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); printf("G01 Z%07.0f\nG00 Z%07.0f\n", // langsam Eintauchen, schnell hoch 2011-01-27 Actualmilldeep*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; case Res3_2 : CNCsolution = 1; printf("G00 X%05.2f Y%05.2f\n", // Format 2.4 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); printf("G01 Z%05.2f\nG00 Z%05.2f\n", // langsam Eintauchen, schnell hoch 2011-01-27 Actualmilldeep*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; case Res3_3 : CNCsolution = 1; printf("G00 X%06.3f Y%06.3f\n", // Format 2.4 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); printf("G01 Z%06.3f\nG00 Z%06.3f\n", // langsam Eintauchen, schnell hoch 2011-01-27 Actualmilldeep*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; case Res3_4 : CNCsolution = 1; printf("G00 X%07.4f Y%07.4f\n", // Format 2.4 Mirror * u2mm(x2 + Mill_OffsetX)*CNCsolution + u2mm(MillMirr_Offset)*CNCsolution, u2mm(y2 + Ref_null_offsetY)*CNCsolution ); printf("G01 Z%07.4f\nG00 Z%07.4f\n", // langsam Eintauchen, schnell hoch 2011-01-27 Actualmilldeep*CNCsolution, Actualmilldeep*-1*CNCsolution ); break; } break; case One_line : fullineCnc(x1, y1, x2, y2); break; } break; } return; } // *** reinitialize the machine *** void DeviceReInit(int tool_pass, int Layer, string info) { // Do anything necessary the secondary initialize the output device set_tool_rack(); // 2013-04-25 switch (SelectedDevice) { case devScript: // *** SCRIPT *** switch (tool_pass) { case PadDrill: printf("\n#2554 CHANGE DRILL %.2f;# PAD\n", DrillPad); // 2013-02-19 break; case ViaDrill: printf("\n#2558 CHANGE DRILL %.2f; # VIA\n", DrillVia); // 2013-02-19 break; case HoleDrill: printf("\n#2562 CHANGE DRILL %.2f; # HOLE\n", DrillHole); // 2013-02-19 break; case Contour: printf("#2566 DeviceReinit case Contour:\n"); printf("ChANGE LAYER %d;\n", Layer + 100); printf("CHANGE wIDTH %.8f;\n", MillToolOutl); break; case BlowUp_RubOut: printf("#2572 DeviceReinit case BlowUp_RubOut:\n"); if (Layer == 45) { printf("CHaNGE LAYER %d;\n", Layer); // Layer 45 Holes 2005-09-30 } else { printf("CHAnGE LAYER %d;\n", Layer + 101); // 2006-07-26 separate Layer for RubOut } printf("#2579 BlowUp_RubOut or drills\n"); // 2011-10-20 printf("\nCHANGE WiDTH %.8f;\nWIRe\n", MillToolFree);// 2010-10-14 break; case DimensionLine: printf("\n#2584 DeviceReinit case DimensionLine:\n"); if (SelectedLayer1) { if (MillOnlyContour) printf("LAYER Milloutlines103 %d;\n", 103); // 2012-01-25 printf("CHANgE LAYER %d; #2579 layer for milling dimension outline in script\n", 103); // 2012-01-13 separate Layer for out milling of raw material } else { if (MillOnlyContour) printf("LAYER Milloutlines118 %d;\n", 118); // 2012-01-25 printf("CHANgE LAYER %d; #2583 layer for milling dimension outline in script\n", 118); // 2012-01-13 separate Layer for out milling of raw material } printf("CHANGE WIdTH %.8f;\n", DimensionMillTool); // die Fräserbreite um das PCB aus dem Träger zu fräsen break; case MirrorPCB: printf("\n#2597 swap/mirror PCB for other side\n"); break; case nrMaxDrillDiameter: printf("\n#2601 drill are milling\n"); break; default: printf("#2605 CHANGE DRILL %.2f;\n", Drill_tools[tool_pass] ); break; } break; case devHPGL: // *** HPGL *** printf("\nSP%d;\nPU;", tool_pass); // pen select // \n#2610 Reinit\n // output(filesetext(MillFileName,".pli"), "at") { string pli; if (InPassDimensionPoly) pli = PassDimensionPoly; else if (InPass2) pli = Pass2; else if (InPassPour) pli = PassPour; else if (InPassOutmill) pli = PassOutmill; else pli = "Drill"; printf("use PEN #%02d %s %.2f #2610 <- %s\n", tool_pass, pli, Drill_tools[tool_pass], info); } break; case devISEL: // *** ISEL *** /* ********************************************************** #### Beispiel von Herr Koppel 2005-08-12 alf@cadsoft.de #### MOVEABS Y99850 FASTABS Z2000 ; Werkzeugwechselpos. COOLANT OFF ; Kühlung aus SPINDLE OFF ; *** BLOCK INSERTED BY PROTRAP *** FASTABS Z80000 HALT ; ********************** ; * PLATINE UMDREHEN * ; ********************** ; *** BLOCK INSERTED BY PROTRAP *** SPINDLE CW RPM15000 ; BLOCK 2 FASTABS Z2000 ; Werkzeugwechselpos. soll Sicherheitshöhe sein. alf GETTOOL 15 ; D0.3 - HSS - STICHEL 90 GRAD SPINDLE CW RPM15000 COOLANT ON ; Kühlung ein ************************************************************* */ printf("FASTABS Z%.0f ; Sicherheitshöhe\n", Mill_z_safety*ISELsolution); printf("SPINDLE OFF\n"); printf("COOLANT OFF\n"); if (tool_pass == MirrorPCB) { // Platine umdrehen ** printf("FASTABS Z%.0f; Parkposition Z\n", ParkZposition*ISELsolution); // 80mm printf("FASTABS X%.0f; Parkposition X\n", ParkXposition*ISELsolution); // 10mm printf("FASTABS Y%.0f; Parkposition Y\n", ParkYposition*ISELsolution); // 10mm printf("HALT\n"); printf("; **********************\n"); printf("; * PLATINE UMDREHEN *\n"); printf("; **********************\n"); } else { printf("GETTOOL %d ; %s %.1f mm \n", tool_pass, PenList[tool_pass], Drill_tools[tool_pass]); printf("SPINDLE CW RPM%d\n", Spindle_rpm); printf("COOLANT ON\n"); } if(test) printf("; # ISEL tools\n"); output(filesetext(MillFileName,".isi"), "at") { if (Onlydrill && tool_pass == Contour); printf("Tool #%d = %s mm\t%s\n", tool_pass, sToolValue[tool_pass], PenList[tool_pass]); } break; case devCNC: // *** CNC *** if (tool_pass == MirrorPCB) { // Platine umdrehen ** // Meldung an CNC um Platine umzudrehen 2005-11-15 printf("M01 'CNC' Platine umdrehen!\n"); } else { printf("G36 T%2d\n", tool_pass); // Werkzeugwechsel 2001-02-01 } if(test) printf("; # CNC tools\n"); output(filesetext(MillFileName,".nci"), "at") { if (Onlydrill && tool_pass == Contour); printf("Tool #%d = %s mm\t%s\n", tool_pass, sToolValue[tool_pass], PenList[tool_pass]); } break; } return; } real Length(real x1, real y1, real x2, real y2) { return sqrt((pow(x2 - x1, 2) + pow(y2 - y1, 2)) ); } // *** collect Rack data void AddRack(int Size) { real r = round(u2mm(Size) * pow(10, 1)) / pow(10, 1); if (!r) dlgMessageBox("!Drill zero 0.0 diamter found.", "Ok"); if (r) { // <= Max_Drill_Diameter) 2013-02-20 alle Drills auflisten for (int i = Cnt_tools; --i > nrMaxDrillDiameter; ) { if (Drill_tools[i] == r) return; } Drill_tools[Cnt_tools] = r; Cnt_tools++; } else { string h; sprintf(h, "Found drill diameter %.1f mm\n", r); Drilltoolsplus += h; } return; } // *** collect Drill/Hole data **** void AddDrilling(int Size, int x, int y) { real r = round(u2mm(Size) * pow(10, 1)) / pow(10, 1); if (!r) dlgMessageBox("!Drill zero 0.0 diamter found.", "Ok"); Nc_drill[Cnt_ncdrill] = Size; // nicht benutzt -->> Mark; // Mark this drill not calculated Nc_drilld[Cnt_ncdrill] = Size; Nc_drilldround[Cnt_ncdrill] = r; // gerundet auf 0.1mm Nc_drillx[Cnt_ncdrill] = x; Nc_drilly[Cnt_ncdrill] = y; Cnt_ncdrill++; return; } void get_rack(UL_BOARD B) { status(" collect Rack"); B.elements(E) { E.package.contacts(C) if(C.pad) AddRack(C.pad.drill); E.package.holes(H) AddRack(H.drill); } B.signals(S) S.vias(V) AddRack(V.drill); B.holes(H) AddRack(H.drill); status(" finish, collect Rack"); sort(Cnt_tools, Drill_tools); return; } void get_drills(UL_BOARD B) { status(" collect Drills"); B.elements(E) { E.package.contacts(C) if(C.pad) AddDrilling(C.pad.drill, C.pad.x, C.pad.y); } B.signals(S) S.vias(V) AddDrilling(V.drill, V.x, V.y); status(" finish, collect Drills"); return; } void get_holes(UL_BOARD B) { // nach dem isolieren und evtl. blow-up die Holes bohren Cnt_ncdrill = 0; status("collect Holes"); B.elements(E) { E.package.holes(H) AddDrilling(H.drill, H.x, H.y); } B.holes(H) AddDrilling(H.drill, H.x, H.y); status(" finish, collect Holes"); return; } void output_drills(string s) { sort(Cnt_ncdrill, Dindex, Nc_drilldround, Nc_drillx, Nc_drilly); int n; int Tcode = -1; real new_drill = -1; switch (SelectedDevice) { case devScript: if (s) printf("# Layer 145 Mil_sDrill; # Gesamt %d %s\n", Cnt_ncdrill, s); break; case devHPGL : //if (s) printf(";\nLBGesamt %d %s%c\n", Cnt_ncdrill, s, 3); break; case devISEL : if (s) printf(";Isel: Gesamt %d %s\n", Cnt_ncdrill, s); break; case devCNC : if (s) printf("M999 Gesamt %d %s\n", Cnt_ncdrill, s); break; } int initCode = 0; // Flag zum initiaisieren des T-Code zum Fräsen von grossen Löchern. 2011-02-14 // die Drills sind nach Durchmesser sortiert, als muß nur einmal mit T9 // Reinitialisiert werden. for (n = 0; n < Cnt_ncdrill; n++) { if (Nc_drilldround[Dindex[n]] != new_drill) { new_drill = Nc_drilldround[Dindex[n]]; Tcode = get_tool(new_drill); if (Tcode > false) { if (test2) { string h; sprintf(h, "# Tcode == %d in #2773", Tcode); if(dlgMessageBox(h, "ok2759", "esc2759") != 0) exit(-2781); } if (initCode != nrMaxDrillDiameter) { initCode = Tcode; if (test2) printf("#2784"); DeviceReInit(Tcode, 45, "2785"); // the Hole layer } } } if (Tcode == nrMaxDrillDiameter) { // T-Code 9 ist fräsen switch (SelectedDevice) { case devScript: if (s) printf("#2792 fräsen von Bohrungen grösser Tn\n"); printf("CHANGe LAYER %d;\n", 145); // holes > maxdiameter milling in Mil_Hole layer 2013-02-19 break; case devHPGL : break; case devISEL : if (s) printf(";isel fräsen von Bohrungen grösser Tn mit T'%d'\n", Tcode); // 2011-02-11 zum testen break; case devCNC : if (s) printf("M998 fräsen von Bohrungen grösser Tn\n"); break; } // große Drills werden gefräst, 2012-03-20 CircleDraw( Nc_drillx[Dindex[n]], Nc_drilly[Dindex[n]], Nc_drilld[Dindex[n]], Nc_drilldround[Dindex[n]], Tcode); } else DeviceDraw(Nc_drilld[Dindex[n]], mm2u(Nc_drilldround[Dindex[n]]), Nc_drillx[Dindex[n]], Nc_drilly[Dindex[n]], 3); // Nc_drilldround[] is real! 2013-03-05 } return; } // ** generate plus layer data for Text milling ** 2005-06-08 void genPlusLayer(int Layer) { board(B) { B.texts(T) { int firstinit = 1; if (T.layer == Layer) { if (firstinit) { DeviceReInit(Contour, Layer, "2778"); // *** additional Text-Layer milling with Contour-Tool *** firstinit = 0; } string tl; int State = One_line; int lastX = INT_MAX, lastY = INT_MAX; int x1[], y1[], x2[], y2[], cnt = 0; T.wires(W) { x1[cnt] = W.x1; y1[cnt] = W.y1; x2[cnt] = W.x2; y2[cnt] = W.y2; cnt++; } for (int n = 0; n < cnt; n++) { if (lastX != x1[n] || lastY != y1[n]) { if (x2[n] == x1[n+1] && y2[n] == y1[n]) { if (State == First_line) State == Middle_line; else State == First_line; } else { if (State == Middle_line) State = Last_line; else State = One_line; } } else if (x2[n] != x1[n+1] || y2[n] != y1[n]) State = One_line; if (n == cnt-1 && (State == First_line || State == Middle_line) ) State = Last_line; lastX = x2[n]; lastY = y2[n]; DeviceDraw(x1[n], y1[n], x2[n], y2[n], State); } } } } return; } void scriptHeader(void) { board(B) printf("# Generated with %s at %s\n# from %s\n", filename(argv[0]), t2string(time()), B.name); printf("gRID mm;\n"); printf("CHANGE SIZE 0.1;\n"); printf("SET OPTIMIZING OFF;\nSET WIRE_BEND 2;\n"); // 2010-10-28 Optimizing ON kann man nicht erwarten, bei einer Vielzahl von WIRE. if (!test) printf("#SET UNDO_LOG OFF;\n"); printf("LAYER %d Mill_Isol%d;\n", 1 + 100, 1); // 2008-11-12 use not flag, use 1 printf("SET FILL_LAYER %d %s;\n", 1 + 100, Fillstyle1); printf("SET COLOR_LAYER %d %s;\n", 1 + 100, "Brown"); // *** 2006-07-26 *** printf("LAYER %d Mill_Pour%d;\nSET FILL_LAYER %d %s;\n", 1 + 101, 1 + 101, 1 + 101, Fillstyle1); printf("SET COLOR_LAYER %d %s;\n", 1 + 101, "Magenta"); printf("LAYER %d Mill_Out%d;\nSET FILL_LAYER %d %s;\n", 1 + 102, 1 + 102, 1 + 102, Fillstyle1); printf("SET COLOR_LAYER %d %s;\n", 1 + 102, "LGray"); //printf("CHANGE lAYER %d;\n", 1 + 100 ); printf("LAYER %d Mill_Isol%d;\n", 16 + 100, 16); // 2008-11-12 use not flag, use 16 printf("SET FILL_LAYER %d %s;\n", 16 + 100, Fillstyle16); printf("SET COLOR_LAYER %d %s;\n", 16 + 100, "Brown"); // *** 2006-07-26 *** printf("LAYER %d Mill_Pour%d;\nSET FILL_LAYER %d %s;\n", 16 + 101, 16 + 101, 16 + 101, Fillstyle16); printf("SET COLOR_LAYER %d %s;\n", 16 + 101, "Cyan"); printf("LAYER %d Mill_Out%d;\nSET FILL_LAYER %d %s;\n", 16 + 102, 16 + 102, 16 + 102, Fillstyle16); printf("SET COLOR_LAYER %d %s;\n", 16 + 102, "LGray"); // 2013-02-19 printf("LAYER %d Mill_Dril;\nSET FILL_LAYER %d %s;\n", 144, 144, Fillstyle16); printf("SET COLOR_LAYER %d %s;\n", 144, "LGray"); printf("LAYER %d Mill_Hole;\nSET FILL_LAYER %d %s;\n", 145, 145, Fillstyle16); printf("SET COLOR_LAYER %d %s;\n", 145, "LGray"); // 2005-06-21 if (SelectedPlusLayerTop) { printf("LAYER %d plusLayerTop%d;\n", SelectedPlusLayerTop + 100, SelectedPlusLayerTop); printf("SET COLOR_LAYER %d %s;\n", SelectedPlusLayerTop + 100, "LRed"); } if (SelectedPlusLayerBot) { printf("LAYER %d plusLayerBot%d;\n", SelectedPlusLayerBot + 100, SelectedPlusLayerBot); printf("SET COLOR_LAYER %d %s;\n", SelectedPlusLayerBot + 100, "LCyan"); } return; } // ***Device output functions *** void DeviceInit(int tool, int Layer) { int n; set_tool_rack(); // Do anything necessary to initialize the output device switch (SelectedDevice) { case devScript: // TODO make the layer user definable? if (Layer == 45) { printf("CHANGE LAYER %d;\n", Layer + 100); // 2013-02-19 } else if (InPassPour) { real overlap = MillToolFree * OverlapOutlPercent / 100; if (Layer == 44) { printf("CHANGE Layer %d;\n", Layer + 100); // 2013-02-19 } else { printf("CHANGE LAyER %d;\n", Layer + 101); // 2006-07-26 printf("CHANGE WIDtH %.8f;\n", MillToolFree); printf("SET WIRE_BEND 2;\n"); } } break; case devHPGL: if (Generatedrills) { if (!InPassDimensionPoly && !InPass2 && !InPassPour && !InPassOutmill) { output(filesetext(MillFileName,".pli"), "at") { printf("#2933\n%s\n", Tool_Rack_string); } } if (!InitDone) { printf ("IN;\nIP 0,0,100,100;\nSC 0,100,0,100;\nPU;"); // #HPGL2929"); // 2013-04-18 InitDone = 1; } } break; case devISEL: // Source: Übersicht des isel Zwischenformat zur Maschinensteuerung // Stand: 1.2/g 08.11.99 output(filesetext(MillFileName,".isi"), "at") { for (n = 0; n < Cnt_tools; n++) { printf("; T%02dC%.1f\n", n+1, Drill_tools[n]); // als Kommentar // ** defintion T = Tool C = Diameter ** } } if (!InPassDimensionPoly && !InPass2 && !InPassPour && !InPassOutmill) { printf("IMF_PBL_V1.0 - PICTURES BY PC\n"); // 2005-06-16 // printf("REF X0Y0Z0\n"); printf("VEL %.0f\n", Tool_vel * ISELsolution); printf("FASTVEL %.0f\n", Fast_vel * ISELsolution); string tr[]; int cntr = strsplit(tr, Tool_Rack_string, '\n'); for (int n = 0; n < cntr; n++) { printf("; %s\n", tr[n]); } } break; case devCNC : output(filesetext(MillFileName,".nci"), "at") { printf("T%-2d = %s mm\t%s\n", tool, sToolValue[tool], PenList[tool]); } // Source: Programmierung Excellon Format Multi-Control X10 // MANIA Electronic 05.03.1985 / 27.02.1986 printf("%%\n"); // Excellon format printf("M48\n"); // Header start printf("M71\n"); // Unit mm | M72 = Inch printf("G21\n"); // datron.de: CAT3D Konverter 2005-11-15 alf@cadsoft.de printf("G90\n"); // Absolute mode | G91 incremental for (n = 0; n < Cnt_tools; n++) { printf("T%02dC%.1f\n", n+1, Drill_tools[n]); // ** defintion T = Tool C = Diameter ** } printf("%%\n"); // end of block / new block if (tool == Contour) { printf("%%\n"); // end of block / new block } break; } return; } void DeviceEnd(void) { // Do anything necessary to end output to the device switch (SelectedDevice) { case devScript: break; case devHPGL: printf("\nSP0;\n"); // 2013-03-06 #HPGL2989 ende der Fräsdaten\n"); // Ende der Fräsdaten break; case devISEL: printf("\FASTABS Z2000\nCOOLANT OFF\nSPINDLE OFF\nPROGEND\n"); break; case devCNC: printf("M74\nM30 Device ende\n"); // referenzpunkt anfahren 2011-01-27 break; } return; } // *** generate HOLES with short way *** void WriteHoles(int Layer) { board(B) get_holes(B); output_drills("; Holes"); return; } void genDrills(void) { Actualmilldeep = Drill_z_deep; // 2011-01-27 board(B) { set_tool_rack(); output(MillFileName, "wt") { // 2008-12-05 new file = "wt" if (test2) printf("#3025 *** Drills bohren\n"); switch (SelectedDevice) { case devScript: scriptHeader(); if (Generatedrills) { DeviceInit(PadDrill, 44); // 2013-02-19 , OutlineMillSignalLayer); output_drills("#3031 Script-Drills"); } break; case devHPGL: if (Generatedrills) { DeviceInit(PadDrill, 44); // 2004-10-05 , OutlineMillSignalLayer); output_drills("#3038 HPGL drills"); // no message in actual drill file } break; case devISEL: // Source: Übersicht des isel Zwischenformat zur Maschinensteuerung // Stand: 1.2/g 08.11.99 if (Generatedrills) { DeviceInit(PadDrill, 44); // 2004-10-05 , OutlineMillSignalLayer); output_drills("Isel-Drills (Pads/Vias)"); } break; case devCNC: // Source: Programmierung Excellon Format Multi-Control X10 // MANIA Electronic 05.03.1985 / 27.02.1986 if (Generatedrills) { DeviceInit(PadDrill, 44); // 2004-10-05 , OutlineMillSignalLayer); output_drills("; CNC-Drills"); } break; } if(test2) printf("\n#3060 Drills bohren Ende\n"); } } return; } // TRUE OUTLINE *** void trueOutlineDraw(string SignalName) { board(B) { B.signals(S) { if (S.name == SignalName) { S.polygons(P) { int x1 = INT_MAX, y1 = INT_MAX, x2 = INT_MIN, y2 = INT_MIN; int x0, y0; int FrameWire; string s; int first = 1; P.wires(W) { x1 = min(x1, W.x1); x2 = max(x2, W.x1); y1 = min(y1, W.y1); y2 = max(y2, W.y1); } string lasts = ""; P.contours(W) { if (first) { // a new partial polygon is starting x0 = W.x1; y0 = W.y1; FrameWire = (x1 == x0 || x2 == x0) && (y1 == y0 || y2 == y0); sprintf(s, " (%.8f %.8f)", u2mm(W.x1), u2mm(W.y1) ); TrueOutline_coordinate = s; lasts = s; first = 0; } else if (W.x2 == x0 && W.y2 == y0) { // this was the last wire of the partial polygon, // so the next wire (if any) will be the first wire // of the next partial polygon sprintf(s, " (%.8f %.8f)", u2mm(W.x2), u2mm(W.y2) ); if (lasts != s) TrueOutline_coordinate += s; lasts = s; first = 1; } else ; if (!FrameWire) { sprintf(s, " (%.8f %.8f)", u2mm(W.x2), u2mm(W.y2) ); if (lasts != s) TrueOutline_coordinate += s; lasts = s; } } } } } return ; } } // *** the return string to start the ULP rekursiv *** string RUN_pass(string run_Pass) { string s; sprintf(s, "RUN '%s' '%s' '%.8f' '%.8f' '%.8f' '%d' '%d' '%d' '%d' '%s' '%s' '%.1f' '%.1f' '%.1f' '%d' '%d' '%.8f' '%.8f' '%d' '%.8f' '%d' '%d' '%s' '%d' '%.1f' '%d' '%d' '%d' '%d' '%d' '%d' '%d' '%.8f' '%.8f' '%.8f' '%.8f' '%d' '%.8f' '%d' '%d' '%d';\n", // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 35 35 36 37 38 39 40 argv[0], Device, // argv[1] MillToolOutl, // argv[2] MillToolIsolate, // argv[3] MillToolFree, // argv[4] SelectedLayer1, // argv[5] ToMillLayer1, // ergv[6] SelectedLayer16, // argv[7] ToMillLayer16, // argv[8] MillFileName, // argv[9] run_Pass, // argv[10] DrillPad, // argv[11] DrillVia, // argv[12] DrillHole, // argv[13] OverlapOutlPercent, // argv[14] OverlapRubOutPercent, // argv[15] Distance_Copper_Dimension, // argv[16] DimensionMillTool, // argv[17] Millfreeyes, // argv[18] Holder_Spacing, // argv[19] Onlydrill, // argv[20] Generatedrills, // argv[21] TrueOutline_coordinate, // argv[22] OutlineMillSignalLayer, // argv[23] Max_Drill_Diameter, // argv[24] UseRack, // argv[25] SelectedPlusLayerTop, // argv[26] SelectedPlusLayerBot, // argv[27] Mirror_On, // argv[28] Dim_on_off, // argv[29] MInner_contour, // argv[30] CNCmillResolution, // argv[31] 2011-02-02 Mill_z_safety, // argv[32] 2011-02-03 Drill_z_deep, // argv[33] Z_down, // argv[34] Z_dimension, // argv[35] MillOnlyContour, // argv[36] 2011-03-10 GridDistance, // argv[37] GridUnit, // argv[38] GridUnitdist, // argv[39] 2013-03-05 InitDone // argv[40] 2013-04-18 ); if (test) if (viewtest(" RUN_pass ("+run_Pass+") Returnstring:", s) != 0) exit(-3168); return s; } void save_defaults(void) { output(filesetext(argv[0], ".def"), "wt") { printf("%s\n", DeviceNames[SelectedDevice]); printf("%d; 1 SelectedDevice\n", SelectedDevice); printf("%.8f; 2 MillToolOutl\n", MillToolOutl); printf("%.8f; 3 MillToolIsolate fuer Polygon-Isolate\n", MillToolIsolate); printf("%.8f; 4 MillToolFree\n", MillToolFree); printf("%d; 5 SelectedLayer1\n", SelectedLayer1); printf("%d; 6 SelectedLayer16\n", SelectedLayer16); printf("%.1f; 7 DrillPad\n", DrillPad); printf("%.1f; 8 DrillVia\n", DrillVia); printf("%.1f; 9 DrillHole\n", DrillHole); printf("%d; 10 OverlapOutlPercent\n", OverlapOutlPercent); printf("%d; 11 OverlapRubOutPercent\n", OverlapRubOutPercent); printf("%.8f; 12 Distance_Copper_Dimension\n", Distance_Copper_Dimension); printf("%.8f; 13 DimensionMillTool\n", DimensionMillTool); printf("%d; 14 Millfreeyes\n", Millfreeyes); printf("%.8f; 15 Holder_Spacing\n", Holder_Spacing); printf("%d; 16 Onlydrill\n", Onlydrill); printf("%d; 17 Generatedrills\n", Generatedrills); printf("%.1f; 18 Max_Drill_Diameter\n", Max_Drill_Diameter); printf("%.8f; 19 Z_down\n", Z_down); printf("%.8f; 20 Drill_z_deep\n", Drill_z_deep); // drill deep for drilling pads, via, holes printf("%.8f; 21 Mill_z_safety\n", Mill_z_safety); // safety distance to pcb for change tool printf("%d; 22 Spindle_rpm\n", Spindle_rpm); // spindel rotation per minute printf("%.8f; 23 Tool_vel\n", Tool_vel); printf("%.8f; 24 Fast_vel\n", Fast_vel); printf("%.8f; 25 Drill_Vel\n", Drill_Vel); printf("%d; 26 DrillRefOn\n", DrillRefOn); printf("%.8f; 27 DrillRefDiameter\n", DrillRefDiameter); printf("%.8f; 28 DrillRefDeep\n", DrillRefDeep); printf("%d; 29 UseRack\n", UseRack); printf("%d; 30 SelectedPlusLayerTop\n", SelectedPlusLayerTop); printf("%d; 31 SelectedPlusLayerBot\n", SelectedPlusLayerBot); printf("%d; 32 Mirror_On\n", Mirror_On); printf("%d; 33 MachineMenuOn\n", MachineMenuOn); printf("%.8f; 34 ParkXposition\n", ParkXposition); printf("%.8f; 35 ParkYposition\n", ParkYposition); printf("%.8f; 36 ParkZposition\n", ParkZposition); printf("%.8f; 37 Z_dimension\n", Z_dimension); printf("%d; 38 Dim_on_off\n", Dim_on_off); printf("%.8f; 39 Mz_down\n", Mz_down); printf("%.8f; 40 Mdrill_z_deep\n", Mdrill_z_deep); printf("%.8f; 41 Mmill_z_safety\n", Mmill_z_safety); printf("%d; 42 Mspindle_rpm\n", Mspindle_rpm); printf("%.8f; 43 Mtool_vel\n", Mtool_vel); printf("%.8f; 44 Mfast_vel\n", Mfast_vel); printf("%.8f; 45 MDrill_Vel\n", MDrill_Vel); printf("%d; 46 MdrillRefOn\n", MdrillRefOn); printf("%.8f; 47 MdrillRefDiameter\n", MdrillRefDiameter); printf("%.8f; 48 MdrillRefDeep\n", MdrillRefDeep); printf("%.8f; 49 MparkXposition\n", MparkXposition); printf("%.8f; 50 MparkYposition\n", MparkYposition); printf("%.8f; 51 MparkZposition\n", MparkZposition); printf("%.8f; 52 Mz_dimension\n", Mz_dimension); printf("%d; 53 Mdim_on_off\n", Mdim_on_off); printf("%d; 54 Mmillfreeyes\n", Mmillfreeyes); printf("%.8f; 55 MMillToolFree\n", MMillToolFree); printf("%.8f; 56 MDimensionMillTool\n", MDimensionMillTool); printf("%d; 57 MInner_contour\n", MInner_contour); printf("%d; 58 CNCmillResolution\n", CNCmillResolution); printf("%d; 59 MillOnlyContour\n", MillOnlyContour); // 2011-03-10 printf("! *** Do not change the order of this lines *** !\n"); } string sinfo = info; string sinfotext = Infotext; info = "

"; Infotext = SaveInfo; dlgRedisplay(); wait(2); info = sinfo; Infotext = sinfotext; dlgRedisplay(); return; } void load_menu_values(string file) { string l[]; int n = fileread(l, file); n = 0; Device = l[n++]; // 0 SelectedDevice = strtol(l[n++]); // 1 LastSelectedDevice = SelectedDevice; MillToolOutl = strtod(l[n++]); // 2 MillToolIsolate = strtod(l[n++]); // 3 für Polygon-Isolate MillToolFree = strtod(l[n++]); // 4 SelectedLayer1 = strtol(l[n++]); // 5 SelectedLayer16 = strtol(l[n++]); // 6 DrillPad = strtod(l[n++]); // 7 DrillVia = strtod(l[n++]); // 8 DrillHole = strtod(l[n++]); // 9 OverlapOutlPercent = strtol(l[n++]); // 10 OverlapRubOutPercent = strtol(l[n++]); // 11 Distance_Copper_Dimension = strtod(l[n++]); // 12 DimensionMillTool = strtod(l[n++]); // 13 Millfreeyes = strtol(l[n++]); // 14 Holder_Spacing = strtod(l[n++]); // 15 Onlydrill = strtol(l[n++]); // 16 Generatedrills = strtol(l[n++]); // 17 Max_Drill_Diameter = round(strtod(l[n++]) * 10) / 10; // 18 Z_down = strtod(l[n++]); // 19 Drill_z_deep = strtod(l[n++]); // 20 Mill_z_safety = strtod(l[n++]); // 21 Spindle_rpm = strtol(l[n++]); // 22 Tool_vel = strtod(l[n++]); // 23 Fast_vel = strtod(l[n++]); // 24 Drill_Vel = strtod(l[n++]); // 25 DrillRefOn = strtol(l[n++]); // 26 DrillRefDiameter = strtod(l[n++]); // 27 DrillRefDeep = strtod(l[n++]); // 28 UseRack = strtol(l[n++]); // 29 SelectedPlusLayerTop = strtol(l[n++]); // 30 SelectedPlusLayerBot = strtol(l[n++]); // 31 Mirror_On = strtol(l[n++]); // 32 MachineMenuOn = strtol(l[n++]); // 33 ParkXposition = strtod(l[n++]); // 34 ParkYposition = strtod(l[n++]); // 35 ParkZposition = strtod(l[n++]); // 36 Z_dimension = strtod(l[n++]); // 37 Dim_on_off = strtol(l[n++]); // 38 Mz_down = strtod(l[n++]); // 39 Mdrill_z_deep = strtod(l[n++]); // 40 Mmill_z_safety = strtod(l[n++]); // 41 Mspindle_rpm = strtod(l[n++]); // 42 Mtool_vel = strtod(l[n++]); // 43 Mfast_vel = strtod(l[n++]); // 44 MDrill_Vel = strtod(l[n++]); // 45 MdrillRefOn = strtol(l[n++]); // 46 MdrillRefDiameter = strtod(l[n++]); // 47 MdrillRefDeep = strtod(l[n++]); // 48 MparkXposition = strtod(l[n++]); // 49 MparkYposition = strtod(l[n++]); // 50 MparkZposition = strtod(l[n++]); // 51 Mz_dimension = strtod(l[n++]); // 52 Mdim_on_off = strtol(l[n++]); // 53 Mmillfreeyes = strtod(l[n++]); // 54 MMillToolFree = strtod(l[n++]); // 55 MDimensionMillTool = strtod(l[n++]); // 56 MInner_contour = strtod(l[n++]); // 57 CNCmillResolution = strtod(l[n++]); // 58 // 2011-02-02 MillOnlyContour = strtol(l[n++]); // 59 // 2011-03-10 MOI = round((MillToolOutl + Inaccurateness) *1000) / 1000; // 2012-02-09 Problem bei vergleich von Realzahlen return; } // ** check if exist a control file ** void read_defaults(void) { string def_file = filesetext(argv[0], ".def"); string f[]; int n = fileglob(f, def_file); if (n) load_menu_values(def_file); return; } // *** first place a VIA outside the board with the same signal name // *** for used polygon to calculate the true Board-Outline (Dimesion) void generateTruePolygonOutlines(void) { // the true outlines of board board(B) { int temp_millMirr_Offset = MillMirr_Offset; if(SelectedLayer16 && ToMillLayer16) { if (Mirror_On) { MillMirr_Offset += MillMirr_Offset; // ** set mirror offset ** 2005-06-21 Mirror = -1.0; // *** Mirror flag for Layer 16 *** } else { MillMirr_Offset = 0; // ** reset mirror offset ** Mirror = 1.0; } } else if(SelectedLayer1 && ToMillLayer1) { MillMirr_Offset = 0; // ** reset mirror offset ** Mirror = 1.0; } if (Onlydrill) { // *** only export Drill Holes 2006-01-23 genDrills(); // generate Drill data output(MillFileName, "at") { // 2013-02-19 printf("\n#3354"); WriteHoles(OutlineMillSignalLayer); // generate Holes | 2008-12-05 new file == "wt" } } else { // *************************** genDrills(); // *** generate Drill data *** // *************************** MillMirr_Offset = temp_millMirr_Offset; // ** OK ** restore the origin value 2005-05-23 real x1 = u2mm(B.area.x1) - DimensionMillTool, y1 = u2mm(B.area.y1) - DimensionMillTool, x2 = u2mm(B.area.x2) + DimensionMillTool, y2 = u2mm(B.area.y2) + DimensionMillTool; DistanceDimension = DimensionMillTool - Distance_Copper_Dimension*2; // 2009-02-05 string h; if (DistanceDimension < 0) { DistanceDimension = 0; } string Cmd; sprintf(Cmd, "GRid mm FINEST;\n" "CHANGE DRILL 0.3;\nCHANGE DIAMETER 0.5;\nCHANGE SHAPE ROUND;\n" "SET POLYGON_RATSNEST ON;\n" "SET WIRE_BEND 0;\n" "CHANGE RANK 1;\n" // 2006-07-26 to generate the true outline of dimension "CHANGE POUR SOLID;\n" "CHANGE THERMAL OFF;\n" "DISPLAY NONE 17 %d;\n", OutlineMillSignalLayer ); // make the 1st temporary Net for Normal Polygon Orphans OFF // to generate the true outline for place the spacial polygon // make a partial VIA for generate Polygon with orphans off string millout; sprintf(millout, "VIA '%s' (%.8f %.8f);\nCHANGE LAYeR %d;\n", OutlineMillSignal, x1 - Distance_Copper_Dimension - 2, y1 - Distance_Copper_Dimension - 2, OutlineMillSignalLayer ); Cmd += millout; sprintf(millout, "CHANGE ISOLATE 0;\nCHANGE ORPHANS OFF;\n"); Cmd += millout; sprintf(millout, "CHANGE LAYEr %d;\n", OutlineMillSignalLayer); Cmd += millout; sprintf(millout, "POLYGON '%s' %.8f (%.8f %.8f) (%.8f %.8f)(%.8f %.8f);\nRATSNEST;\n", OutlineMillSignal, MillToolOutl, // 2008-11-12 tool#1 x1 - DimensionMillTool - Distance_Copper_Dimension - 4, y1 - DimensionMillTool - Distance_Copper_Dimension - 4, x2 + DimensionMillTool + Distance_Copper_Dimension + 4, // der Abstand muß größer sein damit das Umschliessende Polygon y2 + DimensionMillTool + Distance_Copper_Dimension + 4, // wirklich groß genug wird x1 - DimensionMillTool - Distance_Copper_Dimension - 4, y1 - DimensionMillTool - Distance_Copper_Dimension - 4 ); Cmd += millout; Cmd += "WINDOW FIT;\nSET WIRE_BEND 2;\n"; // 2011-09-28 wieder auf Diagonal schalten MillMirr_Offset = temp_millMirr_Offset; // restore the origin value 2013-04-30 Cmd += RUN_pass(PassDimensionPoly); if (test) if (viewtest("2008-11-12 *****************:", Cmd) != 0) exit(-3410); if (test) output(filesetext(B.name, "-cmd.txt"), "wtD") printf("%s", Cmd); exit(Cmd); } } } real wire_angle(int x1, int y1, int x2, int y2) { // real xa = u2mm(x2); real ya = u2mm(y2); real xe = u2mm(x1); real ye = u2mm(y1); real RADIUS = sqrt(((xa - xe) * (xa - xe)) + ((ya - ye) * (ya - ye))); if ((xa > xe) && (ya >= ye)) { /* Quadrant 1 */ return acos((xa - xe) / RADIUS) * 57.29578; } if ((xa < xe) && (ya >= ye)) { /* Quadrant 2 */ return acos((xa - xe) / RADIUS) * 57.29578; } if ((xa < xe) && (ya < ye)) { /* Quadrant 3 */ return 360 - acos((xa - xe) / RADIUS) * 57.29578; } if ((xa > xe) && (ya < ye)) { /* Quadrant 4 */ return 360 - acos((xa - xe) / RADIUS) * 57.29578; } if ((xa == xe) && (ya == ye)) { /* 0° */ return (xa - xe); } if ((xa == xe) && (ya > ye)) { /* 90° */ return (xa - xe + 90); } if ((xa == xe) && (ya < ye)) { /* 270° */ return (xa - xe + 270); } } void draw_contour(void) { // draw polygon contour 2006-02-14 if (SelectedDevice == devScript) printf("#3451 Polygon contour rechts-drehend!\n"); // only in Script DeviceDraw( Pcwx[0], Pcwy[0], Pcwx[1], Pcwy[1], First_line); for (int n = 1; n < Cntpcw-1; n++) { DeviceDraw( Pcwx[n], Pcwy[n], Pcwx[n+1], Pcwy[n+1], Middle_line); } DeviceDraw( Pcwx[n], Pcwy[n], Pcwx[0], Pcwy[0], Last_line); return; } // 2010-01-25 collect contour void collect_contour(int lx, int ly) { Pcwx[Cntpcw] = lx; Pcwy[Cntpcw] = ly; Cntpcw++; return; } string polycoord1(string polcoord) { // // 2012-03-09 string sp[]; int scnt = strsplit(sp, polcoord, ' '); if (!scnt) { dlgMessageBox("#3474 Fehler in polycoord1() string:"+polcoord, "OK"); exit(-3475); } return sp[1] + " " + sp[2]; // der String beginnt immer mit einem Space! } // ReservedOutlineSignalName string WriteOutlines( string SignalName, int Layer) { if (Layer == 16) { if (Mirror_On) { MillMirr_Offset += MillMirr_Offset; // ** set mirror offset ** 2005-05-21 Mirror = -1.0; // *** mirror flag for Layer 16 *** 2005-06-21 } else { MillMirr_Offset = 0; // ** set mirror offset ** 2005-06-21 Mirror = 1.0; } } else { MillMirr_Offset = 0; // ** set mirror offset ** 2005-06-21 Mirror = 1.0; } board(B) { string Cmd; B.signals(S) { if (S.name == SignalName && !Onlydrill) { S.polygons(P) { if (P.layer == Layer) { if (InPass2) DeviceReInit(Contour, Layer, "3462"); if (InPassPour) DeviceReInit(BlowUp_RubOut, Layer, "3463"); if (InPassOutmill) { if (test2) printf("\n#3507 jetzt holes bohren"); WriteHoles(OutlineMillSignalLayer); // zuerst bohren! DeviceReInit(DimensionLine, Layer, "3487"); if (test2) printf("\n#3509 jetzt aus Träger fräsen"); InPassPour = ""; // Reset pouring 2006-10-10 MillToolFree = 0.0; } int x1 = INT_MAX, y1 = INT_MAX, x2 = INT_MIN, y2 = INT_MIN; int x0, y0; int State; int first = 1; P.wires(W) { x1 = min(x1, W.x1); x2 = max(x2, W.x1); y1 = min(y1, W.y1); y2 = max(y2, W.y1); } // *** check more at one contours inside the board *** if (InPass2 || InPassPour || MillToolFree) { // 2011-02-02 auch wenn nur 1. Isolation int i = -1; int active; do { // 2020-01-25 use contour index active = 0; first = 1; Cntpcw = 0; // Reset polygon contour wiresegment counter P.contours(W, i) { // start milling polygon contours ** active = 1; if (first) { collect_contour( W.x1, W.y1); // count polygon contour wire collect_contour( W.x2, W.y2); // count polygon contour wire first = 0; } else collect_contour(W.x2, W.y2); } draw_contour(); i--; } while (active); if (MInner_contour || InPassPour) { // 2010-04-08 milling always contour of pooring i = 1; // draw also right rotation contours inside SIGNAL-Filling Polygon do { active = 0; first = 1; Cntpcw = 0; // Reset polygon contour wiresegment counter P.contours(W, i) { // start milling polygon contours ** active = 1; if (first) { collect_contour( W.x1, W.y1); // count polygon contour wire collect_contour( W.x2, W.y2); // count polygon contour wire first = 0; } else collect_contour(W.x2, W.y2); } draw_contour(); i++; } while (active); } if (InPassPour && Millfreeyes) { if (SelectedDevice == devScript) { printf("\n#3569 start pouring\n"); } DeviceReInit(BlowUp_RubOut, Layer, "3529"); int fx1[], fy1[], fx2[], fy2[], dir[], down[]; int fcnt = 0; P.fillings(F) { fx1[fcnt] = F.x1; fy1[fcnt] = F.y1; fx2[fcnt] = F.x2; fy2[fcnt] = F.y2; fcnt++; } int diry = fy1[0]; int m; for (m = 0; m < fcnt; m++) { if (diry == fy1[m]) { dir[m] = 0; } else { // ****** milling reverse ****** diry = fy1[m]; // set direction next y_line int mbx1[], mby1[], mbx2[], mby2[];; for (int mb = m; mb <= fcnt; mb++) { if (diry == fy1[mb]) { mbx1[mb] = fx1[mb]; mby1[mb] = fy1[mb]; mbx2[mb] = fx2[mb]; mby2[mb] = fy2[mb]; dir[mb] = -1; } else break; // Y is changed also change direction back } --mb; // *** OK for/break beendet bei counter +1 for(int mback = mb ; mback >= m; mback--) { // DeviceDraw(fx2[mback], fy2[mback], fx1[mback], fy1[mback], State); // reverse milling 2002-05-08 alf@cadsoft.de // swap array backward int xdif = mback - m; int nx = m + (mb - mback); fx1[nx] = mbx2[mback]; fy1[nx] = mby2[mback]; fx2[nx] = mbx1[mback]; fy2[nx] = mby1[mback]; } m = ++mb; // *** OK for beendet bei counter -1 diry = fy1[m]; // set direction next y_line } } // check X, if not changed do not lift up milling tool int downdist = MillToolFree * 10000 / 2; // tool radius for (m = 0; m < fcnt-1; m++) { int lx = abs(fx2[m] - fx1[m+1]); if (lx < downdist) { // *** do not lift up if distance < tool radius 2005-06-08 *** if (fy2[m] != fy1[m+1]) { // 2005-06-28 down[m] = 1; down[m+1] = 1; } } if (m) { int lx1 = abs(fx2[m-1] - fx1[m]); int lx2 = abs(fx2[m] - fx1[m+1]); if (lx1 < downdist && lx2 < downdist) { // *** do not lift up if distance < tool radius 2005-06-08 *** down[m]++; } } } // enum { First_line, Middle_line, Last_line, Drill_coord, One_line } State = One_line; int LastLine; for (m = 0; m < fcnt; m++) { if (Lift_Off) { switch(down[m]) { case 0 : State = One_line; break; case 1 : // 2005-06-28 if (State == First_line) { DeviceDraw(0, 0, fx1[m], fy1[m], Middle_line); State = Last_line; } else if (State == Last_line) State = First_line; else if (State == Middle_line) { DeviceDraw(0, 0, fx1[m], fy1[m], Middle_line); State = Last_line; } else if (State == One_line) State = First_line; break; case 2 : State = Middle_line; DeviceDraw(0, 0, fx1[m], fy1[m], State); break; } } if (test) if (SelectedDevice == devScript) printf("#test m %d\n", m); // nur zum testen mit SCRIPT !!! 2005-06-24 DeviceDraw(fx1[m], fy1[m], fx2[m], fy2[m], State); } } } // start board out milling // nur die berechnete Kontur zum ausfräsen aus dem Träger ausgeben. // if (InPassOutmill) { // ReservedOutlineSignalName == "~_REAL_OUTLINEMILL_~") int pw1x, pw1y; P.wires(W) { pw1x = W.x1; pw1y = W.y1; } int countContourP = 0; // 2011-10-04 int countContourN = 0; int ip = 0; int in = 0; int active; do { countContourP = 0; P.contours(W, ip) { countContourP = 1; break; } if (countContourP) ip++; else break; } while (ip); countContourP = ip-1; // 2011-10-04 do not draw defined polygon contour // the last polygonoutline ist the defined outline do { countContourN = 0; P.contours(W, in) { countContourN = 1; break; } if (countContourN) in--; else break; } while (in); countContourN = in; first = 1; // printf("M999 die Platine aus dem Träger fräsen.\n"); //**** 2011-10-04 int i = -1; // draw left rotation contours inside SIGNAL-Filling Polygon active; do { if (i == countContourN) break; active = 0; first = 1; Cntpcw = 0; // Reset polygon contour wire segment counter P.contours(W, i) { // start milling polygon contours ** active = 1; if (first) { collect_contour( W.x1, W.y1); // count polygon contour wire collect_contour( W.x2, W.y2); // count polygon contour wire first = 0; } else collect_contour(W.x2, W.y2); } draw_contour(); i--; } while (active); i = 1; // draw right rotation contours inside SIGNAL-Filling Polygon do { if (i == countContourP) break; active = 0; first = 1; Cntpcw = 0; // Reset polygon contour wiresegment counter P.contours(W, i) { // start milling polygon contours ** active = 1; if (first) { collect_contour( W.x1, W.y1); // count polygon contour wire collect_contour( W.x2, W.y2); // count polygon contour wire first = 0; } else collect_contour(W.x2, W.y2); } draw_contour(); i++; } while (active); //**** 2011-10-04 } // end of board out milling } break; } } } return Cmd; } } // *** Pen assign *** void toolAssign(void) { set_tool_rack(); dlgDialog("Mill outlines - Tool Assignment") { dlgHBoxLayout dlgSpacing(300); switch (SelectedDevice) { case devScript : dlgLabel(Script_Used); dlgHBoxLayout { dlgVBoxLayout dlgSpacing(400); dlgVBoxLayout { dlgLabel("Drill Rack"); dlgTextView(Tool_Rack_string); } } if (Drilltoolsplus) { dlgHBoxLayout { dlgTextView(Drilltoolsplus + "! This drills are milling !"); } } break; case devHPGL : dlgHBoxLayout { dlgVBoxLayout dlgSpacing(400); dlgVBoxLayout { dlgLabel("PEN definition #3777"); dlgTextView(Tool_Rack_string); } } if (Drilltoolsplus) { dlgHBoxLayout { dlgTextView(Drilltoolsplus + "! This drills are milling !"); } } break; case devISEL : dlgHBoxLayout { dlgVBoxLayout dlgSpacing(400); dlgVBoxLayout { dlgLabel("Drill Rack"); dlgTextView(Tool_Rack_string); } } if (Drilltoolsplus) { dlgHBoxLayout { dlgTextView(Drilltoolsplus + "! This drills are milling !"); } } break; case devCNC : dlgHBoxLayout { dlgVBoxLayout dlgSpacing(400); dlgVBoxLayout { dlgLabel("Drill Rack"); dlgTextView(Tool_Rack_string); } } if (Drilltoolsplus) { dlgHBoxLayout { dlgTextView(Drilltoolsplus + "! This drills are milling !"); } } break; default : dlgLabel("No device selected!
"); break; } dlgHBoxLayout { dlgStretch(0); dlgPushButton("+OK") dlgAccept(); dlgStretch(1); } }; return; } void selectDevice(void) { Xfile = filesetext(MillFileName, DeviceExt[SelectedDevice]); switch (SelectedDevice) { case devScript : info = Showpic[13]; zinfo = Showpic[13]; if (language() == "de") { Infotext = "
Erzeugt Fräswege als Eagle-SCRIPT
und liest das Script in das Board ein.
" + "Der Ziel-Layer ist der Layer 101 bzw. 116 für die Isolation.

" + "Layer 102 / 117 für das Freifräsen (Pouring).
" + "Layer 103 / 118 für die Aussenkontur (Dimension).
" + "Layer 144 für die Drills (PAD/VIA).
" "Layer 145 für die Holes."; // 2013-02-27 } else { Infotext = "Generate the milling tracks in to a Eagle SCRIPT
" "and read this script in to the Board.
" + "The target layer is the layer 101 respectively 116.

" + "Layer 102 / 117 to read copper pouring milling.
" + "Layer 103 / 118 to read real outlines milling (Dimension).
" "Layer 144 to read drills (PAD/VIA).
" "Layer 145 to read holes."; // 2013-02-27 } DrillLabel = "Drill file"; if (LastSelectedDevice != devScript && LastSelectedDevice != devHPGL) { // 2006-02-15 Mz_down = Z_down; Mdrill_z_deep = Drill_z_deep; Mmill_z_safety = Mill_z_safety; Mspindle_rpm = Spindle_rpm; Mtool_vel = Tool_vel; Mfast_vel = Fast_vel; MDrill_Vel = Drill_Vel; MdrillRefOn = DrillRefOn; MdrillRefDeep = DrillRefDeep; MparkXposition = ParkXposition; MparkYposition = ParkYposition; MparkZposition = ParkZposition; Mz_dimension = Z_dimension; } Z_down = 0; Drill_z_deep = 0; Mill_z_safety = 0; Spindle_rpm = 0; Tool_vel = 0; Fast_vel = 0; Drill_Vel = 0; ParkXposition = 0; ParkYposition = 0; ParkZposition = 0; Z_dimension = 0; LastSelectedDevice = devScript; Machineparameter = "Not used for SCRIPT"; break; case devHPGL : info = Showpic[14]; if (language() == "de") { Infotext = "Generiert die Daten (Fräswege) als HPGL Datei.
" + "PEN #8 ist reserviert zum wechseln der Platine
" + "Vorder - Rückseite (spiegeln).
"; DrillLabel = "Drills in HPGL Datei enthalten"; } else { Infotext = "Generate the milling tracks as HPGL file.
" + "PEN #8 is reserved for switch pcb to milling second side.
"; DrillLabel = "HPGL file include drills"; } if (LastSelectedDevice != devScript && LastSelectedDevice != devHPGL) { // 2006-02-15 Mz_down = Z_down; Mdrill_z_deep = Drill_z_deep; Mmill_z_safety = Mill_z_safety; Mspindle_rpm = Spindle_rpm; Mtool_vel = Tool_vel; Mfast_vel = Fast_vel; MDrill_Vel = Drill_Vel; MdrillRefOn = DrillRefOn; MdrillRefDeep = DrillRefDeep; MparkXposition = ParkXposition; MparkYposition = ParkYposition; MparkZposition = ParkZposition; Mz_dimension = Z_dimension; } Z_down = 0; Drill_z_deep = 0; Mill_z_safety = 0; Spindle_rpm = 0; Tool_vel = 0; Fast_vel = 0; Drill_Vel = 0; ParkXposition = 0; ParkYposition = 0; ParkZposition = 0; Z_dimension = 0; LastSelectedDevice = devHPGL; Machineparameter = "Not used for HPGL"; break; case devISEL : info = Showpic[23]; if (language() == "de") { Infotext = "Generiert die Daten (Fräswege) als ISEL Zwischenformat."; DrillLabel = "Drills in ISEL Datei enthalten"; } else { Infotext = "Generate the milling tracks as ISEL intermediate format file."; DrillLabel = "ISEL file include drils"; } if (LastSelectedDevice == devScript || LastSelectedDevice == devHPGL) { // 2006-02-15 Z_down = Mz_down; Drill_z_deep = Mdrill_z_deep; Mill_z_safety = Mmill_z_safety; Spindle_rpm = Mspindle_rpm; Tool_vel = Mtool_vel; Fast_vel = Mfast_vel; Drill_Vel = MDrill_Vel; DrillRefOn = MdrillRefOn; DrillRefDeep = MdrillRefDeep; ParkXposition = MparkXposition; ParkYposition = MparkYposition; ParkZposition = MparkZposition; Z_dimension = Mz_dimension; } LastSelectedDevice = devISEL; Machineparameter = "Use for ISEL"; break; case devCNC : info = Showpic[24]; if (language() == "de") { Infotext = "Generiert die Daten (Fräswege) als CNC Datei."; DrillLabel = "Drills in CNC Datei enthalten"; } else { Infotext = "Generate the milling tracks as CNC file."; DrillLabel = "CNC file include drills"; } if (LastSelectedDevice == devScript || LastSelectedDevice == devHPGL) { // 2006-02-15 Z_down = Mz_down; Drill_z_deep = Mdrill_z_deep; Mill_z_safety = Mmill_z_safety; Spindle_rpm = Mspindle_rpm; Tool_vel = Mtool_vel; Fast_vel = Mfast_vel; Drill_Vel = MDrill_Vel; DrillRefOn = MdrillRefOn; DrillRefDeep = MdrillRefDeep; ParkXposition = MparkXposition; ParkYposition = MparkYposition; ParkZposition = MparkZposition; Z_dimension = Mz_dimension; } LastSelectedDevice = devCNC; Machineparameter = "Use for CNC"; break; default : info = Showpic[21]; Infotext = "
No device selected!
"; Xfile = ""; DrillLabel = "D&rill file"; Mz_down = Z_down; Mdrill_z_deep = Drill_z_deep; Mmill_z_safety = Mill_z_safety; Mspindle_rpm = Spindle_rpm; Mtool_vel = Tool_vel; Mfast_vel = Fast_vel; MDrill_Vel = Drill_Vel; MdrillRefOn = DrillRefOn; MdrillRefDeep = DrillRefDeep; Z_down = 0; Drill_z_deep = 0; Mill_z_safety = 0; Spindle_rpm = 0; Tool_vel = 0; Fast_vel = 0; Drill_Vel = 0; ParkXposition = MparkXposition; ParkYposition = MparkYposition; ParkZposition = MparkZposition; Z_dimension = Mz_dimension; Z_dimension = 0; Machineparameter = "Not used"; break; } return; } // *** the milling offset, if reference package placed *** void setMillOffset(void) { board(B) { Path = filedir(B.name); B.elements(E) { if (E.package.name == Ref_pac) { Ref_offsetX[Ref_cnto] = E.x; Ref_offsetY[Ref_cnto] = E.y; Ref_cnto++; E.package.circles(C) { if (C.layer == 45) { Ref_offsetX[Ref_cnto] = C.x; Ref_offsetY[Ref_cnto] = C.y; Ref_cnto++; } } if (Ref_cnto == 3) { // *** a reference package is found *** // *** OK 2005-05-12 *** Ref_null_offsetY = abs(Ref_offsetY[0]); Mill_OffsetX = abs(Ref_offsetX[0]); MillMirr_Offset = abs(Ref_offsetX[0]) + ((Ref_offsetX[1] + Ref_offsetX[2]) / 2); if (language() == "de") sprintf(Mirror_axis, "Spiegeloffset (0 0) %.8f / Spiegelachse (0 0) %.8f mm", u2mm(MillMirr_Offset), u2mm(MillMirr_Offset - Mill_OffsetX) ); else sprintf(Mirror_axis, "Mirror offset (0 0) %.8f / Mirror axis (0 0) %.8f mm", u2mm(MillMirr_Offset), u2mm(MillMirr_Offset - Mill_OffsetX) ); } else { Ref_cnto = 0; // more then 2 circles can't use as reference if (language() == "de") { if (dlgMessageBox("Das Referenzpackage enthält mehr als 2 Kreise im Layer 45,
" + "die Fräsdaten werden nicht auf den Nullpunkt der Anlage bezogen berechnet.", ACCEPT, CANCEL) != 0) exit(0); } else { if (dlgMessageBox("The reference Hole-Package contains more then 2 Circles in Layer 45\n" + "generate outlines without reference-offset", ACCEPT, CANCEL) != 0) exit(0); } } } } } return; } void mirror_info(void) { if (Mirror_On) Infotext = INFOmirror1; else Infotext = INFOmirror0; return; } void layer_info(void) { if (SelectedLayer1 && SelectedLayer16) { Infotext = INFOtext1_on + "

" + INFOtext16_on; } else if (!SelectedLayer1 && !SelectedLayer16) { info = ""; Infotext = "Kein Layer gewählt!"; } else if (SelectedLayer1 && !SelectedLayer16) { Infotext = INFOtext1_on + "

" + INFOtext16_off; } else if (!SelectedLayer1 && SelectedLayer16) { Infotext = INFOtext1_off + "

" + INFOtext16_on; } return; } void setblowinfo(void) { if (MillToolFree) { if (Millfreeyes) { info = Showpic[18]; if (Millfreeyes && !MillToolFree) Infotext = MILLfreeYes; else Infotext = TOOLdiamBlow; } else { info = Showpic[20]; Infotext = TOOLdiamRub; } } else { if(Millfreeyes) { info = Showpic[21]; // Question? Infotext = MILLfreeYes; } else { info = Showpic[19]; // No second isolate grey Infotext = MILLfreeNo; } } return; } void checkDimension(UL_BOARD B) { B.layers(L) { if (L.number == 20) { if (L.used) return; dlgMessageBox(MissingDimension, "OK"); exit(-4121); } } } void dlg_PlaceVia(void) { // 2010-08-04 dlgMessageBox kann keine Bitmaps mit Texten gemixt als String anzeigen. dlgDialog("mill-outlines place VIA") { dlgLabel(Showpic[22]); dlgLabel(INFOinnerContour); dlgHBoxLayout { dlgStretch(1); dlgPushButton("PlaceVIA") { dlgAccept(); exit ("VIA '~_REAL_OUTLINEMILL_~'"); } dlgPushButton(CANCEL) dlgReject(); dlgStretch(1); } }; return; } // *************** // Main program: // *************** if (!argv[1]) { board(B) drufile = filesetext(B.name , ".dru"); string cmd ="DRC SAVE '"+drufile+"'; RUN '"+argv[0]+"' DRCsaved"; exit(cmd); // 2012-01-16 immer Design-Regeln aktuell speichern } setMillOffset(); // get info if special package placed // get Command-Line parameter if use RUN if (argv[1]) { if (argv[1] == "DRCsaved") ; // 2012-01-16 else { Device = argv[1]; if (argv[2]) { MillToolOutl = strtod(argv[2]); if (MillToolOutl <= 0) { if (language() == "de") { Fatal("Falscher Durchmesser für das Isolieren (tool #1): " + argv[2], "Der Durchmesser grösser als 0 sein."); } else { Fatal("Illegal diameter for milling tool #1: " + argv[2], "The diameter must be greater than zero."); } } MillToolIsolate = strtod(argv[3]); // für Polygon Isolate MillToolFree = strtod(argv[4]); SelectedLayer1 = strtol(argv[5]); ToMillLayer1 = strtol(argv[6]); SelectedLayer16 = strtol(argv[7]); ToMillLayer16 = strtol(argv[8]); MillFileName = argv[9]; if (argv[10] == PassDimensionPoly) { InPassDimensionPoly = argv[10]; // 1. generate true outlines } else if (argv[10] == Pass2) { InPass2 = argv[10]; // 2. smal isolate } else if (argv[10] == PassPour) { InPassPour = argv[10]; // 3. wide isolate plus pouring } else if (argv[10] == PassOutmill) { InPassOutmill = argv[10]; // 4. milling out from big material } else { dlgMessageBox("! argv[11] unknown!\n" + argv[10], "OK"); exit(-4190); } DrillPad = strtod(argv[11]); DrillVia = strtod(argv[12]); DrillHole = strtod(argv[13]); OverlapOutlPercent = strtol(argv[14]); OverlapRubOutPercent = strtol(argv[15]); Distance_Copper_Dimension = strtod(argv[16]); DimensionMillTool = strtod(argv[17]); Millfreeyes = strtol(argv[18]); Holder_Spacing = strtod(argv[19]); Onlydrill = strtol(argv[20]); Generatedrills = strtol(argv[21]); TrueOutline_coordinate = argv[22]; OutlineMillSignalLayer = strtol(argv[23]); Max_Drill_Diameter = round(strtod(argv[24]) * 10) / 10; UseRack = strtol(argv[25]); SelectedPlusLayerTop = strtol(argv[26]); SelectedPlusLayerBot = strtol(argv[27]); Mirror_On = strtol(argv[28]); Dim_on_off = strtol(argv[29]); MInner_contour = strtol(argv[30]); CNCmillResolution = strtol(argv[31]); // 2011-02-02 Mill_z_safety = strtod(argv[32]); Drill_z_deep = strtod(argv[33]); Z_down = strtod(argv[34]); Z_dimension = strtod(argv[35]); MillOnlyContour = strtol(argv[36]); // 2011-03-10 GridDistance = strtod(argv[37]); GridUnit = strtol(argv[38]); GridUnitdist = strtol(argv[39]); // 2013-03-05 InitDone = strtol(argv[40]); // 2013-04-18 // check parameters if (!SelectedLayer1 && !SelectedLayer16) Fatal("Illegal layer: " + argv[5] + " /" + argv[6], "The layer(s) must be 1 or/and 16."); if (Generatedrills) { // wenn keine Drills erzeugt werden, // muß auch die Gültigkeit nicht abgefragt werden 2006-01-26 if (DrillPad <= 0) { if (language() == "de") { Fatal("Verbotener Bohrdurchmasser für Pad: " + argv[10], "Der diameter muß größer als 0 sein."); } else { Fatal("Illegal diameter for Pad drill tool: " + argv[10], "The diameter must be greater than zero."); } } if (DrillVia <= 0) { if (language() == "de") { Fatal("Verbotener Bohrdurchmasser für Via: " + argv[11], "Der diameter muß größer als 0 sein."); } else { Fatal("Illegal diameter for Via drill tool: " + argv[11], "The diameter must be greater than zero."); } } if (DrillHole <= 0) { if (language() == "de") { Fatal("Verbotener Bohrdurchmasser für Hole: " + argv[12], "Der diameter muß größer als 0 sein."); } else { Fatal("Illegal diameter for Hole drill tool: " + argv[12], "The diameter must be greater than zero."); } } } } } } if (!MillFileName) board(B) MillFileName = filesetext(B.name, DefaultSuffix); if (Device) { ValueInit(); int n; while (DeviceNames[n]) { // upper case if (strupr(DeviceNames[n]) == strupr(Device)) { SelectedDevice = n; break; } n++; } if (!SelectedDevice) { if (language() == "de") { Fatal("Kein Device gewählt: " + Device, "Wählen Sie ein gültiges Device."); } else { Fatal("Illegal device: " + Device, "Please select one of the known devices."); } } } // ******** main menu ******** if ( !InPass2 && !InPassPour && !InPassOutmill && !InPassDimensionPoly) { int ForceDialog = (!Device || !MillToolOutl); board(B) { checkDimension(B); int n; string del_pol; B.signals(S) { if (S.name == ReservedOutlineSignalName) { // 2008-11-12 if exist reseved polygon, first delete S.polygons(POL) { POL.wires(W) { sprintf(del_pol, "GriD MM;\nDELETE (S %.8f %.8f);", u2mm(W.x1), u2mm(W.y1) ); break; } break; } if (language() == "de") { if (Error("Es existiert ein Signal " + ReservedOutlineSignalName + " in dem Board!", "Dieser Signalname ist für das ULP reserviert!
Stellen Sie sicher das kein Signal mit diesem Namen im Layout benutzt wird.
", "OK", "Delete") != 0) exit(del_pol); exit(-4303); } else { Fatal("There is already a signal named " + ReservedOutlineSignalName + " in this board!", "Please make sure that there is no such signal in this board."); } } // *** Check if used Rank 6 - 2006-07-26 *** string s; int is_polygon = 0; S.polygons(P) { is_polygon++; if (P.rank == 6) { P.contours(W) { if (language() == "de") { sprintf(s, "!%s Polygon in Layer %d an (%.8f %.8f)mm hat Rank 6.\n\nBenutzen Sie nicht Rank 6 wenn Sie dieses ULP nutzen.\n" + "Prüfen Sie die Ranks 1..5 bevor Sie dieses ULP nochmal starten.", S.name, P.layer, u2mm(W.x1), u2mm(W.y1) ); } else { sprintf(s, "!%s Polygon in Layer %d at (%.8f %.8f)mm has Rank 6.\n\nDo not use Rank 6 while working with this ULP.\n" + "Change the rank to 1..5 before using this ULP again.", S.name, P.layer, u2mm(W.x1), u2mm(W.y1) ); } break; } dlgMessageBox(s, "OK"); exit(0); } } Class_used[S.class.number]++; } if (!SelectedLayer1 && !SelectedLayer16) { ForceDialog = 1; } // ******************* int fault; if (ForceDialog) { GridDistance = B.grid.distance; // argv[37] GridUnit = B.grid.unit; // argv[38] GridUnitdist = B.grid.unitdist; // argv[39] 2013-03-05 SelectedDevice = Defaultdevice; // overwritten by load_menu_values() string plus_Text[] = { "none" }; int cnt_plusText = 1; B.layers(L) { if (L.used) { sprintf(plus_Text[L.number], "%2d %s", L.number, L.name); ++cnt_plusText; } else { sprintf(plus_Text[L.number], "%2d nu", L.number); } if (L.number == 1 && L.visible && L.used) { SelectedLayer1 = 1; sprintf(Layer1, "%d %s", L.number, L.name); } if (L.number == 16 && L.visible && L.used) { SelectedLayer16 = 16; sprintf(Layer16, "%d %s", L.number, L.name); } } read_defaults(); // 2012-01-13 string dru_file = get_DesignRules(B.name); // 2006-11-08 / 2012-02-09 read the CopperDimension value from Designrules // check CLASS and change if not enuff string chclass = checkClassClear(B); if (chclass) { chclass += "\n CLASS\n"; exit(chclass); // 2012-01-16 return CLASS definition } get_rack(B); // collect Rackdata for drilling machine get_drills(B); // collect Drilldata for drilling Pad and Via selectDevice(); // 2005-05-18 *** set the default device and filenames *** if (!Distance_Copper_Dimension) { if (language() == "de") { dlgMessageBox("!Benutzen Sie nicht den Wert 0, für Distance Copper/Dimension
ULP gestoppt!", "OK"); } else { dlgMessageBox("!Do not use zero for Distance Copper/Dimension\nULP Stoped!", "OK"); } exit("DRC"); } if (DRC_changed) { string h; sprintf(h, "%s\nSet all %d values to tool diameter #1 + %.8f = %.8f mm ?", DRC_changed_message, DRC_changed, Inaccurateness, MillToolOutl + Inaccurateness ); dlgDialog("Design Rules") { dlgLabel(h); // 2020-10-28 dlgHBoxLayout { dlgPushButton("+"+YES) dlgAccept(); dlgPushButton("Change Tool #1") { // 2012-01-25 DRC_changed = 0; MillToolOutl = minDistWireWire - Inaccurateness; Clearance_check = ""; // reset clearance check save_defaults(); dlgAccept(); } dlgStretch(1); } }; output(drufile, "wt") { for (int n = 0; n < DRUlcnt; n++) { printf("%s\n", DRUvalues[n]); } } if (test) dlgMessageBox("Jetzt werden die Design-Reglen geladen und wieder gespeichert", "OK"); if (DRC_changed) exit("SET Interface.PreferredUnit 2;\nDRC LOAD '"+drufile+"';\n DRC SAVE '"+drufile+"';\nDRC;\n RUN '" + argv[0]+"'"); } if (Clearance_check) { fault = Error(Error5, "" + Clearance_check + "", "Change &Tool #1", DRCCHECK); // [Change &Tool #1] 2012-01-20 if (fault) exit("CLASS"); } Showpic[0] = ""; Showpic[1] = ""; Showpic[2] = ""; Showpic[3] = ""; Showpic[4] = ""; Showpic[5] = ""; Showpic[6] = ""; Showpic[7] = ""; Showpic[8] = ""; Showpic[9] = ""; Showpic[10] = ""; Showpic[11] = ""; Showpic[12] = ""; Showpic[13] = ""; Showpic[14] = ""; Showpic[15] = ""; Showpic[16] = ""; Showpic[17] = ""; Showpic[18] = ""; Showpic[19] = ""; Showpic[20] = ""; Showpic[21] = ""; Showpic[22] = ""; Showpic[23] = ""; Showpic[24] = ""; Showpic[25] = ""; Showpic[26] = ""; Showpic[27] = ""; Showpic[28] = ""; Showpic[29] = ""; Showpic[30] = ""; Showpic[31] = ""; Showpic[32] = ""; Showpic[33] = ""; // 2011-02-07 Nullpunkt des Board = Maschinennullpunkt Showpic[34] = ""; Showpic[35] = ""; Showpic[36] = ""; // 2010-01-25 inner/outer polygon contour Showpic[37] = ""; Showpic[38] = ""; // 2011-02-02 Auflösung Vor- Nachkommastellen Showpic[39] = ""; // 2011-02-11 info = Showpic[10]; zinfo = Showpic[24]; zInfotext = Z_Machine_Menu; if (Mill_OffsetX) { Infotext = DRCinfo; } else { Infotext = REFinfo2 + DRCinfo; } Xfile = MillFileName; string sDistance_Copper_Dimension; sprintf(sDistance_Copper_Dimension, "%.6f mm", Distance_Copper_Dimension); selectDevice(); if (Ref_cnto == 3) { if (dlgMessageBox(InfoREFPack+"

Option Mill Board/Dim = On?", YES, NO) != 0) { // 2013-04-19 Ausfräsen aus Träger, trotzt Fangzapfen? Dim_on_off = 0; // wenn ein Refpackage platziert ist, darf die Aussenkontur eventuell nicht gefräst werden, // denn sonst würde/könnte der Fräser die Haltestifte durchfräsen und dabei zerstört werden. // 2011-02-09 } } dlgDialog(Header) { dlgTabWidget { dlgTabPage("General") { dlgHBoxLayout { dlgGridLayout { dlgCell( 0, 0) dlgLabel("&Device"); dlgCell( 0, 1) dlgComboBox(DeviceNames, SelectedDevice) selectDevice(); dlgCell( 0, 3) dlgLabel(LayerStack); // 2012-01-16 dlgCell( 0, 4) dlgPushButton("Tool &Assignment") toolAssign(); dlgCell( 1, 4) dlgCheckBox("&Gen. drills", Generatedrills) { info = Showpic[7]; if (Generatedrills) { Infotext = GENdrilON; DrillPad = MDrillPad; DrillVia = MDrillVia; DrillHole = MDrillHole; } else { Infotext = GENdrilOFF; MDrillPad = DrillPad; MDrillVia = DrillVia; MDrillHole = DrillHole; DrillPad = 0; DrillVia = 0; DrillHole = 0; } } dlgCell( 2, 4) dlgCheckBox("Use rac&k", UseRack) { info = Showpic[6]; if (!UseRack) { Infotext = USErackOFF; } else { Infotext = USErackON; } } dlgCell( 3, 4) dlgCheckBox("Onl&y Drills ", Onlydrill) { if (Onlydrill) { Generatedrills = 1; info = Showpic[7]; Infotext = OnlyDrillHpgl; DrillPad = MDrillPad; DrillVia = MDrillVia; DrillHole = MDrillHole; MMillToolOutl = MillToolOutl; MillToolOutl = 0; MOverlapOutlPercent = OverlapOutlPercent; OverlapOutlPercent = 0; MMillToolFree = MillToolFree; MillToolFree = 0; MOverlapRubOutPercent = OverlapRubOutPercent; OverlapRubOutPercent = 0; Mmillfreeyes = Millfreeyes; Millfreeyes = 0; MDimensionMillTool = DimensionMillTool; DimensionMillTool = 0; Mdim_on_off = Dim_on_off; Dim_on_off = 0; MHolder_Spacing = Holder_Spacing; Holder_Spacing = 0; } else { MillToolOutl = MMillToolOutl; OverlapOutlPercent = MOverlapOutlPercent; MillToolFree = MMillToolFree; OverlapRubOutPercent = MOverlapRubOutPercent; Millfreeyes = Mmillfreeyes; DimensionMillTool = MDimensionMillTool; Holder_Spacing = MHolder_Spacing; Dim_on_off = Mdim_on_off; } } dlgCell( 1, 1) dlgHBoxLayout { dlgLabel("Layer "); dlgCheckBox("Top ", SelectedLayer1) { info = ""; layer_info(); } dlgStretch(1); } dlgCell( 1, 3) dlgHBoxLayout { dlgLabel("plus Layer"); dlgComboBox(plus_Text, SelectedPlusLayerTop) { info = ""; Infotext = TextInfoPlus; } dlgStretch(1); } dlgCell( 2, 0) dlgHBoxLayout { dlgCheckBox("&Mirror ", Mirror_On) { if (Mirror_On) info = ""; else info = ""; mirror_info(); } dlgStretch(1); } dlgCell( 2, 1) dlgHBoxLayout { dlgLabel("Layer "); dlgCheckBox("Bottom ", SelectedLayer16) { info = ""; layer_info(); } dlgStretch(1); } dlgCell( 2, 3) dlgHBoxLayout { dlgLabel("plus Layer"); dlgComboBox(plus_Text, SelectedPlusLayerBot) { info = ""; Infotext = TextInfoPlus; } dlgStretch(1); } dlgCell( 3, 0) dlgLabel("Tool#&1 Isolate"); dlgCell( 3, 1) dlgRealEdit(MillToolOutl, 0.005, 3.0); // 2007-10-08 min. 5 micron wg. Laser dlgCell( 3, 2) dlgLabel("mm "); dlgCell( 3, 3) dlgPushButton("Isolate Info") { info = Showpic[1]; Infotext = TOOLdiamIso + "
" + DRC_checked + INFOInaccurat; } dlgCell( 4, 0) dlgLabel("Milling"); dlgCell( 4, 1) dlgCheckBox("inner &contour", MInner_contour) { if (MInner_contour) info = Showpic[37]; //2010-01-25 else info = Showpic[36]; //2010-01-25 Infotext = Mill_mInner_contour; } dlgCell( 4, 2) dlgLabel("On/Off"); dlgCell( 4, 3) dlgPushButton("Contour Info") { if (MInner_contour) info = Showpic[37]; //2010-01-25 else info = Showpic[36]; //2010-01-25 Infotext = Mill_mInner_contour; } dlgCell( 5, 0) dlgLabel("Overlap\nisolate/blo&w-up"); dlgCell( 5, 1) dlgIntEdit(OverlapOutlPercent, 0, 99); dlgCell( 5, 2) dlgLabel("%"); dlgCell( 5, 3) dlgPushButton("Overlap Info") { info = Showpic[2]; Infotext = OVERlapIso; } dlgCell( 6, 0) dlgLabel("Tool#&2 blow-up"); dlgCell( 6, 1) dlgRealEdit(MillToolFree, 0.0, 10); dlgCell( 6, 2) dlgLabel("mm"); dlgCell( 6, 3) dlgCheckBox("Rub &out", Millfreeyes) { //Mmillfreeyes = Millfreeyes; if (Millfreeyes) { MillToolFree = MMillToolFree; OverlapOutlPercent = MOverlapOutlPercent; OverlapRubOutPercent = MOverlapRubOutPercent; } else { MOverlapRubOutPercent = OverlapRubOutPercent; //OverlapRubOutPercent = 0; MMillToolFree = MillToolFree; // 2006-01-26 //MillToolFree = 0; } setblowinfo(); } dlgCell( 7, 0) dlgLabel("Overlap rub-o&ut"); dlgCell( 7, 1) dlgIntEdit(OverlapRubOutPercent, 0, 99); dlgCell( 7, 2) dlgLabel("%"); dlgCell( 7, 3) dlgPushButton("Overlap Info") { info = Showpic[4]; Infotext = OVERlapRubOut; } dlgCell( 8, 0) dlgLabel("&Pad drill"); dlgCell( 8, 1) dlgRealEdit(DrillPad, 0.0, 10); dlgCell( 8, 2) dlgLabel("mm"); dlgCell( 8, 3) dlgPushButton("Pad Info") { info = Showpic[5]; Infotext = PADdrildiam; } dlgCell( 9, 0) dlgLabel("&Via drill"); dlgCell( 9, 1) dlgRealEdit(DrillVia, 0.0, 10); dlgCell( 9, 2) dlgLabel("mm "); dlgCell( 9, 3) dlgPushButton("Via Info") { info = Showpic[6]; Infotext = VIAdrilldiam; } dlgCell(10, 0) dlgLabel("&Hole drill"); dlgCell(10, 1) dlgRealEdit(DrillHole, 0.0, 10); dlgCell(10, 2) dlgLabel("mm "); dlgCell(10, 3) dlgPushButton("Hole Info") { info = Showpic[7]; Infotext = HOLEdrildiam; } dlgCell(11, 0) dlgLabel("Max. drill diam "); dlgCell(11, 1) dlgRealEdit(Max_Drill_Diameter); dlgCell(11, 2) dlgLabel("mm "); dlgCell(11, 3) dlgPushButton("Max. Info") { info = Showpic[7]; Infotext = INFOmaxdrill; } dlgCell(12, 0) dlgLabel("Dist. Copper/Dim"); dlgCell(12, 1) dlgLabel(sDistance_Copper_Dimension); dlgCell(12, 3) dlgPushButton("Distance Info") { info = Showpic[10]; Infotext = DRCinfo; } dlgCell(13, 0) dlgLabel("Mill Board/D&im"); dlgCell(13, 1) dlgRealEdit(DimensionMillTool, 0.0, 5); dlgCell(13, 2) dlgLabel("mm "); dlgCell(13, 3) dlgHBoxLayout { dlgCheckBox("On&/Off", Dim_on_off) { info = Showpic[16]; if (Dim_on_off) { if (Ref_cnto == 3) { if (dlgMessageBox(InfoREFPack, YES, NO) != 0) { MDimensionMillTool = DimensionMillTool; DimensionMillTool = 0; // 2006-01-26 Dim_on_off = 0; Mdim_on_off = Dim_on_off; MHolder_Spacing = Holder_Spacing; Holder_Spacing = 0; Infotext = DIMmiltoolOFF; } else { // Dim_on_off = 1; DimensionMillTool = MDimensionMillTool; Mdim_on_off = Dim_on_off; Holder_Spacing = MHolder_Spacing; Infotext = DIMmiltoolON; } } DimensionMillTool = MDimensionMillTool; Mdim_on_off = Dim_on_off; Holder_Spacing = MHolder_Spacing; Infotext = DIMmiltoolON; } else { MDimensionMillTool = DimensionMillTool; DimensionMillTool = 0; // 2006-01-26 Mdim_on_off = Dim_on_off; MHolder_Spacing = Holder_Spacing; Holder_Spacing = 0; Infotext = DIMmiltoolOFF; } } dlgCheckBox("mill. only Dim.", MillOnlyContour) { // 2011-03-10 if (MillOnlyContour) { info = Showpic[16]; Infotext = "Nur Konturfräsen aus dem Träger.!
" + "Option Gen. drill wurde abgewählt!"; Holder_Spacing = 0; Generatedrills = 0; Dim_on_off = 1; } else { info = Showpic[0]; Infotext = "Aktivieren Sie evtl. weitere benötigte Optionen!"; } } } dlgCell(14, 0) dlgLabel("Holde&r spacing"); dlgCell(14, 1) dlgRealEdit(Holder_Spacing, 0.0, 800); dlgCell(14, 2) dlgLabel("mm"); dlgCell(14, 3) dlgPushButton("Spacing Info") { info = Showpic[15]; Infotext = INFOspacing; } } // Gridlayout Ende dlgStretch(0); dlgVBoxLayout { dlgHBoxLayout dlgSpacing(400); // Breite des Infofenster (Bild) sonst sprintg des Menu dlgLabel(info, 1); dlgLabel(Infotext, 1); dlgStretch(1); dlgHBoxLayout { if (Ref_cnto == 3) { // ist ein Ref-Package platziert? 2011-02-09 dlgLabel(A_refpack); /* *** a reference package is found *** dlgGroup(A_refpack) { dlgVBoxLayout { dlgHBoxLayout { dlgCheckBox(InfoRefHole, DrillRefOn) { if (DrillRefOn) { info = Showpic[39]; Infotext = InfoRefOn; DrillRefDiameter = MdrillRefDiameter; DrillRefDeep = MdrillRefDeep; } else { info = Showpic[17]; Infotext = InfoRefOff; MdrillRefDiameter = DrillRefDiameter; MdrillRefDeep = DrillRefDeep; } } dlgStretch(1); dlgPushButton("Do it") dlgMessageBox("Not implemented yet", "OK"); // 2013-04-30 } dlgVBoxLayout { dlgHBoxLayout { dlgLabel(RefDrillDiameter); dlgRealEdit(DrillRefDiameter); dlgLabel(" mm "); dlgStretch(1); } dlgHBoxLayout { if (language() == "de") dlgSpacing(56); else dlgSpacing(34); dlgLabel(RefDrillDeep); dlgRealEdit(DrillRefDeep); dlgLabel(" mm "); dlgStretch(1); } } } } */ } else { dlgSpacing(60); dlgPushButton(ZeroRef) { info = Showpic[17]; Infotext = InfoREFERENCE; setZeroReference(); } } dlgStretch(1); } // unterer Rand des Menu } // Vbox ende } // Hbox Ende } // Tab 1 Ende dlgTabPage("Z axis") { dlgHBoxLayout { dlgVBoxLayout dlgSpacing(420); // die Tabhöhe vorgeben dlgVBoxLayout { dlgLabel(Machineparameter, 1); dlgHBoxLayout { dlgVBoxLayout { dlgStretch(1); dlgGroup("Resolution: Integer/Fractioal Digits") { // 2011-02-02 dlgHBoxLayout { dlgRadioButton("3 2 ", CNCmillResolution) { MCNCmillResolution = CNCmillResolution; zinfo = Showpic[38]; zInfotext = INFOresolution; } dlgRadioButton("3 3 ", CNCmillResolution) { MCNCmillResolution = CNCmillResolution; zinfo = Showpic[38]; zInfotext = INFOresolution; } dlgRadioButton("3 4 ", CNCmillResolution) { MCNCmillResolution = CNCmillResolution; zinfo = Showpic[38]; zInfotext = INFOresolution; } dlgRadioButton("3.2 ", CNCmillResolution) { MCNCmillResolution = CNCmillResolution; zinfo = Showpic[38]; zInfotext = INFOresolution; } dlgRadioButton("3.3 ", CNCmillResolution) { MCNCmillResolution = CNCmillResolution; zinfo = Showpic[38]; zInfotext = INFOresolution; } dlgRadioButton("3.4 ", CNCmillResolution) { MCNCmillResolution = CNCmillResolution; zinfo = Showpic[38]; zInfotext = INFOresolution; } } } } dlgSpacing(60); // Abstand zum Bild dlgVBoxLayout { dlgStretch(1); dlgLabel(zinfo, 1); } dlgVBoxLayout { dlgStretch(1); dlgLabel(zInfotext, 1); } dlgStretch(1); } dlgHBoxLayout { dlgGroup("Machine parameter") { dlgHBoxLayout { dlgStretch(1); } dlgGridLayout { dlgCell( 1, 0) dlgLabel("Z safety "); dlgCell( 1, 1) dlgRealEdit(Mill_z_safety); dlgCell( 1, 2) dlgLabel(" mm "); dlgCell( 1, 3) dlgPushButton("Safety Info") { zinfo = Showpic[25]; zInfotext = INFOzsafety; } dlgCell( 1, 4) dlgSpacing(8); dlgCell( 2, 0) dlgLabel("Z drill deep "); dlgCell( 2, 1) dlgRealEdit(Drill_z_deep); dlgCell( 2, 2) dlgLabel(" mm "); dlgCell( 2, 3) dlgPushButton("Deep Info") { zinfo = Showpic[26]; zInfotext = INFOdeep; } dlgCell( 3, 0) dlgLabel("Z milling down "); dlgCell( 3, 1) dlgRealEdit(Z_down); dlgCell( 3, 2) dlgLabel(" mm "); dlgCell( 3, 3) dlgPushButton("Z down Info") { zinfo = Showpic[28]; zInfotext = INFOzAxisDown; } dlgCell( 4, 0) dlgLabel("Z Board Dim. "); dlgCell( 4, 1) dlgRealEdit(Z_dimension); dlgCell( 4, 2) dlgLabel(" mm "); dlgCell( 4, 3) dlgPushButton("Z Dim. Info") { zinfo = Showpic[34]; zInfotext = DIMdown; } dlgCell( 5, 0) dlgLabel("


"); dlgCell( 5, 1) dlgLabel("
"); dlgCell( 5, 2) dlgLabel("
"); dlgCell( 5, 3) dlgLabel("
"); dlgCell( 6, 0) dlgLabel("* Park pos. Z "); dlgCell( 6, 1) dlgRealEdit(ParkZposition); dlgCell( 6, 2) dlgLabel(" mm "); dlgCell( 6, 3) dlgPushButton("Park Info") { zinfo = Showpic[35]; zInfotext = PARKinfo; } dlgCell( 1, 9) dlgSpacing(8); dlgCell( 1, 5) dlgLabel("* Spindle "); dlgCell( 1, 6) dlgIntEdit(Spindle_rpm); dlgCell( 1, 7) dlgLabel(" rpm "); dlgCell( 1, 8) dlgPushButton("RPM Info") { zinfo = Showpic[31]; zInfotext = INFOrpm; } dlgCell( 2, 5) dlgLabel("* Tool velocity "); dlgCell( 2, 6) dlgRealEdit(Tool_vel); dlgCell( 2, 7) dlgLabel(" mm/s "); dlgCell( 2, 8) dlgPushButton("Velocity Info") { zinfo = Showpic[29]; zInfotext = INFOvelocity; } dlgCell( 3, 5) dlgLabel("* Fast velocity "); dlgCell( 3, 6) dlgRealEdit(Fast_vel); dlgCell( 3, 7) dlgLabel(" mm/s "); dlgCell( 3, 8) dlgPushButton("Fast Info") { zinfo = Showpic[30]; zInfotext = INFOfastVel; } dlgCell( 4, 5) dlgLabel("* Drill velocity "); dlgCell( 4, 6) dlgRealEdit(Drill_Vel); dlgCell( 4, 7) dlgLabel(" mm/s "); dlgCell( 4, 8) dlgPushButton("V-Drill Info") { zinfo = Showpic[32]; zInfotext = INFOvdrill; } dlgCell( 4, 9) dlgLabel(" * currently not used."); dlgCell( 6, 5) dlgLabel("* Park pos. X "); dlgCell( 6, 6) dlgRealEdit(ParkXposition); dlgCell( 6, 8) dlgLabel("* Park pos. Y "); dlgCell( 6, 9) dlgRealEdit(ParkYposition); } } dlgStretch(1); } } } } // tab Ende } // tab Widget Ende dlgStretch(1); // 2013-02-19 // the file Path/name dlgHBoxLayout { dlgGridLayout { dlgCell( 0, 1) dlgSpacing(15); dlgCell( 0, 2) dlgSpacing(500); dlgCell( 1, 1) { dlgStretch(1); dlgLabel("Mill fil&e"); } dlgCell( 1, 2) dlgStringEdit(Xfile); dlgCell( 1, 3) dlgPushButton(DrBrowse) { string fn = dlgFileSave(SAVE_file, Xfile); if (fn) { Xfile = fn; MillFileName = fn; info = Showpic[1]; } } } dlgStretch(1); } dlgHBoxLayout dlgSpacing(600); dlgLabel("Design Rules:" + dru_file); dlgHBoxLayout { dlgStretch(0); dlgPushButton("OK") { //Z_up = Z_down * -1.0; // 2011-01-27 Up und Down muss immer der gleiche Wert sein! if (!SelectedDevice) Error("No device selected!", "Please select a device.", NEXT, CANCEL); else { if (DimensionMillTool) { // **** if used ? **** DistanceDimension = DimensionMillTool - Distance_Copper_Dimension*2; // 2009-02-05 if (DistanceDimension < 0) { // 2009-02-05 correct wire width for millout string d, d2; sprintf(d, "%.8f", DistanceDimension/2); // 2009-02-05 if (language() == "de") { // 2008-11-12 sprintf(d2, "Achtung!
Die Platine wird um %.8f mm ausserhalb der Dimension aus dem Träger gefäst!", DistanceDimension/2); } else { sprintf(d2, "Attention!\nThe millout is %.8f mm outher the dimension!", DistanceDimension/2); } fault = dlgMessageBox(FaultDRCdist1 + d + FaultDRCdist2 + d2, ACCEPT, BACK); DistanceDimension = 0; } } if(!Onlydrill) { // if (!MillToolOutl) { fault = Error("Illegal diameter: 0", "The Isolate diameter must be greater than zero.", NEXT, CANCEL); } if (!SelectedLayer1 && !SelectedLayer16) { if (!MillOnlyContour) { // 2011-03-10 nur Kontur fräsen fault = Error("No layer selected!", "Select layer 1 or 16 or both.", BREAK, CANCEL); } } if (Clearance_check) { fault = Error(Error5, "" + Clearance_check + "", "Change &Tool #1", DRCCHECK); if (fault) exit("CLASS"); fault = 1; } } if (Holder_Spacing && Holder_Spacing < DimensionMillTool*3) { // 2011-09-28 nur wenn der Fräsweg min. 3 mal länger als der Fräser im Durchmesser ist. fault = Error("", "Holder spacing to smal.", "OK", BACK); } if (!fault) { if (MillOnlyContour) dlgMessageBox("!Milling only Dimension selected.", "OK"); MillFileName = Xfile; if (test) output(filesetext(B.name, "-cmd.txt"), "at"); Max_Drill_Diameter = round(Max_Drill_Diameter*10) / 10; dlgAccept(); } } } dlgPushButton(CANCEL) { dlgReject(); exit(0); } dlgSpacing(32); dlgPushButton(SavePar) save_defaults(); dlgSpacing(32); dlgPushButton(INFOinside) { dlg_PlaceVia(); } dlgStretch(5); dlgLabel(Version); dlgStretch(1); dlgPushButton(INFOhelpBut) dlgMessageBox(INFOhelp, "OK"); } }; } Device = DeviceNames[SelectedDevice]; if (SelectedLayer1) { ToMillLayer1 = SelectedLayer1; OutlineMillSignalLayer = SelectedLayer1; // set OutlineMillSignalLayer to last used layer } if (SelectedLayer16) { ToMillLayer16 = SelectedLayer16; OutlineMillSignalLayer = SelectedLayer16; } fileerror(); output(MillFileName, "wt"); // creat new file Ftop = filenametop(MillFileName); if (Ftop != MillFileName) output(Ftop, "wt"); // erzeuge zusätzliche Datei für Top bei HPGL 2013-04-30 if (fileerror()) exit (-1); output(filesetext(B.name, "_display~tmp.scr"), "wtD") { printf("DISPLAY NONE 17 18 20 "); board(B) { B.layers(L) { if (L.visible) printf("%d ",L.number); } } switch (SelectedDevice) { case devScript: if (MillOnlyContour) { // 2011-03-10 printf(" %d %d ", 1 + 102, 118); } else { if (SelectedLayer1) printf(" %d %d %d", 1 + 100, 1 + 101, 1 + 102); // 2008-11-12 if (SelectedLayer16) printf(" %d %d %d", 16 + 100, 16 + 101, 16 + 102); if (SelectedPlusLayerTop) printf(" %d", SelectedPlusLayerTop + 100); if (SelectedPlusLayerBot) printf(" %d", SelectedPlusLayerBot + 100); printf(" 144 145 "); // 2013-02-19 die beiden Layer auch noch anzeigen printf(";#5076 layer reset\n"); } break; case devHPGL: output(filesetext(MillFileName,".pli"), "wt") { printf("# Plot info generated by:\n# %s\n# %s\n# from %s\n# at %s\n# Drill tools\n", argv[0], Version, B.name, t2string(time()) ); } toolFiles(); // generate Rack and Wheel file break; case devISEL: output(filesetext(MillFileName,".isi"), "wt") { printf("IMF_PBL_V1.0 - PICTURES BY PC - Eagle mill-outline.ulp\n"); printf("; Plot info generated by %s %s\n# from %s\n# at %s\n# Used tools\n", argv[0], Version, B.name, t2string(time()) ); } toolFiles(); // generate Rack and Wheel file break; case devCNC: output(filesetext(MillFileName,".nci"), "wt") { printf("#M48 Plot info generated by %s %s\n# from %s\n# at %s\n# Used tools\n", argv[0], Version, B.name, t2string(time()) ); } break; } } if (MillOnlyContour) { // ***** 2011-03-10 ***** string omillout; string Cmd; sprintf(Cmd, "LAYER Milloutlines %d;\n", 1 + 102); DistanceDimension = DimensionMillTool - Distance_Copper_Dimension*2; if (DistanceDimension < 0) { // 2009-02-05 correct wire width for millout DistanceDimension = 0; } real x1 = u2mm(B.area.x1) - DimensionMillTool/2, y1 = u2mm(B.area.y1) - MillToolFree/2, x2 = u2mm(B.area.x2) + DimensionMillTool/2, y2 = u2mm(B.area.y2) + MillToolFree/2; sprintf(omillout, "grID MM;\nDISPLAY NONE 17 %d;\n", ToMillLayer1 + ToMillLayer16); Cmd += omillout; // ** make temporary Net for Normal Polygon Orphen OFF // ** to milling the pcb-contour with holder ** sprintf(omillout, "chANGE laYER 1;\n"); /**** mit dieser Option immer von Top fräsen *****/ Cmd += omillout; Cmd += "SET WIRE_BEND 2;\n"; sprintf(omillout, "VIA '%s' (%.8f %.8f);\n", OutlineMillSignal, x1 - DimensionMillTool/2, // plaziere Via innerhalb des Polygon y1 - DimensionMillTool/2 // damit es kein Orphan wird. ); Cmd += omillout; sprintf(omillout, "CHANGE ISOLATE 0;\n"); Cmd += omillout; sprintf(omillout, "CHANGE ORPHANS OFF;\n"); Cmd += omillout; Cmd += "SET WIRE_BEND 0;\n"; Cmd += "CHANGE RANK 1;\n"; // 2006-07-26 sprintf(omillout, "POLyGON '%s' %.8f (%.8f %.8f) (%.8f %.8f) (%.8f %.8f);\nRATSNEST;\n", OutlineMillSignal, DistanceDimension, x1 - DimensionMillTool - Distance_Copper_Dimension, y1 - DimensionMillTool - Distance_Copper_Dimension, x2 + DimensionMillTool + Distance_Copper_Dimension, y2 + DimensionMillTool + Distance_Copper_Dimension, x1 - DimensionMillTool - Distance_Copper_Dimension, y1 - DimensionMillTool - Distance_Copper_Dimension); Cmd += omillout; Cmd += "SET WIRE_BEND 2;\n"; // 2011-09-28 Cmd += RUN_pass(PassOutmill); exit(Cmd); } generateTruePolygonOutlines(); // generate the true Dimension outline as polygon. } } // *** generate Copper pouring *** void genInPassPour(int Layer) { string fname = MillFileName; if (Layer == 1) fname = filenametop(MillFileName); // 2013-04-30 if(SelectedLayer16 && ToMillLayer16) { if (Mirror_On) { Mirror = -1.0; // *** mirror flag for Layer 16 *** 2005-06-21 } else { MillMirr_Offset = 0; // ** reset mirror offset ** Mirror = 1.0; } } else if(SelectedLayer1 && ToMillLayer1) { MillMirr_Offset = 0; // ** reset mirror offset ** Mirror = 1.0; } output(fname, "at") { if (test) printf(";#*** InPassPour\n"); if (SelectedDevice == devScript) printf("\n# 2. isolate\n"); if (InPassPour && MillToolFree == 0) return; // 2011-02-08 printf("%s", WriteOutlines(ReservedOutlineSignalName, Layer )); } return; } // *** generate outlines by polygon.contours.wires *** void genPass2(int Layer) { board(B) { Actualmilldeep = Z_down; // 2011-01-27 milling Z Achse real x1 = u2mm(B.area.x1) - MillToolFree/2 , y1 = u2mm(B.area.y1) - MillToolFree/2 ; string fname = MillFileName; if(Layer == 1) { // wenn Top und HPGL dann in 2. Datei schreiben fname = filenametop(MillFileName); } output(fname, "at") { if (SelectedDevice == devScript) { printf("\n#5200 InPass2 1. isolate Layer %d \n", Layer); // 2013-04-30 } DeviceInit(Contour, Layer); printf("%s", WriteOutlines(ReservedOutlineSignalName, Layer )); // the isolated contour gecheckt 2001-01-31 if (SelectedPlusLayerTop && Layer == 1) genPlusLayer(SelectedPlusLayerTop); if (SelectedPlusLayerBot && Layer == 16) genPlusLayer(SelectedPlusLayerBot); } if (MillToolFree < 0) MillToolFree = 0.2; real overlapfree = MillToolFree * OverlapRubOutPercent / 100; real overlapoutl = MillToolOutl * OverlapOutlPercent / 100; string Cmd; sprintf(Cmd, "CHANGe wIDTH %.8f %s;\nCHANGe iSOLATE %.8f %s;\n", MillToolFree - overlapfree, polycoord1(TrueOutline_coordinate), // x1, y1, waren die falschen Koordinaten! MillToolOutl + ( (overlapfree / 2 ) - overlapoutl), polycoord1(TrueOutline_coordinate) ); // 2012-03-09 benutze zum ändern der Breite eine Koordinate des Polygon selbst. if (test2) if (dlgMessageBox("!5168 Anschliesend muß das Polygon die untenstehende Breite erhalten!\n" + Cmd, "OK", "CANCEL") != 0) exit(-5215); Cmd += "RATSNEST;\n" + RUN_pass(PassPour); if (test) output(filesetext(B.name, "-cmd.txt"), "at") printf("%s", Cmd); if (test) if (viewtest("5389 if (InPass2) Jetzt bekommt das Polygon die andere Breite!!! genPass2() " + PassPour +":", Cmd) != 0) exit(-5219); exit(Cmd); } } /****************** *** run passes **** *******************/ if (InPassDimensionPoly) { // ## first run calculate the real outline ## if (test2) if (dlgMessageBox("#5228 1. Dimension ermitteln", "ok", "esc") != 0) exit(-5228); // // The actual outlines (Dimension) generator // board(B) { Actualmilldeep = Z_dimension; trueOutlineDraw(OutlineMillSignal); string s; string Cmd; real x1 = u2mm(B.area.x1) - MillToolFree, y1 = u2mm(B.area.y1) - MillToolFree, x2 = u2mm(B.area.x2) + MillToolFree, y2 = u2mm(B.area.y2) + MillToolFree; DistanceDimension = (DimensionMillTool / 2 - Distance_Copper_Dimension); if (DistanceDimension < 0) DistanceDimension = 0.001; // ** delete the temporary Polygon ** // 2008-11-12 get actual coordinate B.signals(S) { if (S.name == OutlineMillSignal) { int cntco = 0; S.polygons(PL) { int i = 1; int active; do { active = 0; PL.contours(W, i) { active = 1; // do something with the wire cntco++; // 2010-01-20 Anzahl der Konturen ermitteln, break; } i++; } while (active); i = -1; PL.wires(W) { sprintf( s, "DELETE (S%.8f %.8f);\n", u2mm(W.x1), u2mm(W.y1) ); Cmd += s; break; } break; } S.vias(V) { // get absolut coordiante of via // ** delete the temporary Via after board outline contour and inner contour** cntcontvia++; // 2015-03-24 do not ripup the via befor milling a exist inner contour // sprintf( s, "RIPUP (%.8f %.8f);\n", u2mm(V.x), u2mm(V.y) ); // if (dlgMessageBox(s, "nein", "ja") != 0) { // Cmd += s; // } } if (cntco > cntcontvia+1) { // 2011-10-04 wenn Anzahl der Kontouren+1 größer als vorhandene Vias, // dann ist die Diemension nicht in Ordnung! string i1, i2; sprintf(i1, "%d Konturen im Polygon %s gefunden

" + "Überprüfen Sie die Dimension (Layer 20). " + "Das Layout besteht aus mehreren Outlines. ", cntco, S.name); sprintf(i2, "Beispiel:
Auf der linken Seite im Bild ist ausserhalb der Platine ein Kreis im Layer 20. " + "Verbinden Sie die zweite Kontur mit einer Linie im Layer 20, wie auf der rechten Seite zu sehen ist.

" + "


" + "Anschliessend an diese Meldung wird nur der Layer Dimension angezeigt!
" + "Schalten Sie entsprechende Layer wieder mit DISPLAY ein.

"); dlgDialog("Contour error") { // 2010-01-20 dlgLabel(i1); dlgLabel(""); dlgLabel(i2); dlgHBoxLayout { dlgStretch(1); dlgPushButton("OK") dlgAccept(); dlgStretch(1); } }; exit (Cmd+"DISPLAY NONE 20;\nWIN FIT;LAYER 20 "); // 2010-01-20 Polygon und Via löschen, und nur Layer Dimension anzeigen. } } } Cmd += "SET WIRE_BEND 2;\n"; sprintf(s, "CHANGE ISOLATE %.8f;\n", MillToolIsolate); // 2006-07-26 Cmd += s; sprintf(s, "CHANGE RANK 6;\n"); // 2006-07-26 Cmd += s; if (SelectedLayer16) { sprintf(s, "CHANGE LAYER 16;\n"); // first milling bottom layer Cmd += s; } else if (SelectedLayer1) { sprintf(s, "CHANGE LAYER 1;\n"); Cmd += s; } sprintf(s, "POLYGOn '%s' %.8f %s;\nRATSNEST;\n", ReservedOutlineSignalName, MillToolOutl, TrueOutline_coordinate); Cmd += s; Cmd += RUN_pass(Pass2); if (test) if (viewtest("if (InPassDimensionPoly) 2008-11-12 *****************:", Cmd) != 0) exit(-5324); if (test) output(filesetext(B.name, "-cmd.txt"), "at") printf("%s", Cmd); exit(Cmd); } } // ****************** the passes **************************** // *** milling the isolation #1 *** if (InPass2) { // second run, first isolate if (test2) if (dlgMessageBox("#5335 2. Erste Isolation fräsen Pass2\nPolygonstart: " + TrueOutline_coordinate, "ok", "esc") != 0) exit(-5335); Actualmilldeep = Z_down; // 2011-01-27 milling Z Achse /*** after InPass2 must/can Copper pouring ***/ if(SelectedLayer16 && ToMillLayer16) { if (Mirror_On) { Mirror = -1.0; } else { MillMirr_Offset = 0; // ** reset mirror offset ** Mirror = 1.0; } OutlineMillSignalLayer = SelectedLayer16; genPass2(16); // 2008-11-12 nicht das Flag übergeben, sondern den Layer } else if(SelectedLayer1 && ToMillLayer1) { MillMirr_Offset = 0; // ** reset mirror offset ** Mirror = 1.0; OutlineMillSignalLayer = SelectedLayer1; genPass2(1); // 2008-11-12 nicht das Flag übergeben, sondern den Layer } } // *** Copper pouring *** if (InPassPour) { // third run, wide isolate und copper pouring if (test2) if (dlgMessageBox("#5360 3. zweites mal Isolation fräsen mit breiteren Fräser und ausräumen!", "ok", "esc") != 0) exit(-5360); string Cmd; string millout; string s; string coordoutline; Actualmilldeep = Z_down; // 2011-01-27 milling Z Achse board(B) { real x1 = u2mm(B.area.x1) - MillToolFree/2, y1 = u2mm(B.area.y1) - MillToolFree/2; real x2 = u2mm(B.area.x2) + MillToolFree/2, y2 = u2mm(B.area.y2) + MillToolFree/2; // 2008-11-12 Polygon-Layer ermitteln B.signals(S) { if (S.name == ReservedOutlineSignalName) { S.polygons(P) { sprintf(s, "DISPLAY %d;\n", P.layer); // 2008-11-12 ermittle den aktuellen Polygon Layer Cmd += s; P.wires(W) { sprintf(coordoutline, "(%.8f %.8f)", u2mm(W.x1), u2mm(W.y1) ); break; } break; } break; } } if(ToMillLayer16 && ToMillLayer1) { // *** if double layer, first generate Layer 16 (mirrored) *** genInPassPour(16); // 2008-11-12 use layer not flag ToMillLayer16 = 0; output(MillFileName, "at") { // *** the first run is finished *** // *** ReInit with mirror PCB on machine *** // *** 2005-05-24 DeviceReInit(MirrorPCB, ToMillLayer16, "5338"); // *** message to personal must mirror the milling PCB on machine *** } sprintf(s, "CHANGE ISOLATE 0 %s;\nCHANGE LAYER 1 %s;\nCHANGE WIDTH %.8f %s;\nRATSNEST;\n", coordoutline, coordoutline, MillToolOutl, coordoutline); if (test2) if (dlgMessageBox("#5398 Breiter Fräser:\n" + s, "ok", "esc") != 0) exit(-5398); Cmd += s; Cmd += RUN_pass(Pass2); exit(Cmd); } else if(ToMillLayer16 || ToMillLayer1) { if(ToMillLayer16) genInPassPour(16); // 2008-11-12 else if (ToMillLayer1) { MillMirr_Offset = 0; // ** OK reset mirror offset ** 2005-05-23 genInPassPour(1); } B.signals(S) { if (S.name == ReservedOutlineSignalName) { S.polygons(P) { P.wires(W) { sprintf(DelPoly, "DELETE (S %.8f %.8f);\n", u2mm(W.x1), u2mm(W.y1) ); // 2009-03-31 gesamtes Polygon löschen Cmd += DelPoly; break; } break; } break; } } sprintf(millout, "DISPLAY NONE 17 %d;\n", ToMillLayer1 + ToMillLayer16); Cmd += millout; // ** make temporary Net for Normal Polygon Orphen OFF // ** to milling the pcb-contour with holder ** string millout; // 2009-03-31 set correct layer for milling out if (SelectedLayer16 && ToMillLayer16) OutlineMillSignalLayer = 16; // 2009-03-31 sprintf(millout, "cHANGE lAYER %d;\n", OutlineMillSignalLayer); Cmd += millout; sprintf(millout, "VIA '%s' (%.8f %.8f);\n", OutlineMillSignal, x1 + .1, // plaziere Via innerhalb des Polygon 2006-05-17 y1 + .1 // damit es kein Orphan wird. ); Cmd += millout; sprintf(millout, "CHANGE ISOLATE 0;\n"); Cmd += millout; sprintf(millout, "CHANGE ORPHANS OFF;\n"); Cmd += millout; Cmd += "SET WIRE_BEND 0;\n"; Cmd += "CHANGE RANK 1;\n"; // 2006-07-26 DistanceDimension = DimensionMillTool - Distance_Copper_Dimension*2; if (DistanceDimension < 0) { // 2009-02-05 correct wire width for millout DistanceDimension = 0; } } sprintf(millout, "POLyGON '%s' %.8f (%.8f %.8f) (%.8f %.8f) (%.8f %.8f);\nRATSNEST;\n", OutlineMillSignal, DistanceDimension, x1 - DimensionMillTool - Distance_Copper_Dimension, y1 - DimensionMillTool - Distance_Copper_Dimension, x2 + DimensionMillTool + Distance_Copper_Dimension, y2 + DimensionMillTool + Distance_Copper_Dimension, x1 - DimensionMillTool - Distance_Copper_Dimension, y1 - DimensionMillTool - Distance_Copper_Dimension); Cmd += millout; Cmd += "SET WIRE_BEND 2;\n"; // 2011-09-28 Cmd += RUN_pass(PassOutmill); if (test) output(filesetext(B.name, "-cmd.txt"), "at") printf("%s", Cmd); if (test) if (viewtest("if (InPassPour) >> " + PassOutmill + ": jetzt kommt aus dem Träger ausfräsen:", Cmd) != 0) exit(-5463); exit(Cmd); } } // *** drill holes (milling bigger holes) and milling out from holder *** if (InPassOutmill) { // ## fourth run, drill holes, milling big holes and milling out from raw matarial by dimension if (test2) if (dlgMessageBox("#5471 4. Aus dem Träger fräsen!", "ok", "esc") != 0) exit(-5471); Actualmilldeep = Drill_z_deep; // 2011-01-27 string fname = MillFileName; if (SelectedLayer16 && ToMillLayer16) OutlineMillSignalLayer = 16; // 2009-03-31 if (OutlineMillSignalLayer == 16) { if (Mirror_On) { Mirror = -1.0; // *** mirror flag for Layer 16 *** } else { MillMirr_Offset = 0; // ** reset mirror offset ** Mirror = 1.0; } } else if(OutlineMillSignalLayer == 1) { fname = filenametop(MillFileName); MillMirr_Offset = 0; // ** reset mirror offset ** Mirror = 1.0; } // ** OK ** 2005-06-23 board(B) { Actualmilldeep = Drill_z_deep; // 2011-01-27 get_rack(B); set_tool_rack(); // ** set tool rack again for Holes drilling string Cmd; output(fname, "at") { if (test2) if (dlgMessageBox("#5498 Aus dem Träger fräsen!\n" + MillFileName, "ok", "esc") != 0) exit(-5498); // *** now milling PCB from holder outside Dimension Line *** 2006-11-07 if (SelectedDevice == devScript) printf("\n# milling dimension #5500\n"); if (Dim_on_off) { // soll überhaupt die Dimension gefräst werden? 2011-02-09 if (MillOnlyContour) OutlineMillSignalLayer = 1; /**** 2011-03-10 wenn nur Konturfräsen, dann immer Layer 1 ****/ printf("%s", WriteOutlines( OutlineMillSignal, OutlineMillSignalLayer )) ; // milling outline(Dimension) 2009-03-31 } // *** last but not least the HOLE(s) *** switch (SelectedDevice) { case devScript: /**** 2008-12-05 new file == "wt" ****/ printf("#5508 WriteHoles() in the same script\n"); // 2013-02-19 // WriteHoles(OutlineMillSignalLayer); ist schon erledigt printf("SET UNDO_LOG ON;\n"); printf("WIN FIT;\n"); break; case devHPGL: break; case devISEL: if (Generatedrills) { printf("#5518\n"); WriteHoles(OutlineMillSignalLayer); } break; case devCNC: if (Generatedrills) { printf("#5522\n"); WriteHoles(OutlineMillSignalLayer); } break; default: dlgMessageBox("undefined Device!\nULP aborted.", "OK"); exit(0); break; } DeviceEnd(); real x1 = u2mm(B.area.x1) - DimensionMillTool/2, y1 = u2mm(B.area.y1) - MillToolFree/2, x2 = u2mm(B.area.x2) + DimensionMillTool/2, y2 = u2mm(B.area.y2) + MillToolFree/2; // delete temporary Polygon and VIA B.signals(S) { // 2008-11-12 get absolute coordinate of reseved polygon if (S.name == OutlineMillSignal) { int cntcontp = 0; int cntcontn = 0; int cntvia = 0; S.vias(V) { cntvia++; } string del_pol; S.polygons(POL) { POL.wires(W) { sprintf(del_pol, "Grid MM;\nDELETE (S %.8f %.8f);", u2mm(W.x1), u2mm(W.y1) ); Cmd += del_pol; break; } break; } S.vias(V) { // 2008-11-12 get actual coordiante of via // ** delete the temporary Via ** sprintf( del_pol, "RIPUP (%.8f %.8f);\nRATSNEST;\n", u2mm(V.x), u2mm(V.y) ); // 2009-02-04 clear via airwire Cmd += del_pol; } int activ; S.polygons(POL) { // 2011-03-10 check Elemente ausserhalb der Dimension do { activ = 0; POL.contours(W, cntcontp+1) { cntcontp++; activ = 1; break; } POL.contours(W, cntcontn-1) { cntcontn--; activ = 1; break; } } while (activ); } cntcontn *= -1; if (cntcontp == cntvia && cntcontn == 1) { // 2011-10-04 ; // alles in bester Ordnung } else { if (MillToolFree) { // 2013-03-05 nur wenn Tool#2 blow-up benutzt string polerror; string polerrorimg = ""; sprintf(polerror, "ERROR: %d VIA, %d positive und %d negative Konturen im Polygon %s

" + "Überprüfen Sie, ob außerhalb der Boardkontur, Texte, Logos oder sonstige Elemente im Top oder Bottom Layer " + "platziert sind und entweder entfernen Sie diese Elemente oder wechseln sie in einen nicht Kupferlayer.
" + "Entfernen Sie mit DELETE/RIPUP alle Elemente außerhalb der Dimension, bzw. verbinden
" + "Sie evtl. mehrfach vorhandene Dimensionen (Konturen) miteinander.
Beispiel:", cntvia, cntcontp, cntcontn, OutlineMillSignal ); dlgDialog("Polygon Error") { dlgLabel(polerror); dlgLabel(polerrorimg); dlgHBoxLayout { dlgStretch(1); dlgPushButton("OK") dlgAccept(); dlgStretch(1); } }; } Cmd += "SCRIPT '" + filesetext(B.name, "_display~tmp.scr") + "';\n"; string g; sprintf(g, "GRID %s %.f;\nWIN FIT;", Gridunit[GridUnitdist], GridDistance); Cmd+=g; } } } if (SelectedDevice == devScript) { printf("\n#5607 *** InPassOutmill\n"); printf("# milling dimension\n"); } } // SelectedLayer1 beim letzten PASS2 muß 1 ToMillLayerX noch übrig bleiben !!! // SelectedLayer16 überprüfen ob noch ein Layer aktiv ist, der letzte !! 2006-10-05 switch (SelectedDevice) { case devScript: if (MillOnlyContour) { // 2011-03-10 Cmd += "SCRIPT '" + MillFileName + "';\n"; // execute script Cmd += "SCRIPT '" + filesetext(B.name, "_display~tmp.scr") + "';\n"; } else { Cmd += "SCRIPT '" + MillFileName + "';\n"; // execute script Cmd += "SCRIPT '" + filesetext(B.name, "_display~tmp.scr") + "';\n"; string s; if (ToMillLayer1) { sprintf(s, "DISPLAY %d;\n", SelectedLayer1 + 101); // 2006-07-26 Cmd += s; sprintf(s, "DISPLAY %d;\n", SelectedLayer1 + 102); Cmd += s; } if (ToMillLayer16) { sprintf(s, "DISPLAY %d;\n", SelectedLayer16 + 101); // 2012-01-13 Cmd += s; sprintf(s, "DISPLAY %d;\n", SelectedLayer16 + 102); // 2012-01-13 Cmd += s; } } break; case devHPGL: Cmd += "script '" + filesetext(B.name, "_display~tmp.scr") + "';\n"; break; case devISEL: Cmd += "script '" + filesetext(B.name, "_display~tmp.scr") + "';\n"; break; case devCNC: Cmd += "script '" + filesetext(B.name, "_display~tmp.scr") + "';\n"; break; } string g; if (test) output(filesetext(B.name, "-cmd.txt"), "at") printf("%s", Cmd); sprintf(g, "GRID %s %.f;\nWIN FIT;\n", Gridunit[GridUnitdist], GridDistance); Cmd += g + "SET OPTIMIZING ON;\n"; if (!test) Cmd += "SET UNDO_LOG ON;\n"; switch (SelectedDevice) { case devScript: break; case devHPGL: if (test) showHPGLinfo(); break; case devISEL: if (test) showISELinfo(); break; case devCNC: if (test) showCNCinfo(); break; } if (test) if (viewtest("if (InPassOutmill) :", Cmd) != 0) exit(-5675); sprintf(g, "GRID %s %.f;\nWIN FIT;\n", Gridunit[GridUnitdist], GridDistance); Cmd+=g; if (SelectedDevice == devHPGL) { sprintf(g, "RUN ulpmessage 'Erzeugte Dateien:
%s
%s'", MillFileName, filenametop(MillFileName)); // 2014-10-06 } else { sprintf(g, "RUN ulpmessage 'Erzeugte Datei
%s'", MillFileName); // 2014-10-06 } Cmd+=g; exit(Cmd); } }