summaryrefslogtreecommitdiffstats
path: root/src/libdepixelize
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2014-04-01 17:00:00 +0000
committerJabiertxof <jtx@jtx.marker.es>2014-04-01 17:00:00 +0000
commit208ccdf9782984702f79b8ba416e67dd1e2c2dfa (patch)
tree79d15123aa526c49c6386db6245fbfc6b7a63eaf /src/libdepixelize
parentupdate to trunk (diff)
parentpartial 2geom update: (diff)
downloadinkscape-208ccdf9782984702f79b8ba416e67dd1e2c2dfa.tar.gz
inkscape-208ccdf9782984702f79b8ba416e67dd1e2c2dfa.zip
update to trunk
(bzr r12588.1.32)
Diffstat (limited to 'src/libdepixelize')
-rw-r--r--src/libdepixelize/kopftracer2011.cpp415
-rw-r--r--src/libdepixelize/kopftracer2011.h26
-rw-r--r--src/libdepixelize/priv/homogeneoussplines.h21
-rw-r--r--src/libdepixelize/priv/pixelgraph.h80
-rw-r--r--src/libdepixelize/priv/simplifiedvoronoi.h271
5 files changed, 655 insertions, 158 deletions
diff --git a/src/libdepixelize/kopftracer2011.cpp b/src/libdepixelize/kopftracer2011.cpp
index ab31d05c3..e2f387c86 100644
--- a/src/libdepixelize/kopftracer2011.cpp
+++ b/src/libdepixelize/kopftracer2011.cpp
@@ -31,7 +31,6 @@
#include <glibmm/threads.h>
#endif
-#include <utility>
#include <algorithm>
#include "kopftracer2011.h"
#include "priv/colorspace.h"
@@ -40,6 +39,11 @@
#include "priv/splines-kopf2011.h"
#include "priv/iterator.h"
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+#include <glibmm/datetime.h>
+#include <iostream>
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
namespace Tracer {
namespace Heuristics {
@@ -86,7 +90,95 @@ Splines Kopf2011::to_voronoi(const std::string &filename,
Splines Kopf2011::to_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ SimplifiedVoronoi<Precision, false> voronoi
+ = _voronoi<Precision, false>(buf, options);
+
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ Splines ret(voronoi);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Splines construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
return Splines(_voronoi<Precision, false>(buf, options));
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+}
+
+Splines Kopf2011::to_grouped_voronoi(const std::string &filename,
+ const Options &options)
+{
+ return to_grouped_voronoi(Gdk::Pixbuf::create_from_file(filename), options);
+}
+
+Splines Kopf2011::to_grouped_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
+ const Options &options)
+{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ SimplifiedVoronoi<Precision, false> voronoi
+ = _voronoi<Precision, false>(buf, options);
+
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ HomogeneousSplines<Precision> splines(voronoi);
+
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
+ HomogeneousSplines<Precision> splines(_voronoi<Precision, false>
+ (buf, options));
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::HomogeneousSplines<" << typeid(Precision).name()
+ << ">(Tracer::SimplifiedVoronoi<" << typeid(Precision).name()
+ << ",false>) construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ for ( HomogeneousSplines<Precision>::iterator it = splines.begin(),
+ end = splines.end() ; it != end ; ++it ) {
+ for ( HomogeneousSplines<Precision>::Polygon::points_iter
+ it2 = it->vertices.begin(), end2 = it->vertices.end()
+ ; it2 != end2 ; ++it2 ) {
+ it2->smooth = false;
+ }
+ for ( HomogeneousSplines<Precision>::Polygon::holes_iter
+ it2 = it->holes.begin(), end2 = it->holes.end()
+ ; it2 != end2 ; ++it2 ) {
+ for ( HomogeneousSplines<Precision>::Polygon::points_iter
+ it3 = it2->begin(), end3 = it2->end()
+ ; it3 != end3 ; ++it3 ) {
+ it3->smooth = false;
+ }
+ }
+ }
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::to_grouped_voronoi internal work time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ Splines ret(splines, false, options.nthreads);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Splines construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
+ return Splines(splines, false, options.nthreads);
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
}
Splines Kopf2011::to_splines(const std::string &filename,
@@ -98,9 +190,36 @@ Splines Kopf2011::to_splines(const std::string &filename,
Splines Kopf2011::to_splines(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ SimplifiedVoronoi<Precision, true> voronoi
+ = _voronoi<Precision, true>(buf, options);
+
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ HomogeneousSplines<Precision> splines(voronoi);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::HomogeneousSplines<" << typeid(Precision).name()
+ << "> construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ Splines ret(splines, options.optimize, options.nthreads);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Splines construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
HomogeneousSplines<Precision> splines(_voronoi<Precision, true>
(buf, options));
return Splines(splines, options.optimize, options.nthreads);
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
}
template<class T, bool adjust_splines>
@@ -108,47 +227,131 @@ SimplifiedVoronoi<T, adjust_splines>
Kopf2011::_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
PixelGraph graph(buf);
- /*if ( !graph.width() || !graph.height() )
- return;*/
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::PixelGraph creation time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ // gdk-pixbuf2 already checks if image size is meaningful, but asserts state
+ // preconditions and will be useful if gdk-pixbuf is replaced later
+ assert(graph.width() > 0);
+ assert(graph.height() > 0);
#ifndef NDEBUG
graph.checkConsistency();
#endif
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
// This step could be part of the initialization of PixelGraph
// and decrease the necessary number of passes
graph.connectAllNeighbors();
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::PixelGraph::connectAllNeighbors() time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
#ifndef NDEBUG
graph.checkConsistency();
#endif
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
// This step can't be part of PixelGraph initilization without adding some
// cache misses due to random access patterns that might be injected
_disconnect_neighbors_with_dissimilar_colors(graph);
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::"
+ "_disconnect_neighbors_with_dissimilar_colors(Tracer::PixelGraph) time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
#ifndef NDEBUG
graph.checkConsistency();
#endif
- // This and below steps must be executed in separate.
- // Otherwise, there will be colateral effects due to misassumption about the
- // data being read.
- _remove_crossing_edges_safe(graph);
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ {
+ // edges_safe and edges_unsafe must be executed in separate.
+ // Otherwise, there will be colateral effects due to misassumption about
+ // the data being read.
+ PixelGraph::EdgePairContainer edges = graph.crossingEdges();
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::PixelGraph::crossingEdges() time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ _remove_crossing_edges_safe(edges);
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::_remove_crossing_edges_safe"
+ "(Tracer::PixelGraph) time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
#ifndef NDEBUG
- graph.checkConsistency();
+ graph.checkConsistency();
#endif
- _remove_crossing_edges_unsafe(graph, options);
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ _remove_crossing_edges_unsafe(graph, edges, options);
+ }
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::_remove_crossing_edges_unsafe"
+ "(Tracer::PixelGraph) time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
#ifndef NDEBUG
graph.checkConsistency();
#endif
+ assert(graph.crossingEdges().size() == 0);
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ SimplifiedVoronoi<T, adjust_splines> ret(graph);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::SimplifiedVoronoi<" << typeid(T).name() << ','
+ << (adjust_splines ? "true" : "false")
+ << ">(Tracer::PixelGraph) construction time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
return SimplifiedVoronoi<T, adjust_splines>(graph);
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
}
// TODO: move this function (plus connectAllNeighbors) to PixelGraph constructor
@@ -192,123 +395,115 @@ Kopf2011::_disconnect_neighbors_with_dissimilar_colors(PixelGraph &graph)
*
* In this case the two diagonal connections can be safely removed without
* affecting the final result.
- *
- * \TODO: It should remember/cache who are the unsafe crossing edges?
*/
-inline void Kopf2011::_remove_crossing_edges_safe(PixelGraph &graph)
+template<class T>
+void Kopf2011::_remove_crossing_edges_safe(T &container)
{
- if ( graph.width() < 2 || graph.height() < 2 )
- return;
-
- PixelGraph::iterator it = graph.begin();
- for ( int i = 0 ; i != graph.height() - 1 ; ++i, ++it ) {
- for ( int j = 0 ; j != graph.width() - 1 ; ++j, ++it ) {
- // this <-> right
- if ( !it->adj.right )
- continue;
-
- // this <-> down
- if ( !it->adj.bottom )
- continue;
-
- PixelGraph::iterator down_right = it + graph.width() + 1;
-
- // down_right <-> right
- if ( !down_right->adj.top )
- continue;
+ for ( typename T::reverse_iterator it = container.rbegin(),
+ end = container.rend() ; it != end ; ) {
+ /* A | B
+ --+--
+ C | D */
+ PixelGraph::iterator a = it->first.first;
+ PixelGraph::iterator b = it->second.first;
+ PixelGraph::iterator c = it->second.second;
+ PixelGraph::iterator d = it->first.second;
+
+ if ( !a->adj.right || !a->adj.bottom || !b->adj.bottom
+ || !c->adj.right ) {
+ ++it;
+ continue;
+ }
- // down_right <-> down
- if ( !down_right->adj.left )
- continue;
+ // main diagonal
+ a->adj.bottomright = 0;
+ d->adj.topleft = 0;
- // main diagonal
- // this <-> down_right
- it->adj.bottomright = 0;
- down_right->adj.topleft = 0;
+ // secondary diagonal
+ b->adj.bottomleft = 0;
+ c->adj.topright = 0;
- // secondary diagonal
- // right <-> down
- (it + 1)->adj.bottomleft = 0;
- (it + graph.width())->adj.topright = 0;
- }
+ // base iterator is always past one
+ typename T::iterator current = --(it.base());
+ ++it;
+ container.erase(current);
}
}
/**
* This method removes crossing edges using the heuristics.
*/
-inline
-void Kopf2011::_remove_crossing_edges_unsafe(PixelGraph &graph,
+template<class T>
+void Kopf2011::_remove_crossing_edges_unsafe(PixelGraph &graph, T &edges,
const Options &options)
{
- if ( graph.width() < 2 || graph.height() < 2 )
- return;
-
- // Iterate over the graph, 2x2 blocks at time
- PixelGraph::iterator it = graph.begin();
- for (int i = 0 ; i != graph.height() - 1 ; ++i, ++it ) {
- for ( int j = 0 ; j != graph.width() - 1 ; ++j, ++it ) {
- using std::pair;
- using std::make_pair;
-
- typedef pair<PixelGraph::iterator, PixelGraph::iterator> Edge;
- typedef pair<Edge, int> EdgeWeight;
-
- EdgeWeight diagonals[2] = {
- make_pair(make_pair(it, graph.nodeBottomRight(it)), 0),
- make_pair(make_pair(graph.nodeRight(it), graph.nodeBottom(it)),
- 0)
- };
-
- // Check if there are crossing edges
- if ( !diagonals[0].first.first->adj.bottomright
- || !diagonals[1].first.first->adj.bottomleft ) {
- continue;
- }
-
- // Compute weights
- for ( int i = 0 ; i != 2 ; ++i ) {
- // Curves and islands heuristics
- PixelGraph::const_iterator a = diagonals[i].first.first;
- PixelGraph::const_iterator b = diagonals[i].first.second;
-
- diagonals[i].second += Heuristics::curves(graph, a, b)
- * options.curvesMultiplier;
-
- diagonals[i].second += Heuristics::islands(a, b)
- * options.islandsWeight;
- }
-
- {
- // Sparse pixels heuristic
- Heuristics::SparsePixels sparse_pixels;
-
- for ( int i = 0 ; i != 2 ; ++i )
- sparse_pixels.diagonals[i] = diagonals[i];
-
- sparse_pixels(graph, options.sparsePixelsRadius);
-
- for ( int i = 0 ; i != 2 ; ++i ) {
- diagonals[i].second += sparse_pixels.diagonals[i].second
- * options.sparsePixelsMultiplier;
- }
- }
+ std::vector< std::pair<int, int> > weights(edges.size(),
+ std::make_pair(0, 0));
+
+ // Compute weights
+ for ( typename T::size_type i = 0 ; i != edges.size() ; ++i ) {
+ /* A | B
+ --+--
+ C | D */
+ PixelGraph::iterator a = edges[i].first.first;
+ PixelGraph::iterator b = edges[i].second.first;
+ PixelGraph::iterator c = edges[i].second.second;
+ PixelGraph::iterator d = edges[i].first.second;
+
+ // Curves heuristic
+ weights[i].first += Heuristics::curves(graph, a, d)
+ * options.curvesMultiplier;
+ weights[i].second += Heuristics::curves(graph, b, c)
+ * options.curvesMultiplier;
+
+ // Islands heuristic
+ weights[i].first += Heuristics::islands(a, d) * options.islandsWeight;
+ weights[i].second += Heuristics::islands(b, c) * options.islandsWeight;
+
+ // Sparse pixels heuristic
+ using Heuristics::SparsePixels;
+ SparsePixels sparse_pixels;
+
+ sparse_pixels.diagonals[SparsePixels::MAIN_DIAGONAL].first
+ = edges[i].first;
+ sparse_pixels.diagonals[SparsePixels::SECONDARY_DIAGONAL].first
+ = edges[i].second;
+
+ sparse_pixels(graph, options.sparsePixelsRadius);
+
+ weights[i].first
+ += sparse_pixels.diagonals[SparsePixels::MAIN_DIAGONAL].second
+ * options.sparsePixelsMultiplier;
+ weights[i].second
+ += sparse_pixels.diagonals[SparsePixels::SECONDARY_DIAGONAL].second
+ * options.sparsePixelsMultiplier;
+ }
- // Remove edges with lower weight
- if ( diagonals[0].second > diagonals[1].second ) {
- diagonals[1].first.first->adj.bottomleft = 0;
- diagonals[1].first.second->adj.topright = 0;
- } else if ( diagonals[0].second < diagonals[1].second ) {
- diagonals[0].first.first->adj.bottomright = 0;
- diagonals[0].first.second->adj.topleft = 0;
- } else {
- diagonals[0].first.first->adj.bottomright = 0;
- diagonals[0].first.second->adj.topleft = 0;
- diagonals[1].first.first->adj.bottomleft = 0;
- diagonals[1].first.second->adj.topright = 0;
- }
+ // Remove edges with lower weight
+ for ( typename T::size_type i = 0 ; i != edges.size() ; ++i ) {
+ /* A | B
+ --+--
+ C | D */
+ PixelGraph::iterator a = edges[i].first.first;
+ PixelGraph::iterator b = edges[i].second.first;
+ PixelGraph::iterator c = edges[i].second.second;
+ PixelGraph::iterator d = edges[i].first.second;
+
+ if ( weights[i].first > weights[i].second ) {
+ b->adj.bottomleft = 0;
+ c->adj.topright = 0;
+ } else if ( weights[i].first < weights[i].second ) {
+ a->adj.bottomright = 0;
+ d->adj.topleft = 0;
+ } else {
+ a->adj.bottomright = 0;
+ b->adj.bottomleft = 0;
+ c->adj.topright = 0;
+ d->adj.topleft = 0;
}
}
+
+ edges.clear();
}
inline int Heuristics::curves(const PixelGraph &graph,
diff --git a/src/libdepixelize/kopftracer2011.h b/src/libdepixelize/kopftracer2011.h
index c224abe9a..598f6c79c 100644
--- a/src/libdepixelize/kopftracer2011.h
+++ b/src/libdepixelize/kopftracer2011.h
@@ -88,6 +88,23 @@ public:
/**
* # Exceptions
*
+ * \p options.optimize and options.nthreads will be ignored
+ *
+ * Glib::FileError
+ * Gdk::PixbufError
+ */
+ static Splines to_grouped_voronoi(const std::string &filename,
+ const Options &options = Options());
+
+ /*
+ * \p options.optimize and options.nthreads will be ignored
+ */
+ static Splines to_grouped_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
+ const Options &options = Options());
+
+ /**
+ * # Exceptions
+ *
* Glib::FileError
* Gdk::PixbufError
*/
@@ -106,8 +123,13 @@ private:
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,
+
+ // here, T/template is only used as an easy way to not expose internal
+ // symbols
+ template<class T>
+ static void _remove_crossing_edges_safe(T &container);
+ template<class T>
+ static void _remove_crossing_edges_unsafe(PixelGraph &graph, T &edges,
const Options &options);
};
diff --git a/src/libdepixelize/priv/homogeneoussplines.h b/src/libdepixelize/priv/homogeneoussplines.h
index 57c77a163..6c4894dd8 100644
--- a/src/libdepixelize/priv/homogeneoussplines.h
+++ b/src/libdepixelize/priv/homogeneoussplines.h
@@ -38,6 +38,12 @@ class HomogeneousSplines
public:
struct Polygon
{
+ typedef std::vector< Point<T> > Points;
+ typedef typename Points::iterator points_iter;
+ typedef typename Points::const_iterator const_points_iter;
+ typedef typename std::vector<Points>::iterator holes_iter;
+ typedef typename std::vector<Points>::const_iterator const_holes_iter;
+
Polygon() {}
Polygon(const guint8 (&rgba)[4])
{
@@ -59,7 +65,8 @@ public:
typedef typename std::vector<Polygon>::const_iterator const_iterator;
typedef typename std::vector<Polygon>::size_type size_type;
- HomogeneousSplines(const SimplifiedVoronoi<T> &voronoi);
+ template<bool adjust_splines>
+ HomogeneousSplines(const SimplifiedVoronoi<T, adjust_splines> &voronoi);
// Iterators
iterator begin()
@@ -98,12 +105,7 @@ public:
}
private:
- typedef typename SimplifiedVoronoi<T>::Cell Cell;
typedef std::vector< Point<T> > Points;
-
- typedef typename SimplifiedVoronoi<T>::iterator voronoi_iter;
- typedef typename SimplifiedVoronoi<T>::const_iterator voronoi_citer;
-
typedef typename Points::iterator points_iter;
typedef typename Points::const_iterator points_citer;
typedef typename Points::reverse_iterator points_riter;
@@ -171,7 +173,9 @@ private:
};
template<class T>
-HomogeneousSplines<T>::HomogeneousSplines(const SimplifiedVoronoi<T> &voronoi) :
+template<bool adjust_splines>
+HomogeneousSplines<T>::HomogeneousSplines(const SimplifiedVoronoi<T,
+ adjust_splines> &voronoi) :
_width(voronoi.width()),
_height(voronoi.height())
{
@@ -179,6 +183,9 @@ HomogeneousSplines<T>::HomogeneousSplines(const SimplifiedVoronoi<T> &voronoi) :
// return;
using colorspace::same_color;
+ typedef typename SimplifiedVoronoi<T, adjust_splines>::const_iterator
+ voronoi_citer;
+
// Identify visible edges (group polygons with the same color)
for ( voronoi_citer cell_it = voronoi.begin(), cell_end = voronoi.end()
; cell_it != cell_end ; ++cell_it ) {
diff --git a/src/libdepixelize/priv/pixelgraph.h b/src/libdepixelize/priv/pixelgraph.h
index 9e8c2124a..112242647 100644
--- a/src/libdepixelize/priv/pixelgraph.h
+++ b/src/libdepixelize/priv/pixelgraph.h
@@ -28,6 +28,7 @@
#include <gdkmm/pixbuf.h>
#include <vector>
#include <cassert>
+#include <utility>
namespace Tracer {
@@ -76,6 +77,10 @@ public:
typedef std::vector<Node>::reverse_iterator reverse_iterator;
typedef std::vector<Node>::const_reverse_iterator const_reverse_iterator;
+ typedef std::pair<iterator, iterator> Edge;
+ typedef std::pair<Edge, Edge> EdgePair;
+ typedef std::vector<EdgePair> EdgePairContainer;
+
class ColumnView
{
public:
@@ -162,6 +167,7 @@ public:
// Algorithms
void connectAllNeighbors();
+ EdgePairContainer crossingEdges();
int toX(const_iterator n) const
{
@@ -389,14 +395,23 @@ inline void PixelGraph::connectAllNeighbors()
// ...then the "top" nodes...
if ( _width > 2 ) {
Node *it = &_nodes[1];
- for ( int i = 1 ; i != _width - 1 ; ++i ) {
- it->adj.right = 1;
- it->adj.bottomright = 1;
- it->adj.bottom = 1;
- it->adj.bottomleft = 1;
- it->adj.left = 1;
+ if ( _height > 1 ) {
+ for ( int i = 1 ; i != _width - 1 ; ++i ) {
+ it->adj.right = 1;
+ it->adj.bottomright = 1;
+ it->adj.bottom = 1;
+ it->adj.bottomleft = 1;
+ it->adj.left = 1;
- ++it;
+ ++it;
+ }
+ } else {
+ for ( int i = 1 ; i != _width - 1 ; ++i ) {
+ it->adj.right = 1;
+ it->adj.left = 1;
+
+ ++it;
+ }
}
}
@@ -417,14 +432,23 @@ inline void PixelGraph::connectAllNeighbors()
// ...then the "left" nodes...
if ( _height > 2 ) {
iterator it = nodeBottom(begin()); // [0][1]
- for ( int i = 1 ; i != _height - 1 ; ++i ) {
- it->adj.top = 1;
- it->adj.topright = 1;
- it->adj.right = 1;
- it->adj.bottomright = 1;
- it->adj.bottom = 1;
+ if ( _width > 1 ) {
+ for ( int i = 1 ; i != _height - 1 ; ++i ) {
+ it->adj.top = 1;
+ it->adj.topright = 1;
+ it->adj.right = 1;
+ it->adj.bottomright = 1;
+ it->adj.bottom = 1;
- it = nodeBottom(it);
+ it = nodeBottom(it);
+ }
+ } else {
+ for ( int i = 1 ; i != _height - 1 ; ++i ) {
+ it->adj.top = 1;
+ it->adj.bottom = 1;
+
+ it = nodeBottom(it);
+ }
}
}
@@ -482,6 +506,34 @@ inline void PixelGraph::connectAllNeighbors()
}
}
+PixelGraph::EdgePairContainer PixelGraph::crossingEdges()
+{
+ EdgePairContainer ret;
+
+ if ( width() < 2 || height() < 2 )
+ return ret;
+
+ // Iterate over the graph, 2x2 blocks at time
+ PixelGraph::iterator it = begin();
+ for (int i = 0 ; i != height() - 1 ; ++i, ++it ) {
+ for ( int j = 0 ; j != width() - 1 ; ++j, ++it ) {
+ EdgePair diagonals(
+ Edge(it, nodeBottomRight(it)),
+ Edge(nodeRight(it), nodeBottom(it)));
+
+ // Check if there are crossing edges
+ if ( !diagonals.first.first->adj.bottomright
+ || !diagonals.second.first->adj.bottomleft ) {
+ continue;
+ }
+
+ ret.push_back(diagonals);
+ }
+ }
+
+ return ret;
+}
+
inline PixelGraph::Node &PixelGraph::ColumnView::operator[](int line)
{
return _nodes[line * _width + _column];
diff --git a/src/libdepixelize/priv/simplifiedvoronoi.h b/src/libdepixelize/priv/simplifiedvoronoi.h
index 8a25bc626..84feab08d 100644
--- a/src/libdepixelize/priv/simplifiedvoronoi.h
+++ b/src/libdepixelize/priv/simplifiedvoronoi.h
@@ -296,21 +296,40 @@ SimplifiedVoronoi<T, adjust_splines>
PixelGraph::const_iterator graph_it = graph.begin() + 1;
Cell *cells_it = &_cells.front() + 1;
- for ( int i = 1 ; i != _width - 1 ; ++i, ++graph_it, ++cells_it ) {
- for ( int j = 0 ; j != 4 ; ++j )
- cells_it->rgba[j] = graph_it->rgba[j];
+ if ( _height > 1 ) {
+ for ( int i = 1 ; i != _width - 1 ; ++i, ++graph_it, ++cells_it ) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
- // Top-left
- cells_it->vertices.push_back(Point<T>(i, 0, false));
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(i, 0, false));
- // Top-right
- cells_it->vertices.push_back(Point<T>(i + 1, 0, false));
+ // Top-right
+ cells_it->vertices.push_back(Point<T>(i + 1, 0, false));
- // Bottom-right
- _complexBottomRight(graph, graph_it, cells_it, i, 0);
+ // Bottom-right
+ _complexBottomRight(graph, graph_it, cells_it, i, 0);
- // Bottom-left
- _complexBottomLeft(graph, graph_it, cells_it, i, 0);
+ // Bottom-left
+ _complexBottomLeft(graph, graph_it, cells_it, i, 0);
+ }
+ } else {
+ for ( int i = 1 ; i != _width - 1 ; ++i, ++graph_it, ++cells_it ) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
+
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(i, 0, false));
+
+ // Top-right
+ cells_it->vertices.push_back(Point<T>(i + 1, 0, false));
+
+ // Bottom-right
+ cells_it->vertices.push_back(Point<T>(i + 1, 1, false));
+
+ // Bottom-left
+ cells_it->vertices.push_back(Point<T>(i, 1, false));
+ }
}
}
@@ -344,24 +363,46 @@ SimplifiedVoronoi<T, adjust_splines>
PixelGraph::const_iterator graph_it = graph.begin() + _width;
Cell *cells_it = &_cells.front() + _width;
- for ( int i = 1 ; i != _height - 1 ; ++i) {
- for ( int j = 0 ; j != 4 ; ++j )
- cells_it->rgba[j] = graph_it->rgba[j];
+ if ( _width > 1 ) {
+ for ( int i = 1 ; i != _height - 1 ; ++i) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
- // Top-left
- cells_it->vertices.push_back(Point<T>(0, i, false));
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(0, i, false));
- // Top-right
- _complexTopRight(graph, graph_it, cells_it, 0, i);
+ // Top-right
+ _complexTopRight(graph, graph_it, cells_it, 0, i);
- // Bottom-right
- _complexBottomRight(graph, graph_it, cells_it, 0, i);
+ // Bottom-right
+ _complexBottomRight(graph, graph_it, cells_it, 0, i);
- // Bottom-left
- cells_it->vertices.push_back(Point<T>(0, i + 1, false));
+ // Bottom-left
+ cells_it->vertices.push_back(Point<T>(0, i + 1, false));
- graph_it += _width;
- cells_it += _width;
+ graph_it += _width;
+ cells_it += _width;
+ }
+ } else {
+ for ( int i = 1 ; i != _height - 1 ; ++i) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
+
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(0, i, false));
+
+ // Top-right
+ cells_it->vertices.push_back(Point<T>(1, i, false));
+
+ // Bottom-right
+ cells_it->vertices.push_back(Point<T>(1, i, false));
+
+ // Bottom-left
+ cells_it->vertices.push_back(Point<T>(0, i + 1, false));
+
+ graph_it += _width;
+ cells_it += _width;
+ }
}
}
@@ -890,7 +931,11 @@ SimplifiedVoronoi<T, adjust_splines>
}
if ( !smooth[0] && adjust_splines ) {
- cells_it->vertices.push_back(vertices[0].invisible());
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
+ cells_it->vertices.push_back(vertices[0].invisible());
+#else
+ cells_it->vertices.push_back(vertices[0]);
+#endif
{
Point<T> another = vertices[0];
transform(another,
@@ -899,7 +944,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- ( 0.5625
- ( topright(a_it) + topleft(b_it) ) * 0.1875 ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[0];
@@ -910,7 +959,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.1875
- ( topright(a_it) + topleft(b_it) ) * 0.0625) );
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[0];
@@ -920,7 +973,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.0625
+ ( bottomright(b_it) - topright(d_it) ) * 0.0625);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
transform(vertices[0],
@@ -932,7 +989,9 @@ SimplifiedVoronoi<T, adjust_splines>
+ ( topright(d_it) - topright(a_it)
- topleft(b_it) - bottomright(b_it) )
* 0.03125 ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertices[0].visible = false;
+#endif
}
}
@@ -950,7 +1009,11 @@ SimplifiedVoronoi<T, adjust_splines>
0.0625
+ ( bottomleft(a_it) - bottomleft(d_it)
- topleft(c_it) - bottomright(c_it) ) * 0.03125);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[1];
@@ -960,7 +1023,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.1875
- ( bottomright(c_it) + bottomleft(d_it) ) * 0.0625);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[1];
@@ -973,7 +1040,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( bottomleft(a_it) - topleft(c_it) )
* 0.0625 ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[1];
@@ -985,9 +1056,15 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.1875
- ( bottomleft(a_it) - topleft(c_it) )
* 0.1875 ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertices[1].visible = false;
+#endif
}
cells_it->vertices.push_back(vertices[1]);
@@ -1029,13 +1106,21 @@ SimplifiedVoronoi<T, adjust_splines>
- ( ( bottomright(c_it) + topleft(c_it) )
* 0.03125 );
transform(another, - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(c_it);
transform(another, amount, 0.25 - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1043,16 +1128,26 @@ SimplifiedVoronoi<T, adjust_splines>
transform(another, - ( 0.25 - amount ),
- amount);
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(c_it);
transform(another, - ( 0.75 - amount ),
- amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
} else if ( twin_is_contour ) {
T amount = 0.125
- ( ( bottomleft(d_it) + topright(d_it) )
@@ -1076,7 +1171,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) + topright(d_it)
- bottomleft(a_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1087,7 +1186,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topright(d_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1099,7 +1202,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1110,9 +1217,15 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else {
// {this, right} is the pair with the angle
@@ -1146,13 +1259,21 @@ SimplifiedVoronoi<T, adjust_splines>
if ( !vertex.smooth ) {
if ( another_is_contour ) {
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(b_it);
transform(another, - amount,
- ( 0.75 - amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1160,20 +1281,30 @@ SimplifiedVoronoi<T, adjust_splines>
transform(another, - amount,
- ( 0.25 - amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(b_it);
transform(another, 0.25 - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
T amount = 0.125
- (bottomright(b_it) + topleft(b_it))
* 0.03125;
transform(vertex, amount, - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else if ( twin_is_contour ) {
T amount = 0.125
@@ -1187,7 +1318,11 @@ SimplifiedVoronoi<T, adjust_splines>
// I REALLY NEED lambdas to improve this code without
// creating yet another interface that takes a million
// of function parameters and keep code locality
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875;
@@ -1197,7 +1332,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.75
- ( topleft(b_it) + topright(a_it) )
* amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1209,7 +1348,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( topleft(b_it) + topright(a_it) )
* amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1219,7 +1362,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.25 - amount
* ( bottomleft(d_it) + bottomright(c_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
transform(vertex,
@@ -1230,7 +1377,9 @@ SimplifiedVoronoi<T, adjust_splines>
( topleft(b_it) - bottomleft(d_it)
+ topright(a_it) - bottomright(c_it) )
* 0.03125);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
}
} else {
@@ -1273,28 +1422,46 @@ SimplifiedVoronoi<T, adjust_splines>
- ( topleft(c_it) + bottomright(c_it) )
* 0.03125;
transform(another, - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(c_it);
transform(another, amount, 0.25 - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * topleft(c_it);
transform(another, - ( 0.25 - amount ), - amount);
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(c_it);
transform(another, - ( 0.75 - amount ), - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
} else {
special = true;
}
@@ -1308,7 +1475,11 @@ SimplifiedVoronoi<T, adjust_splines>
}
if ( special ) {
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875;
@@ -1318,7 +1489,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.75
- ( topleft(b_it) + topright(a_it) )
* amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1330,7 +1505,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( topleft(b_it) + topright(a_it) )
* amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1340,7 +1519,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.25 - amount
* ( bottomleft(d_it) + bottomright(c_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
transform(vertex,
@@ -1351,7 +1534,9 @@ SimplifiedVoronoi<T, adjust_splines>
( topleft(b_it) - bottomleft(d_it)
+ topright(a_it) - bottomright(c_it) )
* 0.03125);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
}
} else if ( right(c_it) && adjust_splines ) {
@@ -1372,31 +1557,49 @@ SimplifiedVoronoi<T, adjust_splines>
if ( !vertex.smooth ) {
if ( similar_neighbor_is_contour ) {
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(b_it);
transform(another, - amount, - ( 0.75 - amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * topleft(b_it);
transform(another, - amount, - ( 0.25 - amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(b_it);
transform(another, 0.25 - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
T amount = 0.125
- 0.03125 * (topleft(b_it) + bottomright(b_it));
transform(vertex, amount, - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else {
special = true;
@@ -1422,7 +1625,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) + topright(d_it)
- bottomleft(a_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1433,7 +1640,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topright(d_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1445,7 +1656,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1456,9 +1671,15 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else {
// there is a 4-color pattern, where the current node