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

PAD结构
  1.     /// PAD  数据类型
  2.     public struct gP
  3.     {
  4.         public gPoint p;
  5.         public bool negative;//polarity-- positive  negative
  6.         public int angle;
  7.         public bool mirror;
  8.         public string symbols;
  9.         public string attribut;
  10.         public double width;
  11.     }
线结构
  1. /// Line 数据类型
  2. public struct gL
  3. {
  4.   public gPoint ps;
  5.   public gPoint pe;
  6.   public bool negative;//polarity-- positive  negative
  7.   public string symbols;
  8.   public string attribut;
  9.   public double width;
  10. }
弧结构
  1.   /// ARC 数据类型
  2. public struct gA
  3. {
  4.   public gPoint ps;
  5.   public gPoint pe;
  6.   public gPoint pc;
  7.   public bool negative;//polarity-- positive  negative
  8.   public bool ccw; //direction-- cw ccw
  9.   public string symbols;
  10.   public string attribut;
  11.   public double width;
  12. }
铜皮结构
  1.   /// Surface 坐标泛型集类1
  2.     public struct gSur_Point
  3.     {
  4.         public gPoint p;
  5.         /// 0为折点  1为顺时针 2为逆时针  
  6.         public byte type_point;
  7.     }
  8.     /// Surface 坐标泛型集类2
  9.     public class gSur_list
  10.     {
  11.         public List<gSur_Point> sur_list = new List<gSur_Point>();

  12.         /// 是否为空洞
  13.         /// </summary>
  14.         public bool is_hole { get; set; }

  15.         /// 是否逆时针
  16.         public bool is_ccw { get; set; }
  17.     }
  18.     /// Surface 坐标泛型集类3
  19.     public class gS
  20.     {
  21.         public List<gSur_list> sur_group = new List<gSur_list>();
  22.         /// 是否为负  polarity-- P N
  23.         public bool negative { get; set; }
  24.         public string attribut { get; set; }
  25.     }

文字结构

看这个结构比Surface铜皮结构还简单呀,为什么文字结构更复杂了,这里只是实现最普通的字体结构,实际复杂程度远大于Surface,需要解析到所用到的字体库中的的坐标,而且字体存在各式各样的,有二维码,点阵字,有条码,要想保证和Genesis所显示一致,这里需要下点功夫。
  1.     /// Text 文本数据类型  简易型  更复杂的需要扩展
  2.     public struct gT
  3.     {
  4.         public gPoint ps;
  5.         public string font;
  6.         public bool negative;//polarity-- positive  negative
  7.         public int angle;
  8.         public bool mirror;
  9.         public double x_size;
  10.         public double y_size;
  11.         public double width;
  12.         public string Text;
  13.         public string attribut;
  14.     }
那么为什么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:\genesis\fw\lib\fonts,这是明文坐标很好解决,直接解析就好了。

