介绍一种:SMD帖片与铜皮接触的周长按比例划分新层,采用Genesis实现方法
一.需求说明
1.SMD与铜皮接触的周长(绿色线条标识)与SMD周长按比例进行划分,拆分到新层
如下所示:周长所占比例不同拆分到新的层。
二.脚本实现思路
具体体查看代码实现(和整板字符缩放原理相同).
三. 代码实现
1.调用主方法【SMD帖片与铜皮接触的周长按比例划分新层】
将 cs层SMD与铜皮接触周长所占比例,0%-20%,20%-40%,40%-60%,60%-80%,80%-100%划分新层
SolderMaskHandle.SMDLengthScaleToLayer("cs", new List<int>() { 20, 40, 60, 80 });
2.主方法实现【SMD帖片与铜皮接触的周长按比例划分新层】
/// <summary> /// SMD帖片与铜皮接触的周长按比例划分新层 /// </summary> /// <param name="WorkLayer"></param> /// <param name="PercentageList"></param> public static void SMDLengthScaleToLayer(string WorkLayer, List<int> PercentageList) { if (PercentageList.Count() == 0) return; if (!g.Check_Layer_Exist(WorkLayer)) return; if (PercentageList[PercentageList.Count - 1] != 100) PercentageList.Add(100); g.SetWorkLayer(); g.SetAffectedLayer(WorkLayer); g.FilterReset(); g.FilterAtrSet(".smd;.bga"); g.FilterAtr_Logic(); g.FilterSelect(); if (g.getSelectCount() > 0) { //拷贝贴片与线路 分别到新层 string WorkLayer_smd = $"{WorkLayer}_smd"; string WorkLayer_signal = $"{WorkLayer}_signal"; g.Sel_CopyLayer(WorkLayer_smd); g.FilterSelect(); g.COM(g._sel_reverse); g.Sel_CopyLayer(WorkLayer_signal); g.FilterReset(); //转Surface g.SetAffectedLayer(WorkLayer_smd); g.Sel_Contourize(0, 0); g.SetAffectedLayer(WorkLayer_signal); g.Sel_Ref_feat(Ref_feat_mode.touch, WorkLayer_smd); g.COM(g._sel_reverse); if (g.getSelectCount() > 0) g.COM(g._sel_delete); g.Sel_Contourize(0, 0); //挑选没有被覆盖的PAD g.SetAffectedLayer(WorkLayer_smd); g.Sel_Ref_feat(Ref_feat_mode.disjoint, WorkLayer_signal); if (g.getSelectCount() > 0) g.Sel_MoveLayer($"{WorkLayer}_disjoint"); //挑选完全覆盖的PAD g.Sel_Ref_feat(Ref_feat_mode.cover, WorkLayer_signal); if (g.getSelectCount() > 0) g.Sel_MoveLayer($"{WorkLayer}_covered"); //接触PAD g.CopyLayer(WorkLayer_smd, $"{WorkLayer}_touch"); //2层转为Outline g.SetAffectedLayer(WorkLayer_signal); g.CopyLayer(WorkLayer_smd, WorkLayer_signal, false, true); g.Sel_Contourize(0, 0); g.Sel_Resize(-1); g.Sel_Resize(1); g.Sel_Surf2Outline(10); g.SetAffectedLayer(WorkLayer_smd); g.Sel_Surf2Outline(20); //WorkLayer_smd outline转为surface做为参考 g.CopyLayer(WorkLayer_smd, $"{WorkLayer_smd}_ref"); g.SetAffectedLayer($"{WorkLayer_smd}_ref"); g.Sel_Contourize(0, 0); //处理一半覆盖且一半不覆盖SMD g.SetAffectedLayer(WorkLayer_signal); g.Sel_Ref_feat(Ref_feat_mode.cover, WorkLayer_smd); if (g.getSelectCount() > 0) { g.COM(g._sel_reverse); if (g.getSelectCount() > 0) g.COM(g._sel_delete); g.SetAffectedLayer($"{WorkLayer}_touch"); g.COM(g._sel_reverse); var touchCount = g.getSelectCount(); g.COM(g._sel_clear_feat); g.CopyLayer(WorkLayer_signal, $"{WorkLayer}_touch", false); d2 calc2 = new d2(); for (int i = 1; i <= touchCount; i++) { g.Sel_Layer_feat(i, $"{WorkLayer}_touch"); g.Sel_Ref_feat(Ref_feat_mode.touch); if (g.getSelectCount() > 0) { var LayerFeat = g.getFEATURES($"{WorkLayer}_touch"); var LineLength = LayerFeat.Llist.Sum(tt => calc2.p2p_di(tt.ps, tt.pe)); var ArcLength = LayerFeat.Alist.Sum(tt => calc2.a_Length(tt)); g.COM(g._sel_clear_feat); g.Sel_Layer_feat(i, $"{WorkLayer}_touch"); LayerFeat = g.getFEATURES($"{WorkLayer}_touch"); var SurfaceLength = calc2.s_Length(LayerFeat.Slist); var SMD_CoverScale = (LineLength + ArcLength) / SurfaceLength * 100; var Index = PercentageList.FindIndex(tt => SMD_CoverScale <= tt); var PreScaleVal = Index == 0 ? 0 : PercentageList[Index - 1]; var CurrentScaleVal = PercentageList[Index]; g.Sel_CopyLayer($"{WorkLayer}_{PreScaleVal}_{CurrentScaleVal}"); } } g.SetAffectedLayer($"{WorkLayer}_touch"); g.FilterFeatTypeSet(@"line;pad;arc;text"); g.FilterSelect(); if (g.getSelectCount() > 0) g.COM(g._sel_delete); g.FilterReset(); g.SetAffectedLayer(); } g.DelLayer($"{WorkLayer_smd}_ref"); g.DelLayer($"{WorkLayer_smd}"); g.DelLayer($"{WorkLayer_signal}"); } }
3.相关铜皮周长计算用到的方法:
/// <summary> /// 求Surface 总周长 /// </summary> /// <param name="gS_list"></param> /// <returns></returns> public double s_Length(List<gS> gS_list) { int Surface_Count = gS_list.Count(); double SurfaceArea = 0; foreach (var gS_item in gS_list) { foreach (var Polyline in gS_item.sur_group) { SurfaceArea += s_Length(Polyline.sur_list); } } return SurfaceArea; } /// <summary> /// 求Surface 总周长 /// </summary> /// <param name="gSur_Point_list"></param> /// <returns></returns> public double s_Length(List<gSur_Point> gSur_Point_list) { double sum_lenght = 0; bool is_flag = false; bool ccw = false; for (int i = 1; i < gSur_Point_list.Count; i++) { if (is_flag) { is_flag = false; continue; } if (gSur_Point_list[i].type_point > 0) { if (gSur_Point_list[i].type_point == 2) ccw = true; else ccw = false; sum_lenght += a_Length(gSur_Point_list[i - 1].p, gSur_Point_list[i].p, gSur_Point_list[i + 1].p, ccw); is_flag = true; } else { sum_lenght += l_Length(gSur_Point_list[i - 1].p, gSur_Point_list[i].p); } } return sum_lenght; } /// <summary> /// 求弧Arc长度 3点 /// </summary> /// <param name="ps"></param> /// <param name="pc"></param> /// <param name="pe"></param> /// <returns></returns> public double a_Length(gPoint ps, gPoint pc, gPoint pe, bool ccw = false) { return pi / 180 * p2p_di(pc, ps) * a_Angle(ps, pc, pe, ccw); } /// <summary> /// 求线Line长度 2点 /// </summary> /// <param name="ps"></param> /// <param name="pe"></param> /// <returns></returns> public double l_Length(gPoint ps, gPoint pe) { return Math.Sqrt((ps.x - pe.x) * (ps.x - pe.x) + (ps.y - pe.y) * (ps.y - pe.y)); } /// <summary> /// 求弧Arc圆心角 3点 //后续改进 用叉积 与3P求角度求解 验证哪个效率高 /// </summary> /// <param name="ps"></param> /// <param name="pc"></param> /// <param name="pe"></param> /// <param name="ccw"></param> /// <returns></returns> public double a_Angle(gPoint ps, gPoint pc, gPoint pe, bool ccw, bool islg180deg = false) { double angle_s, angle_e, angle_sum; if (ccw) { angle_s = p_ang(pc, pe); angle_e = p_ang(pc, ps); } else { angle_s = p_ang(pc, ps); angle_e = p_ang(pc, pe); } if (angle_s == 360) { angle_s = 0; } if (angle_e >= angle_s) { angle_sum = 360 - (angle_e - angle_s); //360 - Math.Abs(angle_s - angle_e); } else { angle_sum = angle_s - angle_e;//Math.Abs(angle_s - angle_e); } if (islg180deg && angle_sum > 180) { angle_sum = 360 - angle_sum; } return angle_sum; }
四.实现效果
将 cs层SMD与铜皮接触周长所占有比例,0%-20%,20%-40%,40%-60%,60%-80%,80%-100%划分新层
新层分别为: cs_0_20,cs_20_40,cs_40_60,cs_60_80,cs_80_100