} // Excellon drill statistics for the layer. // Constructor public GerberImage(string fileTypeName) { ImageInfo = new GerberImageInfo(); ImageInfo.MinX = double.MaxValue; ImageInfo.MinY = double.MaxValue; ImageInfo.MaxX = double.MinValue; ImageInfo.MaxY = double.MinValue; if (string.IsNullOrEmpty(fileTypeName)) { ImageInfo.FileTypeName = "Unknown"; } else { ImageInfo.FileTypeName = fileTypeName; } // The individual file parsers will have to set this. ImageInfo.AttributeList = null; ImageInfo.NumberOfAttribute = 0; apertureMacroList = new Collection <ApertureMacro>(); ApertureArray = new ApertureDefinition[Gerber.MaximumApertures]; LevelList = new List <GerberLevel>(); NetStateList = new List <GerberNetState>(); Format = new GerberFormat(); gerberNetList = new Collection <GerberNet>(); GerberStats = new GerberFileStats(); DrillStats = new DrillFileStats(); GerberNet gerberNet = new GerberNet(); // Create first gerberNet and fill in some initial values. gerberNet.Level = new GerberLevel(this); // Create our first level and fill with some default values. gerberNet.NetState = new GerberNetState(this); // Create our first netState. gerberNet.Label = String.Empty; GerberNetList.Add(gerberNet); }
// Simplify the aperture macro. public static bool SimplifyApertureMacro(ApertureDefinition aperture, double scale) { const int extraStackSize = 10; bool success = true; int numberOfParameters = 0; bool clearOperatorUsed = false; double[] localParameters = new double[Gerber.MaximumApertureParameters]; // Local copy of parameters. double[] tmp = { 0.0, 0.0 }; int index = 0; GerberApertureType type = GerberApertureType.None; SimplifiedApertureMacro macro; if (aperture == null || aperture.ApertureMacro == null) { throw new GerberApertureException("In SimplifyApertureMacro, aperture = null"); } // Allocate stack for VM. MacroStack.InitializeStack(aperture.ApertureMacro.NufPushes + extraStackSize); // Make a copy of the parameter list that we can rewrite if necessary. localParameters = new double[Gerber.MaximumApertureParameters]; foreach (double p in aperture.Parameters) { localParameters[index++] = p; } foreach (GerberInstruction instruction in aperture.ApertureMacro.InstructionList) { switch (instruction.Opcode) { case GerberOpcodes.NOP: break; case GerberOpcodes.Push: MacroStack.Push(instruction.Data.DoubleValue); break; case GerberOpcodes.PushParameter: MacroStack.Push(localParameters[instruction.Data.IntValue - 1]); break; case GerberOpcodes.PopParameter: MacroStack.Pop(ref tmp[0]); localParameters[instruction.Data.IntValue - 1] = tmp[0]; break; case GerberOpcodes.Add: MacroStack.Pop(ref tmp[0]); MacroStack.Pop(ref tmp[1]); MacroStack.Push(tmp[1] + tmp[0]); break; case GerberOpcodes.Subtract: MacroStack.Pop(ref tmp[0]); MacroStack.Pop(ref tmp[1]); MacroStack.Push(tmp[1] - tmp[0]); break; case GerberOpcodes.Multiple: MacroStack.Pop(ref tmp[0]); MacroStack.Pop(ref tmp[1]); MacroStack.Push(tmp[1] * tmp[0]); break; case GerberOpcodes.Divide: MacroStack.Pop(ref tmp[0]); MacroStack.Pop(ref tmp[1]); MacroStack.Push(tmp[1] / tmp[0]); break; case GerberOpcodes.Primative: // This handles the exposure thing in the aperture macro. // The exposure is always the first element on stack independent // of aperture macro. switch (instruction.Data.IntValue) { case 1: //Debug.Write(" Aperture macro circle [1] ("); type = GerberApertureType.MacroCircle; numberOfParameters = 4; break; case 3: break; // EOF. case 4: //Debug.Write(" Aperture macro outline [4] ("); type = GerberApertureType.MacroOutline; // Number of parameters are: // Number of points defined in entry 1 of the stack + start point. Times two since it is both X and Y. // Then three more; exposure, nuf points and rotation. numberOfParameters = ((int)MacroStack.Values[1] + 1) * 2 + 3; break; case 5: //Debug.Write(" Aperture macro polygon [5] ("); type = GerberApertureType.MacroPolygon; numberOfParameters = 6; break; case 6: //Debug.WriteLine(" Aperture macro moiré [6] ("); type = GerberApertureType.MacroMoire; numberOfParameters = 9; break; case 7: //Debug.Write(" Aperture macro thermal [7] ("); type = GerberApertureType.MacroThermal; numberOfParameters = 6; break; case 2: case 20: //Debug.Write(" Aperture macro line 20/2 ("); type = GerberApertureType.MacroLine20; numberOfParameters = 7; break; case 21: //Debug.Write(" Aperture macro line 21 ("); type = GerberApertureType.MarcoLine21; numberOfParameters = 6; break; case 22: //Debug.Write(" Aperture macro line 22 ("); type = GerberApertureType.MacroLine22; numberOfParameters = 6; break; default: success = false; break; } if (type != GerberApertureType.None) { if (numberOfParameters > Gerber.MaximumApertureParameters) { throw new GerberApertureException("Too many parameters for aperture macro;"); // GERB_COMPILE_ERROR("Number of parameters to aperture macro are more than gerbv is able to store\n"); } // Create a new simplified aperture macro and start filling in the blanks. macro = new SimplifiedApertureMacro(); macro.ApertureType = type; index = 0; for (int i = 0; i < numberOfParameters; i++) { macro.Parameters[i] = MacroStack.Values[i]; } // Convert any mm values to inches. switch (type) { case GerberApertureType.MacroCircle: if (Math.Abs(macro.Parameters[0]) < 0.001) { clearOperatorUsed = true; } macro.Parameters[1] /= scale; macro.Parameters[2] /= scale; macro.Parameters[3] /= scale; break; case GerberApertureType.MacroOutline: if (Math.Abs(macro.Parameters[0]) < 0.001) { clearOperatorUsed = true; } for (int i = 2; i < numberOfParameters - 1; i++) { macro.Parameters[i] /= scale; } break; case GerberApertureType.MacroPolygon: if (Math.Abs(macro.Parameters[0]) < 0.001) { clearOperatorUsed = true; } macro.Parameters[2] /= scale; macro.Parameters[3] /= scale; macro.Parameters[4] /= scale; break; case GerberApertureType.MacroMoire: macro.Parameters[0] /= scale; macro.Parameters[1] /= scale; macro.Parameters[2] /= scale; macro.Parameters[3] /= scale; macro.Parameters[4] /= scale; macro.Parameters[6] /= scale; macro.Parameters[7] /= scale; break; case GerberApertureType.MacroThermal: macro.Parameters[0] /= scale; macro.Parameters[1] /= scale; macro.Parameters[2] /= scale; macro.Parameters[3] /= scale; macro.Parameters[4] /= scale; break; case GerberApertureType.MacroLine20: if (Math.Abs(macro.Parameters[0]) < 0.001) { clearOperatorUsed = true; } macro.Parameters[1] /= scale; macro.Parameters[2] /= scale; macro.Parameters[3] /= scale; macro.Parameters[4] /= scale; macro.Parameters[5] /= scale; break; case GerberApertureType.MarcoLine21: case GerberApertureType.MacroLine22: if (Math.Abs(macro.Parameters[0]) < 0.001) { clearOperatorUsed = true; } macro.Parameters[1] /= scale; macro.Parameters[2] /= scale; macro.Parameters[3] /= scale; macro.Parameters[4] /= scale; break; default: break; } aperture.SimplifiedMacroList.Add(macro); //for (int i = 0; i < numberOfParameters; i++) // Debug.Write(String.Format("{0}, ", MacroStack.Values[i])); //Debug.WriteLine(")"); } // Here we reset the stack pointer. It's not generally // correct to do this, but since I know how the compiler works // I can do this. The correct way to do this should be to // subtract number of used elements in each primitive operation. MacroStack.Reset(); break; default: break; } } // Store a flag to let the renderer know if it should expect any "clear" primatives. aperture.Parameters[0] = clearOperatorUsed ? 1.0f : 0.0f; return(success); }