三.5类元素基本数据结构
这是基本的不全面,可以扩展并改进的.
  1. /// 点  数据类型 (XY)
  2.     /// </summary>
  3.     public struct gPoint
  4.     {
  5.         public gPoint(gPoint p_)
  6.         {
  7.             this.x = p_.x;
  8.             this.y = p_.y;
  9.         }
  10.         public gPoint(double x_val, double y_val)
  11.         {
  12.             this.x = x_val;
  13.             this.y = y_val;
  14.         }
  15.         public double x;
  16.         public double y;
  17.         public static gPoint operator +(gPoint p1, gPoint p2)
  18.         {
  19.             p1.x += p2.x;
  20.             p1.y += p2.y;
  21.             return p1;
  22.         }
  23.         public static gPoint operator -(gPoint p1, gPoint p2)
  24.         {
  25.             p1.x -= p2.x;
  26.             p1.y -= p2.y;
  27.             return p1;
  28.         }


  29.     }

  30.     /// <summary>
  31.     /// 精简 PAD  数据类型
  32.     /// </summary>
  33.     public struct gPP
  34.     {
  35.         public gPP(double x_val, double y_val, double width_)
  36.         {
  37.             this.p = new gPoint(x_val, y_val);
  38.             this.symbols = "r";
  39.             this.width = width_;
  40.         }
  41.         public gPP(gPoint p_, double width_)
  42.         {
  43.             this.p = p_;
  44.             this.symbols = "r";
  45.             this.width = width_;
  46.         }
  47.         public gPP(gPoint p_, string symbols_, double width_)
  48.         {
  49.             this.p = p_;
  50.             this.symbols = symbols_;
  51.             this.width = width_;
  52.         }
  53.         public gPoint p;
  54.         public string symbols;
  55.         public double width;
  56.         public static gPP operator +(gPP p1, gPP p2)
  57.         {
  58.             p1.p += p2.p;
  59.             return p1;
  60.         }
  61.         public static gPP operator +(gPP p1, gPoint p2)
  62.         {
  63.             p1.p += p2;
  64.             return p1;
  65.         }
  66.         public static gPP operator -(gPP p1, gPP p2)
  67.         {
  68.             p1.p -= p2.p;
  69.             return p1;
  70.         }
  71.         public static gPP operator -(gPP p1, gPoint p2)
  72.         {
  73.             p1.p -= p2;
  74.             return p1;
  75.         }
  76.     }
  77.     /// <summary>
  78.     /// PAD  数据类型
  79.     /// </summary>
  80.     public struct gP
  81.     {
  82.         public gP(double x_val, double y_val, double width_)
  83.         {
  84.             this.p = new gPoint(x_val, y_val);
  85.             this.negative = false;
  86.             this.angle = 0;
  87.             this.mirror = false;
  88.             this.symbols = "r";
  89.             this.attribut = string.Empty;
  90.             this.width = width_;
  91.         }
  92.         public gP(gPoint p_, double width_)
  93.         {
  94.             this.p = p_;
  95.             this.negative = false;
  96.             this.angle = 0;
  97.             this.mirror = false;
  98.             this.symbols = "r";
  99.             this.attribut = string.Empty;
  100.             this.width = width_;
  101.         }
  102.         public gP(gPoint p_, string symbols_, double width_)
  103.         {
  104.             this.p = p_;
  105.             this.negative = false;
  106.             this.angle = 0;
  107.             this.mirror = false;
  108.             this.symbols = symbols_;
  109.             this.attribut = string.Empty;
  110.             this.width = width_;
  111.         }

  112.         public gPoint p;
  113.         public bool negative;//polarity-- positive  negative
  114.         public int angle;
  115.         public bool mirror;
  116.         public string symbols;
  117.         public string attribut;
  118.         public double width;
  119.         public static gP operator +(gP p1, gP p2)
  120.         {
  121.             p1.p += p2.p;
  122.             return p1;
  123.         }
  124.         public static gP operator +(gP p1, gPP p2)
  125.         {
  126.             p1.p += p2.p;
  127.             return p1;
  128.         }
  129.         public static gP operator +(gP p1, gPoint p2)
  130.         {
  131.             p1.p += p2;
  132.             return p1;
  133.         }
  134.         public static gP operator -(gP p1, gP p2)
  135.         {
  136.             p1.p -= p2.p;
  137.             return p1;
  138.         }
  139.         public static gP operator -(gP p1, gPP p2)
  140.         {
  141.             p1.p -= p2.p;
  142.             return p1;
  143.         }
  144.         public static gP operator -(gP p1, gPoint p2)
  145.         {
  146.             p1.p -= p2;
  147.             return p1;
  148.         }
  149.     }
  150.     /// <summary>
  151.     /// Line 数据类型
  152.     /// </summary>
  153.     public struct gL
  154.     {
  155.         public gL(double ps_x, double ps_y, double pe_x, double pe_y, double width_)
  156.         {
  157.             this.ps = new gPoint(ps_x, ps_y);
  158.             this.pe = new gPoint(pe_x, pe_y);
  159.             this.negative = false;
  160.             this.symbols = "r" + width_.ToString();
  161.             this.attribut = string.Empty;
  162.             this.width = width_;
  163.         }
  164.         public gL(gPoint ps_, gPoint pe_, double width_)
  165.         {
  166.             this.ps = ps_;
  167.             this.pe = pe_;
  168.             this.negative = false;
  169.             this.symbols = "r" + width_.ToString();
  170.             this.attribut = string.Empty;
  171.             this.width = width_;
  172.         }
  173.         public gL(gPoint ps_, gPoint pe_, string symbols_, double width_)
  174.         {
  175.             this.ps = ps_;
  176.             this.pe = pe_;
  177.             this.negative = false;
  178.             this.symbols = symbols_;
  179.             this.attribut = string.Empty;
  180.             this.width = width_;
  181.         }
  182.         public gPoint ps;
  183.         public gPoint pe;
  184.         public bool negative;//polarity-- positive  negative
  185.         public string symbols;
  186.         public string attribut;
  187.         public double width;
  188.         public static gL operator +(gL l1, gPoint move_p)
  189.         {
  190.             l1.ps += move_p;
  191.             l1.pe += move_p;
  192.             return l1;
  193.         }
  194.         public static gL operator +(gL l1, gPP move_p)
  195.         {
  196.             l1.ps += move_p.p;
  197.             l1.pe += move_p.p;
  198.             return l1;
  199.         }
  200.         public static gL operator +(gL l1, gP move_p)
  201.         {
  202.             l1.ps += move_p.p;
  203.             l1.pe += move_p.p;
  204.             return l1;
  205.         }
  206.         public static gL operator -(gL l1, gPoint move_p)
  207.         {
  208.             l1.ps -= move_p;
  209.             l1.pe -= move_p;
  210.             return l1;
  211.         }
  212.         public static gL operator -(gL l1, gPP move_p)
  213.         {
  214.             l1.ps -= move_p.p;
  215.             l1.pe -= move_p.p;
  216.             return l1;
  217.         }
  218.         public static gL operator -(gL l1, gP move_p)
  219.         {
  220.             l1.ps -= move_p.p;
  221.             l1.pe -= move_p.p;
  222.             return l1;
  223.         }
  224.     }
  225.     /// <summary>
  226.     /// ARC 数据类型
  227.     /// </summary>
  228.     public struct gA
  229.     {
  230.         public gA(double ps_x, double ps_y, double pc_x, double pc_y, double pe_x, double pe_y, double width_, bool ccw_)
  231.         {
  232.             this.ps = new gPoint(ps_x, ps_y);
  233.             this.pc = new gPoint(pc_x, pc_y);
  234.             this.pe = new gPoint(pe_x, pe_y);
  235.             this.negative = false;
  236.             this.ccw = ccw_;
  237.             this.symbols = "r" + width_.ToString();
  238.             this.attribut = string.Empty;
  239.             this.width = width_;
  240.         }
  241.         public gA(gPoint ps_, gPoint pc_, gPoint pe_, double width_, bool ccw_ = false)
  242.         {
  243.             this.ps = ps_;
  244.             this.pc = pc_;
  245.             this.pe = pe_;
  246.             this.negative = false;
  247.             this.ccw = ccw_;
  248.             this.symbols = "r" + width_.ToString();
  249.             this.attribut = string.Empty;
  250.             this.width = width_;
  251.         }
  252.         public gPoint ps;
  253.         public gPoint pe;
  254.         public gPoint pc;
  255.         public bool negative;//polarity-- positive  negative
  256.         public bool ccw; //direction-- cw ccw
  257.         public string symbols;
  258.         public string attribut;
  259.         public double width;
  260.         public static gA operator +(gA arc1, gPoint move_p)
  261.         {
  262.             arc1.ps += move_p;
  263.             arc1.pe += move_p;
  264.             arc1.pc += move_p;
  265.             return arc1;
  266.         }
  267.         public static gA operator +(gA arc1, gPP move_p)
  268.         {
  269.             arc1.ps += move_p.p;
  270.             arc1.pe += move_p.p;
  271.             arc1.pc += move_p.p;
  272.             return arc1;
  273.         }
  274.         public static gA operator +(gA arc1, gP move_p)
  275.         {
  276.             arc1.ps += move_p.p;
  277.             arc1.pe += move_p.p;
  278.             arc1.pc += move_p.p;
  279.             return arc1;
  280.         }
  281.         public static gA operator -(gA arc1, gPoint move_p)
  282.         {
  283.             arc1.ps -= move_p;
  284.             arc1.pe -= move_p;
  285.             arc1.pc -= move_p;
  286.             return arc1;
  287.         }
  288.         public static gA operator -(gA arc1, gPP move_p)
  289.         {
  290.             arc1.ps -= move_p.p;
  291.             arc1.pe -= move_p.p;
  292.             arc1.pc -= move_p.p;
  293.             return arc1;
  294.         }
  295.         public static gA operator -(gA arc1, gP move_p)
  296.         {
  297.             arc1.ps -= move_p.p;
  298.             arc1.pe -= move_p.p;
  299.             arc1.pc -= move_p.p;
  300.             return arc1;
  301.         }

  302.     }
  303.     /// <summary>
  304.     /// Text 文本数据类型  简易型  更复杂的需要扩展
  305.     /// </summary>
  306.     public struct gT
  307.     {
  308.         public gPoint ps;
  309.         public string font;
  310.         public bool negative;//polarity-- positive  negative
  311.         public int angle;
  312.         public bool mirror;
  313.         public double x_size;
  314.         public double y_size;
  315.         public double width;
  316.         public string Text;
  317.         public string attribut;
  318.     }
  319.     /// <summary>
  320.     /// Surface 坐标泛型集类1
  321.     /// </summary>
  322.     public struct gSur_Point
  323.     {
  324.         public gSur_Point(double x_val, double y_val, byte type_point_)
  325.         {
  326.             this.p.x = x_val;
  327.             this.p.y = y_val;
  328.             this.type_point = type_point_;
  329.         }
  330.         public gSur_Point(gPoint p, byte type_point_)
  331.         {
  332.             this.p = p;
  333.             this.type_point = type_point_;
  334.         }
  335.         public gPoint p;
  336.         /// <summary>
  337.         /// 0为折点  1为顺时针 2为逆时针  
  338.         /// </summary>
  339.         public byte type_point;
  340.     }
  341.     /// <summary>
  342.     /// Surface 坐标泛型集类2
  343.     /// </summary>
  344.     public class gSur_list
  345.     {
  346.         public List<gSur_Point> sur_list = new List<gSur_Point>();
  347.         /// <summary>
  348.         /// 是否为空洞
  349.         /// </summary>
  350.         public bool is_hole { get; set; }
  351.         /// <summary>
  352.         /// 是否逆时针
  353.         /// </summary>
  354.         public bool is_ccw { get; set; }
  355.     }
  356.     /// <summary>
  357.     /// Surface 坐标泛型集类3
  358.     /// </summary>
  359.     public class gS
  360.     {
  361.         public List<gSur_list> sur_group = new List<gSur_list>();
  362.         /// <summary>
  363.         /// 是否为负  polarity-- P N
  364.         /// </summary>
  365.         public bool negative { get; set; }
  366.         public string attribut { get; set; }
  367.     }
  368.     /// <summary>
  369.     /// 整层Layer坐标泛型集类
  370.     /// </summary>
  371.     public class gLayer  //坐标
  372.     {
  373.         public List<gP> Plist = new List<gP>();
  374.         public List<gL> Llist = new List<gL>();
  375.         public List<gA> Alist = new List<gA>();
  376.         public List<gT> Tlist = new List<gT>();
  377.         public List<gS> Slist = new List<gS>();
  378.     }

来源:多物理场仿真技术