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:\genesis\fw\lib\fonts,这是明文坐标很好解决,直接解析就好了。

三.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>();
    }

四.net实现效果图:

小结:

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

原文地址:https://www.cnblogs.com/pcbren/p/9710843.html

时间: 2024-08-30 01:18:58

PCB ODB++(Gerber)图形绘制实现方法的相关文章

MFC绘图总结-DIB图形绘制

参考文档: http://blog.csdn.net/hnust_xiehonghao/article/details/37652927 http://blog.sina.com.cn/s/blog_4c75bd8c0100zsw7.html 绘制DIB图到到设备,明确一点,DIB设备无关图形向设备CDC上绘的话,肯定是需要经过图形pixel像素转换的,要转换成设备的颜色像素格式. 参考这段说明: DIB的颜色信息储存在自己的颜色表中,程序一般要根据颜色表为DIB创建逻辑调色板. 在输出一幅DI

C#中的GDI+图形绘制方法

GDI+图形绘制方法 1.首先对于绘制图形,必须的先将命名空间导入:using System.Drawing.Drawing2D; 2.然后在一个事件中写入程序 首先先将Graphics这个对象实例化: 然后就是实例化笔(pen)或者刷子(brush): 对于笔的实例化Pen mypen = new Pen(Color(选择颜色),笔的线条粗度) 刷子的实例化 solidbrush:它的实例化只需要指定color属性值就可以了: hatchbrush:它的实例化需要指定所需要绘制的图形以及颜色:

iOS:quartz2D绘图(给图形绘制阴影)

quartz2D既可以绘制原始图形,也可以给原始图形绘制阴影. 绘制阴影时,需要的一些参数:上下文.阴影偏移量.阴影模糊系数 注意:在对绘制的图形做了绘制阴影处理前,需要先对上下文进行保存,绘制阴影成功后,还要对上下文进行复位.目的是为了不影响后面的绘图操作. 举例的阴影绘制实例如下: 1.自定义一个视图类DemoView,并将控制器的视图关联该自定义类,同时在该定义类中重写- (void)drawRect:(CGRect)rect,将绘制无阴影图形和绘制阴影图形的调用方法写在里面.     

Quartz2D--iOS下的图形绘制

一.基本介绍 Quartz 2D是一个二维绘图引擎,Quartz 2D的API是C语言,来自CoreGraphics框架,没有面向对象的思想. 1.作用:绘制图形:线条.三角形.矩形.圆.弧等 绘制文字 绘制.生成图片(图形) 读取.生成PDF 截图.裁剪图片 自定义UI控件 2.图形上下文(Graphics Context):是一个CGContextRef类型的数据 图形上下文的作用:1.保存绘图信息.绘图状态 2.决定绘制的输出目标(绘制到什么地方,输出目标可以是PDF文件.Bitmap或者

图形绘制-线段绘制相关

最近公司的项目要用到一些图表效果,本来也打算在github上找一些第三方.然而第三方的风格与公司的需求不尽相同,改动起来较麻烦.于是自己写了一个,并且通用化,现已共享至github上.一下是自己的一些开发历程. 1.刚起手的时候,想完全用Quartz2D来绘制,然而Quartz2D只能绘制一些基本的图形,并不能达到路径绘制的动画效果.想要完全用UIBezierPath(UIBezierPath实际上也是使用OC语法将Quartz2D封装而成,使用更加方便)绘制,有觉得大材小用了,最终觉得使用Qu

Android中GPU硬件加速控制及其在2D图形绘制上的局限

图形的渲染可分为两种:软件渲染和硬件渲染.软件渲染是靠CPU计算各种坐标并绘制,主要是占用内存:硬件渲染是靠GPU,主要占用显存,一般的3D图形程序(OpenGL.DirectX)都是GPU加速的. 在Android3.0之前,2D绘图API只支持软件渲染模式,从Android3.0开始,2D绘图API开始支持GPU硬件渲染,即View中的Canvas的绘图操作会使用GPU,所以从Android 3.0(API Level 11)开始,View中就多了一些和硬件相关的方法.如果App的Andro

android游戏开发中图形绘制:Canvas和Paint的使用

android游戏开发中,使用android.graphics中的类来绘制2D向量图和文字. 一 画布Canvas 在Android中的绘图应该继承View组件,并重写它的onDraw(Canvas canvas)方法. Canvas代表指定View上的画布,常用方法如图: 二 画刷Paint Paint代表Canvas上的画刷,主要用于绘制风格,包括画刷颜色.画刷笔触粗细.填充风格等. 大体上可以分为两类,一类与图形绘制相关,一类与文本绘制相关. 常用方法如图: 三 路径Path Path表示

Android官方开发文档Training系列课程中文版:OpenGL绘图之图形绘制

原文地址:http://android.xsoftlab.net/training/graphics/opengl/draw.html 如果你还不清楚如何定义图形及坐标系统,请移步:Android官方开发文档Training系列课程中文版:OpenGL绘图之图形定义. 在定义了图形之后,你接下来需要做的就是将它绘制到屏幕上.不过使用OpenGL ES 2.0 API来绘制这个图形所需要的代码量可能要比想象中的多一些,这是因为API为图形渲染管道提供了大量的控制细节. 这节课会展示如何绘制上节课所

matlab学习笔记之五种常见的图形绘制功能

分类: 离散数据图形绘制 函数图形绘制 网格图形绘制 曲面图形绘制 特殊图形绘制 本文重点介绍matlab五种图形绘制方法的后三种. 一.网格图形绘制 以绘制函数z=f(x,y)三维网格图为例,下面为绘制步骤: 确定自变量x和y的取值范围和取值间隔 x = x1:dx:x2; y = y1:dy:y2; 2.构成xoy平面上的自变量采样格点矩阵 1)  利用“格点”矩阵生成原理生成矩阵 X = ones(size(y))*x; Y = y*ones(size(x)); 2)  利用meshgri