[Libreoffice-commits] libvisio.git: src/lib

Fridrich Å trba fridrich.strba at bluewin.ch
Tue Jul 9 17:30:10 PDT 2013


 src/lib/VSDCollector.h          |    2 
 src/lib/VSDContentCollector.cpp |  136 +++++++++++++++++++++-------------------
 src/lib/VSDContentCollector.h   |    2 
 src/lib/VSDStylesCollector.cpp  |    5 -
 src/lib/VSDStylesCollector.h    |    5 -
 5 files changed, 79 insertions(+), 71 deletions(-)

New commits:
commit f611310868933279a8d6899e6eabb9c5f820e929
Author: Fridrich Å trba <fridrich.strba at bluewin.ch>
Date:   Wed Jul 10 02:29:44 2013 +0200

    Some more trying of refactoring of nurbs-related code

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);


More information about the Libreoffice-commits mailing list