/* This file is part of the libdepixelize project Copyright (C) 2013 Vinícius dos Santos Oliveira GNU Lesser General Public License Usage This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . GNU General Public License Usage Alternatively, this library may be used under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. You should have received a copy of the GNU General Public License along with this library. If not, see . This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ #ifndef LIBDEPIXELIZE_TRACER_SPLINES_KOPF2011_H #define LIBDEPIXELIZE_TRACER_SPLINES_KOPF2011_H #include "../splines.h" #include "homogeneoussplines.h" #include "optimization-kopf2011.h" namespace Tracer { /** * Maybe the pass-by-value and then move idiom should be more efficient. But all * this is inlinable and we're not even in C++11 yet. */ template Geom::Path worker_helper(const std::vector< Point > &source1, bool optimize) { typedef Geom::LineSegment Line; typedef Geom::QuadraticBezier Quad; typedef typename std::vector< Point >::const_iterator iterator; std::vector< Point > source; if ( optimize ) source = Tracer::optimize(source1); else source = source1; iterator it = source.begin(); Point prev = source.back(); Geom::Path ret(to_geom_point(midpoint(prev, *it))); for ( iterator end = source.end() ; it != end ; ++it ) { #if LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES // remove redundant points if ( !it->visible ) { prev = *it; continue; } #endif // LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES if ( !prev.visible ) { Geom::Point middle = to_geom_point(midpoint(prev, *it)); if ( ret.finalPoint() != middle ) { // All generated invisible points are straight lines ret.appendNew(middle); } } Point next = (it + 1 == end) ? source.front() : *(it + 1); Point middle = midpoint(*it, next); if ( !it->smooth ) { ret.appendNew(to_geom_point(*it)); ret.appendNew(to_geom_point(middle)); } else { ret.appendNew(to_geom_point(*it), to_geom_point(middle)); } prev = *it; } return ret; } /** * It should be used by worker threads. Convert only one object. */ template void worker(const typename HomogeneousSplines::Polygon &source, Splines::Path &dest, bool optimize) { //dest.pathVector.reserve(source.holes.size() + 1); for ( int i = 0 ; i != 4 ; ++i ) dest.rgba[i] = source.rgba[i]; dest.pathVector.push_back(worker_helper(source.vertices, optimize)); for ( typename std::vector< std::vector< Point > >::const_iterator it = source.holes.begin(), end = source.holes.end() ; it != end ; ++it ) { dest.pathVector.push_back(worker_helper(*it, optimize)); } } template Splines::Splines(const SimplifiedVoronoi &diagram) : _width(diagram.width()), _height(diagram.height()) { _paths.reserve(diagram.size()); for ( typename SimplifiedVoronoi::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 >::const_iterator it2 = ++it->vertices.begin(), end2 = it->vertices.end() ; it2 != end2 ; ++it2 ) { path.pathVector.back() .appendNew(Geom::Point(it2->x, it2->y)); } for ( int i = 0 ; i != 4 ; ++i ) path.rgba[i] = it->rgba[i]; _paths.push_back(path); } } template Splines::Splines(const HomogeneousSplines &homogeneousSplines, bool optimize, int /*nthreads*/) : _paths(homogeneousSplines.size()), _width(homogeneousSplines.width()), _height(homogeneousSplines.height()) { // TODO: It should be threaded iterator paths_it = begin(); for ( typename HomogeneousSplines::const_iterator it = homogeneousSplines.begin(), end = homogeneousSplines.end() ; it != end ; ++it, ++paths_it ) { worker(*it, *paths_it, optimize); } } } // namespace Tracer #endif // LIBDEPIXELIZE_TRACER_SPLINES_KOPF2011_H /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :