|
Ankit Kumar Dwivedi |
7dd184 |
/* === S Y N F I G ========================================================= */
|
|
Ankit Kumar Dwivedi |
7dd184 |
/*! \file centerlinecolors.cpp
|
|
Ankit Kumar Dwivedi |
7dd184 |
** \brief centerlinecolors File
|
|
Ankit Kumar Dwivedi |
7dd184 |
**
|
|
Ankit Kumar Dwivedi |
7dd184 |
** $Id$
|
|
Ankit Kumar Dwivedi |
7dd184 |
**
|
|
Ankit Kumar Dwivedi |
7dd184 |
** \legal
|
|
Ankit Kumar Dwivedi |
7dd184 |
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
|
|
Ankit Kumar Dwivedi |
7dd184 |
**
|
|
Ankit Kumar Dwivedi |
7dd184 |
** This package is free software; you can redistribute it and/or
|
|
Ankit Kumar Dwivedi |
7dd184 |
** modify it under the terms of the GNU General Public License as
|
|
Ankit Kumar Dwivedi |
7dd184 |
** published by the Free Software Foundation; either version 2 of
|
|
Ankit Kumar Dwivedi |
7dd184 |
** the License, or (at your option) any later version.
|
|
Ankit Kumar Dwivedi |
7dd184 |
**
|
|
Ankit Kumar Dwivedi |
7dd184 |
** This package is distributed in the hope that it will be useful,
|
|
Ankit Kumar Dwivedi |
7dd184 |
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Ankit Kumar Dwivedi |
7dd184 |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Ankit Kumar Dwivedi |
7dd184 |
** General Public License for more details.
|
|
Ankit Kumar Dwivedi |
7dd184 |
** \endlegal
|
|
Ankit Kumar Dwivedi |
7dd184 |
*/
|
|
Ankit Kumar Dwivedi |
7dd184 |
/* ========================================================================= */
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
/* === H E A D E R S ======================================================= */
|
|
Ankit Kumar Dwivedi |
a195e8 |
#include "polygonizerclasses.h"
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
121288 |
#include <synfig surface.h=""></synfig>
|
|
Ankit Kumar Dwivedi |
121288 |
#include <synfig rendering="" software="" surfacesw.h=""></synfig>
|
|
Ankit Kumar Dwivedi |
121288 |
#include <math.h></math.h>
|
|
Ankit Kumar Dwivedi |
121288 |
#include <etl handle=""></etl>
|
|
Ankit Kumar Dwivedi |
121288 |
#include <synfig layer_bitmap.h="" layers=""></synfig>
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
/* === U S I N G =========================================================== */
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
using namespace std;
|
|
Ankit Kumar Dwivedi |
7dd184 |
using namespace etl;
|
|
Ankit Kumar Dwivedi |
7dd184 |
using namespace studio;
|
|
Ankit Kumar Dwivedi |
a195e8 |
using namespace synfig;
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
/* === M A C R O S ========================================================= */
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
/* === G L O B A L S ======================================================= */
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
/* === P R O C E D U R E S ================================================= */
|
|
Ankit Kumar Dwivedi |
a195e8 |
|
|
|
a4bbdd |
synfig::Color pixelToColor(const Surface &rsurface, int x, int y, const Gamma &gamma)
|
|
Ankit Kumar Dwivedi |
a195e8 |
{
|
|
|
a4bbdd |
const int Y = rsurface.get_h() - y - 1;
|
|
|
a4bbdd |
return gamma.apply(rsurface[Y][x]);
|
|
Ankit Kumar Dwivedi |
a195e8 |
}
|
|
Ankit Kumar Dwivedi |
a195e8 |
|
|
|
a4bbdd |
bool checkPixelThreshold(const Surface &rsurface, int x, int y, int threshold)
|
|
Ankit Kumar Dwivedi |
a195e8 |
{
|
|
|
a4bbdd |
const int Y = rsurface.get_h() - y -1;
|
|
|
a4bbdd |
const Color color = rsurface[Y][x];
|
|
|
a4bbdd |
int r = 255.99*color.get_r();
|
|
|
a4bbdd |
int g = 255.99*color.get_g();
|
|
|
a4bbdd |
int b = 255.99*color.get_b();
|
|
|
a4bbdd |
int a = 255.99*color.get_a();
|
|
|
a4bbdd |
return std::max(r,std::max(g,b)) < threshold * (a / 255.0);
|
|
Ankit Kumar Dwivedi |
a195e8 |
}
|
|
Ankit Kumar Dwivedi |
a195e8 |
|
|
Ankit Kumar Dwivedi |
4792ed |
//------------------------------------------------------------------------
|
|
|
a4bbdd |
static synfig::Point3 firstInkChangePosition(
|
|
|
a4bbdd |
const Surface &ras,
|
|
|
a4bbdd |
const synfig::Point3 &start,
|
|
|
a4bbdd |
const synfig::Point3 &end,
|
|
|
a4bbdd |
int threshold,
|
|
|
a4bbdd |
const Gamma &gamma )
|
|
Ankit Kumar Dwivedi |
121288 |
{
|
|
Ankit Kumar Dwivedi |
121288 |
double dist = (end - start).mag();
|
|
Ankit Kumar Dwivedi |
121288 |
|
|
Ankit Kumar Dwivedi |
a195e8 |
int sampleMax = ceil_to_int(dist), sampleCount = sampleMax + 1;
|
|
Ankit Kumar Dwivedi |
121288 |
double sampleMaxD = double(sampleMax);
|
|
Ankit Kumar Dwivedi |
121288 |
|
|
Ankit Kumar Dwivedi |
121288 |
// Get first ink color
|
|
Ankit Kumar Dwivedi |
a195e8 |
int s;
|
|
Ankit Kumar Dwivedi |
a195e8 |
synfig::Color color ;
|
|
Ankit Kumar Dwivedi |
121288 |
|
|
Ankit Kumar Dwivedi |
a195e8 |
for (s = 0; s != sampleCount; ++s)
|
|
Ankit Kumar Dwivedi |
a195e8 |
{
|
|
Ankit Kumar Dwivedi |
a195e8 |
synfig::Point3 p = start * (1 - s/sampleMaxD) + end * (s/sampleMaxD);
|
|
Ankit Kumar Dwivedi |
a195e8 |
// const TPixelCM32 &pix = pixel(*ras, p.x, p.y);
|
|
Ankit Kumar Dwivedi |
a195e8 |
if (checkPixelThreshold(ras,p[0],p[1], threshold))
|
|
Ankit Kumar Dwivedi |
a195e8 |
{
|
|
|
a4bbdd |
color = pixelToColor(ras, p[0], p[1], gamma);
|
|
Ankit Kumar Dwivedi |
121288 |
break;
|
|
Ankit Kumar Dwivedi |
121288 |
}
|
|
Ankit Kumar Dwivedi |
121288 |
}
|
|
Ankit Kumar Dwivedi |
121288 |
|
|
Ankit Kumar Dwivedi |
121288 |
// Get second color
|
|
Ankit Kumar Dwivedi |
a195e8 |
for (; s != sampleCount; ++s)
|
|
Ankit Kumar Dwivedi |
a195e8 |
{
|
|
Ankit Kumar Dwivedi |
a195e8 |
synfig::Point3 p = start *(1 - s/sampleMaxD) + end * (s/sampleMaxD);
|
|
Ankit Kumar Dwivedi |
a195e8 |
// const TPixelCM32 &pix = pixel(*ras, p.x, p.y);
|
|
Ankit Kumar Dwivedi |
121288 |
|
|
|
a4bbdd |
if (checkPixelThreshold(ras,p[0],p[1],threshold) && pixelToColor(ras, p[0], p[1], gamma) != color)
|
|
Ankit Kumar Dwivedi |
a195e8 |
break;
|
|
Ankit Kumar Dwivedi |
121288 |
}
|
|
Ankit Kumar Dwivedi |
121288 |
|
|
Ankit Kumar Dwivedi |
121288 |
// Return middle position between s-1 and s
|
|
Ankit Kumar Dwivedi |
121288 |
if (s < sampleCount)
|
|
Ankit Kumar Dwivedi |
a195e8 |
return start * (1 - ((s - 0.5) / sampleMaxD)) + end * ((s - 0.5) / sampleMaxD);
|
|
Ankit Kumar Dwivedi |
121288 |
|
|
Ankit Kumar Dwivedi |
a195e8 |
return synfig::Point3::nan();
|
|
Ankit Kumar Dwivedi |
121288 |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Find color of input sequence. Will be copied to its equivalent stroke.
|
|
Ankit Kumar Dwivedi |
4792ed |
// Currently in use only on colormaps
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Summary: It is better to test the color to be assigned to the strokes
|
|
Ankit Kumar Dwivedi |
4792ed |
// to check
|
|
Ankit Kumar Dwivedi |
4792ed |
// sequences * before * convert them to TStroke (since you lose part
|
|
Ankit Kumar Dwivedi |
4792ed |
// of the original grip
|
|
Ankit Kumar Dwivedi |
4792ed |
// to the line). You specify a number of 'taste points' of the broken line
|
|
Ankit Kumar Dwivedi |
4792ed |
// equidistant from each other,
|
|
Ankit Kumar Dwivedi |
4792ed |
// on which the value of the corresponding pixel input is taken. If
|
|
Ankit Kumar Dwivedi |
4792ed |
// identifies a change
|
|
Ankit Kumar Dwivedi |
4792ed |
// of color, the sequence breaking procedure is launched: yes
|
|
Ankit Kumar Dwivedi |
4792ed |
// identifies the point
|
|
Ankit Kumar Dwivedi |
4792ed |
// of breaking, and the sequence s is blocked there; a new one is built
|
|
Ankit Kumar Dwivedi |
4792ed |
// sequence newSeq e
|
|
Ankit Kumar Dwivedi |
4792ed |
// sampleColor is re-launched (ras, newSeq, sOpposite). Sequences between two points
|
|
Ankit Kumar Dwivedi |
4792ed |
// of breaking up
|
|
Ankit Kumar Dwivedi |
4792ed |
// are inserted into the vector 'globals-> singleSequences'.
|
|
Ankit Kumar Dwivedi |
4792ed |
// In the case of circular sequences there is a small change: the first point of
|
|
Ankit Kumar Dwivedi |
4792ed |
// splitting
|
|
Ankit Kumar Dwivedi |
4792ed |
// * only redefines * the s-node, without introducing new sequences.
|
|
Ankit Kumar Dwivedi |
4792ed |
// The sequence sOpposite, 'inverse' of s, remains and becomes 'forward-oriented'
|
|
Ankit Kumar Dwivedi |
4792ed |
// after updating
|
|
Ankit Kumar Dwivedi |
4792ed |
// of the tail.
|
|
Ankit Kumar Dwivedi |
4792ed |
// Notice that the break nodes are entered with the signature
|
|
Ankit Kumar Dwivedi |
4792ed |
// 'SAMPLECOLOR_SIGN'.
|
|
Ankit Kumar Dwivedi |
4792ed |
// NOTE: The J-S 'upper' graph structure is not altered in here.
|
|
Ankit Kumar Dwivedi |
4792ed |
// Eventualm. to do outside.
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
|
a4bbdd |
static void sampleColor(
|
|
|
a4bbdd |
const etl::handle<synfig::layer_bitmap> &ras,</synfig::layer_bitmap>
|
|
|
a4bbdd |
int threshold,
|
|
|
a4bbdd |
Sequence &seq,
|
|
|
a4bbdd |
Sequence &seqOpposite,
|
|
|
a4bbdd |
SequenceList &singleSequences,
|
|
|
a4bbdd |
const Gamma &gamma )
|
|
Ankit Kumar Dwivedi |
121288 |
{
|
|
Ankit Kumar Dwivedi |
4792ed |
SkeletonGraph *currGraph = seq.m_graphHolder;
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Calculate sequence parametrization
|
|
Ankit Kumar Dwivedi |
4792ed |
std::vector<unsigned int=""> nodes;</unsigned>
|
|
Ankit Kumar Dwivedi |
4792ed |
std::vector<double> params;</double>
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Meanwhile, ensure each point belong to ras. Otherwise, typically an error
|
|
Ankit Kumar Dwivedi |
a195e8 |
// occured in the thinning process and it's better avoid sampling procedure. Only
|
|
Ankit Kumar Dwivedi |
4792ed |
// exception, when
|
|
Ankit Kumar Dwivedi |
121288 |
// a point has x==rsurface.get_w() || y==rsurface.get_h(); that is accepted.
|
|
Ankit Kumar Dwivedi |
32d730 |
synfig::rendering::SurfaceResource::LockRead<synfig::rendering::surfacesw> lock( ras->rendering_surface ); </synfig::rendering::surfacesw>
|
|
Ankit Kumar Dwivedi |
121288 |
const Surface &rsurface = lock->get_surface();
|
|
Ankit Kumar Dwivedi |
4792ed |
{
|
|
Ankit Kumar Dwivedi |
4792ed |
const synfig::Point3 &headPos = *currGraph->getNode(seq.m_head);
|
|
Ankit Kumar Dwivedi |
4792ed |
// get bounds rectangle with = 0,0,lx -1, ly-1
|
|
Ankit Kumar Dwivedi |
121288 |
if (headPos[0] < 0 || rsurface.get_w() < headPos[0] || headPos[1] < 0 || rsurface.get_h() < headPos[1])// check again and return
|
|
Ankit Kumar Dwivedi |
4792ed |
return;
|
|
Ankit Kumar Dwivedi |
32d730 |
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
unsigned int curr, currLink, next;
|
|
Ankit Kumar Dwivedi |
a195e8 |
double meanThickness = currGraph->getNode(seq.m_head)->operator[](2);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
params.push_back(0);
|
|
Ankit Kumar Dwivedi |
4792ed |
nodes.push_back(seq.m_head);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
for (curr = seq.m_head, currLink = seq.m_headLink;
|
|
Ankit Kumar Dwivedi |
4792ed |
curr != seq.m_tail || params.size() == 1; seq.next(curr, currLink))
|
|
Ankit Kumar Dwivedi |
4792ed |
{
|
|
Ankit Kumar Dwivedi |
4792ed |
next = currGraph->getNode(curr).getLink(currLink).getNext();
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
const synfig::Point3 &nextPos = *currGraph->getNode(next);
|
|
Ankit Kumar Dwivedi |
121288 |
if (nextPos[0] < 0 || rsurface.get_w() < nextPos[0] || nextPos[1] < 0 || rsurface.get_h() < nextPos[1])
|
|
Ankit Kumar Dwivedi |
4792ed |
{
|
|
Ankit Kumar Dwivedi |
32d730 |
return;
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
32d730 |
params.push_back(params.back() + (*currGraph->getNode(next) - *currGraph->getNode(curr)).mag());
|
|
Ankit Kumar Dwivedi |
4792ed |
nodes.push_back(next);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
121288 |
meanThickness += currGraph->getNode(next)->operator[](2);
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
meanThickness /= params.size();
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Exclude 0-length sequences
|
|
Ankit Kumar Dwivedi |
32d730 |
if (params.back() < 0.01)
|
|
Ankit Kumar Dwivedi |
32d730 |
{
|
|
|
a4bbdd |
seq.m_color = pixelToColor(
|
|
|
a4bbdd |
rsurface,
|
|
|
a4bbdd |
currGraph->getNode(seq.m_head)->operator[](0),
|
|
|
a4bbdd |
currGraph->getNode(seq.m_head)->operator[](1),
|
|
|
a4bbdd |
gamma );
|
|
Ankit Kumar Dwivedi |
4792ed |
return;
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Prepare sampling procedure
|
|
Ankit Kumar Dwivedi |
4792ed |
int paramCount = params.size(), paramMax = paramCount - 1;
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
32d730 |
int sampleMax = std::max(params.back() / std::max(meanThickness, 1.0),3.0), // Number of color samples depends on
|
|
Ankit Kumar Dwivedi |
4792ed |
sampleCount = sampleMax + 1; // the ratio params.back() / meanThickness
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
std::vector<double> sampleParams(sampleCount); // Sampling lengths</double>
|
|
Ankit Kumar Dwivedi |
32d730 |
std::vector<synfig::point> samplePoints(sampleCount); // Image points for color sampling</synfig::point>
|
|
Ankit Kumar Dwivedi |
32d730 |
std::vector<int> sampleSegments(sampleCount); // Sequence segment index for the above</int>
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Sample colors
|
|
Ankit Kumar Dwivedi |
32d730 |
for (int s = 0, j = 0; s != sampleCount; ++s)
|
|
Ankit Kumar Dwivedi |
32d730 |
{
|
|
Ankit Kumar Dwivedi |
4792ed |
double samplePar = params.back() * (s / double(sampleMax));
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
32d730 |
while (j != paramMax && params[j + 1] < samplePar) // params[j] < samplePar <= params[j+1]
|
|
Ankit Kumar Dwivedi |
4792ed |
++j;
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
double t = (samplePar - params[j]) / (params[j + 1] - params[j]);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
synfig::Point3 samplePoint(*currGraph->getNode(nodes[j]) * (1 - t) +
|
|
Ankit Kumar Dwivedi |
4792ed |
*currGraph->getNode(nodes[j + 1]) * t);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
sampleParams[s] = samplePar;
|
|
Ankit Kumar Dwivedi |
4792ed |
samplePoints[s] = synfig::Point(
|
|
Ankit Kumar Dwivedi |
4792ed |
std::min(samplePoint[0],
|
|
Ankit Kumar Dwivedi |
121288 |
double(rsurface.get_w() - 1)), // This deals with sample points at
|
|
Ankit Kumar Dwivedi |
4792ed |
std::min(samplePoint[1],
|
|
Ankit Kumar Dwivedi |
121288 |
double(rsurface.get_h() - 1))); // the top/right raster border
|
|
Ankit Kumar Dwivedi |
4792ed |
sampleSegments[s] = j;
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// NOTE: Extremities of a sequence are considered unreliable: they typically
|
|
Ankit Kumar Dwivedi |
4792ed |
// happen
|
|
Ankit Kumar Dwivedi |
4792ed |
// to be junction points shared between possibly different-colored
|
|
Ankit Kumar Dwivedi |
4792ed |
// strokes.
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Find first and last extremity-free sampled points
|
|
Ankit Kumar Dwivedi |
4792ed |
synfig::Point3 first(*currGraph->getNode(seq.m_head));
|
|
Ankit Kumar Dwivedi |
4792ed |
synfig::Point3 last(*currGraph->getNode(seq.m_tail));
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
int i, k;
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
for (i = 1;
|
|
Ankit Kumar Dwivedi |
121288 |
params.back() * i / double(sampleMax) <= first[2] && i < sampleCount; ++i)
|
|
Ankit Kumar Dwivedi |
4792ed |
;
|
|
Ankit Kumar Dwivedi |
4792ed |
for (k = sampleMax - 1;
|
|
Ankit Kumar Dwivedi |
121288 |
params.back() * (sampleMax - k) / double(sampleMax) <= last[2] && k >= 0;
|
|
Ankit Kumar Dwivedi |
4792ed |
--k)
|
|
Ankit Kumar Dwivedi |
4792ed |
;
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Give s the first sampled ink color found
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Initialize with a last-resort reasonable color - not just 0
|
|
|
a4bbdd |
seq.m_color = seqOpposite.m_color = pixelToColor(rsurface, samplePoints[0][0], samplePoints[0][1], gamma);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
int l;
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
121288 |
for (l = i - 1; l >= 0; --l)
|
|
Ankit Kumar Dwivedi |
121288 |
{
|
|
|
a4bbdd |
if (checkPixelThreshold(rsurface, samplePoints[l][0], samplePoints[l][1], threshold))
|
|
Ankit Kumar Dwivedi |
121288 |
{
|
|
|
a4bbdd |
seq.m_color = seqOpposite.m_color = pixelToColor(rsurface, samplePoints[l][0], samplePoints[l][1], gamma);
|
|
Ankit Kumar Dwivedi |
4792ed |
break;
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Then, look for the first reliable ink
|
|
Ankit Kumar Dwivedi |
121288 |
for (l = i; l <= k; ++l)
|
|
Ankit Kumar Dwivedi |
121288 |
{
|
|
Ankit Kumar Dwivedi |
a195e8 |
if (checkPixelThreshold(rsurface,samplePoints[l][0],samplePoints[l][1], threshold))
|
|
Ankit Kumar Dwivedi |
121288 |
{
|
|
|
a4bbdd |
seq.m_color = seqOpposite.m_color = pixelToColor(rsurface, samplePoints[l][0], samplePoints[l][1], gamma);
|
|
Ankit Kumar Dwivedi |
4792ed |
break;
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
if (i >= k) goto _getOut; // No admissible segment found for splitting
|
|
Ankit Kumar Dwivedi |
4792ed |
// check.
|
|
Ankit Kumar Dwivedi |
4792ed |
// Find color changes between sampled colors
|
|
Ankit Kumar Dwivedi |
121288 |
for (l = i; l < k; ++l)
|
|
Ankit Kumar Dwivedi |
121288 |
{
|
|
Ankit Kumar Dwivedi |
121288 |
const int x1 = samplePoints[l + 1][0], y1 = samplePoints[l + 1][1],
|
|
Ankit Kumar Dwivedi |
121288 |
x2 = samplePoints[l + 2][0], y2 = samplePoints[l + 2][1];
|
|
Ankit Kumar Dwivedi |
121288 |
|
|
Ankit Kumar Dwivedi |
121288 |
// const TPixelCM32
|
|
Ankit Kumar Dwivedi |
121288 |
// &nextSample = ras->pixels(x1)[y1],
|
|
Ankit Kumar Dwivedi |
121288 |
// &nextSample2 = ras->pixels(x2)[y2]; // l < k < sampleMax - so +2 is ok
|
|
Ankit Kumar Dwivedi |
121288 |
|
|
|
a4bbdd |
if (checkPixelThreshold(rsurface, x1, y1, threshold) &&
|
|
|
a4bbdd |
pixelToColor(rsurface, x1, y1, gamma) != seq.m_color &&
|
|
|
a4bbdd |
checkPixelThreshold(rsurface, x2, y2, threshold) &&
|
|
|
a4bbdd |
pixelToColor(rsurface, x2, y2, gamma) == pixelToColor(rsurface, x1, y1, gamma)) // Ignore single-sample color changes
|
|
Ankit Kumar Dwivedi |
4792ed |
{
|
|
Ankit Kumar Dwivedi |
4792ed |
// Found a color change - apply splitting procedure
|
|
Ankit Kumar Dwivedi |
4792ed |
// NOTE: The function RETURNS BEFORE THE FOR IS CONTINUED!
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
|
a4bbdd |
synfig::Color nextColor = pixelToColor(rsurface, x1, y1, gamma);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Identify split segment
|
|
Ankit Kumar Dwivedi |
4792ed |
int u;
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
121288 |
for (u = sampleSegments[l]; u < sampleSegments[l + 1]; ++u)
|
|
Ankit Kumar Dwivedi |
121288 |
{
|
|
Ankit Kumar Dwivedi |
121288 |
const int x = currGraph->getNode(nodes[u + 1])->operator[](0),
|
|
Ankit Kumar Dwivedi |
121288 |
y = currGraph->getNode(nodes[u + 1])->operator[](1);
|
|
|
a4bbdd |
if (checkPixelThreshold(rsurface, x, y, threshold) && pixelToColor(rsurface, x, y, gamma) != seq.m_color)
|
|
Ankit Kumar Dwivedi |
121288 |
break;
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Now u indicates the splitting segment. Search for splitting point by
|
|
Ankit Kumar Dwivedi |
4792ed |
// binary subdivision.
|
|
Ankit Kumar Dwivedi |
4792ed |
const synfig::Point3 &nodeStartPos = *currGraph->getNode(nodes[u]),
|
|
Ankit Kumar Dwivedi |
121288 |
&nodeEndPos = *currGraph->getNode(nodes[u + 1]);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
|
a4bbdd |
synfig::Point3 splitPoint = firstInkChangePosition(rsurface, nodeStartPos, nodeEndPos, threshold, gamma);
|
|
Ankit Kumar Dwivedi |
a195e8 |
|
|
Ankit Kumar Dwivedi |
a195e8 |
if (splitPoint == synfig::Point3::nan())
|
|
Ankit Kumar Dwivedi |
a195e8 |
splitPoint = (nodeStartPos + nodeEndPos) * 0.5;
|
|
Ankit Kumar Dwivedi |
a195e8 |
// A color change was found, but could not be precisely located. Just take
|
|
Ankit Kumar Dwivedi |
a195e8 |
// a reasonable representant. Insert a corresponding new node in basic graph structure.
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
unsigned int splitNode = currGraph->newNode(splitPoint);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
unsigned int nodesLink =
|
|
Ankit Kumar Dwivedi |
4792ed |
currGraph->getNode(nodes[u]).linkOfNode(nodes[u + 1]);
|
|
Ankit Kumar Dwivedi |
4792ed |
currGraph->insert(splitNode, nodes[u], nodesLink);
|
|
Ankit Kumar Dwivedi |
4792ed |
*currGraph->node(splitNode).link(0) =
|
|
Ankit Kumar Dwivedi |
4792ed |
*currGraph->getNode(nodes[u]).getLink(nodesLink);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
nodesLink = currGraph->getNode(nodes[u + 1]).linkOfNode(nodes[u]);
|
|
Ankit Kumar Dwivedi |
4792ed |
currGraph->insert(splitNode, nodes[u + 1], nodesLink);
|
|
Ankit Kumar Dwivedi |
4792ed |
*currGraph->node(splitNode).link(1) =
|
|
Ankit Kumar Dwivedi |
4792ed |
*currGraph->getNode(nodes[u + 1]).getLink(nodesLink);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
a195e8 |
currGraph->node(splitNode).setAttribute(SAMPLECOLOR_SIGN); // Sign all split-inserted nodes
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
if (seq.m_head == seq.m_tail &&
|
|
Ankit Kumar Dwivedi |
4792ed |
currGraph->getNode(seq.m_head).getLinksCount() == 2 &&
|
|
Ankit Kumar Dwivedi |
a195e8 |
!currGraph->getNode(seq.m_head).hasAttribute(SAMPLECOLOR_SIGN))
|
|
Ankit Kumar Dwivedi |
a195e8 |
{
|
|
Ankit Kumar Dwivedi |
4792ed |
// Circular case: we update s to splitNode and relaunch this very
|
|
Ankit Kumar Dwivedi |
4792ed |
// procedure on it.
|
|
Ankit Kumar Dwivedi |
4792ed |
seq.m_head = seq.m_tail = splitNode;
|
|
|
a4bbdd |
sampleColor(ras, threshold, seq, seqOpposite, singleSequences, gamma);
|
|
Ankit Kumar Dwivedi |
a195e8 |
}
|
|
Ankit Kumar Dwivedi |
a195e8 |
else
|
|
Ankit Kumar Dwivedi |
a195e8 |
{
|
|
Ankit Kumar Dwivedi |
4792ed |
// Update upper (Joint-Sequence) graph data
|
|
Ankit Kumar Dwivedi |
4792ed |
Sequence newSeq;
|
|
Ankit Kumar Dwivedi |
4792ed |
newSeq.m_graphHolder = currGraph;
|
|
Ankit Kumar Dwivedi |
4792ed |
newSeq.m_head = splitNode;
|
|
Ankit Kumar Dwivedi |
4792ed |
newSeq.m_headLink = 0;
|
|
Ankit Kumar Dwivedi |
4792ed |
newSeq.m_tail = seq.m_tail;
|
|
Ankit Kumar Dwivedi |
4792ed |
newSeq.m_tailLink = seq.m_tailLink;
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
seq.m_tail = splitNode;
|
|
Ankit Kumar Dwivedi |
4792ed |
seq.m_tailLink = 1; // (link from splitNode to nodes[u] inserted for
|
|
Ankit Kumar Dwivedi |
4792ed |
// second by 'insert')
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
a195e8 |
seqOpposite.m_graphHolder = seq.m_graphHolder; // Inform that a split was found
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// NOTE: access on s terminates at newSeq's push_back, due to possible
|
|
Ankit Kumar Dwivedi |
4792ed |
// reallocation of globals->singleSequences
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
if ((!(seq.m_head == newSeq.m_tail &&
|
|
Ankit Kumar Dwivedi |
4792ed |
currGraph->getNode(seq.m_head).getLinksCount() == 2)) &&
|
|
Ankit Kumar Dwivedi |
4792ed |
currGraph->getNode(seq.m_head).hasAttribute(SAMPLECOLOR_SIGN))
|
|
Ankit Kumar Dwivedi |
4792ed |
singleSequences.push_back(seq);
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
|
a4bbdd |
sampleColor(ras, threshold, newSeq, seqOpposite, singleSequences, gamma);
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
return;
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
_getOut:
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
4792ed |
// Color changes not found (and therefore no newSeq got pushed back); if a
|
|
Ankit Kumar Dwivedi |
4792ed |
// split happened, update sOpposite.
|
|
Ankit Kumar Dwivedi |
4792ed |
if (currGraph->getNode(seq.m_head).hasAttribute(SAMPLECOLOR_SIGN)) {
|
|
Ankit Kumar Dwivedi |
4792ed |
seqOpposite.m_color = seq.m_color;
|
|
Ankit Kumar Dwivedi |
4792ed |
seqOpposite.m_head = seq.m_tail;
|
|
Ankit Kumar Dwivedi |
4792ed |
seqOpposite.m_headLink = seq.m_tailLink;
|
|
Ankit Kumar Dwivedi |
4792ed |
seqOpposite.m_tail = seq.m_head;
|
|
Ankit Kumar Dwivedi |
4792ed |
seqOpposite.m_tailLink = seq.m_headLink;
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
}
|
|
Ankit Kumar Dwivedi |
4792ed |
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
/* === M E T H O D S ======================================================= */
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
/* === E N T R Y P O I N T ================================================= */
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
|
a4bbdd |
void studio::calculateSequenceColors(const etl::handle<synfig::layer_bitmap> &ras, VectorizerCoreGlobals &g, const Gamma &gamma)</synfig::layer_bitmap>
|
|
Ankit Kumar Dwivedi |
7dd184 |
{
|
|
Ankit Kumar Dwivedi |
7dd184 |
int threshold = g.currConfig->m_threshold;
|
|
Ankit Kumar Dwivedi |
7dd184 |
SequenceList &singleSequences = g.singleSequences;
|
|
Ankit Kumar Dwivedi |
7dd184 |
JointSequenceGraphList &organizedGraphs = g.organizedGraphs;
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
unsigned int i, j, k;
|
|
Ankit Kumar Dwivedi |
7dd184 |
int l;
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
32d730 |
if (ras && g.currConfig->m_maxThickness > 0.0)
|
|
Ankit Kumar Dwivedi |
7dd184 |
{
|
|
Ankit Kumar Dwivedi |
7dd184 |
// singleSequence is traversed back-to-front because new, possibly splitted
|
|
Ankit Kumar Dwivedi |
7dd184 |
// sequences
|
|
Ankit Kumar Dwivedi |
7dd184 |
// are inserted at back - and don't have to be re-sampled.
|
|
Ankit Kumar Dwivedi |
7dd184 |
for (l = singleSequences.size() - 1; l >= 0; --l)
|
|
Ankit Kumar Dwivedi |
7dd184 |
{
|
|
Ankit Kumar Dwivedi |
7dd184 |
Sequence rear;
|
|
|
a4bbdd |
sampleColor(ras, threshold, singleSequences[l], rear, singleSequences, gamma);
|
|
Ankit Kumar Dwivedi |
7dd184 |
// If rear is built, a split occurred and the rear of this
|
|
Ankit Kumar Dwivedi |
7dd184 |
// single sequence has to be pushed back.
|
|
Ankit Kumar Dwivedi |
7dd184 |
if (rear.m_graphHolder) singleSequences.push_back(rear);
|
|
Ankit Kumar Dwivedi |
7dd184 |
}
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
for (i = 0; i < organizedGraphs.size(); ++i)
|
|
Ankit Kumar Dwivedi |
7dd184 |
{
|
|
Ankit Kumar Dwivedi |
7dd184 |
for (j = 0; j < organizedGraphs[i].getNodesCount(); ++j)
|
|
Ankit Kumar Dwivedi |
7dd184 |
{
|
|
Ankit Kumar Dwivedi |
32d730 |
if (!organizedGraphs[i].getNode(j).hasAttribute(JointSequenceGraph::ELIMINATED))
|
|
Ankit Kumar Dwivedi |
32d730 |
{
|
|
Ankit Kumar Dwivedi |
32d730 |
for (k = 0; k < organizedGraphs[i].getNode(j).getLinksCount(); ++k)
|
|
Ankit Kumar Dwivedi |
32d730 |
{
|
|
Ankit Kumar Dwivedi |
32d730 |
Sequence &s = *organizedGraphs[i].node(j).link(k);
|
|
Ankit Kumar Dwivedi |
32d730 |
if (s.isForward() && !s.m_graphHolder->getNode(s.m_tail).hasAttribute(SAMPLECOLOR_SIGN))
|
|
Ankit Kumar Dwivedi |
32d730 |
{
|
|
Ankit Kumar Dwivedi |
7dd184 |
unsigned int next = organizedGraphs[i].node(j).link(k).getNext();
|
|
Ankit Kumar Dwivedi |
7dd184 |
unsigned int nextLink = organizedGraphs[i].tailLinkOf(j, k);
|
|
Ankit Kumar Dwivedi |
7dd184 |
Sequence &sOpposite = *organizedGraphs[i].node(next).link(nextLink);
|
|
|
a4bbdd |
sampleColor(ras, threshold, s, sOpposite, singleSequences, gamma);
|
|
Ankit Kumar Dwivedi |
32d730 |
}
|
|
Ankit Kumar Dwivedi |
32d730 |
}
|
|
Ankit Kumar Dwivedi |
32d730 |
}
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
}
|
|
Ankit Kumar Dwivedi |
7dd184 |
}
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
}
|
|
Ankit Kumar Dwivedi |
7dd184 |
}
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
7dd184 |
//==========================================================================
|
|
Ankit Kumar Dwivedi |
f0aee8 |
//==========================================================================
|
|
Ankit Kumar Dwivedi |
f0aee8 |
|
|
Ankit Kumar Dwivedi |
f0aee8 |
// Take samples of image colors to associate each stroke to its corresponding
|
|
Ankit Kumar Dwivedi |
f0aee8 |
// palette color. Currently working on colormaps, closest-to-black strokes
|
|
Ankit Kumar Dwivedi |
f0aee8 |
// otherwise.
|
|
Ankit Kumar Dwivedi |
d3f8e5 |
/*
|
|
Ankit Kumar Dwivedi |
f0aee8 |
void applyStrokeColors(std::vector<tstroke *=""> &strokes, const TRasterP &ras,</tstroke>
|
|
Ankit Kumar Dwivedi |
f0aee8 |
TPalette *palette, VectorizerCoreGlobals &g) {
|
|
Ankit Kumar Dwivedi |
f0aee8 |
JointSequenceGraphList &organizedGraphs = g.organizedGraphs;
|
|
Ankit Kumar Dwivedi |
f0aee8 |
SequenceList &singleSequences = g.singleSequences;
|
|
Ankit Kumar Dwivedi |
f0aee8 |
|
|
Ankit Kumar Dwivedi |
f0aee8 |
TRasterCM32P cm = ras;
|
|
Ankit Kumar Dwivedi |
f0aee8 |
unsigned int i, j, k, n;
|
|
Ankit Kumar Dwivedi |
f0aee8 |
|
|
Ankit Kumar Dwivedi |
f0aee8 |
if (cm && g.currConfig->m_maxThickness > 0.0)
|
|
Ankit Kumar Dwivedi |
f0aee8 |
{
|
|
Ankit Kumar Dwivedi |
f0aee8 |
applyStrokeIndices(&g);
|
|
Ankit Kumar Dwivedi |
f0aee8 |
|
|
Ankit Kumar Dwivedi |
f0aee8 |
// Treat single sequences before, like conversionToStrokes(..)
|
|
Ankit Kumar Dwivedi |
f0aee8 |
for (i = 0; i < singleSequences.size(); ++i)
|
|
Ankit Kumar Dwivedi |
f0aee8 |
strokes[i]->setStyle(singleSequences[i].m_color);
|
|
Ankit Kumar Dwivedi |
f0aee8 |
|
|
Ankit Kumar Dwivedi |
f0aee8 |
// Then, treat remaining graph-strokes
|
|
Ankit Kumar Dwivedi |
f0aee8 |
n = i;
|
|
Ankit Kumar Dwivedi |
f0aee8 |
|
|
Ankit Kumar Dwivedi |
f0aee8 |
for (i = 0; i < organizedGraphs.size(); ++i)
|
|
Ankit Kumar Dwivedi |
f0aee8 |
for (j = 0; j < organizedGraphs[i].getNodesCount(); ++j)
|
|
Ankit Kumar Dwivedi |
f0aee8 |
if (!organizedGraphs[i].getNode(j).hasAttribute(
|
|
Ankit Kumar Dwivedi |
f0aee8 |
JointSequenceGraph::ELIMINATED)) // due to junction recovery
|
|
Ankit Kumar Dwivedi |
f0aee8 |
for (k = 0; k < organizedGraphs[i].getNode(j).getLinksCount(); ++k) {
|
|
Ankit Kumar Dwivedi |
f0aee8 |
Sequence &s = *organizedGraphs[i].node(j).link(k);
|
|
Ankit Kumar Dwivedi |
f0aee8 |
if (s.isForward()) {
|
|
Ankit Kumar Dwivedi |
f0aee8 |
// vi->getStroke(n)->setStyle(s.m_color);
|
|
Ankit Kumar Dwivedi |
f0aee8 |
strokes[n]->setStyle(s.m_color);
|
|
Ankit Kumar Dwivedi |
f0aee8 |
++n;
|
|
Ankit Kumar Dwivedi |
f0aee8 |
}
|
|
Ankit Kumar Dwivedi |
f0aee8 |
}
|
|
Ankit Kumar Dwivedi |
f0aee8 |
|
|
Ankit Kumar Dwivedi |
f0aee8 |
// Order vector image according to actual color-coverings at junctions.
|
|
Ankit Kumar Dwivedi |
f0aee8 |
orderColoredStrokes(organizedGraphs, strokes, cm, palette);
|
|
Ankit Kumar Dwivedi |
f0aee8 |
}
|
|
Ankit Kumar Dwivedi |
f0aee8 |
else
|
|
Ankit Kumar Dwivedi |
f0aee8 |
{
|
|
Ankit Kumar Dwivedi |
f0aee8 |
// Choose closest-to-black palette color
|
|
Ankit Kumar Dwivedi |
f0aee8 |
int blackStyleId = palette->getClosestStyle(TPixel32::Black);
|
|
Ankit Kumar Dwivedi |
f0aee8 |
|
|
Ankit Kumar Dwivedi |
f0aee8 |
unsigned int i;
|
|
Ankit Kumar Dwivedi |
f0aee8 |
for (i = 0; i < strokes.size(); ++i) strokes[i]->setStyle(blackStyleId);
|
|
Ankit Kumar Dwivedi |
f0aee8 |
}
|
|
Ankit Kumar Dwivedi |
f0aee8 |
}
|
|
Ankit Kumar Dwivedi |
7dd184 |
|
|
Ankit Kumar Dwivedi |
d3f8e5 |
*/
|
|
Ankit Kumar Dwivedi |
7dd184 |
|