ODB++资料解析

ODB++文件是由VALOR提出的一种ASCII码,双向传输文件。奥宝公司和康代公司的设备都是用的ODB++格式进行PCB的生产和检测。

对ODB++文件进行解析把数据栅格化很重要,查了网上找不到一个成熟能用的ODB++文件解析代码。自己上手写了一个。

当前解析一些载板,软硬结合板都没有问题。

 

 

解析思路:

文件注释:

代码思路:

 Commom下只有两个文件,主要存放一些常用的算法,一些常量定义,一些枚举类型

Job目录下存放跟ODB++资料紧密相关的类

这部分内容需要了解ODB++资料才能理解。

实际上就是ODB+文件是一个JOB类,包含有step等等信息,一般整个板就是一个panel,panel是由set组合成的,set又是有一个pcs组合来的,pcs就是对应我们的PCB单板了。 

odbGeometry 存放ODB++的图元,主要用到的pad(焊盘)segment(线)surface (铜皮)arc(弧线)

和其他的一些辅助类,所有图元类继承自图元基类odbBase.

就这几个解析我手上几个G的ODB资料都没问题。

 需要解析奥宝康代等扫描机,曝光机资料的可私信我。

(二)用C++重写的odb++模块

支持C#和Python调用

C++函数接口

#pragma once

#include "ecam_global.h"
#include <QRectF>
#include <QString>
#include <QRectF>
#include <QImage>
#include <memory>
#include <vector>

class ICAM;

enum class eCamType
{
	ODBPP,  //奥宝康代普遍使用的AOI导入格式
	AOIIMG, //奥宝特有的AOI格式
	RLE,    //行程编码
	GERBER, //行业通用格式,精度问题导致在高端板逐渐被弃用
};

extern "C" {
	class ECAM_EXPORT ECAM
	{
	public:
		ECAM(eCamType type);
		~ECAM();
		/// <summary>
		/// 设置文件路径,支持导入tgz格式文件 && 已解压出来的资料文件夹
		/// </summary>
		/// <param name="path"></param>
		void SetFilePath(QString path);
		/// <summary>
		/// 预解析,解析资料的整体信息,包括Panel,Step,Layer,Matrix以获取层别等信息
		/// </summary>
		/// <returns></returns>
		int PreAnalyze();
		/// <summary>
		/// 获取板子长宽信息,默认单位是um
		/// </summary>
		/// <returns></returns>
		QRectF GetBoundingBox();
		/// <summary>
		/// 选择解析出来的层别,只支持一个信号层,可支持多个通孔层
		/// </summary>
		/// <param name="step">Step名称,如PNL,PCS</param>
		/// <param name="signalLayer">信号层名称</param>
		/// <param name="drillLayer">通孔层名称</param>
		/// <returns></returns>
		int Select(QString step, QString signalLayer, QStringList drillLayer);
		/// <summary>
		/// 解析资料,分析资料的特征信息
		/// </summary>
		/// <returns></returns>
		int Analyze();
		/// <summary>
		/// 绘制图像
		/// </summary>
		/// <param name="imgWidth">图像宽</param>
		/// <param name="imgHeight">图像高</param>
		/// <param name="img">绘制出来的图像</param>
		/// <param name="drawRect">绘制的区域大小</param>
		/// <returns></returns>
		int Draw(int imgWidth, int imgHeight, QImage& img, QRectF& drawRect);
		/// <summary>
		/// 
		/// </summary>
		/// <param name="pageScale"></param>
		/// <param name="path"></param>
		/// <returns></returns>
		int DrawProfile(double pageScale, QString path);
		int Draw(int imgWidth, int imgHeight, QString path, QRectF& drawRect);
		int Draw(int imgWidth, int imgHeight, uchar** imgData, QRectF& drawRect);
		std::vector<QString> GetSignalLayerNames();
		std::vector<QString> GetStepNames() const;
		void ClearJob();
		void FreeMem();
	private:
		std::shared_ptr<ICAM> icam;
	};

//#pragma region 以下接口为导出到C#使用的接口,接口使用同上一致
	int ECAM_EXPORT InitEcam(int type);

	int ECAM_EXPORT SetFilePath(const char* path);

	int ECAM_EXPORT PreAnalyze();

	int ECAM_EXPORT GetStepNames(char*& stepNames);

	int ECAM_EXPORT GetSignalLayerNames(char*& signalLayerNames);

	int ECAM_EXPORT Select(const char* step, const char* signalLayer, const char* drillLayer);

	int ECAM_EXPORT Analyze();

	int ECAM_EXPORT GetBoundingBox(double& x, double& y, double& width, double& height);

	int ECAM_EXPORT DrawProfile(double pageScale, const char* path);

	int ECAM_EXPORT DrawImageFile(int x, int y, int drawWidth, int drawHeight, int imgWidth, int imgHeight, const char* path);

	int ECAM_EXPORT DrawImageData(int x, int y, int drawWidth, int drawHeight, int imgWidth, int imgHeight, uchar** imgData);

	int ECAM_EXPORT ClearJob();

	void ECAM_EXPORT FreeMem();
	//int ECAM_EXPORT ExportImage(uchar** image, int& width, int& height, int& stride);
//#pragma endregion


}

C#调用接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace ECAMCSharp
{
    public partial class ECAM
    {
        [DllImport("ECAMd.dll", EntryPoint = "InitEcam", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int InitEcam(int type);

        [DllImport("ECAMd.dll", EntryPoint = "SetFilePath", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetFilePath(string path);

        [DllImport("ECAMd.dll", EntryPoint = "PreAnalyze", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int PreAnalyze();

        [DllImport("ECAMd.dll", EntryPoint = "GetStepNames", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int GetStepNames(out IntPtr stepNames);

        [DllImport("ECAMd.dll", EntryPoint = "GetSignalLayerNames", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int GetSignalLayerNames(out IntPtr signalLayerNames);

        [DllImport("ECAMd.dll", EntryPoint = "Select", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Select(string step, string signalLayer, string drillLayer);

        [DllImport("ECAMd.dll", EntryPoint = "Analyze", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int Analyze();

        [DllImport("ECAMd.dll", EntryPoint = "GetBoundingBox", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int GetBoundingBox(ref double x, ref double y, ref double width, ref double height);

        [DllImport("ECAMd.dll", EntryPoint = "DrawProfile", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int DrawProfile(double pageScale, string path);

        [DllImport("ECAMd.dll", EntryPoint = "DrawImageFile", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int DrawImageFile(int x, int y, int drawWidth, int drawHeight, int imgWidth, int imgHeight, string path);

        [DllImport("ECAMd.dll", EntryPoint = "DrawImageData", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int DrawImageData(int x, int y, int drawWidth, int drawHeight, int imgWidth, int imgHeight, out IntPtr imgData);

        [DllImport("ECAMd.dll", EntryPoint = "ClearJob", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern int ClearJob();

        [DllImport("ECAMd.dll", EntryPoint = "FreeMem", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern void FreeMem();
    }
}

ECAM测试程序

C#测试程序

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

究极调参工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值