summaryrefslogtreecommitdiffstats
path: root/src/libdepixelize
diff options
context:
space:
mode:
Diffstat (limited to 'src/libdepixelize')
-rw-r--r--src/libdepixelize/!PLEASE DON'T MAKE CHANGES IN THESE FILES.README9
-rw-r--r--src/libdepixelize/kopftracer2011.cpp57
-rw-r--r--src/libdepixelize/kopftracer2011.h10
-rw-r--r--src/libdepixelize/priv/simplifiedvoronoi.h391
-rw-r--r--src/libdepixelize/priv/splines-kopf2011.h10
-rw-r--r--src/libdepixelize/splines.h6
6 files changed, 300 insertions, 183 deletions
diff --git a/src/libdepixelize/!PLEASE DON'T MAKE CHANGES IN THESE FILES.README b/src/libdepixelize/!PLEASE DON'T MAKE CHANGES IN THESE FILES.README
new file mode 100644
index 000000000..df63435d6
--- /dev/null
+++ b/src/libdepixelize/!PLEASE DON'T MAKE CHANGES IN THESE FILES.README
@@ -0,0 +1,9 @@
+All code files in this directory are *direct* copies of the files in
+libdepixelize's BZR repo.
+If you want to change the code, please change it in libdepixelize, then copy the
+files here.
+Otherwise, I will probably miss that you changed something in Inkscape's copy,
+and destroy your changes by copying libdepixelize's files over it during the
+next time I update Inkscape's copy of libdepixelize.
+
+libdepixelize's BZR repo = lp:libdepixelize
diff --git a/src/libdepixelize/kopftracer2011.cpp b/src/libdepixelize/kopftracer2011.cpp
index 5e6e26048..ab31d05c3 100644
--- a/src/libdepixelize/kopftracer2011.cpp
+++ b/src/libdepixelize/kopftracer2011.cpp
@@ -86,7 +86,7 @@ Splines Kopf2011::to_voronoi(const std::string &filename,
Splines Kopf2011::to_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
- return Splines(_voronoi<Precision>(buf, options));
+ return Splines(_voronoi<Precision, false>(buf, options));
}
Splines Kopf2011::to_splines(const std::string &filename,
@@ -98,13 +98,15 @@ Splines Kopf2011::to_splines(const std::string &filename,
Splines Kopf2011::to_splines(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
- HomogeneousSplines<Precision> splines(_voronoi<Precision>(buf, options));
+ HomogeneousSplines<Precision> splines(_voronoi<Precision, true>
+ (buf, options));
return Splines(splines, options.optimize, options.nthreads);
}
-template<class T>
-SimplifiedVoronoi<T> Kopf2011::_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
- const Options &options)
+template<class T, bool adjust_splines>
+SimplifiedVoronoi<T, adjust_splines>
+Kopf2011::_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
+ const Options &options)
{
PixelGraph graph(buf);
@@ -146,13 +148,7 @@ SimplifiedVoronoi<T> Kopf2011::_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &b
graph.checkConsistency();
#endif
- _remove_puzzle_pattern(graph);
-
-#ifndef NDEBUG
- graph.checkConsistency();
-#endif
-
- return SimplifiedVoronoi<T>(graph);
+ return SimplifiedVoronoi<T, adjust_splines>(graph);
}
// TODO: move this function (plus connectAllNeighbors) to PixelGraph constructor
@@ -315,40 +311,6 @@ void Kopf2011::_remove_crossing_edges_unsafe(PixelGraph &graph,
}
}
-inline
-void Kopf2011::_remove_puzzle_pattern(PixelGraph &graph)
-{
- if ( graph.width() < 2 || graph.height() < 2 )
- return;
-
- PixelGraph::iterator it = graph.begin();
- for ( int i = 0 ; i + 1 != graph.height() ; ++i ) {
- PixelGraph::iterator it2 = it;
- for ( int j = 0 ; j + 1 != graph.width() ; ++j ) {
- // Evil pattern currently not handled correctly in SimplifiedVoronoi
- if ( it2->adj.right + it2->adj.bottom
- + graph.nodeBottomRight(it2)->adj.left
- + graph.nodeBottomRight(it2)->adj.top == 3 ) {
- // We fake a new connection =)
- it2->adj.right = true;
- graph.nodeRight(it2)->adj.left = true;
-
- it2->adj.bottom = true;
- graph.nodeBottom(it2)->adj.top = true;
-
- graph.nodeBottomRight(it2)->adj.left = true;
- graph.nodeBottom(it2)->adj.right = true;
-
- graph.nodeBottomRight(it2)->adj.top = true;
- graph.nodeRight(it2)->adj.bottom = true;
- }
-
- it2 = graph.nodeRight(it2);
- }
- it = graph.nodeBottom(it);
- }
-}
-
inline int Heuristics::curves(const PixelGraph &graph,
PixelGraph::const_iterator a,
PixelGraph::const_iterator b)
@@ -374,8 +336,7 @@ inline int Heuristics::curves(const PixelGraph &graph,
{
// There are only two values that won't be zero'ed
// and one of them has the same value of prev
- guintptr aux = guintptr(to_ptr(it));
- aux = (it->adj.top
+ guintptr aux = (it->adj.top
* guintptr(to_ptr(graph.nodeTop(it))))
+ (it->adj.topright
* guintptr(to_ptr(graph.nodeTopRight(it))))
diff --git a/src/libdepixelize/kopftracer2011.h b/src/libdepixelize/kopftracer2011.h
index aff39d3d8..c224abe9a 100644
--- a/src/libdepixelize/kopftracer2011.h
+++ b/src/libdepixelize/kopftracer2011.h
@@ -35,8 +35,6 @@
namespace Tracer {
class PixelGraph;
-template<typename T> class SimplifiedVoronoi;
-template<typename T> class HomogeneousSplines;
class Kopf2011
{
@@ -102,15 +100,15 @@ public:
private:
typedef Geom::Coord Precision;
- template<class T>
- static SimplifiedVoronoi<T> _voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
- const Options &options);
+ template<class T, bool adjust_splines>
+ static SimplifiedVoronoi<T, adjust_splines>
+ _voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
+ const Options &options);
static void _disconnect_neighbors_with_dissimilar_colors(PixelGraph &graph);
static void _remove_crossing_edges_safe(PixelGraph &graph);
static void _remove_crossing_edges_unsafe(PixelGraph &graph,
const Options &options);
- static void _remove_puzzle_pattern(PixelGraph &graph);
};
} // namespace Tracer
diff --git a/src/libdepixelize/priv/simplifiedvoronoi.h b/src/libdepixelize/priv/simplifiedvoronoi.h
index d5ebc36e5..8a25bc626 100644
--- a/src/libdepixelize/priv/simplifiedvoronoi.h
+++ b/src/libdepixelize/priv/simplifiedvoronoi.h
@@ -32,7 +32,7 @@
namespace Tracer {
-template<typename T>
+template<typename T, bool adjust_splines>
class SimplifiedVoronoi
{
public:
@@ -121,8 +121,10 @@ public:
}
private:
+#ifdef LIBDEPIXELIZE_VERY_TYPE_SAFE
typedef void (*PointTransform)(Point<T> &p, T dx, T dy);
typedef bool (*NodeTransform)(PixelGraph::const_iterator);
+#endif // LIBDEPIXELIZE_VERY_TYPE_SAFE
/**
* Output is translated by -.5 in each axis. This function fixes this error.
@@ -221,6 +223,9 @@ private:
* indirection, except for the problem of too many layers of indirection."
* -- David J. Wheeler
*/
+#ifndef LIBDEPIXELIZE_VERY_TYPE_SAFE
+ template<class PointTransform, class NodeTransform>
+#endif // LIBDEPIXELIZE_VERY_TYPE_SAFE
void _genericComplexBottomRight(PixelGraph::const_iterator a_it,
PixelGraph::const_iterator b_it,
PixelGraph::const_iterator c_it,
@@ -241,8 +246,9 @@ private:
std::vector<Cell> _cells;
};
-template<class T>
-SimplifiedVoronoi<T>::SimplifiedVoronoi(const PixelGraph &graph) :
+template<class T, bool adjust_splines>
+SimplifiedVoronoi<T, adjust_splines>
+::SimplifiedVoronoi(const PixelGraph &graph) :
_width(graph.width()),
_height(graph.height()),
_cells(graph.size())
@@ -481,10 +487,11 @@ SimplifiedVoronoi<T>::SimplifiedVoronoi(const PixelGraph &graph) :
}
}
-template<class T> void
-SimplifiedVoronoi<T>::_complexTopLeft(const PixelGraph &graph,
- PixelGraph::const_iterator graph_it,
- Cell *const cells_it, int x, int y)
+template<class T, bool adjust_splines> void
+SimplifiedVoronoi<T, adjust_splines>
+::_complexTopLeft(const PixelGraph &graph,
+ PixelGraph::const_iterator graph_it, Cell *const cells_it,
+ int x, int y)
{
_genericComplexBottomRight(graph_it,
graph.nodeLeft(graph_it),
@@ -502,10 +509,11 @@ SimplifiedVoronoi<T>::_complexTopLeft(const PixelGraph &graph,
&SimplifiedVoronoi::_complexTopLeftTransformTopLeft);
}
-template<class T> void
-SimplifiedVoronoi<T>::_complexTopRight(const PixelGraph &graph,
- PixelGraph::const_iterator graph_it,
- Cell *const cells_it, int x, int y)
+template<class T, bool adjust_splines> void
+SimplifiedVoronoi<T, adjust_splines>
+::_complexTopRight(const PixelGraph &graph,
+ PixelGraph::const_iterator graph_it, Cell *const cells_it,
+ int x, int y)
{
_genericComplexBottomRight(graph_it,
graph.nodeTop(graph_it),
@@ -523,10 +531,11 @@ SimplifiedVoronoi<T>::_complexTopRight(const PixelGraph &graph,
&SimplifiedVoronoi::_complexTopRightTransformTopLeft);
}
-template<class T> void
-SimplifiedVoronoi<T>::_complexBottomRight(const PixelGraph &graph,
- PixelGraph::const_iterator graph_it,
- Cell *const cells_it, int x, int y)
+template<class T, bool adjust_splines> void
+SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomRight(const PixelGraph &graph,
+ PixelGraph::const_iterator graph_it, Cell *const cells_it,
+ int x, int y)
{
_genericComplexBottomRight(graph_it,
graph.nodeRight(graph_it),
@@ -544,10 +553,11 @@ SimplifiedVoronoi<T>::_complexBottomRight(const PixelGraph &graph,
&SimplifiedVoronoi::_complexBottomRightTransformTopLeft);
}
-template<class T> void
-SimplifiedVoronoi<T>::_complexBottomLeft(const PixelGraph &graph,
- PixelGraph::const_iterator graph_it,
- Cell *const cells_it, int x, int y)
+template<class T, bool adjust_splines> void
+SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomLeft(const PixelGraph &graph,
+ PixelGraph::const_iterator graph_it, Cell *const cells_it,
+ int x, int y)
{
_genericComplexBottomRight(graph_it,
graph.nodeBottom(graph_it),
@@ -565,229 +575,268 @@ SimplifiedVoronoi<T>::_complexBottomLeft(const PixelGraph &graph,
&SimplifiedVoronoi::_complexBottomLeftTransformTopLeft);
}
-template<class T> void
-SimplifiedVoronoi<T>::_complexTopLeftTransform(Point<T> &p, T dx, T dy)
+template<class T, bool adjust_splines> void
+SimplifiedVoronoi<T, adjust_splines>
+::_complexTopLeftTransform(Point<T> &p, T dx, T dy)
{
p.x -= dx;
p.y -= dy;
}
-template<class T> void
-SimplifiedVoronoi<T>::_complexTopRightTransform(Point<T> &p, T dx, T dy)
+template<class T, bool adjust_splines> void
+SimplifiedVoronoi<T, adjust_splines>
+::_complexTopRightTransform(Point<T> &p, T dx, T dy)
{
p.x += dy;
p.y -= dx;
}
-template<class T> void
-SimplifiedVoronoi<T>::_complexBottomRightTransform(Point<T> &p, T dx, T dy)
+template<class T, bool adjust_splines> void
+SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomRightTransform(Point<T> &p, T dx, T dy)
{
p.x += dx;
p.y += dy;
}
-template<class T> void
-SimplifiedVoronoi<T>::_complexBottomLeftTransform(Point<T> &p, T dx, T dy)
+template<class T, bool adjust_splines> void
+SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomLeftTransform(Point<T> &p, T dx, T dy)
{
p.x -= dy;
p.y += dx;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopLeftTransformTop(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopLeftTransformTop(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottom;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopLeftTransformTopRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopLeftTransformTopRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottomleft;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopLeftTransformRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopLeftTransformRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.left;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopLeftTransformBottomRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopLeftTransformBottomRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.topleft;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopLeftTransformBottom(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopLeftTransformBottom(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.top;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopLeftTransformBottomLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopLeftTransformBottomLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.topright;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopLeftTransformLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopLeftTransformLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.right;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopLeftTransformTopLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopLeftTransformTopLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottomright;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopRightTransformTop(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopRightTransformTop(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.left;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopRightTransformTopRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopRightTransformTopRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.topleft;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopRightTransformRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopRightTransformRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.top;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopRightTransformBottomRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopRightTransformBottomRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.topright;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopRightTransformBottom(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopRightTransformBottom(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.right;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopRightTransformBottomLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopRightTransformBottomLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottomright;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopRightTransformLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopRightTransformLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottom;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexTopRightTransformTopLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexTopRightTransformTopLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottomleft;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomRightTransformTop(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomRightTransformTop(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.top;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomRightTransformTopRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomRightTransformTopRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.topright;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomRightTransformRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomRightTransformRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.right;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomRightTransformBottomRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomRightTransformBottomRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottomright;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomRightTransformBottom(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomRightTransformBottom(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottom;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomRightTransformBottomLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomRightTransformBottomLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottomleft;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomRightTransformLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomRightTransformLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.left;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomRightTransformTopLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomRightTransformTopLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.topleft;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomLeftTransformTop(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomLeftTransformTop(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.right;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomLeftTransformTopRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomLeftTransformTopRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottomright;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomLeftTransformRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomLeftTransformRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottom;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomLeftTransformBottomRight(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomLeftTransformBottomRight(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.bottomleft;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomLeftTransformBottom(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomLeftTransformBottom(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.left;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomLeftTransformBottomLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomLeftTransformBottomLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.topleft;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomLeftTransformLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomLeftTransformLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.top;
}
-template<class T>
-bool SimplifiedVoronoi<T>::_complexBottomLeftTransformTopLeft(PixelGraph::const_iterator graph_it)
+template<class T, bool adjust_splines>
+bool SimplifiedVoronoi<T, adjust_splines>
+::_complexBottomLeftTransformTopLeft(PixelGraph::const_iterator graph_it)
{
return graph_it->adj.topright;
}
-template<class T>
+template<class T, bool adjust_splines>
+#ifndef LIBDEPIXELIZE_VERY_TYPE_SAFE
+template<class PointTransform, class NodeTransform>
+#endif // LIBDEPIXELIZE_VERY_TYPE_SAFE
void
-SimplifiedVoronoi<T>
+SimplifiedVoronoi<T, adjust_splines>
::_genericComplexBottomRight(PixelGraph::const_iterator a_it,
PixelGraph::const_iterator b_it,
PixelGraph::const_iterator c_it,
@@ -817,8 +866,12 @@ SimplifiedVoronoi<T>
// this and bottom-right are connected
bool smooth[2] = {
- same_color(a_it->rgba, d_it->rgba) || right(a_it),
- same_color(a_it->rgba, d_it->rgba) || bottom(a_it)
+ ( same_color(a_it->rgba, d_it->rgba)
+ || same_color(a_it->rgba, b_it->rgba)
+ || same_color(b_it->rgba, d_it->rgba) ),
+ ( same_color(a_it->rgba, d_it->rgba)
+ || same_color(a_it->rgba, c_it->rgba)
+ || same_color(c_it->rgba, d_it->rgba) )
};
Point<T> borderMid = initial;
@@ -836,7 +889,7 @@ SimplifiedVoronoi<T>
vertices[1] = _adjust(midpoint(borderMid, vertices[1]), smooth[1]);
}
- if ( !smooth[0] ) {
+ if ( !smooth[0] && adjust_splines ) {
cells_it->vertices.push_back(vertices[0].invisible());
{
Point<T> another = vertices[0];
@@ -885,7 +938,7 @@ SimplifiedVoronoi<T>
cells_it->vertices.push_back(vertices[0]);
- if ( !smooth[1] ) {
+ if ( !smooth[1] && adjust_splines ) {
{
Point<T> another = vertices[1];
transform(another,
@@ -954,7 +1007,7 @@ SimplifiedVoronoi<T>
vertex = _adjust(midpoint(initial, vertex));
// compute smoothness
- if ( right(a_it) ) {
+ if ( right(a_it) && adjust_splines ) {
// this and right are connected
if ( !right(c_it) && !( bottom(a_it) && bottom(b_it) ) ) {
@@ -1006,11 +1059,65 @@ SimplifiedVoronoi<T>
* 0.03125 );
transform(vertex, amount, amount);
}
+ } else if ( !same_color(a_it->rgba, b_it->rgba) ) {
+ vertex.smooth = false;
+ // This is the same code of the if ( special )
+ // I REALLY NEED lambdas to improve this code without
+ // creating yet another interface that takes a million
+ // of function parameters and keep code locality
+ {
+ Point<T> another = vertex;
+ T amount = 0.03125;
+ transform(another,
+ amount
+ * ( topleft(c_it) - topright(d_it)
+ + bottomleft(a_it) - bottomright(b_it) ),
+ // y
+ - amount
+ * ( topleft(c_it) + topright(d_it)
+ - bottomleft(a_it) - bottomright(b_it) ));
+ cells_it->vertices.push_back(another.invisible());
+ }
+ {
+ Point<T> another = vertex;
+ T amount = 0.0625;
+ transform(another,
+ 0.25 - amount
+ * ( topright(d_it) + bottomright(b_it) ),
+ // y
+ - amount
+ * ( topright(d_it) - bottomright(b_it) ));
+ cells_it->vertices.push_back(another.invisible());
+ }
+ {
+ Point<T> another = vertex;
+ T amount = 0.0625;
+ transform(another,
+ - ( 0.25 - amount
+ * ( topleft(c_it) + bottomleft(a_it) ) ),
+ // y
+ - amount
+ * ( topleft(c_it) - bottomleft(a_it) ));
+ another.smooth = true;
+ cells_it->vertices.push_back(another);
+ }
+ {
+ Point<T> another = vertex;
+ T amount = 0.1875;
+ transform(another,
+ - ( 0.75 - amount
+ * ( topleft(c_it) + bottomleft(a_it) ) ),
+ // y
+ - amount
+ * ( topleft(c_it) - bottomleft(a_it) ));
+ cells_it->vertices.push_back(another.invisible());
+ }
+ vertex.visible = false;
}
} else {
// {this, right} is the pair with the angle
// closest to 180 degrees
- vertex.smooth = true;
+ vertex.smooth = same_color(a_it->rgba, b_it->rgba);
}
} else {
// there might be 2-color, then vertex.smooth = true
@@ -1018,17 +1125,12 @@ SimplifiedVoronoi<T>
// or it might be 1-color and doesn't matter,
// because the current node will disappear
vertex.smooth
- = !( bottom(a_it) ^ bottom(b_it) );
-
- if ( vertex.smooth ) {
- vertex.smooth
- = same_color(a_it->rgba, b_it->rgba)
- + same_color(a_it->rgba, c_it->rgba)
- + same_color(d_it->rgba, b_it->rgba)
- + same_color(d_it->rgba, c_it->rgba) == 2;
- }
+ = same_color(a_it->rgba, b_it->rgba)
+ + same_color(a_it->rgba, c_it->rgba)
+ + same_color(d_it->rgba, b_it->rgba)
+ + same_color(d_it->rgba, c_it->rgba) == 2;
}
- } else if ( bottom(a_it) ) {
+ } else if ( bottom(a_it) && adjust_splines ) {
// this and bottom are connected
if ( !bottom(b_it) && !( right(a_it) && right(c_it) ) ) {
@@ -1079,28 +1181,75 @@ SimplifiedVoronoi<T>
* 0.03125 );
transform(vertex, amount, amount);
}
+ } else if ( !same_color(a_it->rgba, c_it->rgba) ) {
+ vertex.smooth = false;
+ // This is the same code of the if ( special )
+ // I REALLY NEED lambdas to improve this code without
+ // creating yet another interface that takes a million
+ // of function parameters and keep code locality
+ cells_it->vertices.push_back(vertex.invisible());
+ {
+ Point<T> another = vertex;
+ T amount = 0.1875;
+ transform(another,
+ - ( topleft(b_it) - topright(a_it) ) * amount,
+ // y
+ - ( 0.75
+ - ( topleft(b_it) + topright(a_it) )
+ * amount ));
+ cells_it->vertices.push_back(another.invisible());
+ }
+ {
+ Point<T> another = vertex;
+ T amount = 0.0625;
+ transform(another,
+ - ( topleft(b_it) - topright(a_it) ) * amount,
+ // y
+ - ( 0.25
+ - ( topleft(b_it) + topright(a_it) )
+ * amount ));
+ another.smooth = true;
+ cells_it->vertices.push_back(another);
+ }
+ {
+ Point<T> another = vertex;
+ T amount = 0.0625;
+ transform(another, - amount
+ * ( bottomleft(d_it) - bottomright(c_it) ),
+ // y
+ 0.25 - amount
+ * ( bottomleft(d_it) + bottomright(c_it) ));
+ cells_it->vertices.push_back(another.invisible());
+ }
+ {
+ transform(vertex,
+ - ( topleft(b_it) + bottomleft(d_it)
+ - topright(a_it) - bottomright(c_it) )
+ * 0.03125,
+ // y
+ ( topleft(b_it) - bottomleft(d_it)
+ + topright(a_it) - bottomright(c_it) )
+ * 0.03125);
+ vertex.visible = false;
+ }
}
} else {
// {this, bottom} is the pair with the angle
// closest to 180 degrees
- vertex.smooth = true;
+ vertex.smooth = same_color(a_it->rgba, c_it->rgba);
}
} else {
// there might be 2-color, then vertex.smooth = true
// or it might be 1-color and doesn't matter,
// because the current node will disappear
- vertex.smooth = !( right(a_it) ^ right(c_it) );
-
- if ( vertex.smooth ) {
- vertex.smooth
- = same_color(a_it->rgba, c_it->rgba)
- + same_color(a_it->rgba, b_it->rgba)
- + same_color(d_it->rgba, b_it->rgba)
- + same_color(d_it->rgba, c_it->rgba) == 2;
- }
+ vertex.smooth
+ = same_color(a_it->rgba, c_it->rgba)
+ + same_color(a_it->rgba, b_it->rgba)
+ + same_color(d_it->rgba, b_it->rgba)
+ + same_color(d_it->rgba, c_it->rgba) == 2;
}
- } else if ( bottom(b_it) ) {
+ } else if ( bottom(b_it) && adjust_splines ) {
// right and bottom-right are connected
bool special = false;
@@ -1205,7 +1354,7 @@ SimplifiedVoronoi<T>
vertex.visible = false;
}
}
- } else if ( right(c_it) ) {
+ } else if ( right(c_it) && adjust_splines ) {
// bottom and bottom-right are connected
bool special = false;
diff --git a/src/libdepixelize/priv/splines-kopf2011.h b/src/libdepixelize/priv/splines-kopf2011.h
index eb84c3bfb..fb4f8ba1e 100644
--- a/src/libdepixelize/priv/splines-kopf2011.h
+++ b/src/libdepixelize/priv/splines-kopf2011.h
@@ -107,22 +107,22 @@ void worker(const typename HomogeneousSplines<T>::Polygon &source,
}
}
-template<typename T>
-Splines::Splines(const SimplifiedVoronoi<T> &diagram) :
+template<typename T, bool adjust_splines>
+Splines::Splines(const SimplifiedVoronoi<T, adjust_splines> &diagram) :
_width(diagram.width()),
_height(diagram.height())
{
_paths.reserve(diagram.size());
- for ( typename SimplifiedVoronoi<T>::const_iterator it = diagram.begin()
- , end = diagram.end() ; it != end ; ++it ) {
+ for ( typename SimplifiedVoronoi<T, adjust_splines>::const_iterator
+ it = diagram.begin() , end = diagram.end() ; it != end ; ++it ) {
Path path;
path.pathVector
.push_back(Geom::Path(to_geom_point(it->vertices.front())));
for ( typename std::vector< Point<T> >::const_iterator
- it2 = it->vertices.begin(), end2 = it->vertices.end()
+ it2 = ++it->vertices.begin(), end2 = it->vertices.end()
; it2 != end2 ; ++it2 ) {
path.pathVector.back()
.appendNew<Geom::LineSegment>(Geom::Point(it2->x, it2->y));
diff --git a/src/libdepixelize/splines.h b/src/libdepixelize/splines.h
index c4b455aae..b06ba8ba9 100644
--- a/src/libdepixelize/splines.h
+++ b/src/libdepixelize/splines.h
@@ -30,7 +30,7 @@
namespace Tracer {
-template<typename T>
+template<typename T, bool adjust_splines = true>
class SimplifiedVoronoi;
template<typename T>
@@ -54,8 +54,8 @@ public:
Splines() /* = default */ {}
- template<typename T>
- Splines(const SimplifiedVoronoi<T> &simplifiedVoronoi);
+ template<typename T, bool adjust_splines>
+ Splines(const SimplifiedVoronoi<T, adjust_splines> &simplifiedVoronoi);
/**
* There are two levels of optimization. The first level only removes