Use Gmprat for Path bounds with TRANSFORM_BEZIERS_TO_PATH
authorSam Moore <matches@ucc.asn.au>
Sat, 27 Sep 2014 16:08:19 +0000 (00:08 +0800)
committerSam Moore <matches@ucc.asn.au>
Sat, 27 Sep 2014 16:08:19 +0000 (00:08 +0800)
So, the bounds of Paths are stored with Gmprat
The Bezier's are all stored relative to the Path, as floats

The transformations are only applied to the Path Gmprat bounds.

This seems to work rather well.

In other news, the DeCasteljau algorithm in the CPU
renderer had no upper limit, which is why it was slowing down so much.

The CPU renderer tends to suffer from SIGFPE-itis when using floats,
because when you do a cast there is a SIGFPE if the resultant type can't represent the operand.
This occurs in a few places that don't actually affect the rendering...

12 files changed:
src/Makefile
src/bezier.cpp
src/bezier.h
src/document.cpp
src/eye_of_the_rabbit.script
src/gmprat.h
src/objectrenderer.cpp
src/objectrenderer.h
src/path.cpp
src/path.h
src/real.h
src/view.h

index 31ea736..805964e 100644 (file)
@@ -9,8 +9,8 @@ QT_INCLUDE := -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCor
 QT_DEF := -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB
 QT_LIB :=  -L/usr/lib/x86_64-linux-gnu -lQtGui -lQtCore -lpthread 
 
-LIB_x86_64 = ../contrib/lib/libSDL2-2.0.so.0 -lGL
-LIB_i386 = ../contrib/lib32/libSDL2-2.0.so.0 -lGL 
+LIB_x86_64 = ../contrib/lib/libSDL2-2.0.so.0 -lGL -lgmp
+LIB_i386 = ../contrib/lib32/libSDL2-2.0.so.0 -lGL -lgmp
 LIB_i686 = $(LIB_i386)
 
 MAINRPATH_x86_64 = -Wl,-rpath,'$$ORIGIN/../contrib/lib'
index 3c682a6..daa0736 100644 (file)
@@ -4,6 +4,8 @@
 #include <cmath>
 #include <algorithm>
 
+
+
 using namespace std;
 
 namespace IPDF
@@ -424,3 +426,4 @@ Rect Bezier::SolveBounds() const
 }
 
 } // end namespace
+
index cedf8d4..fbfbb61 100644 (file)
@@ -8,6 +8,7 @@
 #include "rect.h"
 
 
+
 namespace IPDF
 {
        extern int Factorial(int n);
@@ -356,4 +357,6 @@ namespace IPDF
 
 }
 
+#undef Real
+
 #endif //_BEZIER_H
