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); } } }
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> 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(); //-------------------------------------------------- }