介紹一種: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
 
