diff options
author | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2013-07-10 02:29:44 +0200 |
---|---|---|
committer | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2013-07-10 02:29:44 +0200 |
commit | f611310868933279a8d6899e6eabb9c5f820e929 (patch) | |
tree | 5e25c504daf9558e1b39816c20bf32df98d753b1 | |
parent | 0e8734be3d3294454d3f6f8f9de282c31bdf28bf (diff) |
Some more trying of refactoring of nurbs-related code
-rw-r--r-- | src/lib/VSDCollector.h | 2 | ||||
-rw-r--r-- | src/lib/VSDContentCollector.cpp | 136 | ||||
-rw-r--r-- | src/lib/VSDContentCollector.h | 2 | ||||
-rw-r--r-- | src/lib/VSDStylesCollector.cpp | 5 | ||||
-rw-r--r-- | src/lib/VSDStylesCollector.h | 5 |
5 files changed, 79 insertions, 71 deletions
diff --git a/src/lib/VSDCollector.h b/src/lib/VSDCollector.h index 2313e83..af47078 100644 --- a/src/lib/VSDCollector.h +++ b/src/lib/VSDCollector.h @@ -65,7 +65,7 @@ public: virtual void collectLineTo(unsigned id, unsigned level, double x, double y) = 0; virtual void collectArcTo(unsigned id, unsigned level, double x2, double y2, double bow) = 0; virtual void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, unsigned char xType, unsigned char yType, unsigned degree, - std::vector<std::pair<double, double> > controlPoints, std::vector<double> knotVector, std::vector<double> weights) = 0; + const std::vector<std::pair<double, double> > &ctrlPnts, const std::vector<double> &kntVec, const std::vector<double> &weights) = 0; virtual void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, double knot, double knotPrev, double weight, double weightPrev, unsigned dataID) = 0; virtual void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, double knot, double knotPrev, double weight, double weightPrev, const NURBSData &data) = 0; virtual void collectPolylineTo(unsigned id, unsigned level, double x, double y, unsigned char xType, unsigned char yType, const std::vector<std::pair<double, double> > &points) = 0; diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp index 2b0b29a..d6f55f1 100644 --- a/src/lib/VSDContentCollector.cpp +++ b/src/lib/VSDContentCollector.cpp @@ -989,6 +989,7 @@ void libvisio::VSDContentCollector::collectRelCubBezTo(unsigned /* id */, unsign transformPoint(x, y); m_x = x; m_y = y; + WPXPropertyList node; node.insert("libwpg:path-action", "C"); node.insert("svg:x",m_scale*x); @@ -1271,11 +1272,11 @@ void libvisio::VSDContentCollector::collectArcTo(unsigned /* id */, unsigned lev transformPoint(x2, y2); double angle = 0.0; transformAngle(angle); + m_x = x2; + m_y = y2; if (bow == 0) { - m_x = x2; - m_y = y2; WPXPropertyList end; end.insert("svg:x", m_scale*m_x); end.insert("svg:y", m_scale*m_y); @@ -1294,8 +1295,6 @@ void libvisio::VSDContentCollector::collectArcTo(unsigned /* id */, unsigned lev bool sweep = (bow < 0); transformFlips(sweep, sweep); - m_x = x2; - m_y = y2; arc.insert("svg:rx", m_scale*radius); arc.insert("svg:ry", m_scale*radius); arc.insert("libwpg:rotate", angle*180/M_PI, WPX_GENERIC); @@ -1462,52 +1461,63 @@ void libvisio::VSDContentCollector::_generateBezierSegmentsFromNURBS(unsigned de } } -#define VSD_NUM_POLYLINES_PER_NURBS 200 +double libvisio::VSDContentCollector::_NURBSBasis(unsigned knot, unsigned degree, double point, const std::vector<double> &knotVector) +{ + double basis = 0; + if (knotVector.empty()) + return basis; + if (degree == 0) + { + if (knotVector[knot] <= point && point < knotVector[knot+1]) + return 1; + else + return 0; + } + if (knotVector.size() > knot+degree && fabs(knotVector[knot+degree]-knotVector[knot]) > LIBVISIO_EPSILON) + basis = (point-knotVector[knot])/(knotVector[knot+degree]-knotVector[knot]) * _NURBSBasis(knot, degree-1, point, knotVector); + + if (knotVector.size() > knot+degree+1 && fabs(knotVector[knot+degree+1] - knotVector[knot+1]) > LIBVISIO_EPSILON) + basis += (knotVector[knot+degree+1]-point)/(knotVector[knot+degree+1]-knotVector[knot+1]) * _NURBSBasis(knot+1, degree-1, point, knotVector); + + return basis; +} + +#define VSD_NUM_POLYLINES_PER_KNOT 100 void libvisio::VSDContentCollector::_generatePolylineFromNURBS(unsigned degree, const std::vector<std::pair<double, double> > &controlPoints, const std::vector<double> &knotVector, const std::vector<double> &weights) { - // Generate NURBS using VSD_NUM_POLYLINES_PER_NURBS polylines + if (m_noShow) + return; + WPXPropertyList node; - double step = (knotVector.back() - knotVector[0]) / VSD_NUM_POLYLINES_PER_NURBS; - for (unsigned i = 0; i < VSD_NUM_POLYLINES_PER_NURBS; i++) + for (unsigned i = 0; i < VSD_NUM_POLYLINES_PER_KNOT * knotVector.size(); i++) { node.clear(); node.insert("libwpg:path-action", "L"); - double nextX = 0; - double nextY = 0; + double x = 0; + double y = 0; double denominator = LIBVISIO_EPSILON; for (unsigned p = 0; p < controlPoints.size() && p < weights.size(); p++) { - double basis = _NURBSBasis(p, degree, knotVector[0] + i * step, knotVector); - nextX += basis * controlPoints[p].first * weights[p]; - nextY += basis * controlPoints[p].second * weights[p]; + double basis = _NURBSBasis(p, degree, (double)i / (VSD_NUM_POLYLINES_PER_KNOT * knotVector.size()), knotVector); + x += basis * controlPoints[p].first * weights[p]; + y += basis * controlPoints[p].second * weights[p]; denominator += weights[p] * basis; } - nextX = (nextX/denominator); - nextY = (nextY/denominator); - transformPoint(nextX, nextY); - node.insert("svg:x", m_scale*nextX); - node.insert("svg:y", m_scale*nextY); + x /= denominator; + y /= denominator; + transformPoint(x, y); + node.insert("svg:x", m_scale*x); + node.insert("svg:y", m_scale*y); + if (!m_noFill && !m_noShow) m_currentFillGeometry.push_back(node); if (!m_noLine && !m_noShow) m_currentLineGeometry.push_back(node); } - - double x = controlPoints.back().first; - double y = controlPoints.back().second; - transformPoint(x, y); - node.clear(); - node.insert("libwpg:path-action", "L"); - node.insert("svg:x", m_scale*x); - node.insert("svg:y", m_scale*y); - if (!m_noFill && !m_noShow) - m_currentFillGeometry.push_back(node); - if (!m_noLine && !m_noShow) - m_currentLineGeometry.push_back(node); } bool libvisio::VSDContentCollector::_isUniform(const std::vector<double> weights) const @@ -1526,29 +1536,31 @@ bool libvisio::VSDContentCollector::_isUniform(const std::vector<double> weights } void libvisio::VSDContentCollector::collectNURBSTo(unsigned /* id */, unsigned level, double x2, double y2, - unsigned char xType, unsigned char yType, unsigned degree, std::vector<std::pair<double, double> > controlPoints, - std::vector<double> knotVector, std::vector<double> weights) + unsigned char xType, unsigned char yType, unsigned degree, const std::vector<std::pair<double, double> > &ctrlPnts, + const std::vector<double> &kntVec, const std::vector<double> &weights) { _handleLevelChange(level); - if (knotVector.empty() || controlPoints.empty() || weights.empty()) + if (kntVec.empty() || ctrlPnts.empty() || weights.empty()) // Here, maybe we should just draw line to (x2,y2) return; + std::vector<std::pair<double, double> > controlPoints(ctrlPnts); + // Convert control points to static co-ordinates - for (std::vector<std::pair<double, double> >::iterator it = controlPoints.begin(); - it != controlPoints.end(); ++it) + for (std::vector<std::pair<double, double> >::iterator iter = controlPoints.begin(); iter != controlPoints.end(); ++iter) { if (xType == 0) // Percentage - (*it).first *= m_xform.width; - + iter->first *= m_xform.width; if (yType == 0) // Percentage - (*it).second *= m_xform.height; + iter->second *= m_xform.height; } controlPoints.push_back(std::pair<double,double>(x2, y2)); controlPoints.insert(controlPoints.begin(), std::pair<double, double>(m_originalX, m_originalY)); + std::vector<double> knotVector(kntVec); + // Fill in end knots while (knotVector.size() < (controlPoints.size() + degree + 1)) { @@ -1556,37 +1568,35 @@ void libvisio::VSDContentCollector::collectNURBSTo(unsigned /* id */, unsigned l knotVector.push_back(tmpBack); } + // Let knotVector run from 0 to 1 + double firstKnot = knotVector[0]; + double lastKnot = knotVector.back()-knotVector[0]; + for(std::vector<double>::iterator knot = knotVector.begin(); knot != knotVector.end(); ++knot) + { + *knot -= firstKnot; + *knot /= lastKnot; + } + if (degree <= 3 && _isUniform(weights)) _generateBezierSegmentsFromNURBS(degree, controlPoints, knotVector); else _generatePolylineFromNURBS(degree, controlPoints, knotVector, weights); - m_originalX = controlPoints.back().first; - m_originalY = controlPoints.back().second; - m_x = controlPoints.back().first; - m_y = controlPoints.back().second; + m_originalX = x2; + m_originalY = y2; + m_x = x2; + m_y = y2; transformPoint(m_x, m_y); -} - -double libvisio::VSDContentCollector::_NURBSBasis(unsigned knot, unsigned degree, double point, const std::vector<double> &knotVector) -{ - double basis = 0; - if (knotVector.empty()) - return basis; - if (degree == 0) - { - if (knotVector[knot] <= point && point < knotVector[knot+1]) - return 1; - else - return 0; - } - if (knotVector.size() > knot+degree && fabs(knotVector[knot+degree]-knotVector[knot]) > LIBVISIO_EPSILON) - basis = (point-knotVector[knot])/(knotVector[knot+degree]-knotVector[knot]) * _NURBSBasis(knot, degree-1, point, knotVector); - - if (knotVector.size() > knot+degree+1 && fabs(knotVector[knot+degree+1] - knotVector[knot+1]) > LIBVISIO_EPSILON) - basis += (knotVector[knot+degree+1]-point)/(knotVector[knot+degree+1]-knotVector[knot+1]) * _NURBSBasis(knot+1, degree-1, point, knotVector); - - return basis; +#if 1 + WPXPropertyList node; + node.insert("libwpg:path-action", "L"); + node.insert("svg:x", m_scale*m_x); + node.insert("svg:y", m_scale*m_y); + if (!m_noFill && !m_noShow) + m_currentFillGeometry.push_back(node); + if (!m_noLine && !m_noShow) + m_currentLineGeometry.push_back(node); +#endif } void libvisio::VSDContentCollector::collectNURBSTo(unsigned id, unsigned level, double x2, double y2, double knot, double knotPrev, double weight, double weightPrev, const NURBSData &data) diff --git a/src/lib/VSDContentCollector.h b/src/lib/VSDContentCollector.h index 59e6614..b34e9d1 100644 --- a/src/lib/VSDContentCollector.h +++ b/src/lib/VSDContentCollector.h @@ -85,7 +85,7 @@ public: void collectLineTo(unsigned id, unsigned level, double x, double y); void collectArcTo(unsigned id, unsigned level, double x2, double y2, double bow); void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, unsigned char xType, unsigned char yType, unsigned degree, - std::vector<std::pair<double, double> > controlPoints, std::vector<double> knotVector, std::vector<double> weights); + const std::vector<std::pair<double, double> > &ctrlPnts, const std::vector<double> &kntVec, const std::vector<double> &weights); void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, double knot, double knotPrev, double weight, double weightPrev, unsigned dataID); void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, double knot, double knotPrev, double weight, double weightPrev, const NURBSData &data); void collectPolylineTo(unsigned id, unsigned level, double x, double y, unsigned char xType, unsigned char yType, diff --git a/src/lib/VSDStylesCollector.cpp b/src/lib/VSDStylesCollector.cpp index 879f255..5fb1b36 100644 --- a/src/lib/VSDStylesCollector.cpp +++ b/src/lib/VSDStylesCollector.cpp @@ -117,9 +117,8 @@ void libvisio::VSDStylesCollector::collectArcTo(unsigned /* id */, unsigned leve } void libvisio::VSDStylesCollector::collectNURBSTo(unsigned /* id */, unsigned level, double /* x2 */, double /* y2 */, - unsigned char /* xType */, unsigned char /* yType */, unsigned /* degree */, - std::vector<std::pair<double, double> > /* controlPoints */, - std::vector<double> /* knotVector */, std::vector<double> /* weights */) + unsigned char /* xType */, unsigned char /* yType */, unsigned /* degree */, const std::vector<std::pair<double, double> > & /* ctrlPts */, + const std::vector<double> & /* kntVec */, const std::vector<double> & /* weights */) { _handleLevelChange(level); } diff --git a/src/lib/VSDStylesCollector.h b/src/lib/VSDStylesCollector.h index 89a43d8..579df10 100644 --- a/src/lib/VSDStylesCollector.h +++ b/src/lib/VSDStylesCollector.h @@ -75,9 +75,8 @@ public: void collectMoveTo(unsigned id, unsigned level, double x, double y); void collectLineTo(unsigned id, unsigned level, double x, double y); void collectArcTo(unsigned id, unsigned level, double x2, double y2, double bow); - void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, unsigned char xType, unsigned char yType, - unsigned degree, std::vector<std::pair<double, double> > controlPoints, - std::vector<double> knotVector, std::vector<double> weights); + void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, unsigned char xType, unsigned char yType, unsigned degree, + const std::vector<std::pair<double, double> > &ctrlPnts, const std::vector<double> &kntVec, const std::vector<double> &weights); void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, double knot, double knotPrev, double weight, double weightPrev, unsigned dataID); void collectNURBSTo(unsigned id, unsigned level, double x2, double y2, double knot, double knotPrev, double weight, double weightPrev, const NURBSData &data); void collectPolylineTo(unsigned id, unsigned level, double x, double y, unsigned char xType, unsigned char yType, const std::vector<std::pair<double, double> > &points); |