一.为什么增加尾孔呢
看一看下图在panel中增加尾孔的效果;如下图所示,主要有2点原因.
1.孔径大小测量
假设如果不增加尾孔,要检测孔径大小是否符合要求,那么QA检测会选择最后钻的孔进大小进行测量, 但钻孔路径优化后,是不知道哪个孔是最后一个孔钻孔,为了让钻孔QA清楚的知道哪个孔是尾孔,CAM制作时会将每把刀最一个孔放到统一的一个区域内排列。
2.防止漏钻刀
如果最后一把刀尾孔漏钻了,那么QA一眼就看出来漏钻刀了
说一下钻孔工序QA检测孔径要求是:用针规全部测量其尾孔,并随机测量一些板内的孔,检查有无孔大孔小
二.增加尾孔有哪些要求
1.尾孔钻刀大小排序
正常是尾孔的钻刀排序和钻孔输出的钻刀排序一致,每个工厂钻刀排序不同,需结合每个工厂排刀要求而定,通常钻孔是:先排工具孔,再排圆孔,再排槽孔,接着再排除尘孔。这里测试代码钻刀从小到大排列(见下方代码)。
2.尾孔间距
尾孔间距要求比较宽松,0.5-2.0mm之间,一般取中间值就好了,但如遇到钻刀数太多了,会导致孔整个尾孔区域的长度超长了,尾孔会与其它图形或钻孔重叠,这时候可以考虑钻孔间距减少一些了.
3.尾孔位置
通常尾孔加到板角, 尾孔的方向如下图所示
三.C#简易代码实现:
1.genesis加尾孔代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//钻孔尺寸按小到大排序 实际钻刀输出钻刀排序进行排序 var OrderSizeList = symbolsList.OrderBy(tt => tt.width).Select(tt=>tt.width *0.001 ).ToList(); gPoint StartPoint = new gPoint(300, 100); //起点 double Hole2Hole = 1;//孔边到孔边 double Ang_direction = 45; //方位角 List<gP> HoleList = calc2.p_2plist(OrderSizeList, StartPoint, Hole2Hole, Ang_direction); addCOM.pad(HoleList);
2.计算函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// 通过已排序孔大小列表生成点链 /// </summary> /// <param name="OrderSizeList">已排序钻孔</param> /// <param name="StartPoint">起始点</param> /// <param name="Hole2Hole">孔边到孔边</param> /// <param name="Ang_direction">方位角</param> /// <returns></returns> public List<gP> p_2plist(List<double> OrderSizeList, gPoint StartPoint, double Hole2Hole, double Ang_direction) { List<gP> HoleList = new List<gP>(); gPoint newP = StartPoint; int HoleSizeCount = OrderSizeList.Count(); double PreRadSize = 0; if (HoleSizeCount > 0) { HoleList.Add(new gP(newP, OrderSizeList[0] * 1000)); PreRadSize = OrderSizeList[0] * 0.5; } for (int i = 1; i < HoleSizeCount; i++) { var val = PreRadSize + Hole2Hole + OrderSizeList[i] * 0.5; newP = p_val_ang(newP, val, Ang_direction); HoleList.Add(new gP(newP, OrderSizeList[i] * 1000)); PreRadSize = OrderSizeList[i] * 0.5; } return HoleList; } /// <summary> /// 求增量坐标 /// </summary> /// <param name="ps">起点</param> /// <param name="val">增量值</param> /// <param name="ang_direction">角度</param> /// <returns></returns> public gPoint p_val_ang(gPoint ps, double val, double ang_direction) { gPoint pe; pe.x = ps.x + val * Math.Cos(ang_direction * Math.PI / 180); pe.y = ps.y + val * Math.Sin(ang_direction * Math.PI / 180); return pe; }
3.Point,PAD数据结构
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <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 gPoint p; public bool negative;//polarity-- positive negative public double 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, gP p2) { p1.p -= p2.p; return p1; } } /// <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; } }
四.实现效果