public override void GenerateGapChkData(LinkedList <MbeGapChkObj> chkObjList, int _netNum) //public override void GenerateGapChkData(MbeGapChk gapChk, int _netNum) { if (layer != MbeLayer.LayerValue.CMP && layer != MbeLayer.LayerValue.L2 && layer != MbeLayer.LayerValue.L3 && layer != MbeLayer.LayerValue.SOL) { return; } Point pt0 = GetPos(0); Point pt1 = GetPos(1); if (pt0.Equals(pt1)) { MbeGapChkObjPoint gapChkObj = new MbeGapChkObjPoint(); gapChkObj.layer = layer; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetPointValue(pt0, LineWidth); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } else { Point ptVia; bool bendMode = getPointVia(out ptVia); if (bendMode) { MbeGapChkObjLine gapChkObj = new MbeGapChkObjLine(); gapChkObj.layer = layer; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetLineValue(pt0, ptVia, LineWidth); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); gapChkObj = new MbeGapChkObjLine(); gapChkObj.layer = layer; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetLineValue(ptVia, pt1, LineWidth); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } else { MbeGapChkObjLine gapChkObj = new MbeGapChkObjLine(); gapChkObj.layer = layer; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetLineValue(pt0, pt1, LineWidth); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } } }
/// <summary> /// 塗りつぶしの横線の配置 /// </summary> /// <returns></returns> protected bool PlaceFillLines() { //fillLineList.Clear(); int count = orgFrameLineList.Count; int[] xpoint = new int[count]; IComparer comparer = new xpointcomp(); int step = traceWidth - 1500; double y = (double)rcArea.T - step - 0.5; //ポリゴン枠頂点と計算時に一致する面倒を避けるために、小数値でオフセット while (y > rcArea.B) { int xpIndex = 0; foreach (MbeGapChkObjLine obj in orgFrameLineList) { double refX; if (Util.LineCrossingY(obj.p0, obj.p1, y, out refX)) { xpoint[xpIndex] = (int)refX; xpIndex++; if (xpIndex == count) { break; //これでbreakはありえないはず } } } //System.Diagnostics.Debug.Write("FillPolygon dump xpoint1 "); //for (int i = 0; i < xpIndex; i++) System.Diagnostics.Debug.Write(xpoint[i] + " "); //System.Diagnostics.Debug.WriteLine(""); Array.Sort(xpoint, 0, xpIndex, comparer); //System.Diagnostics.Debug.Write("FillPolygon dump xpoint2 "); //for (int i = 0; i < xpIndex; i++) System.Diagnostics.Debug.Write(xpoint[i] + " "); //System.Diagnostics.Debug.WriteLine(""); int nLine = xpIndex / 2; int j = 0; int ny = (int)y; for (int i = 0; i < nLine; i++) { Point pt0 = new Point(xpoint[j], ny); Point pt1 = new Point(xpoint[j + 1], ny); MbeGapChkObjLine objLine = new MbeGapChkObjLine(); objLine.layer = layer; objLine.SetLineValue(pt0, pt1, traceWidth); j += 2; fillLineList.AddLast(objLine); } y = y - step; } return(true); }
public override void GenerateGapChkData(LinkedList <MbeGapChkObj> chkObjList, int _netNum) //public override void GenerateGapChkData(MbeGapChk gapChk, int _netNum) { if (layer != MbeLayer.LayerValue.CMP && layer != MbeLayer.LayerValue.L2 && layer != MbeLayer.LayerValue.L3 && layer != MbeLayer.LayerValue.SOL) { return; } else { bool reverse = (layer == MbeLayer.LayerValue.SOL); LinkedList <CamOutBaseData> camdataLList = new LinkedList <CamOutBaseData>(); MbeView.boardFont.GenerateCamDataString(camdataLList, 0, 0, reverse, signame, TextHeight, LineWidth); Point ptz = new Point(0, 0); Point pt = GetPos(0); foreach (CamOutBaseData camd in camdataLList) { if (dir != 0) { camd.RotateStep90(dir, ptz); } camd.Move(pt); if (camd.pt0.Equals(camd.pt1)) { MbeGapChkObjPoint gapChkObj = new MbeGapChkObjPoint(); gapChkObj.layer = layer; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetPointValue(camd.pt0, LineWidth); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } else { MbeGapChkObjLine gapChkObj = new MbeGapChkObjLine(); gapChkObj.layer = layer; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetLineValue(camd.pt0, camd.pt1, LineWidth); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } } } }
/// <summary> /// 多角形の枠線の生成 /// </summary> /// <param name="polygon"></param> /// <returns></returns> protected bool SetFrame(MbeObjPolygon polygon) { if (!polygon.IsValid()) { return(false); } //frameLineList.Clear(); int posCouont = polygon.PosCount; //layer = polygon.Layer; //traceWidth = polygon.TraceWidth; ptConnect = polygon.GetPos(0); for (int i = 1; i < posCouont; i++) { int index2 = i + 1; if (index2 >= posCouont) { index2 = 1; } Point pt0 = polygon.GetPos(i); Point pt1 = polygon.GetPos(index2); if (i == 1) { rcArea = new MbeRect(pt0, pt1); } else if (index2 > 1) { rcArea.Or(pt1); } MbeGapChkObjLine objLine; objLine = new MbeGapChkObjLine(); objLine.status = LINE_STATUS_FRAME; objLine.layer = layer; objLine.SetLineValue(pt0, pt1, traceWidth); orgFrameLineList.AddLast(objLine); objLine = new MbeGapChkObjLine(); objLine.status = LINE_STATUS_FRAME; objLine.layer = layer; objLine.SetLineValue(pt0, pt1, traceWidth); frameLineList.AddLast(objLine); } return(true); }
public override void GenerateGapChkData(LinkedList <MbeGapChkObj> chkObjList, int _netNum) //public override void GenerateGapChkData(MbeGapChk gapChk,int _netNum) { if (layer != MbeLayer.LayerValue.CMP && layer != MbeLayer.LayerValue.SOL) { return; } if (shape == PadShape.Rect) { MbeGapChkObjRect gapChkObj = new MbeGapChkObjRect(); gapChkObj.layer = layer; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetRectValue(GetPos(0), PadSize.Width, PadSize.Height); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } else { if (PadSize.Width == PadSize.Height) { MbeGapChkObjPoint gapChkObj = new MbeGapChkObjPoint(); gapChkObj.layer = layer; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetPointValue(GetPos(0), PadSize.Width); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } else { MbeGapChkObjLine gapChkObj = new MbeGapChkObjLine(); gapChkObj.layer = layer; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetLineValue(GetPos(0), PadSize.Width, PadSize.Height); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } } }
/// <summary> /// ポリゴンのための輪郭データを生成する。 /// </summary> /// <param name="outlineList"></param> /// <param name="param"></param> /// <remarks>ここで生成する輪郭データは内側に重なっていても良いものとする</remarks> public override void GenerateOutlineData(LinkedList <MbeGapChkObjLine> outlineList, GenOutlineParam param) { //if (param.layer != Layer) return; int distance; Point pt0 = GetPos(0); Point[] pt; distance = (Diameter + param.traceWidth) / 2 + param.gap * 11 / 10;; int left = param.rc.L - distance; int top = param.rc.T + distance; int right = param.rc.R + distance; int bottom = param.rc.B - distance; MbeRect rcArea = new MbeRect(new Point(left, top), new Point(right, bottom)); if (Util.PointIsOutsideLTRB(pt0, rcArea)) { return; } Util.PointOutlineData(pt0, distance, out pt); for (int j = 0; j < 8; j++) { int j2 = j + 1; if (j2 == 8) { j2 = 0; } if (!Util.LineIsOutsideLTRB(pt[j], pt[j2], param.rc)) { MbeGapChkObjLine objLine = new MbeGapChkObjLine(); objLine.SetLineValue(pt[j], pt[j2], param.traceWidth); outlineList.AddLast(objLine); } } }
/// <summary> /// ポリゴンのための輪郭データを生成する。 /// </summary> /// <param name="outlineList"></param> /// <param name="param"></param> /// <remarks>ここで生成する輪郭データは内側に重なっていても良いものとする</remarks> public override void GenerateOutlineData(LinkedList <MbeGapChkObjLine> outlineList, GenOutlineParam param) { //if (param.layer != Layer) return; int distance; Point ptCenter = GetPos(0); Point[] pt; int pointCount; int x = ptCenter.X; int y = ptCenter.Y; if (shape == PadShape.Rect) { distance = param.traceWidth / 2 + param.gap; pt = new Point[4]; pointCount = 4; int xoffset = Width / 2 + distance; int yoffset = Height / 2 + distance; pt[0] = new Point(x - xoffset, y + yoffset); pt[1] = new Point(x + xoffset, y + yoffset); pt[2] = new Point(x + xoffset, y - yoffset); pt[3] = new Point(x - xoffset, y - yoffset); } else { int lineW; int lineL; Point pt0; Point pt1; if (Width < Height) { lineW = Width; lineL = Height - lineW; pt0 = new Point(x, y - lineL / 2); pt1 = new Point(x, y + lineL / 2); } else { lineW = Height; lineL = Width - lineW; pt0 = new Point(x - lineL / 2, y); pt1 = new Point(x + lineL / 2, y); } distance = (lineW + param.traceWidth) / 2 + param.gap * 11 / 10; int left = param.rc.L - distance; int top = param.rc.T + distance; int right = param.rc.R + distance; int bottom = param.rc.B - distance; MbeRect rcArea = new MbeRect(new Point(left, top), new Point(right, bottom)); if (Util.LineIsOutsideLTRB(pt0, pt1, rcArea)) { return; } bool dummyParam; Util.LineOutlineData(pt0, pt1, distance, out pt, out dummyParam); pointCount = 8; } for (int j = 0; j < pointCount; j++) { int j2 = j + 1; if (j2 == pointCount) { j2 = 0; } if (!Util.LineIsOutsideLTRB(pt[j], pt[j2], param.rc)) { MbeGapChkObjLine objLine = new MbeGapChkObjLine(); objLine.SetLineValue(pt[j], pt[j2], param.traceWidth); outlineList.AddLast(objLine); } } }
/// <summary> /// ポリゴンのための輪郭データを生成する。 /// </summary> /// <param name="outlineList"></param> /// <param name="param"></param> /// <remarks>ここで生成する輪郭データは内側に重なっていても良いものとする</remarks> public override void GenerateOutlineData(LinkedList <MbeGapChkObjLine> outlineList, GenOutlineParam param) { if (!doneFillFlag) { return; } //if (fillLineList.Count == 0) return; if (param.layer != Layer) { return; } if (posCount <= 3) { return; } int distance; if (restrictMask) { distance = (RESTRICT_TRACE_WIDTH + param.traceWidth) / 2 + RESTRICT_GAP * 11 / 10; //distance = (traceWidth + param.traceWidth) / 2 + param.gap * 11 / 10; } else { distance = (traceWidth + param.traceWidth) / 2 + param.gap * 11 / 10; } int left = param.rc.L - distance; int top = param.rc.T + distance; int right = param.rc.R + distance; int bottom = param.rc.B - distance; MbeRect rcArea = new MbeRect(new Point(left, top), new Point(right, bottom)); Point[] ptOutline; for (int i = 1; i < PosCount; i++) { int i2 = i + 1; if (i2 == PosCount) { i2 = 1; } Point p0 = GetPos(i); Point p1 = GetPos(i2); if (Util.LineIsOutsideLTRB(p0, p1, rcArea)) { continue; } bool dummyParam; Util.LineOutlineData(p0, p1, distance, out ptOutline, out dummyParam); for (int j = 0; j < 8; j++) { int j2 = j + 1; if (j2 == 8) { j2 = 0; } if (!Util.LineIsOutsideLTRB(ptOutline[j], ptOutline[j2], param.rc)) { MbeGapChkObjLine objLine = new MbeGapChkObjLine(); objLine.SetLineValue(ptOutline[j], ptOutline[j2], param.traceWidth); outlineList.AddLast(objLine); } } } }
public override void GenerateGapChkData(LinkedList <MbeGapChkObj> chkObjList, int _netNum) //public override void GenerateGapChkData(MbeGapChk gapChk, int _netNum) { for (int i = 0; i < gapChkLayerTable.Length; i++) { MbeLayer.LayerValue layerValue = gapChkLayerTable[i]; if (layerValue == MbeLayer.LayerValue.L2 || layerValue == MbeLayer.LayerValue.L3) { //内層のときは非接続時はドリル径+0.4mm。(ただし、表層padサイズを超えない)接続時はpadSizeのWidthかHeightの小さい方 int landDia; if (((ulong)layerValue & innerLayerConnectionInfo) == 0) { landDia = dia + 4000; if (landDia > InnerLandDia) { landDia = InnerLandDia; } } else { landDia = InnerLandDia; } MbeGapChkObjPoint gapChkObj = new MbeGapChkObjPoint(); gapChkObj.layer = layerValue; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetPointValue(GetPos(0), landDia); chkObjList.AddLast(gapChkObj); } else if (shape == PadShape.Rect) { MbeGapChkObjRect gapChkObj = new MbeGapChkObjRect(); gapChkObj.layer = layerValue; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetRectValue(GetPos(0), PadSize.Width, PadSize.Height); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } else { if (PadSize.Width == PadSize.Height) { MbeGapChkObjPoint gapChkObj = new MbeGapChkObjPoint(); gapChkObj.layer = layerValue; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetPointValue(GetPos(0), PadSize.Width); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } else { MbeGapChkObjLine gapChkObj = new MbeGapChkObjLine(); gapChkObj.layer = layerValue; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetLineValue(GetPos(0), PadSize.Width, PadSize.Height); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); } } } }
/// <summary> /// ポリゴンのための輪郭データを生成する。 /// </summary> /// <param name="outlineList"></param> /// <param name="param"></param> /// <remarks>ここで生成する輪郭データは内側に重なっていても良いものとする</remarks> public override void GenerateOutlineData(LinkedList <MbeGapChkObjLine> outlineList, GenOutlineParam param) { //if (param.layer != Layer) return; int distance; Point ptCenter = GetPos(0); Point[] pt; int pointCount; int x = ptCenter.X; int y = ptCenter.Y; if (param.layer == MbeLayer.LayerValue.L2 || param.layer == MbeLayer.LayerValue.L3) { //内層のときは非接続時はドリル径+0.4mm。(ただし、表層padサイズを超えない)接続時はpadSizeのWidthかHeightの小さい方 int landDia; if (((ulong)param.layer & innerLayerConnectionInfo) == 0) { landDia = dia + 4000; if (landDia > InnerLandDia) { landDia = InnerLandDia; } } else { landDia = InnerLandDia; } Point pt0 = new Point(x, y); distance = (landDia + param.traceWidth) / 2 + param.gap * 11 / 10; int left = param.rc.L - distance; int top = param.rc.T + distance; int right = param.rc.R + distance; int bottom = param.rc.B - distance; MbeRect rcArea = new MbeRect(new Point(left, top), new Point(right, bottom)); if (Util.LineIsOutsideLTRB(pt0, pt0, rcArea)) { return; } bool dummyParam; Util.LineOutlineData(pt0, pt0, distance, out pt, out dummyParam); pointCount = 8; } else if (shape == PadShape.Rect) { distance = param.traceWidth / 2 + param.gap; pt = new Point[4]; pointCount = 4; int xoffset = Width / 2 + distance; int yoffset = Height / 2 + distance; pt[0] = new Point(x - xoffset, y + yoffset); pt[1] = new Point(x + xoffset, y + yoffset); pt[2] = new Point(x + xoffset, y - yoffset); pt[3] = new Point(x - xoffset, y - yoffset); } else { int lineW; int lineL; Point pt0; Point pt1; if (Width < Height) { lineW = Width; lineL = Height - lineW; pt0 = new Point(x, y - lineL / 2); pt1 = new Point(x, y + lineL / 2); } else { lineW = Height; lineL = Width - lineW; pt0 = new Point(x - lineL / 2, y); pt1 = new Point(x + lineL / 2, y); } distance = (lineW + param.traceWidth) / 2 + param.gap * 11 / 10; int left = param.rc.L - distance; int top = param.rc.T + distance; int right = param.rc.R + distance; int bottom = param.rc.B - distance; MbeRect rcArea = new MbeRect(new Point(left, top), new Point(right, bottom)); if (Util.LineIsOutsideLTRB(pt0, pt1, rcArea)) { return; } bool dummyParam; Util.LineOutlineData(pt0, pt1, distance, out pt, out dummyParam); pointCount = 8; } for (int j = 0; j < pointCount; j++) { int j2 = j + 1; if (j2 == pointCount) { j2 = 0; } if (!Util.LineIsOutsideLTRB(pt[j], pt[j2], param.rc)) { MbeGapChkObjLine objLine = new MbeGapChkObjLine(); objLine.SetLineValue(pt[j], pt[j2], param.traceWidth); outlineList.AddLast(objLine); } } }
/// <summary> /// ポリゴンのための輪郭データを生成する。 /// </summary> /// <param name="outlineList"></param> /// <param name="param"></param> /// <remarks>ここで生成する輪郭データは内側に重なっていても良いものとする /// 文字列をマジメに一画ごとに処理すると、線分の量が半端でなく大きくなる /// とりあえずは全体を矩形で囲む輪郭を生成する。 /// </remarks> public override void GenerateOutlineData(LinkedList <MbeGapChkObjLine> outlineList, GenOutlineParam param) { if (layer != param.layer) { return; } MbeRect rc = OccupationRect(); //LinkedList<CamOutBaseData> camdataLList = new LinkedList<CamOutBaseData>(); //bool reverse; //switch (layer) { // case MbeLayer.LayerValue.PLS: // case MbeLayer.LayerValue.STS: // case MbeLayer.LayerValue.SOL: // reverse = true; // break; // default: // reverse = false; // break; //} //MbeView.boardFont.GenerateCamDataString(camdataLList, 0, 0, reverse, signame, TextHeight, LineWidth); //int l = System.Int32.MaxValue; //int t = System.Int32.MinValue; //int r = System.Int32.MinValue; //int b = System.Int32.MaxValue; //Point ptz = new Point(0, 0); //Point ptOrigin = GetPos(0); //foreach (CamOutBaseData camd in camdataLList) { // if (dir != 0) { // camd.RotateStep90(dir, ptz); // } // camd.Move(ptOrigin); // if (camd.ctype == CamOutBaseData.CamType.VECTOR) { // if (l > camd.pt0.X) l = camd.pt0.X; // if (l > camd.pt1.X) l = camd.pt1.X; // if (r < camd.pt0.X) r = camd.pt0.X; // if (r < camd.pt1.X) r = camd.pt1.X; // if (b > camd.pt0.Y) b = camd.pt0.Y; // if (b > camd.pt1.Y) b = camd.pt1.Y; // if (t < camd.pt0.Y) t = camd.pt0.Y; // if (t < camd.pt1.Y) t = camd.pt1.Y; // } //} int distance = param.traceWidth / 2 + param.gap; int l = rc.L - distance; int t = rc.T + distance; int r = rc.R + distance; int b = rc.B - distance; Point[] pt = new Point[4]; pt[0] = new Point(l, t); pt[1] = new Point(r, t); pt[2] = new Point(r, b); pt[3] = new Point(l, b); for (int j = 0; j < 4; j++) { int j2 = j + 1; if (j2 == 4) { j2 = 0; } if (!Util.LineIsOutsideLTRB(pt[j], pt[j2], param.rc)) { MbeGapChkObjLine objLine = new MbeGapChkObjLine(); objLine.SetLineValue(pt[j], pt[j2], param.traceWidth); outlineList.AddLast(objLine); } } }
public override void GenerateGapChkData(LinkedList <MbeGapChkObj> chkObjList, int _netNum) //public override void GenerateGapChkData(MbeGapChk gapChk, int _netNum) { if (layer != MbeLayer.LayerValue.CMP && layer != MbeLayer.LayerValue.L2 && layer != MbeLayer.LayerValue.L3 && layer != MbeLayer.LayerValue.SOL) { return; } else { int _endAngle; if (LimitStartEnd()) { _endAngle = startAngle + 3600; } else { _endAngle = endAngle; if (_endAngle == startAngle) { _endAngle = startAngle + 3600; } else if (_endAngle < startAngle) { _endAngle += 3600; } } int angle = startAngle; bool endFlag = false; int x; int y; double angleRad; angleRad = (double)angle / 1800.0 * Math.PI; x = (int)Math.Round(radius * Math.Cos(angleRad)) + posArray[0].X; y = (int)Math.Round(radius * Math.Sin(angleRad)) + posArray[0].Y; Point pt0 = new Point(x, y); Point pt1; double division = radius * Math.PI * 2 / CAMOUT_MAXLINELENGTH; if (division < CAMOUT_DIVISION) { division = CAMOUT_DIVISION; } while (!endFlag) { angle += (int)Math.Round(3600 / division); //angle += 3600 / CAMOUT_DIVISION; if (angle >= _endAngle) { endFlag = true; angle = _endAngle; } angleRad = (double)angle / 1800.0 * Math.PI; x = (int)Math.Round(radius * Math.Cos(angleRad)) + posArray[0].X; y = (int)Math.Round(radius * Math.Sin(angleRad)) + posArray[0].Y; pt1 = new Point(x, y); if (!pt0.Equals(pt1)) { MbeGapChkObjLine gapChkObj = new MbeGapChkObjLine(); gapChkObj.layer = layer; gapChkObj.netNum = _netNum; gapChkObj.mbeObj = this; gapChkObj.SetLineValue(pt0, pt1, lineWidth); //gapChk.Add(gapChkObj); chkObjList.AddLast(gapChkObj); pt0 = pt1; } } } }
/// <summary> /// ポリゴンのための輪郭データを生成する。 /// </summary> /// <param name="outlineList"></param> /// <param name="param"></param> /// <remarks>ここで生成する輪郭データは内側に重なっていても良いものとする</remarks> public override void GenerateOutlineData(LinkedList <MbeGapChkObjLine> outlineList, GenOutlineParam param) { if (param.layer != Layer) { return; } int distance = (LineWidth + param.traceWidth) / 2 + param.gap; distance = distance * 11 / 10; int insideRadius = radius - distance; int outsideRadius = (radius + distance) * 1005 / 1000; distance = outsideRadius - radius; int left = param.rc.L - distance; int top = param.rc.T + distance; int right = param.rc.R + distance; int bottom = param.rc.B - distance; Point[] pt; MbeRect rcArea = new MbeRect(new Point(left, top), new Point(right, bottom)); //-------------------------------------------- int _endAngle; if (LimitStartEnd()) { _endAngle = startAngle + 3600; } else { _endAngle = endAngle; if (_endAngle == startAngle) { _endAngle = startAngle + 3600; } else if (_endAngle < startAngle) { _endAngle += 3600; } } if ((startAngle % 3600) != (_endAngle % 3600)) { for (int i = 1; i <= 2; i++) { if (!Util.PointIsOutsideLTRB(GetPos(i), rcArea)) { Util.PointOutlineData(GetPos(i), distance, out pt); for (int j = 0; j < 8; j++) { int j2 = j + 1; if (j2 == 8) { j2 = 0; } if (!Util.LineIsOutsideLTRB(pt[j], pt[j2], param.rc)) { MbeGapChkObjLine objLine = new MbeGapChkObjLine(); objLine.SetLineValue(pt[j], pt[j2], param.traceWidth); outlineList.AddLast(objLine); } } } } } //-------------------------------------------- //int _endAngle; //if (LimitStartEnd()) { // _endAngle = startAngle + 3600; //} else { // _endAngle = endAngle; // if (_endAngle == startAngle) _endAngle = startAngle + 3600; // else if (_endAngle < startAngle) _endAngle += 3600; //} int angle = startAngle; bool endFlag = false; int x; int y; double angleRad; angleRad = (double)angle / 1800.0 * Math.PI; x = (int)Math.Round(outsideRadius * Math.Cos(angleRad)) + posArray[0].X; y = (int)Math.Round(outsideRadius * Math.Sin(angleRad)) + posArray[0].Y; Point pt0 = new Point(x, y); Point pt1; while (!endFlag) { angle += 3600 / OUTLINE_DIVISION; if (angle >= _endAngle) { endFlag = true; angle = _endAngle; } angleRad = (double)angle / 1800.0 * Math.PI; x = (int)Math.Round(outsideRadius * Math.Cos(angleRad)) + posArray[0].X; y = (int)Math.Round(outsideRadius * Math.Sin(angleRad)) + posArray[0].Y; pt1 = new Point(x, y); if (!pt0.Equals(pt1)) //ゼロ長データは削除 { if (!Util.LineIsOutsideLTRB(pt0, pt1, param.rc)) { MbeGapChkObjLine objLine = new MbeGapChkObjLine(); objLine.SetLineValue(pt0, pt1, param.traceWidth); outlineList.AddLast(objLine); } pt0 = pt1; } } //-------------------------------------------- if (insideRadius > 10) { int division = (insideRadius > 10000 ? OUTLINE_DIVISION : 8); angle = startAngle; endFlag = false; angleRad = (double)angle / 1800.0 * Math.PI; x = (int)Math.Round(insideRadius * Math.Cos(angleRad)) + posArray[0].X; y = (int)Math.Round(insideRadius * Math.Sin(angleRad)) + posArray[0].Y; pt0 = new Point(x, y); while (!endFlag) { angle += 3600 / division; if (angle >= _endAngle) { endFlag = true; angle = _endAngle; } angleRad = (double)angle / 1800.0 * Math.PI; x = (int)Math.Round(insideRadius * Math.Cos(angleRad)) + posArray[0].X; y = (int)Math.Round(insideRadius * Math.Sin(angleRad)) + posArray[0].Y; pt1 = new Point(x, y); if (!pt0.Equals(pt1)) //ゼロ長データは削除 { if (!Util.LineIsOutsideLTRB(pt0, pt1, param.rc)) { MbeGapChkObjLine objLine = new MbeGapChkObjLine(); objLine.SetLineValue(pt0, pt1, param.traceWidth); outlineList.AddLast(objLine); } pt0 = pt1; } } } }
/// <summary> /// 信号パターンの周縁線の配置 /// </summary> protected void PlaceOutlines() { LinkedList <MbeGapChkObjLine> tempList1 = new LinkedList <MbeGapChkObjLine>(); LinkedList <MbeGapChkObjLine> tempList2 = new LinkedList <MbeGapChkObjLine>(); LinkedList <MbeGapChkObjLine> tempList3 = new LinkedList <MbeGapChkObjLine>(); LinkedList <MbeObjPin> pinList = new LinkedList <MbeObjPin>(); //アウトラインを生成するピンのリスト GenOutlineParam outlineParam; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); long time_ms; outlineParam.rc = rcArea; outlineParam.layer = layer; outlineParam.traceWidth = traceWidth; outlineParam.option = 0; //-------------------------------------------------- sw.Start(); //最初にランド、パッドだけの外形線を構築する。 foreach (MbeObj obj in workList) { if (obj.Id() == MbeObjID.MbePTH || obj.Id() == MbeObjID.MbePinSMD) { if (obj.Id() == MbeObjID.MbePinSMD && obj.Layer != layer) { continue; } if (!obj.ConnectionCheckActive || obj.TempPropString.Length > 0) { int netnum; if (!obj.ConnectionCheckActive) { outlineParam.gap = patternGap; netnum = -1; } else { outlineParam.gap = thermalGap; netnum = 0; } int c1 = tempList2.Count; obj.GenerateOutlineData(tempList2, outlineParam); if (c1 != tempList2.Count) { obj.GenerateGapChkData(keepOutPatterns, netnum); pinList.AddLast((MbeObjPin)obj); //アウトラインを生成するピンのリストに登録 } } else { obj.GenerateGapChkData(connectPatterns, 0); } } } //四角枠上下左右外のものを取り除く foreach (MbeGapChkObjLine obj in tempList2) { if (Util.LineIsOutsideLTRB(obj.p0, obj.p1, rcArea)) { continue; } tempList1.AddLast(obj); } tempList2.Clear(); optimizeVHLine(tempList1); //交点で切断する DoDivideLineAtCrossing(tempList1); RemovePtnTouchKeeepOut(tempList1, tempList2); tempList1.Clear(); //ここまででランド、パッドだけの外形線がtempList2に保存される //ランドパッド以外の外形線を追加する foreach (MbeObj obj in workList) { //ランドパッドは処理済みなのでcontinueで飛ばす if (obj.Id() == MbeObjID.MbePTH || obj.Id() == MbeObjID.MbePinSMD) { continue; } outlineParam.option = 0; if (!obj.ConnectionCheckActive) { //↓ランドやパッドに埋まったラインアウトラインの端点キャップは省けるかと考えた // ギャップトレース設定が小さいときは端点のランドやパッドの検索に時間がかかって、 // あまり得にならない。 // ////ラインデータのときは端点にランドパッドがないかチェックする。 ////端点にランドパッドがあって、それが線幅より大きいものであれば、外形線のエンドキャップは要らない if (obj.Id() == MbeObjID.MbeLine && obj.Layer == layer) { int linewidth = ((MbeObjLine)obj).LineWidth; Point leP0 = ((MbeObjLine)obj).GetPos(0); Point leP1 = ((MbeObjLine)obj).GetPos(1); foreach (MbeObjPin objPin in pinList) { Point padPt = objPin.GetPos(0); if (padPt.Equals(leP0)) { Size padSize = objPin.PadSize; if (padSize.Width >= linewidth && padSize.Height >= linewidth) { outlineParam.option |= GenOutlineParam.P0_NO_LINECAP; } } else if (padPt.Equals(leP1)) { Size padSize = objPin.PadSize; if (padSize.Width >= linewidth && padSize.Height >= linewidth) { outlineParam.option |= GenOutlineParam.P1_NO_LINECAP; } } if (outlineParam.option == (GenOutlineParam.P0_NO_LINECAP | GenOutlineParam.P1_NO_LINECAP)) { break; } } } outlineParam.gap = patternGap; int c1 = tempList1.Count; obj.GenerateOutlineData(tempList1, outlineParam); if (c1 != tempList1.Count) { if (obj.Id() == MbeObjID.MbeText) { MbeGapChkObjRect gapChkObj = new MbeGapChkObjRect(); gapChkObj.layer = layer; gapChkObj.netNum = -1; gapChkObj.mbeObj = obj; gapChkObj.SetRectValue(((MbeObjText)obj).AreaRect()); keepOutPatterns.AddLast(gapChkObj); } else if (obj.Id() == MbeObjID.MbePolygon) { ((MbeObjPolygon)obj).FullFillLineData(keepOutPatterns); } else if (obj.Id() == MbeObjID.MbeHole) { ((MbeObjHole)obj).KeepOutData(keepOutPatterns, -1); } else { obj.GenerateGapChkData(keepOutPatterns, -1); } } } else { obj.GenerateGapChkData(connectPatterns, -1); } } sw.Stop(); time_ms = sw.ElapsedMilliseconds; System.Diagnostics.Debug.WriteLine("Fill polygon Step2-1: " + time_ms); sw.Reset(); //-------------------------------------------------- sw.Start(); //if (tempList1.Count == 0) return; //四角枠上下左右外のものを取り除く foreach (MbeGapChkObjLine obj in tempList1) { if (Util.LineIsOutsideLTRB(obj.p0, obj.p1, rcArea)) { continue; } tempList2.AddLast(obj); } optimizeVHLine(tempList2); //サーマルパッド処理 foreach (MbeObj obj in workList) { if (obj.Layer == layer || obj.Layer == MbeLayer.LayerValue.PTH) { if (obj.Id() == MbeObjID.MbePTH || obj.Id() == MbeObjID.MbePinSMD) { if (obj.ConnectionCheckActive && obj.TempPropString.Length > 0) { Point pc = obj.GetPos(0); bool onFrame; //dummy if (!PointIsInside(pc, 0, out onFrame)) { continue; } int padWidth = ((MbeObjPin)obj).PadSize.Width; int padHeight = ((MbeObjPin)obj).PadSize.Height; int hlen = (padWidth + traceWidth) / 2 + thermalGap; int vlen = (padHeight + traceWidth) / 2 + thermalGap; MbeGapChkObjLine thLine; int lineWidthBase = thermalGap * 15 / 10; if (lineWidthBase < 2000) { lineWidthBase = 2000; } int lineWidth; Point pe; pe = pc; pe.X = pc.X - hlen; lineWidth = (lineWidthBase < padHeight ? lineWidthBase : padHeight); thLine = new MbeGapChkObjLine(); thLine.SetLineValue(pc, pe, lineWidth); thLine.netNum = 0; tempList2.AddLast(thLine); pe.X = pc.X + hlen; thLine = new MbeGapChkObjLine(); thLine.SetLineValue(pc, pe, lineWidth); thLine.netNum = 0; tempList2.AddLast(thLine); pe = pc; pe.Y = pc.Y - vlen; lineWidth = (lineWidthBase < padWidth ? lineWidthBase : padWidth); thLine = new MbeGapChkObjLine(); thLine.SetLineValue(pc, pe, lineWidth); thLine.netNum = 0; tempList2.AddLast(thLine); pe = pc; pe.Y = pc.Y + vlen; thLine = new MbeGapChkObjLine(); thLine.SetLineValue(pc, pe, lineWidth); thLine.netNum = 0; tempList2.AddLast(thLine); } } } } sw.Stop(); time_ms = sw.ElapsedMilliseconds; System.Diagnostics.Debug.WriteLine("Fill polygon Step2-2: " + time_ms); sw.Reset(); //-------------------------------------------------- sw.Start(); //作業用枠線を追加する foreach (MbeGapChkObjLine obj in frameLineList) { tempList2.AddLast(obj); } frameLineList.Clear(); //交点で切断する DoDivideLineAtCrossing(tempList2); sw.Stop(); time_ms = sw.ElapsedMilliseconds; System.Diagnostics.Debug.WriteLine("Fill polygon Step2-3: " + time_ms); sw.Reset(); //-------------------------------------------------- sw.Start(); RemovePtnTouchKeeepOut(tempList2, tempList1); sw.Stop(); time_ms = sw.ElapsedMilliseconds; System.Diagnostics.Debug.WriteLine("Fill polygon Step2-4: " + time_ms); sw.Reset(); //-------------------------------------------------- sw.Start(); //片端点が枠外のものを取り除く foreach (MbeGapChkObjLine obj in tempList1) { bool p0onFrame = false; bool p1onFrame = false; if (!PointIsInside(obj.p0, 600, out p0onFrame) || !PointIsInside(obj.p1, 600, out p1onFrame)) { continue; } //両端点が枠内と判定されても、両端点が枠線上にあって、中点が枠外のときは取り除く if (obj.status != LINE_STATUS_FRAME && p0onFrame && p1onFrame) { Point pc = new Point((obj.p0.X + obj.p1.X) / 2, (obj.p0.Y + obj.p1.Y) / 2); bool pconFrame; if (!PointIsInside(pc, 100, out pconFrame)) { continue; } } outlineList.AddLast(obj); } sw.Stop(); time_ms = sw.ElapsedMilliseconds; System.Diagnostics.Debug.WriteLine("Fill polygon Step2-5: " + time_ms); sw.Reset(); //-------------------------------------------------- }
/// <summary> /// ポリゴンのための輪郭データを生成する。 /// </summary> /// <param name="outlineList"></param> /// <param name="param"></param> /// <remarks> /// ここで生成する輪郭データは内側に重なっていても良いものとする /// 2009/01/01 ラインアウトラインの端点キャップ省略を止める。常に端点キャップ生成 /// </remarks> public override void GenerateOutlineData(LinkedList <MbeGapChkObjLine> outlineList, GenOutlineParam param) { if (param.layer != Layer) { return; } Point ptVia; bool bendMode = getPointVia(out ptVia); Point[] pt = new Point[3]; int lines; if (bendMode) { pt[0] = GetPos(0); pt[1] = ptVia; pt[2] = GetPos(1); lines = 2; } else { pt[0] = GetPos(0); pt[1] = GetPos(1); lines = 1; } int distance = (LineWidth + param.traceWidth) / 2 + param.gap * 11 / 10; int left = param.rc.L - distance; int top = param.rc.T + distance; int right = param.rc.R + distance; int bottom = param.rc.B - distance; MbeRect rcArea = new MbeRect(new Point(left, top), new Point(right, bottom)); Point[] ptOutline; for (int i = 0; i < lines; i++) { if (Util.LineIsOutsideLTRB(pt[i], pt[i + 1], rcArea)) { continue; } bool revBeginEnd; Util.LineOutlineData(pt[i], pt[i + 1], distance, out ptOutline, out revBeginEnd); bool p0Nocap = false; bool p1Nocap = false; if (bendMode) { if (i == 0) { if (revBeginEnd) { p1Nocap = (param.option & GenOutlineParam.P0_NO_LINECAP) != 0; } else { p0Nocap = (param.option & GenOutlineParam.P0_NO_LINECAP) != 0; } } else if (i == 1) { if (revBeginEnd) { p0Nocap = (param.option & GenOutlineParam.P1_NO_LINECAP) != 0; } else { p1Nocap = (param.option & GenOutlineParam.P1_NO_LINECAP) != 0; } } } else { if (revBeginEnd) { p1Nocap = (param.option & GenOutlineParam.P0_NO_LINECAP) != 0; p0Nocap = (param.option & GenOutlineParam.P1_NO_LINECAP) != 0; } else { p0Nocap = (param.option & GenOutlineParam.P0_NO_LINECAP) != 0; p1Nocap = (param.option & GenOutlineParam.P1_NO_LINECAP) != 0; } } for (int j = 0; j < 8; j++) { int j2 = j + 1; if (j2 == 8) { j2 = 0; } //不要なときはラインキャップを生成しない //if (bendMode) { // if (p0Nocap && i == 0) { // if (j >= 5 && j <= 7) continue; // } // if (p1Nocap && i == 1) { // if (j >= 1 && j <= 3) continue; // } //} else { if (p0Nocap) { //System.Diagnostics.Debug.WriteLine("Skip begin cap"); if (j >= 5 && j <= 7) { continue; } } if (p1Nocap) { //System.Diagnostics.Debug.WriteLine("Skip end cap"); if (j >= 1 && j <= 3) { continue; } } //} if (!Util.LineIsOutsideLTRB(ptOutline[j], ptOutline[j2], param.rc)) { MbeGapChkObjLine objLine = new MbeGapChkObjLine(); objLine.SetLineValue(ptOutline[j], ptOutline[j2], param.traceWidth); outlineList.AddLast(objLine); } } } }