summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFridrich Štrba <fridrich.strba@bluewin.ch>2013-07-10 02:29:44 +0200
committerFridrich Štrba <fridrich.strba@bluewin.ch>2013-07-10 02:29:44 +0200
commitf611310868933279a8d6899e6eabb9c5f820e929 (patch)
tree5e25c504daf9558e1b39816c20bf32df98d753b1
parent0e8734be3d3294454d3f6f8f9de282c31bdf28bf (diff)
Some more trying of refactoring of nurbs-related code
-rw-r--r--src/lib/VSDCollector.h2
-rw-r--r--src/lib/VSDContentCollector.cpp136
-rw-r--r--src/lib/VSDContentCollector.h2
-rw-r--r--src/lib/VSDStylesCollector.cpp5
-rw-r--r--src/lib/VSDStylesCollector.h5
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);