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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM