PCB genesis識別郵票孔開通窗實現方法


       介紹一種常規的genesis識別郵票孔開通窗實現方法

 一.需求:識別郵票孔並開通窗

 二.常見的幾種郵票孔類型

 

 三.郵票孔有哪些特征

     1.  郵票孔屬性是NPTH無銅孔(non_plated)

     2. 郵票孔與郵票孔間距常規<=0.5mm

     3.郵票孔與外形間距<=0.5mm

     4.郵票孔個數 通常>=3個 (也存在1個或2個郵票孔的情況)

 

     5.郵票孔與郵票孔間距步長公差不超過0.2mm

     6.郵票孔與郵票孔角度步長公差不超過0.2度

     7.郵票孔3點最大角>150度(此規則是對第6條特征補充,當郵票孔剛好只有3個孔的時候,可以用角度來判斷是否郵票孔)

 

 

 

 四.代碼實現(跟據定義的郵票孔特征來代碼實現)
        /// <summary>
        /// 從鑽孔層中獲取郵孔並創建新層
        /// </summary>
        /// <param name="DrillLayer">鑽孔層名</param>
        /// <param name="RoutLayer">外形層名</param>
        /// <param name="StampHoleLayer">郵票孔創建層名</param>
        /// <param name="StampHoleUpVal">郵票最大間距</param>
        /// <param name="Ang_Tol">允許角度公差</param>
        /// <param name="Di_Tol">允許距離公差</param>
        /// <param name="AngDiff_Standard">角度差值</param>
        /// <returns>【-1】 未檢測到NPTH孔  【0】檢測到郵票孔 >【0】檢測到郵票孔組數</returns>
        public static int CreateStampHoleLayer(string DrillLayer = "drl", string RoutLayer = "rout", string stamp_holeLayerName = "stamp_hole", double StampHoleUpVal = 500, double Ang_Tol = 0.2, double Di_Tol = 0.2, double AngDiff_Standard = 30)
        {
            StampHoleUpVal *= 2;
            var SurfaceFeatCount = 0;
            g.SetWorkLayer("");
            g.COM(g._change_units_mm);
            g.SetAffectedLayer(DrillLayer);
            g.FilterAtrSet(".drill", "non_plated");
            g.FilterSelect();
            g.FilterReset();
            if (g.getSelectCount() == 0)
                return -1;
            //判斷是否存在郵票孔
            string npth_hole = "npth_hole";
            string npth_hole_surface = "npth_hole_surface";
            g.Sel_CopyLayer(npth_hole);
            g.CopyLayer(npth_hole, npth_hole_surface);
            g.SetAffectedLayer(npth_hole_surface);
            g.Sel_Resize(StampHoleUpVal);
            g.Sel_Contourize();
            if (g.Check_Layer_Exist(RoutLayer))
            {
                g.Sel_Ref_feat(Ref_feat_mode.touch, RoutLayer);
                g.getSelectCountReverseIsDelete();
            }
            g.SetAffectedLayer(npth_hole);
            g.Sel_Resize(StampHoleUpVal + 100);
            g.Sel_Ref_feat(Ref_feat_mode.include, npth_hole_surface);
            g.getSelectCountIsDelete();
            g.Sel_Ref_feat(Ref_feat_mode.touch, npth_hole_surface);
            g.getSelectCountReverseIsDelete();
            g.Sel_Resize(-(StampHoleUpVal + 100));
            var HoleFeatCount = g.getLayerFeatCount();
            g.SetAffectedLayer(npth_hole_surface);
            g.Sel_Ref_feat(Ref_feat_mode.disjoint, npth_hole);
            g.getSelectCountIsDelete();
            SurfaceFeatCount = g.getLayerFeatCount();
            g.DelLayer(stamp_holeLayerName);
            g.CopyLayer(npth_hole_surface, stamp_holeLayerName);
            g.CopyLayer(npth_hole, stamp_holeLayerName);
            g.DelLayer(npth_hole_surface);
            g.DelLayer(npth_hole);

            //選擇並獲取郵票孔
            g.SetAffectedLayer(stamp_holeLayerName);
            gLayer StampHoleLayer = new gLayer();
            d2 calc2 = new d2();
            add addCOM = new add();
            for (int i = 1; i <= SurfaceFeatCount; i++)
            {
                g.COM(g._sel_clear_feat);
                g.Sel_Layer_feat(i, stamp_holeLayerName);
                g.Sel_Ref_feat(Ref_feat_mode.touch);
                if (g.getSelectCount() >= 3)
                {
                    bool isOK = true;
                    bool isArc = false;
                    var StampHoleList = g.getFEATURES(stamp_holeLayerName).Plist;
                    var StampHoleSymbolCount = StampHoleList.GroupBy(tt => tt.symbols).Select(tt => tt.Key).Count();
                    if (StampHoleSymbolCount > 1) continue;
                    var StampHoleRect = calc2.p_RectP(StampHoleList);
                    if (StampHoleRect.size.x > StampHoleRect.size.y)
                        StampHoleList = StampHoleList.OrderBy(tt => tt.p.x).ToList();
                    else
                        StampHoleList = StampHoleList.OrderBy(tt => tt.p.y).ToList();
                    var AngPre = calc2.p_ang(StampHoleList[0].p, StampHoleList[1].p);
                    var AngDiffPre = 0.0;
                    var DiPre = calc2.p2p_di(StampHoleList[0].p, StampHoleList[1].p);
                    for (int j = 2; j < StampHoleList.Count(); j++)
                    {
                        var Ang = calc2.p_ang(StampHoleList[j - 1].p, StampHoleList[j].p);
                        var AngDiff = Math.Abs(Ang - AngPre);
                        isArc = AngDiff > 0.01;
                        var Di = calc2.p2p_di(StampHoleList[j - 1].p, StampHoleList[j].p);
                        if (!(AngDiff <= AngDiff_Standard)) { isOK = false; break; }
                        if (!(Math.Abs(DiPre - Di) <= Di_Tol)) { isOK = false; break; }
                        if (j >= 3 && !(Math.Abs(AngDiffPre - AngDiff) <= Ang_Tol)) { isOK = false; break; }
                        AngPre = Ang;
                        AngDiffPre = AngDiff;
                        DiPre = Di;
                    }
                    if (isOK)
                    {
                        var Width = d2.getSymbolsVal(StampHoleList[0].symbols);
                        if (isArc)
                        {
                            var Pcenter = calc2.a_3Point2Acenter(StampHoleList[0].p, StampHoleList[StampHoleList.Count >> 1].p, StampHoleList[StampHoleList.Count - 1].p);
                            gA arc = new gA(StampHoleList[0].p, Pcenter, StampHoleList[StampHoleList.Count - 1].p, Width);
                            if (calc2.a_Angle(arc) >= 180) arc.ccw = true;
                            addCOM.arc(arc);
                            StampHoleLayer.Alist.Add(arc);
                        }
                        else
                        {
                            gL line = new gL(StampHoleList[0].p, StampHoleList[StampHoleList.Count - 1].p, Width);
                            StampHoleLayer.Llist.Add(line);
                        }
                    }
                }
            }
            g.COM(g._sel_clear_feat);
            g.COM(g._sel_delete);
            int FeatCount = (StampHoleLayer.Llist.Count() + StampHoleLayer.Alist.Count());
            if (FeatCount > 0)
                addCOM.any(StampHoleLayer);
            else
                g.DelLayer(stamp_holeLayerName);
            g.SetAffectedLayer();
            return FeatCount;
        }
 五.實現效果


免責聲明!

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



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