index 4be3ee0..1e768bd 100644 (file)
@@ -1055,6 +1055,16 @@ void Document::TransformObjectBounds(const SVGMatrix & transform)
 
 void Document::TranslateObjects(const Real & dx, const Real & dy, ObjectType type)
 {
+       #ifdef TRANSFORM_BEZIERS_TO_PATH
+               for (unsigned i = 0; i < m_objects.paths.size(); ++i)
+               {
+                       Path & p = m_objects.paths[i];
+                       p.x += dx;
+                       p.y += dy;
+               }
+               return;
+       #endif  
+       
        for (unsigned i = 0; i < m_count; ++i)
        {
                if (type == NUMBER_OF_OBJECT_TYPES || m_objects.types[i] == type)
@@ -1067,6 +1077,22 @@ void Document::TranslateObjects(const Real & dx, const Real & dy, ObjectType typ
 
 void Document::ScaleObjectsAboutPoint(const Real & x, const Real & y, const Real & scale_amount, ObjectType type)
 {
+       #ifdef TRANSFORM_BEZIERS_TO_PATH
+               for (unsigned i = 0; i < m_objects.paths.size(); ++i)
+               {
+                       Path & p = m_objects.paths[i];
+                       p.w /= scale_amount;
+                       p.h /= scale_amount;
+                       p.x -= x;
+                       p.x /= scale_amount;
+                       p.x += x;
+                       p.y -= y;
+                       p.y /= scale_amount;
+                       p.y += y;
+               }
+               return;
+       #endif
+       
        for (unsigned i = 0; i < m_count; ++i)
        {
                if (type != NUMBER_OF_OBJECT_TYPES && m_objects.types[i] != type)
@@ -1084,6 +1110,7 @@ void Document::ScaleObjectsAboutPoint(const Real & x, const Real & y, const Real
                m_objects.bounds[i].y /= scale_amount;
                m_objects.bounds[i].y += y;
        }
+
 }
 
 
index c94bccd..a96efa6 100644 (file)
@@ -1,19 +1,19 @@
 # Test how well document scales back to original...
-cpu
+gpu
 lazy
 label start
 debug Add rabbit 1
 loadsvg svg-tests/rabbit_simple.svg
-loop 200 pxzoom 508 305 1
+loop 250 pxzoom 508 305 1
 debug Add rabbit 2
 loadsvg svg-tests/rabbit_simple.svg
-loop 200 pxzoom 508 305 1
+loop 250 pxzoom 508 305 1
 debug Add rabbit 3
 loadsvg svg-tests/rabbit_simple.svg
-loop 400 pxzoom 508 305 -1
-loop 200 pxzoom 508 305 1
+loop 500 pxzoom 508 305 -1
+loop 250 pxzoom 508 305 1
 loop 1000 wait
-loop 200 pxzoom 508 305 1
+loop 250 pxzoom 508 305 1
 debug Repeat
 #goto start
 wait
index de0e80b..5df43ef 100644 (file)
@@ -32,6 +32,7 @@ class Gmprat
                }
                
                Gmprat & operator=(const Gmprat & equ) {mpq_set(m_op, equ.m_op); return *this;}
+               Gmprat & operator=(const double & equ) {mpq_set_d(m_op, equ); return *this;}
                Gmprat & operator+=(const Gmprat & add) {mpq_add(m_op, m_op, add.m_op); return *this;}
                Gmprat & operator-=(const Gmprat & sub) {mpq_sub(m_op, m_op, sub.m_op); return *this;}
                Gmprat & operator*=(const Gmprat & mul) {mpq_mul(m_op, m_op, mul.m_op); return *this;}
index 6a216bc..21c9648 100644 (file)
@@ -243,14 +243,14 @@ void BezierRenderer::RenderBezierOnCPU(const Bezier & relative, const Rect & bou
                ObjectRenderer::RenderLineOnCPU(pix_bounds.x+pix_bounds.w, pix_bounds.y, pix_bounds.x+pix_bounds.w, pix_bounds.y+pix_bounds.h, target, Colour(0,255,0,0));
        }
        
-       unsigned blen = pix_bounds.w;//min(max(2U, (unsigned)Int64(Real(target.w)/view.GetBounds().w)), 
+       int64_t blen =  min(50L,pix_bounds.w);//min(max(2U, (unsigned)Int64(Real(target.w)/view.GetBounds().w)), 
                        //min((unsigned)(pix_bounds.w+pix_bounds.h)/4 + 1, 100U));
                
                // DeCasteljau Divide the Bezier
        #ifdef BEZIER_CPU_DECASTELJAU
        queue<Bezier> divisions;
        divisions.push(control);
-       while(divisions.size() < blen)
+       while(divisions.size() < (uint64_t)(blen))
        {
                Bezier & current = divisions.front();
                //if (current.GetType() == Bezier::LINE)
@@ -328,7 +328,7 @@ void BezierRenderer::RenderUsingCPU(Objects & objects, const View & view, const
                                        break;
                        }
                }
-               Rect & bounds = objects.bounds[m_indexes[i]];
+               Rect bounds = view.TransformToViewCoords(objects.bounds[m_indexes[i]]);
                Bezier & bez = objects.beziers[objects.data_indices[m_indexes[i]]];
                RenderBezierOnCPU(bez, bounds, view, target, c);
        }
@@ -408,9 +408,10 @@ void PathRenderer::RenderUsingCPU(Objects & objects, const View & view, const CP
                if (m_indexes[i] >= last_obj_id) continue;
                
                
-               Rect bounds(CPURenderBounds(objects.bounds[m_indexes[i]], view, target));
-               PixelBounds pix_bounds(bounds);
+       
                Path & path = objects.paths[objects.data_indices[m_indexes[i]]];
+               Rect bounds(CPURenderBounds(path.GetBounds(objects), view, target));
+               PixelBounds pix_bounds(bounds);
                
                if (view.ShowingFillPoints())
                {
@@ -640,4 +641,12 @@ void ObjectRenderer::FloodFillOnCPU(int64_t x, int64_t y, const PixelBounds & bo
        }
 }
 
+ObjectRenderer::PixelBounds::PixelBounds(const Rect & bounds)
+{
+       x = Int64(Double(bounds.x));
+       y = Int64(Double(bounds.y));
+       w = Int64(Double(bounds.w));
+       h = Int64(Double(bounds.h));
+}
+
 }
index 9ea8a12..85a413b 100644 (file)
@@ -10,6 +10,7 @@
 #include "graphicsbuffer.h"
 #include "shaderprogram.h"
 #include "bufferbuilder.h"
+#include <cstdint>
 
 #define BEZIER_CPU_DECASTELJAU
 
@@ -76,7 +77,7 @@ namespace IPDF
                        struct PixelBounds
                        {
                                int64_t x; int64_t y; int64_t w; int64_t h;
-                               PixelBounds(const Rect & bounds) : x(Double(bounds.x)), y(Double(bounds.y)), w(Double(bounds.w)), h(Double(bounds.h)) {}
+                               PixelBounds(const Rect & bounds);
                        };
                        
                        typedef std::pair<int64_t, int64_t> PixelPoint;
index 04e537c..251de1e 100644 (file)
@@ -55,6 +55,11 @@ Path::Path(Objects & objects, unsigned start, unsigned end, const Colour & fill,
        m_right = objects.beziers[objects.data_indices[right]].ToAbsolute(objects.bounds[right]).GetRight();    
        
        #ifdef TRANSFORM_BEZIERS_TO_PATH
+       x = m_left.x;
+       y = m_top.y;
+       w = m_right.x - m_left.x;
+       h = m_bottom.y - m_top.y;
+       
        Rect bounds = SolveBounds(objects);
        for (unsigned i = m_start; i <= m_end; ++i)
        {
@@ -191,13 +196,20 @@ vector<Vec2> & Path::FillPoints(const Objects & objects, const View & view)
        return m_fill_points;
 }
 
-Rect Path::SolveBounds(const Objects & objects) const
+Rect Path::SolveBounds(const Objects & objects)
 {
-       return Rect(m_left.x, m_top.y, m_right.x-m_left.x, m_bottom.y-m_top.y);
+       #ifdef TRANSFORM_BEZIERS_TO_PATH
+               return Rect(Real(x.ToDouble()), Real(y.ToDouble()), Real(w.ToDouble()), Real(h.ToDouble()));
+       #else
+               return Rect(m_left.x, m_top.y, m_right.x-m_left.x, m_bottom.y-m_top.y);
+       #endif
 }
 
 Rect & Path::GetBounds(Objects & objects) 
 {
+       #ifdef TRANSFORM_BEZIERS_TO_PATH
+               objects.bounds[m_index] = Rect(Real(x.ToDouble()), Real(y.ToDouble()), Real(w.ToDouble()), Real(h.ToDouble()));
+       #endif
        return objects.bounds[m_index];
 }
 
index 7eb8dee..eb2b7b7 100644 (file)
@@ -9,7 +9,9 @@
 #ifdef QUADTREE_DISABLED
 
 #define TRANSFORM_BEZIERS_TO_PATH
-
+#ifdef TRANSFORM_BEZIERS_TO_PATH
+#include "gmprat.h"
+#endif
 
 #endif
 
@@ -35,7 +37,7 @@ namespace IPDF
        {
                Path(Objects & objects, unsigned _start, unsigned _end, const Colour & _fill = Colour(128,128,128,255), const Colour & _stroke = Colour(0,0,0,0));
                
-               Rect SolveBounds(const Objects & objects) const;
+               Rect SolveBounds(const Objects & objects);
                Rect & GetBounds(Objects & objects);
                std::vector<Vec2> & FillPoints(const Objects & objects, const View & view);
                
@@ -53,6 +55,13 @@ namespace IPDF
                
                std::vector<Vec2> m_fill_points;
                
+               #ifdef TRANSFORM_BEZIERS_TO_PATH
+               Gmprat x;
+               Gmprat y;
+               Gmprat w;
+               Gmprat h;
+               #endif
+               
                Colour m_fill;  // colour to fill with  
                Colour m_stroke; // colour to outline with
        };
index e35d952..7f29ca8 100644 (file)
@@ -128,7 +128,14 @@ namespace IPDF
        inline double Double(long double f) {return (double)(f);}
        inline double Sqrt(double f) {return sqrt(f);}
        inline double Abs(double a) {return fabs(a);}
-       inline int64_t Int64(double a){return (int64_t)a;}
+       inline int64_t Int64(double a)
+       {
+               if (a < INT64_MIN)
+                       return INT64_MIN;
+               if (a > INT64_MAX)
+                       return INT64_MAX;
+               return (int64_t)(a);
+       }
        
        inline Real Power(const Real & a, int n)
        {
index 66ccee8..5ea06a0 100644 (file)
@@ -12,7 +12,7 @@
 
 #ifdef QUADTREE_DISABLED
 
-//#define TRANSFORM_OBJECTS_NOT_VIEW
+#define TRANSFORM_OBJECTS_NOT_VIEW
 
 #endif
 

UCC git Repository :: git.ucc.asn.au