PCB SMD帖片与铜皮接触的周长按比例划分新层

      介绍一种: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;
        }
View Code
 四.实现效果

     将 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

 

 

posted @ 2020-05-31 00:57  pcbren  阅读(1197)  评论(0编辑  收藏  举报