From ef962f6008f25ab7cbd4ca21bcc72b97a1e2d76f Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Tue, 5 Jul 2016 18:02:38 +0200 Subject: Imported Upstream version 0.0.34 --- hyp2mat/lib/exec_polygon.cc | 275 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 hyp2mat/lib/exec_polygon.cc (limited to 'hyp2mat/lib/exec_polygon.cc') diff --git a/hyp2mat/lib/exec_polygon.cc b/hyp2mat/lib/exec_polygon.cc new file mode 100644 index 0000000..88e8be2 --- /dev/null +++ b/hyp2mat/lib/exec_polygon.cc @@ -0,0 +1,275 @@ +/* + * hyp2mat - convert hyperlynx files to matlab scripts + * Copyright 2012 Koen De Vleeschauwer. + * + * This file is part of hyp2mat. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "hypfile.h" + +using namespace std; +using namespace HypFile; + +/* + * Hyperlynx 'POLYGON' subrecord of 'NET' record. + * Draws polygonal metal area. + */ + +bool HypFile::Hyp::exec_polygon_begin(parse_param& h) +{ + if (trace_hyp) { + cerr << "polygon begin:"; + if (h.layer_name_set) cerr << " layer_name = " << h.layer_name; + if (h.width_set) cerr << " width = " << h.width; + if (h.polygon_type_set) { + cerr << " polygon_type = " << h.polygon_type << " "; + switch (h.polygon_type) { + case POLYGON_TYPE_PLANE: cerr << "POLYGON_TYPE_PLANE"; break; + case POLYGON_TYPE_POUR: cerr << "POLYGON_TYPE_POUR"; break; + case POLYGON_TYPE_COPPER: cerr << "POLYGON_TYPE_COPPER"; break; + default: cerr << "Error"; break; + } + } + if (h.id_set) cerr << " id = " << h.id; + cerr << " x = " << h.x << " y = " << h.y << endl; + } + + if (!h.layer_name_set) { + error("expected polygon layer L = "); + return true; + } + + if (!h.width_set) h.width = 0; + + if (!h.polygon_type_set) h.polygon_type = POLYGON_TYPE_PLANE; + + if (!h.id_set) { + error("expected polygon id ID = "); + return true; + } + + h.width *= unit; + h.x *= unit; + h.y *= unit; + + current_polygon.id = h.id; + current_polygon.polygon_type = h.polygon_type; + current_polygon.width = h.width; + current_polygon.positive = true; + current_polygon.layer_name = h.layer_name; + current_polygon.vertex.clear(); + current_polygon.vertex.push_back(Point(h.x, h.y)); + + return false; +} + +bool HypFile::Hyp::exec_polygon_end(parse_param& h) +{ + if (trace_hyp) cerr << "polygon end" << endl; + + add_polygon(current_polygon); + + return false; +} + +/* + * Hyperlynx 'POLYVOID' subrecord of 'NET' record. + * Creates polygonal hole in metal area. + */ + +bool HypFile::Hyp::exec_polyvoid_begin(parse_param& h) +{ + if (trace_hyp) { + cerr << "polyvoid begin:"; + if (h.id_set) cerr << " id = " << h.id; + cerr << " x = " << h.x << " y = " << h.y << endl; + } + + if (!h.id_set) { + error("expected polygon id ID = "); + return true; + } + + h.x *= unit; + h.y *= unit; + + current_polygon.id = h.id; + current_polygon.positive = false; + current_polygon.vertex.clear(); + current_polygon.vertex.push_back(Point(h.x, h.y)); + + /* inherit layer_name and width from parent */ + for (PolygonList::iterator i = net.back().metal[h.id].begin(); i != net.back().metal[h.id].end(); ++i) { + if (i->positive) { + current_polygon.polygon_type = i->polygon_type; + current_polygon.width = i->width; + current_polygon.layer_name = i->layer_name; + return false; + } + } + + /* no positive polygon/polyline found with same id */ + error("polyvoid does not have parent polygon or polyline with same id"); + return true; +} + +bool HypFile::Hyp::exec_polyvoid_end(parse_param& h) +{ + if (trace_hyp) cerr << "polyvoid end" << endl; + + add_polygon(current_polygon); + + return false; +} + +/* + * Hyperlynx 'POLYLINE' subrecord of 'NET' record. + * Draws metal trace. + */ + +bool HypFile::Hyp::exec_polyline_begin(parse_param& h) +{ + if (trace_hyp) { + cerr << "polyline begin:"; + if (h.layer_name_set) cerr << " layer_name = " << h.layer_name; + if (h.width_set) cerr << " width = " << h.width; + if (h.polygon_type_set) { + cerr << " polygon_type = " << h.polygon_type << " "; + switch (h.polygon_type) { + case POLYGON_TYPE_PLANE: cerr << "POLYGON_TYPE_PLANE"; break; + case POLYGON_TYPE_POUR: cerr << "POLYGON_TYPE_POUR"; break; + case POLYGON_TYPE_COPPER: cerr << "POLYGON_TYPE_COPPER"; break; + default: cerr << "Error"; break; + } + } + if (h.id_set) cerr << " id = " << h.id; + cerr << " x = " << h.x << " y = " << h.y << endl; + } + + if (!h.layer_name_set) { + error("expected polygon layer L = "); + return true; + } + + if (!h.width_set) { + error("expected polygon width W = "); + return true; + } + + if (!h.polygon_type_set) h.polygon_type = POLYGON_TYPE_PLANE; + + if (!h.id_set) { + error("expected polygon id ID = "); + return true; + } + + h.width *= unit; + h.x *= unit; + h.y *= unit; + + current_polygon.id = h.id; + current_polygon.polygon_type = h.polygon_type; + current_polygon.width = h.width; + current_polygon.positive = true; + current_polygon.layer_name = h.layer_name; + current_polygon.vertex.clear(); + current_polygon.vertex.push_back(Point(h.x, h.y)); + + return false; +} + +bool HypFile::Hyp::exec_polyline_end(parse_param& h) +{ + if (trace_hyp) cerr << "polyline end" << endl; + + // Draw polyline as sequence of line segments + for (PointList::iterator i = current_polygon.vertex.begin(); (i != current_polygon.vertex.end()) && (i != --current_polygon.vertex.end()); ++i) { + Polygon line_segment; + PointList::iterator j = i + 1; + line_segment = segment2poly(i->x, i->y, j->x, j->y, current_polygon.width); + line_segment.id = current_polygon.id; + line_segment.polygon_type = current_polygon.polygon_type; + line_segment.positive = true; + line_segment.layer_name = current_polygon.layer_name; + line_segment.width = 0; + add_polygon(line_segment); + } + + return false; +} + +/* + * Hyperlynx 'LINE' subrecord of 'NET' record. + * Draws straight metal trace. + */ + +bool HypFile::Hyp::exec_line(parse_param& h) +{ + if (trace_hyp) cerr << "line: x = " << h.x << " y = " << h.y << endl; + + h.x *= unit; + h.y *= unit; + + /* add point to current polygon */ + current_polygon.vertex.push_back(Point(h.x, h.y)); + + return false; +} + +/* + * Hyperlynx 'CURVE' subrecord of 'NET' record. + * Draws curved metal trace. + */ + +bool HypFile::Hyp::exec_curve(parse_param& h) +{ + if (trace_hyp) { + cerr << "curve: x1 = " << h.x1 << " y1 = " << h.y1 << " x2 = " << h.x2 << " y2 = " << h.y2; + cerr << " xc = " << h.xc << " yc = " << h.yc << " r = " << h.r << endl; + } + + h.x1 *= unit; + h.y1 *= unit; + h.x2 *= unit; + h.y2 *= unit; + h.xc *= unit; + h.yc *= unit; + h.r *= unit; + h.width *= unit; + + /* calculate arc */ + /* 'CURVE' draws arc counterclockwise */ + Polygon arc = arc2poly(h.x1, h.y1, h.x2, h.y2, h.xc, h.yc, h.r, false); + + /* calculate distance between polygon end vertex and arc begin and arc end */ + double endvertex_x = current_polygon.vertex.back().x; + double endvertex_y = current_polygon.vertex.back().y; + double dist1 = (endvertex_x - h.x1) * (endvertex_x - h.x1) + (endvertex_y - h.y1) * (endvertex_y - h.y1); + double dist2 = (endvertex_x - h.x2) * (endvertex_x - h.x2) + (endvertex_y - h.y2) * (endvertex_y - h.y2); + + /* add arc to current polygon. begin with point closest to end vertex. */ + if (dist1 <= dist2) + /* add arc from (x1, y1) to (x2, y2) */ + current_polygon.vertex.insert(current_polygon.vertex.end(), arc.vertex.begin(), arc.vertex.end()); + else + /* add arc from (x2, y2) to (x1, y1) */ + current_polygon.vertex.insert(current_polygon.vertex.end(), arc.vertex.rbegin(), arc.vertex.rend()); + + return false; +} + +/* not truncated */ -- cgit v1.2.3