summaryrefslogtreecommitdiff
path: root/src/dxfdata.cc
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2011-09-03 20:44:41 (GMT)
committerMarius Kintel <marius@kintel.net>2011-09-03 20:44:41 (GMT)
commit6096f2734a9a2f2c789f2e948c021def6b41f85b (patch)
treeed87e8732c45c19413de488ccd16fafe049111b2 /src/dxfdata.cc
parent946605234c7cf35cadfe9bde5531ebe6655f1b42 (diff)
De-Qt-ification continues, almost done with DxfData
Diffstat (limited to 'src/dxfdata.cc')
-rw-r--r--src/dxfdata.cc214
1 files changed, 111 insertions, 103 deletions
diff --git a/src/dxfdata.cc b/src/dxfdata.cc
index 7bf4364..430a1c3 100644
--- a/src/dxfdata.cc
+++ b/src/dxfdata.cc
@@ -35,12 +35,14 @@
#include <QVector>
#include "mathc99.h"
#include <assert.h>
+#include <boost/unordered_map.hpp>
+#include <boost/foreach.hpp>
+#include <algorithm>
struct Line {
- Vector2d *p[2];
+ int idx[2]; // indices into DxfData::points
bool disabled;
- Line(Vector2d *p1, Vector2d *p2) { p[0] = p1; p[1] = p2; disabled = false; }
- Line() { p[0] = NULL; p[1] = NULL; disabled = false; }
+ Line(int i1 = -1, int i2 = -1) { idx[0] = i1; idx[1] = i2; disabled = false; }
};
DxfData::DxfData()
@@ -48,51 +50,53 @@ DxfData::DxfData()
}
/*!
- Reads a layer from the given file, or all layers if layername.isEmpty()
+ Reads a layer from the given file, or all layers if layername.empty()
*/
-DxfData::DxfData(double fn, double fs, double fa, QString filename, QString layername, double xorigin, double yorigin, double scale)
+DxfData::DxfData(double fn, double fs, double fa,
+ const std::string &filename, const std::string &layername,
+ double xorigin, double yorigin, double scale)
{
- handle_dep(filename); // Register ourselves as a dependency
+ handle_dep(QString::fromStdString(filename)); // Register ourselves as a dependency
- QFile f(filename);
+ QFile f(QString::fromStdString(filename));
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
- PRINTF("WARNING: Can't open DXF file `%s'.", filename.toUtf8().data());
+ PRINTF("WARNING: Can't open DXF file `%s'.", filename.c_str());
return;
}
QTextStream stream(&f);
- Grid2d< QVector<int> > grid(GRID_COARSE);
- QList<Line> lines; // Global lines
- QHash< QString, QList<Line> > blockdata; // Lines in blocks
+ Grid2d< std::vector<int> > grid(GRID_COARSE);
+ std::vector<Line> lines; // Global lines
+ QHash< QString, std::vector<Line> > blockdata; // Lines in blocks
bool in_entities_section = false;
bool in_blocks_section = false;
- QString current_block;
+ std::string current_block;
#define ADD_LINE(_x1, _y1, _x2, _y2) do { \
double _p1x = _x1, _p1y = _y1, _p2x = _x2, _p2y = _y2; \
if (!in_entities_section && !in_blocks_section) \
break; \
if (in_entities_section && \
- !(layername.isEmpty() || layername == layer)) \
+ !(layername.empty() || layername == layer)) \
break; \
grid.align(_p1x, _p1y); \
grid.align(_p2x, _p2y); \
- grid.data(_p1x, _p1y).append(lines.count()); \
- grid.data(_p2x, _p2y).append(lines.count()); \
+ grid.data(_p1x, _p1y).push_back(lines.size()); \
+ grid.data(_p2x, _p2y).push_back(lines.size()); \
if (in_entities_section) \
- lines.append( \
+ lines.push_back( \
Line(addPoint(_p1x, _p1y), addPoint(_p2x, _p2y))); \
- if (in_blocks_section && !current_block.isNull()) \
- blockdata[current_block].append( \
+ if (in_blocks_section && !current_block.empty()) \
+ blockdata[QString::fromStdString(current_block)].push_back( \
Line(addPoint(_p1x, _p1y), addPoint(_p2x, _p2y))); \
} while (0)
- QString mode, layer, name, iddata;
+ std::string mode, layer, name, iddata;
int dimtype = 0;
double coords[7][2]; // Used by DIMENSION entities
- QVector<double> xverts;
- QVector<double> yverts;
+ std::vector<double> xverts;
+ std::vector<double> yverts;
double radius = 0;
double arc_start_angle = 0, arc_stop_angle = 0;
double ellipse_start_angle = 0, ellipse_stop_angle = 0;
@@ -116,7 +120,7 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye
int id = id_str.toInt(&status);
if (!status) {
- PRINTA("WARNING: Illegal ID `%1' in `%3'.", id_str, filename);
+ PRINTF("WARNING: Illegal ID `%s' in `%s'.", id_str.toUtf8().data(), filename.c_str());
break;
}
@@ -234,13 +238,13 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye
else if (mode == "INSERT") {
// scale is stored in ellipse_start|stop_angle, rotation in arc_start_angle;
// due to the parser code not checking entity type
- int n = blockdata[iddata].size();
+ int n = blockdata[QString::fromStdString(iddata)].size();
for (int i = 0; i < n; i++) {
double a = arc_start_angle * M_PI / 180.0;
- double lx1 = (*blockdata[iddata][i].p[0])[0] * ellipse_start_angle;
- double ly1 = (*blockdata[iddata][i].p[0])[1] * ellipse_stop_angle;
- double lx2 = (*blockdata[iddata][i].p[1])[0] * ellipse_start_angle;
- double ly2 = (*blockdata[iddata][i].p[1])[1] * ellipse_stop_angle;
+ double lx1 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[0]][0] * ellipse_start_angle;
+ double ly1 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[0]][1] * ellipse_stop_angle;
+ double lx2 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[1]][0] * ellipse_start_angle;
+ double ly2 = this->points[blockdata[QString::fromStdString(iddata)][i].idx[1]][1] * ellipse_stop_angle;
double px1 = (cos(a)*lx1 - sin(a)*ly1) * scale + xverts[0];
double py1 = (sin(a)*lx1 + cos(a)*ly1) * scale + yverts[0];
double px2 = (cos(a)*lx2 - sin(a)*ly2) * scale + xverts[0];
@@ -249,32 +253,32 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye
}
}
else if (mode == "DIMENSION" &&
- (layername.isEmpty() || layername == layer)) {
- this->dims.append(Dim());
- this->dims.last().type = dimtype;
+ (layername.empty() || layername == layer)) {
+ this->dims.push_back(Dim());
+ this->dims.back().type = dimtype;
for (int i = 0; i < 7; i++)
for (int j = 0; j < 2; j++)
- this->dims.last().coords[i][j] = coords[i][j];
- this->dims.last().angle = arc_start_angle;
- this->dims.last().length = radius;
- this->dims.last().name = name;
+ this->dims.back().coords[i][j] = coords[i][j];
+ this->dims.back().angle = arc_start_angle;
+ this->dims.back().length = radius;
+ this->dims.back().name = name;
}
else if (mode == "BLOCK") {
current_block = iddata;
}
else if (mode == "ENDBLK") {
- current_block = QString();
+ current_block.erase();
}
else if (mode == "ENDSEC") {
}
else if (in_blocks_section || (in_entities_section &&
- (layername.isEmpty() || layername == layer))) {
- unsupported_entities_list[mode]++;
+ (layername.empty() || layername == layer))) {
+ unsupported_entities_list[QString::fromStdString(mode)]++;
}
- mode = data;
- layer = QString();
- name = QString();
- iddata = QString();
+ mode = data.toStdString();
+ layer.erase();
+ name.erase();
+ iddata.erase();
dimtype = 0;
for (int i = 0; i < 7; i++)
for (int j = 0; j < 2; j++)
@@ -288,37 +292,37 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye
}
break;
case 1:
- name = data;
+ name = data.toStdString();
break;
case 2:
- iddata = data;
+ iddata = data.toStdString();
break;
case 8:
- layer = data;
+ layer = data.toStdString();
break;
case 10:
if (in_blocks_section)
- xverts.append((data.toDouble()));
+ xverts.push_back((data.toDouble()));
else
- xverts.append((data.toDouble() - xorigin) * scale);
+ xverts.push_back((data.toDouble() - xorigin) * scale);
break;
case 11:
if (in_blocks_section)
- xverts.append((data.toDouble()));
+ xverts.push_back((data.toDouble()));
else
- xverts.append((data.toDouble() - xorigin) * scale);
+ xverts.push_back((data.toDouble() - xorigin) * scale);
break;
case 20:
if (in_blocks_section)
- yverts.append((data.toDouble()));
+ yverts.push_back((data.toDouble()));
else
- yverts.append((data.toDouble() - yorigin) * scale);
+ yverts.push_back((data.toDouble() - yorigin) * scale);
break;
case 21:
if (in_blocks_section)
- yverts.append((data.toDouble()));
+ yverts.push_back((data.toDouble()));
else
- yverts.append((data.toDouble() - yorigin) * scale);
+ yverts.push_back((data.toDouble() - yorigin) * scale);
break;
case 40:
// CIRCLE, ARC: radius
@@ -357,37 +361,39 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye
QHashIterator<QString, int> i(unsupported_entities_list);
while (i.hasNext()) {
i.next();
- if (layername.isEmpty()) {
+ if (layername.empty()) {
PRINTA("WARNING: Unsupported DXF Entity `%1' (%2x) in `%3'.",
- i.key(), QString::number(i.value()), filename);
+ i.key(), QString::number(i.value()), QString::fromStdString(filename));
} else {
PRINTA("WARNING: Unsupported DXF Entity `%1' (%2x) in layer `%3' of `%4'.",
- i.key(), QString::number(i.value()), layername, filename);
+ i.key(), QString::number(i.value()), QString::fromStdString(layername), QString::fromStdString(filename));
}
}
// Extract paths from parsed data
- QHash<int, int> enabled_lines;
- for (int i = 0; i < lines.count(); i++) {
+ typedef boost::unordered_map<int, int> LineMap;
+ LineMap enabled_lines;
+ for (size_t i = 0; i < lines.size(); i++) {
enabled_lines[i] = i;
}
// extract all open paths
- while (enabled_lines.count() > 0)
+ while (enabled_lines.size() > 0)
{
int current_line, current_point;
- foreach (int i, enabled_lines) {
+ BOOST_FOREACH(const LineMap::value_type &l, enabled_lines) {
+ int idx = l.second;
for (int j = 0; j < 2; j++) {
- QVector<int> *lv = &grid.data((*lines[i].p[j])[0], (*lines[i].p[j])[1]);
- for (int ki = 0; ki < lv->count(); ki++) {
+ std::vector<int> *lv = &grid.data(this->points[lines[idx].idx[j]][0], this->points[lines[idx].idx[j]][1]);
+ for (int ki = 0; ki < lv->size(); ki++) {
int k = lv->at(ki);
- if (k == i || lines[k].disabled)
+ if (k == idx || lines[k].disabled)
continue;
goto next_open_path_j;
}
- current_line = i;
+ current_line = idx;
current_point = j;
goto create_open_path;
next_open_path_j:;
@@ -397,26 +403,26 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye
break;
create_open_path:
- this->paths.append(Path());
- Path *this_path = &this->paths.last();
+ this->paths.push_back(Path());
+ Path *this_path = &this->paths.back();
- this_path->points.append(lines[current_line].p[current_point]);
+ this_path->indices.push_back(lines[current_line].idx[current_point]);
while (1) {
- this_path->points.append(lines[current_line].p[!current_point]);
- const Vector2d &ref_point = *lines[current_line].p[!current_point];
+ this_path->indices.push_back(lines[current_line].idx[!current_point]);
+ const Vector2d &ref_point = this->points[lines[current_line].idx[!current_point]];
lines[current_line].disabled = true;
- enabled_lines.remove(current_line);
- QVector<int> *lv = &grid.data(ref_point[0], ref_point[1]);
- for (int ki = 0; ki < lv->count(); ki++) {
+ enabled_lines.erase(current_line);
+ std::vector<int> *lv = &grid.data(ref_point[0], ref_point[1]);
+ for (int ki = 0; ki < lv->size(); ki++) {
int k = lv->at(ki);
if (lines[k].disabled)
continue;
- if (grid.eq(ref_point[0], ref_point[1], (*lines[k].p[0])[0], (*lines[k].p[0])[1])) {
+ if (grid.eq(ref_point[0], ref_point[1], this->points[lines[k].idx[0]][0], this->points[lines[k].idx[0]][1])) {
current_line = k;
current_point = 0;
goto found_next_line_in_open_path;
}
- if (grid.eq(ref_point[0], ref_point[1], (*lines[k].p[1])[0], (*lines[k].p[1])[1])) {
+ if (grid.eq(ref_point[0], ref_point[1], this->points[lines[k].idx[1]][0], this->points[lines[k].idx[1]][1])) {
current_line = k;
current_point = 1;
goto found_next_line_in_open_path;
@@ -428,31 +434,31 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye
}
// extract all closed paths
- while (enabled_lines.count() > 0)
+ while (enabled_lines.size() > 0)
{
- int current_line = enabled_lines.begin().value(), current_point = 0;
+ int current_line = enabled_lines.begin()->second, current_point = 0;
- this->paths.append(Path());
- Path *this_path = &this->paths.last();
+ this->paths.push_back(Path());
+ Path *this_path = &this->paths.back();
this_path->is_closed = true;
- this_path->points.append(lines[current_line].p[current_point]);
+ this_path->indices.push_back(lines[current_line].idx[current_point]);
while (1) {
- this_path->points.append(lines[current_line].p[!current_point]);
- const Vector2d &ref_point = *lines[current_line].p[!current_point];
+ this_path->indices.push_back(lines[current_line].idx[!current_point]);
+ const Vector2d &ref_point = this->points[lines[current_line].idx[!current_point]];
lines[current_line].disabled = true;
- enabled_lines.remove(current_line);
- QVector<int> *lv = &grid.data(ref_point[0], ref_point[1]);
- for (int ki = 0; ki < lv->count(); ki++) {
+ enabled_lines.erase(current_line);
+ std::vector<int> *lv = &grid.data(ref_point[0], ref_point[1]);
+ for (int ki = 0; ki < lv->size(); ki++) {
int k = lv->at(ki);
if (lines[k].disabled)
continue;
- if (grid.eq(ref_point[0], ref_point[1], (*lines[k].p[0])[0], (*lines[k].p[0])[1])) {
+ if (grid.eq(ref_point[0], ref_point[1], this->points[lines[k].idx[0]][0], this->points[lines[k].idx[0]][1])) {
current_line = k;
current_point = 0;
goto found_next_line_in_closed_path;
}
- if (grid.eq(ref_point[0], ref_point[1], (*lines[k].p[1])[0], (*lines[k].p[1])[1])) {
+ if (grid.eq(ref_point[0], ref_point[1], this->points[lines[k].idx[1]][0], this->points[lines[k].idx[1]][1])) {
current_line = k;
current_point = 1;
goto found_next_line_in_closed_path;
@@ -467,9 +473,9 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye
#if 0
printf("----- DXF Data -----\n");
- for (int i = 0; i < this->paths.count(); i++) {
+ for (int i = 0; i < this->paths.size(); i++) {
printf("Path %d (%s):\n", i, this->paths[i].is_closed ? "closed" : "open");
- for (int j = 0; j < this->paths[i].points.count(); j++)
+ for (int j = 0; j < this->paths[i].points.size(); j++)
printf(" %f %f\n", (*this->paths[i].points[j])[0], (*this->paths[i].points[j])[1]);
}
printf("--------------------\n");
@@ -483,26 +489,26 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye
*/
void DxfData::fixup_path_direction()
{
- for (int i = 0; i < this->paths.count(); i++) {
+ for (size_t i = 0; i < this->paths.size(); i++) {
if (!this->paths[i].is_closed)
break;
this->paths[i].is_inner = true;
- double min_x = (*this->paths[i].points[0])[0];
+ double min_x = this->points[this->paths[i].indices[0]][0];
int min_x_point = 0;
- for (int j = 1; j < this->paths[i].points.count(); j++) {
- if ((*this->paths[i].points[j])[0] < min_x) {
- min_x = (*this->paths[i].points[j])[0];
+ for (size_t j = 1; j < this->paths[i].indices.size(); j++) {
+ if (this->points[this->paths[i].indices[j]][0] < min_x) {
+ min_x = this->points[this->paths[i].indices[j]][0];
min_x_point = j;
}
}
// rotate points if the path is in non-standard rotation
int b = min_x_point;
- int a = b == 0 ? this->paths[i].points.count() - 2 : b - 1;
- int c = b == this->paths[i].points.count() - 1 ? 1 : b + 1;
- double ax = (*this->paths[i].points[a])[0] - (*this->paths[i].points[b])[0];
- double ay = (*this->paths[i].points[a])[1] - (*this->paths[i].points[b])[1];
- double cx = (*this->paths[i].points[c])[0] - (*this->paths[i].points[b])[0];
- double cy = (*this->paths[i].points[c])[1] - (*this->paths[i].points[b])[1];
+ int a = b == 0 ? this->paths[i].indices.size() - 2 : b - 1;
+ int c = b == this->paths[i].indices.size() - 1 ? 1 : b + 1;
+ double ax = this->points[this->paths[i].indices[a]][0] - this->points[this->paths[i].indices[b]][0];
+ double ay = this->points[this->paths[i].indices[a]][1] - this->points[this->paths[i].indices[b]][1];
+ double cx = this->points[this->paths[i].indices[c]][0] - this->points[this->paths[i].indices[b]][0];
+ double cy = this->points[this->paths[i].indices[c]][1] - this->points[this->paths[i].indices[b]][1];
#if 0
printf("Rotate check:\n");
printf(" a/b/c indices = %d %d %d\n", a, b, c);
@@ -511,15 +517,17 @@ void DxfData::fixup_path_direction()
#endif
// FIXME: atan2() usually takes y,x. This variant probably makes the path clockwise..
if (atan2(ax, ay) < atan2(cx, cy)) {
- for (int j = 0; j < this->paths[i].points.count()/2; j++)
- this->paths[i].points.swap(j, this->paths[i].points.count()-1-j);
+ std::reverse(this->paths[i].indices.begin(), this->paths[i].indices.end());
}
}
}
-Vector2d *DxfData::addPoint(double x, double y)
+/*!
+ Adds a vertex and returns the index into DxfData::points
+ */
+int DxfData::addPoint(double x, double y)
{
- this->points.append(Vector2d(x, y));
- return &this->points.last();
+ this->points.push_back(Vector2d(x, y));
+ return this->points.size()-1;
}
contact: Jan Huwald // Impressum