zoukankan      html  css  js  c++  java
  • PCB ODB++(Gerber)图形绘制实现方法

    这里讲解一下用net解析PCB图形绘制实现方法

    一.解析PCB图形绘制实现

          解析PCB图形,说简单也非常简单,先说一下,PCB Gerber图形由:点,线,弧,铜皮,文字 5类元素组成,通常简写为:P,L,A,S,T五类,这几类元素的难易程度,刚好是按这个顺序排列的(个人实际应用这么认为的)。即然是5类就得建立5种元素的数据结构存储它吧,

        PAD结构

        /// <summary>
        /// PAD  数据类型
        /// </summary>
        public struct gP
        {
            public gPoint p;
            public bool negative;//polarity-- positive  negative
            public int angle;
            public bool mirror;
            public string symbols;
            public string attribut;
            public double width;
        }

       线结构

        /// <summary>
        /// Line 数据类型
        /// </summary>
        public struct gL
        {
            public gPoint ps;
            public gPoint pe;
            public bool negative;//polarity-- positive  negative
            public string symbols;
            public string attribut;
            public double width;
        }

     弧结构

        /// <summary>
        /// ARC 数据类型
        /// </summary>
        public struct gA
        {
            public gPoint ps;
            public gPoint pe;
            public gPoint pc;
            public bool negative;//polarity-- positive  negative
            public bool ccw; //direction-- cw ccw
            public string symbols;
            public string attribut;
            public double width;
        }

    铜皮结构

        /// <summary>
        /// Surface 坐标泛型集类1
        /// </summary>
        public struct gSur_Point
        {
            public gPoint p;
            /// <summary>
            /// 0为折点  1为顺时针 2为逆时针  
            /// </summary>
            public byte type_point;
        }
        /// <summary>
        /// Surface 坐标泛型集类2
        /// </summary>
        public class gSur_list
        {
            public List<gSur_Point> sur_list = new List<gSur_Point>();
            /// <summary>
            /// 是否为空洞
            /// </summary>
            public bool is_hole { get; set; }
            /// <summary>
            /// 是否逆时针
            /// </summary>
            public bool is_ccw { get; set; }
        }
        /// <summary>
        /// Surface 坐标泛型集类3
        /// </summary>
        public class gS
        {
            public List<gSur_list> sur_group = new List<gSur_list>();
            /// <summary>
            /// 是否为负  polarity-- P N
            /// </summary>
            public bool negative { get; set; }
            public string attribut { get; set; }
        }

    文字结构

       看这个结构比Surface铜皮结构还简单呀,为什么文字结构更复杂了,这里只是实现最普通的字体结构,实际复杂程度远大于Surface,需要解析到所用到的字体库中的的坐标,而且字体存在各式各样的,有二维码,点阵字,有条码,要想保证和Genesis所显示一致,这里需要下点功夫。

        /// <summary>
        /// Text 文本数据类型  简易型  更复杂的需要扩展
        /// </summary>
        public struct gT
        {
            public gPoint ps;
            public string font;
            public bool negative;//polarity-- positive  negative
            public int angle;
            public bool mirror;
            public double x_size;
            public double y_size;
            public double width;
            public string Text;
            public string attribut;
        }

    那么为什么symbols不算一类呢,因为symbols也是由这5类基础元素组合而成的,绘制时检索symbols中所含元素集合,再将Symbols集合遍历一个一个的元素绘制到画板上来的。

          Gerber数据存储到这个结构中后.那用Graphics类,遍历元素集合,依次绘制元素就好了;下面说一下遇到的问题解决方法

    二.绘制Gerber图形遇到的几个问题解决方法

    1.同一层图形的元素是存在先后顺序的,不能按元素类别分类集合,如List<P>,List<L>,这样是错误的

         若元素要按先后顺序保存,那么这里可以选择用ArrayList集合存储数据

    2.绘制圆形焊盘时,对于Genesis而言它是一个点坐标,在net中是没有直接绘制点方法.

         那么对应net中是用FillEllipse方法绘制就可以了

    3.绘制焊盘有很多种symbols,包含标准symbols和非标准symbols(自定义的),如何判断一个symbols是标准symbols还是非标准symbols呢

      在解析ODB++或Gerber前,提前将自定义symbols名存储为自定义symbols字典集合中,绘制时优先检测symbols名是否存在自定义字典集合中,如果存在,则解析自定义symbosl绘制,如果不存在,则通过标准symbosl名命名规则匹配,不考虑校率用正则也可以的,如:r200,rect200x300,oval200x300,donut_r300x200等,匹配到标准symbols后通过建立各种标准symbols绘制模版,找到对应的symbols模版再绘制。

    4.如绘制:donut_r300x200这个symbols时,是绘制300这个实心圆,再绘制黑色背景实现圆环效果呢,

       其实这样绘制就是错误的,需采用:GraphicsPath类绘制,再用Region类差集裁减掉不需要多余部份图形。

    5.在Gerber图形中一条弧直径只有0.1毫米,转为像素为0,绘制会出错,

        要这里需加以判断,0像素时直接跳出不绘

    6.在Gerber图形中一条线段,线段间距只有0.1毫米, 转为像素为0时,但线宽为5毫米,转为像不为2像素,

       那这是绘呢,还是不绘呢,由于长度像素是0,但线的宽度达到了2个像素,那么就这条线就按一个点来绘制

    7.在Gerber中Surface铜皮中存在空洞时,不能用FillPolygon方法绘制,

         需采用:GraphicsPath类绘制,再用Region类差集裁减掉不需要多余部份图形

    8.在Gerber中Surface铜皮存在弧节点时,不能用FillPolygon方法绘制,这结构它不支持弧节点,

      如果一定要要用FillPolygon可以将弧转为多个节点来绘制多边形,当然另一种方法用GraphicsPath类中增Arc结点来完成弧的绘制

    9.Gerber中如果字体引用了shx字体如何解析呢

        这里就需要熟悉shx的数据结构了才行了,不然一点办法也没有

         点击进去:  https://wenku.baidu.com/view/0f7d49c4aa00b52acfc7cab3.html   这是解析方法,解析后再转为坐标数据就可以了

    10.果是:canned_57,standard等字体如何解析呢

      这是Genesis自带字体,文件一般存放在:C:genesisfwlibfonts,这是明文坐标很好解决,直接解析就好了。

    三.5类元素基本数据结构

          这是基本的不全面,可以扩展并改进的

     /// <summary>
        /// 点  数据类型 (XY)
        /// </summary>
        public struct gPoint
        {
            public gPoint(gPoint p_)
            {
                this.x = p_.x;
                this.y = p_.y;
            }
            public gPoint(double x_val, double y_val)
            {
                this.x = x_val;
                this.y = y_val;
            }
            public double x;
            public double y;
            public static gPoint operator +(gPoint p1, gPoint p2)
            {
                p1.x += p2.x;
                p1.y += p2.y;
                return p1;
            }
            public static gPoint operator -(gPoint p1, gPoint p2)
            {
                p1.x -= p2.x;
                p1.y -= p2.y;
                return p1;
            }
    
    
        }
    
        /// <summary>
        /// 精简 PAD  数据类型
        /// </summary>
        public struct gPP
        {
            public gPP(double x_val, double y_val, double width_)
            {
                this.p = new gPoint(x_val, y_val);
                this.symbols = "r";
                this.width = width_;
            }
            public gPP(gPoint p_, double width_)
            {
                this.p = p_;
                this.symbols = "r";
                this.width = width_;
            }
            public gPP(gPoint p_, string symbols_, double width_)
            {
                this.p = p_;
                this.symbols = symbols_;
                this.width = width_;
            }
            public gPoint p;
            public string symbols;
            public double width;
            public static gPP operator +(gPP p1, gPP p2)
            {
                p1.p += p2.p;
                return p1;
            }
            public static gPP operator +(gPP p1, gPoint p2)
            {
                p1.p += p2;
                return p1;
            }
            public static gPP operator -(gPP p1, gPP p2)
            {
                p1.p -= p2.p;
                return p1;
            }
            public static gPP operator -(gPP p1, gPoint p2)
            {
                p1.p -= p2;
                return p1;
            }
        }
        /// <summary>
        /// PAD  数据类型
        /// </summary>
        public struct gP
        {
            public gP(double x_val, double y_val, double width_)
            {
                this.p = new gPoint(x_val, y_val);
                this.negative = false;
                this.angle = 0;
                this.mirror = false;
                this.symbols = "r";
                this.attribut = string.Empty;
                this.width = width_;
            }
            public gP(gPoint p_, double width_)
            {
                this.p = p_;
                this.negative = false;
                this.angle = 0;
                this.mirror = false;
                this.symbols = "r";
                this.attribut = string.Empty;
                this.width = width_;
            }
            public gP(gPoint p_, string symbols_, double width_)
            {
                this.p = p_;
                this.negative = false;
                this.angle = 0;
                this.mirror = false;
                this.symbols = symbols_;
                this.attribut = string.Empty;
                this.width = width_;
            }
    
            public gPoint p;
            public bool negative;//polarity-- positive  negative
            public int angle;
            public bool mirror;
            public string symbols;
            public string attribut;
            public double width;
            public static gP operator +(gP p1, gP p2)
            {
                p1.p += p2.p;
                return p1;
            }
            public static gP operator +(gP p1, gPP p2)
            {
                p1.p += p2.p;
                return p1;
            }
            public static gP operator +(gP p1, gPoint p2)
            {
                p1.p += p2;
                return p1;
            }
            public static gP operator -(gP p1, gP p2)
            {
                p1.p -= p2.p;
                return p1;
            }
            public static gP operator -(gP p1, gPP p2)
            {
                p1.p -= p2.p;
                return p1;
            }
            public static gP operator -(gP p1, gPoint p2)
            {
                p1.p -= p2;
                return p1;
            }
        }
        /// <summary>
        /// Line 数据类型
        /// </summary>
        public struct gL
        {
            public gL(double ps_x, double ps_y, double pe_x, double pe_y, double width_)
            {
                this.ps = new gPoint(ps_x, ps_y);
                this.pe = new gPoint(pe_x, pe_y);
                this.negative = false;
                this.symbols = "r" + width_.ToString();
                this.attribut = string.Empty;
                this.width = width_;
            }
            public gL(gPoint ps_, gPoint pe_, double width_)
            {
                this.ps = ps_;
                this.pe = pe_;
                this.negative = false;
                this.symbols = "r" + width_.ToString();
                this.attribut = string.Empty;
                this.width = width_;
            }
            public gL(gPoint ps_, gPoint pe_, string symbols_, double width_)
            {
                this.ps = ps_;
                this.pe = pe_;
                this.negative = false;
                this.symbols = symbols_;
                this.attribut = string.Empty;
                this.width = width_;
            }
            public gPoint ps;
            public gPoint pe;
            public bool negative;//polarity-- positive  negative
            public string symbols;
            public string attribut;
            public double width;
            public static gL operator +(gL l1, gPoint move_p)
            {
                l1.ps += move_p;
                l1.pe += move_p;
                return l1;
            }
            public static gL operator +(gL l1, gPP move_p)
            {
                l1.ps += move_p.p;
                l1.pe += move_p.p;
                return l1;
            }
            public static gL operator +(gL l1, gP move_p)
            {
                l1.ps += move_p.p;
                l1.pe += move_p.p;
                return l1;
            }
            public static gL operator -(gL l1, gPoint move_p)
            {
                l1.ps -= move_p;
                l1.pe -= move_p;
                return l1;
            }
            public static gL operator -(gL l1, gPP move_p)
            {
                l1.ps -= move_p.p;
                l1.pe -= move_p.p;
                return l1;
            }
            public static gL operator -(gL l1, gP move_p)
            {
                l1.ps -= move_p.p;
                l1.pe -= move_p.p;
                return l1;
            }
        }
        /// <summary>
        /// ARC 数据类型
        /// </summary>
        public struct gA
        {
            public gA(double ps_x, double ps_y, double pc_x, double pc_y, double pe_x, double pe_y, double width_, bool ccw_)
            {
                this.ps = new gPoint(ps_x, ps_y);
                this.pc = new gPoint(pc_x, pc_y);
                this.pe = new gPoint(pe_x, pe_y);
                this.negative = false;
                this.ccw = ccw_;
                this.symbols = "r" + width_.ToString();
                this.attribut = string.Empty;
                this.width = width_;
            }
            public gA(gPoint ps_, gPoint pc_, gPoint pe_, double width_, bool ccw_ = false)
            {
                this.ps = ps_;
                this.pc = pc_;
                this.pe = pe_;
                this.negative = false;
                this.ccw = ccw_;
                this.symbols = "r" + width_.ToString();
                this.attribut = string.Empty;
                this.width = width_;
            }
            public gPoint ps;
            public gPoint pe;
            public gPoint pc;
            public bool negative;//polarity-- positive  negative
            public bool ccw; //direction-- cw ccw
            public string symbols;
            public string attribut;
            public double width;
            public static gA operator +(gA arc1, gPoint move_p)
            {
                arc1.ps += move_p;
                arc1.pe += move_p;
                arc1.pc += move_p;
                return arc1;
            }
            public static gA operator +(gA arc1, gPP move_p)
            {
                arc1.ps += move_p.p;
                arc1.pe += move_p.p;
                arc1.pc += move_p.p;
                return arc1;
            }
            public static gA operator +(gA arc1, gP move_p)
            {
                arc1.ps += move_p.p;
                arc1.pe += move_p.p;
                arc1.pc += move_p.p;
                return arc1;
            }
            public static gA operator -(gA arc1, gPoint move_p)
            {
                arc1.ps -= move_p;
                arc1.pe -= move_p;
                arc1.pc -= move_p;
                return arc1;
            }
            public static gA operator -(gA arc1, gPP move_p)
            {
                arc1.ps -= move_p.p;
                arc1.pe -= move_p.p;
                arc1.pc -= move_p.p;
                return arc1;
            }
            public static gA operator -(gA arc1, gP move_p)
            {
                arc1.ps -= move_p.p;
                arc1.pe -= move_p.p;
                arc1.pc -= move_p.p;
                return arc1;
            }
    
        }
        /// <summary>
        /// Text 文本数据类型  简易型  更复杂的需要扩展
        /// </summary>
        public struct gT
        {
            public gPoint ps;
            public string font;
            public bool negative;//polarity-- positive  negative
            public int angle;
            public bool mirror;
            public double x_size;
            public double y_size;
            public double width;
            public string Text;
            public string attribut;
        }
        /// <summary>
        /// Surface 坐标泛型集类1
        /// </summary>
        public struct gSur_Point
        {
            public gSur_Point(double x_val, double y_val, byte type_point_)
            {
                this.p.x = x_val;
                this.p.y = y_val;
                this.type_point = type_point_;
            }
            public gSur_Point(gPoint p, byte type_point_)
            {
                this.p = p;
                this.type_point = type_point_;
            }
            public gPoint p;
            /// <summary>
            /// 0为折点  1为顺时针 2为逆时针  
            /// </summary>
            public byte type_point;
        }
        /// <summary>
        /// Surface 坐标泛型集类2
        /// </summary>
        public class gSur_list
        {
            public List<gSur_Point> sur_list = new List<gSur_Point>();
            /// <summary>
            /// 是否为空洞
            /// </summary>
            public bool is_hole { get; set; }
            /// <summary>
            /// 是否逆时针
            /// </summary>
            public bool is_ccw { get; set; }
        }
        /// <summary>
        /// Surface 坐标泛型集类3
        /// </summary>
        public class gS
        {
            public List<gSur_list> sur_group = new List<gSur_list>();
            /// <summary>
            /// 是否为负  polarity-- P N
            /// </summary>
            public bool negative { get; set; }
            public string attribut { get; set; }
        }
        /// <summary>
        /// 整层Layer坐标泛型集类
        /// </summary>
        public class gLayer  //坐标
        {
            public List<gP> Plist = new List<gP>();
            public List<gL> Llist = new List<gL>();
            public List<gA> Alist = new List<gA>();
            public List<gT> Tlist = new List<gT>();
            public List<gS> Slist = new List<gS>();
        }
    View Code

    四.net实现效果图:

    小结:

             .NET图形绘制效率真是个一大问题,图形小绘制还感觉不明显,当元素数量大于20W时绘制时间超长,有时内存爆掉,,但同时打开Genesis却不爆,不管是编程语言,数据结构存储,解析算法上都要更高超,不得不佩服Frontline太有实力。看来只能用NET在图形上只能玩点小玩意了,注定玩不了大了。

  • 相关阅读:
    集合Hashtable Dictionary Hashset
    ArrayList 排序Sort()方法扩展
    Visual Studio 2019使用Intel C++ Compiler
    Visual Studio工具 vcpkg简介
    PE结构学习
    netapi32的一些利用方式
    windows api和创建服务
    导出firfox保存的密码
    在Active Directory中滥用无约束Kerberos委派
    Service Principal Name (SPN)
  • 原文地址:https://www.cnblogs.com/pcbren/p/9710843.html
Copyright © 2011-2022 走看看