Merge pull request #1215 from TomDoingArt/Issue_1151_ResidualGapOnFillGaps
Issue 1151 residual gap on fill gaps
This commit is contained in:
commit
dbf0fc8da2
8 changed files with 491 additions and 174 deletions
|
@ -3717,6 +3717,12 @@ TThickCubic *TCubicStroke::generateCubic3D(const T3DPointD pointsArrayBegin[],
|
||||||
TCubicStroke, cioe' uno stroke cubico. Da questo trova lo stroke
|
TCubicStroke, cioe' uno stroke cubico. Da questo trova lo stroke
|
||||||
quadratico.
|
quadratico.
|
||||||
*/
|
*/
|
||||||
|
//! Returns a stroke from a vector of TThickPoints
|
||||||
|
/*!
|
||||||
|
Transforms an array of TThickPoints into an array of T3DPointDs
|
||||||
|
which is used for a TCubicStroke, i.e. a cubic stroke.
|
||||||
|
From this he finds the stroke quadratic.
|
||||||
|
*/
|
||||||
TStroke *TStroke::interpolate(const vector<TThickPoint> &points, double error,
|
TStroke *TStroke::interpolate(const vector<TThickPoint> &points, double error,
|
||||||
bool findCorners) {
|
bool findCorners) {
|
||||||
vector<T3DPointD> pointsArray3D;
|
vector<T3DPointD> pointsArray3D;
|
||||||
|
|
|
@ -73,6 +73,8 @@ class TTileSaverFullColor;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
DVAPI void outputPixels(const std::string _str, const TRasterCM32P& r);
|
||||||
|
|
||||||
// returns true if the savebox is changed typically, if you fill the bg)
|
// returns true if the savebox is changed typically, if you fill the bg)
|
||||||
DVAPI bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
DVAPI bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
||||||
TTileSaverCM32 *saver = 0, bool fillGaps = false,
|
TTileSaverCM32 *saver = 0, bool fillGaps = false,
|
||||||
|
@ -103,6 +105,12 @@ void DVAPI fullColorFill(const TRaster32P &ras, const FillParameters ¶ms,
|
||||||
bool closeGaps = false, int closeStyleIndex = -1,
|
bool closeGaps = false, int closeStyleIndex = -1,
|
||||||
double autoCloseDistance = -1.0);
|
double autoCloseDistance = -1.0);
|
||||||
|
|
||||||
|
void DVAPI finishGapLines(TRasterCM32P &rin, TRect &rect,
|
||||||
|
const TRasterCM32P &rbefore,
|
||||||
|
const TRasterCM32P &combined, TPalette *plt,
|
||||||
|
int clickedColorStyle, int fillIndex,
|
||||||
|
int closeColorStyle, bool closeGaps);
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//! The class AreaFiller allows to fill a raster area, delimited by rect or
|
//! The class AreaFiller allows to fill a raster area, delimited by rect or
|
||||||
//! spline.
|
//! spline.
|
||||||
|
|
|
@ -22,6 +22,9 @@ class TStroke;
|
||||||
Genera degli stroke sulla base di un vettore di punti,
|
Genera degli stroke sulla base di un vettore di punti,
|
||||||
questo vettore e' fatto di punti che vengono inseriti.
|
questo vettore e' fatto di punti che vengono inseriti.
|
||||||
Consente di visualizzare dei frammenti fatti dai punti che acquisisce.
|
Consente di visualizzare dei frammenti fatti dai punti che acquisisce.
|
||||||
|
Generate strokes based on a vector of points,
|
||||||
|
this vector is made of points that are inserted.
|
||||||
|
Allows you to view fragments made from the points it acquires.
|
||||||
*/
|
*/
|
||||||
class DVAPI StrokeGenerator {
|
class DVAPI StrokeGenerator {
|
||||||
//! Vettore di TThickPoint
|
//! Vettore di TThickPoint
|
||||||
|
|
|
@ -65,6 +65,10 @@ using namespace ToolUtils;
|
||||||
#define POLYLINEFILL L"Polyline"
|
#define POLYLINEFILL L"Polyline"
|
||||||
#define FREEPICKFILL L"Freepick"
|
#define FREEPICKFILL L"Freepick"
|
||||||
|
|
||||||
|
#define GAP_CLOSE_USED 4095
|
||||||
|
#define GAP_CLOSE_TEMP 4094
|
||||||
|
#define IGNORECOLORSTYLE 4093
|
||||||
|
|
||||||
TEnv::IntVar MinFillDepth("InknpaintMinFillDepth", 1);
|
TEnv::IntVar MinFillDepth("InknpaintMinFillDepth", 1);
|
||||||
TEnv::IntVar MaxFillDepth("InknpaintMaxFillDepth", 10);
|
TEnv::IntVar MaxFillDepth("InknpaintMaxFillDepth", 10);
|
||||||
TEnv::StringVar FillType("InknpaintFillType", "Normal");
|
TEnv::StringVar FillType("InknpaintFillType", "Normal");
|
||||||
|
@ -153,6 +157,8 @@ bool applyAutoclose(const TToonzImageP &ti, int distance, int angle,
|
||||||
ras = raux;
|
ras = raux;
|
||||||
if (!ras) return false;
|
if (!ras) return false;
|
||||||
|
|
||||||
|
//outputPixels("ras in applyAutoClose", ras);
|
||||||
|
|
||||||
TAutocloser ac(ras, distance, angle, newInkIndex, opacity);
|
TAutocloser ac(ras, distance, angle, newInkIndex, opacity);
|
||||||
|
|
||||||
std::vector<TAutocloser::Segment> segments;
|
std::vector<TAutocloser::Segment> segments;
|
||||||
|
@ -465,14 +471,9 @@ class RasterFillUndo final : public TRasterUndo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*RasterFillUndo(TTileSetCM32 *tileSet, TPoint fillPoint,
|
/*RasterFillUndo(TTileSetCM32 *tileSet, TPoint fillPoint,
|
||||||
int paintId, int
|
int paintId, int fillDepth, std::wstring fillType,
|
||||||
fillDepth,
|
bool isSegment, bool selective, bool isShiftFill,
|
||||||
std::wstring
|
TXshSimpleLevel* sl, const TFrameId& fid)*/
|
||||||
fillType, bool isSegment,
|
|
||||||
bool selective, bool
|
|
||||||
isShiftFill,
|
|
||||||
TXshSimpleLevel* sl,
|
|
||||||
const TFrameId& fid)*/
|
|
||||||
RasterFillUndo(TTileSetCM32 *tileSet, const FillParameters ¶ms,
|
RasterFillUndo(TTileSetCM32 *tileSet, const FillParameters ¶ms,
|
||||||
TXshSimpleLevel *sl, const TFrameId &fid, bool saveboxOnly,
|
TXshSimpleLevel *sl, const TFrameId &fid, bool saveboxOnly,
|
||||||
bool fillGaps, bool closeGaps, int closeStyleIndex,
|
bool fillGaps, bool closeGaps, int closeStyleIndex,
|
||||||
|
@ -585,13 +586,13 @@ public:
|
||||||
TRasterCM32P ras = image->getRaster();
|
TRasterCM32P ras = image->getRaster();
|
||||||
|
|
||||||
TRasterCM32P tempRaster;
|
TRasterCM32P tempRaster;
|
||||||
int styleIndex = 4094;
|
int styleIndex = GAP_CLOSE_TEMP;
|
||||||
if (m_fillGaps) {
|
if (m_fillGaps) {
|
||||||
TToonzImageP tempTi = image->clone();
|
TToonzImageP tempTi = image->clone();
|
||||||
tempRaster = tempTi->getRaster();
|
tempRaster = tempTi->getRaster();
|
||||||
TRectD doubleFillArea = convert(m_fillArea);
|
TRectD doubleFillArea = convert(m_fillArea);
|
||||||
applyAutoclose(tempTi, AutocloseDistance, AutocloseAngle,
|
applyAutoclose(tempTi, AutocloseDistance, AutocloseAngle,
|
||||||
AutocloseOpacity, 4094, doubleFillArea, m_s);
|
AutocloseOpacity, GAP_CLOSE_TEMP, doubleFillArea, m_s);
|
||||||
} else {
|
} else {
|
||||||
tempRaster = ras;
|
tempRaster = ras;
|
||||||
}
|
}
|
||||||
|
@ -603,25 +604,33 @@ public:
|
||||||
else
|
else
|
||||||
filler.strokeFill(m_s, m_paintId, m_onlyUnfilled, m_colorType != LINES,
|
filler.strokeFill(m_s, m_paintId, m_onlyUnfilled, m_colorType != LINES,
|
||||||
m_colorType != AREAS, m_fillArea);
|
m_colorType != AREAS, m_fillArea);
|
||||||
|
|
||||||
if (m_fillGaps) {
|
if (m_fillGaps) {
|
||||||
|
|
||||||
|
TRect rect = m_fillArea;
|
||||||
|
finishGapLines(
|
||||||
|
tempRaster,
|
||||||
|
rect,
|
||||||
|
ras,
|
||||||
|
tempRaster,
|
||||||
|
m_palette,
|
||||||
|
0,
|
||||||
|
m_paintId,
|
||||||
|
m_closeStyleIndex,
|
||||||
|
m_closeGaps);
|
||||||
|
|
||||||
TPixelCM32 *tempPix = tempRaster->pixels();
|
TPixelCM32 *tempPix = tempRaster->pixels();
|
||||||
TPixelCM32 *keepPix = ras->pixels();
|
TPixelCM32 *keepPix = ras->pixels();
|
||||||
for (int tempY = 0; tempY < tempRaster->getLy(); tempY++) {
|
for (int tempY = 0; tempY < tempRaster->getLy(); tempY++) {
|
||||||
for (int tempX = 0; tempX < tempRaster->getLx();
|
for (int tempX = 0; tempX < tempRaster->getLx();
|
||||||
tempX++, tempPix++, keepPix++) {
|
tempX++, tempPix++, keepPix++) {
|
||||||
keepPix->setPaint(tempPix->getPaint());
|
keepPix->setPaint(tempPix->getPaint());
|
||||||
if (tempPix->getInk() != styleIndex) {
|
if (tempPix->getInk() >= IGNORECOLORSTYLE || tempPix->getPaint() >= IGNORECOLORSTYLE) {
|
||||||
if (m_colorType == AREAS && m_closeGaps &&
|
continue;
|
||||||
tempPix->getInk() == 4095) {
|
} else {
|
||||||
keepPix->setInk(m_closeStyleIndex);
|
keepPix->setInk(tempPix->getInk());
|
||||||
keepPix->setTone(tempPix->getTone());
|
keepPix->setPaint(tempPix->getPaint());
|
||||||
} else if (m_colorType != AREAS && tempPix->getInk() == 4095) {
|
keepPix->setTone(tempPix->getTone());
|
||||||
keepPix->setInk(m_paintId);
|
|
||||||
keepPix->setTone(tempPix->getTone());
|
|
||||||
} else if (tempPix->getInk() != 4095) {
|
|
||||||
keepPix->setInk(tempPix->getInk());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -989,33 +998,37 @@ void fillAreaWithUndo(const TImageP &img, const TRectD &area, TStroke *stroke,
|
||||||
TRectD selArea = stroke ? stroke->getBBox() : area;
|
TRectD selArea = stroke ? stroke->getBBox() : area;
|
||||||
|
|
||||||
if (TToonzImageP ti = img) {
|
if (TToonzImageP ti = img) {
|
||||||
// allargo di 1 la savebox, perche cosi' il rectfill di tutta l'immagine fa
|
// Widen the savebox by 1, because this is how the rectfill of the whole image does
|
||||||
// una sola fillata
|
// a single fill
|
||||||
TRect enlargedSavebox =
|
TRect enlargedSavebox =
|
||||||
fillOnlySavebox
|
fillOnlySavebox
|
||||||
? ti->getSavebox().enlarge(1) * TRect(TPoint(0, 0), ti->getSize())
|
? ti->getSavebox().enlarge(1) * TRect(TPoint(0, 0), ti->getSize())
|
||||||
: TRect(TPoint(0, 0), ti->getSize());
|
: TRect(TPoint(0, 0), ti->getSize());
|
||||||
TRect rasterFillArea =
|
TRect rasterFillArea =
|
||||||
ToonzImageUtils::convertWorldToRaster(selArea, ti) * enlargedSavebox;
|
ToonzImageUtils::convertWorldToRaster(selArea, ti) * enlargedSavebox;
|
||||||
|
|
||||||
if (rasterFillArea.isEmpty()) return;
|
if (rasterFillArea.isEmpty()) return;
|
||||||
|
|
||||||
TRasterCM32P ras = ti->getRaster();
|
TRasterCM32P ras = ti->getRaster();
|
||||||
/*-- tileSetでFill範囲のRectをUndoに格納しておく --*/
|
/* Store the Rect of the Fill range in Undo with tileSet */
|
||||||
TTileSetCM32 *tileSet = new TTileSetCM32(ras->getSize());
|
TTileSetCM32 *tileSet = new TTileSetCM32(ras->getSize());
|
||||||
tileSet->add(ras, rasterFillArea);
|
tileSet->add(ras, rasterFillArea);
|
||||||
|
|
||||||
TRasterCM32P tempRaster;
|
TRasterCM32P tempRaster;
|
||||||
int styleIndex = 4094;
|
int styleIndex = GAP_CLOSE_TEMP;
|
||||||
|
|
||||||
|
TToonzImageP tempTi = ti->clone();
|
||||||
|
tempRaster = tempTi->getRaster();
|
||||||
|
|
||||||
if (fillGaps) {
|
if (fillGaps) {
|
||||||
TToonzImageP tempTi = ti->clone();
|
|
||||||
tempRaster = tempTi->getRaster();
|
|
||||||
applyAutoclose(tempTi, AutocloseDistance, AutocloseAngle,
|
applyAutoclose(tempTi, AutocloseDistance, AutocloseAngle,
|
||||||
AutocloseOpacity, 4094, convert(rasterFillArea), stroke);
|
AutocloseOpacity, GAP_CLOSE_TEMP, convert(rasterFillArea), stroke);
|
||||||
} else {
|
|
||||||
tempRaster = ras;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AreaFiller filler(tempRaster);
|
AreaFiller filler(tempRaster);
|
||||||
|
|
||||||
if (!stroke) {
|
if (!stroke) {
|
||||||
bool ret = filler.rectFill(rasterFillArea, cs, onlyUnfilled,
|
bool ret = filler.rectFill(rasterFillArea, cs, onlyUnfilled,
|
||||||
colorType != LINES, colorType != AREAS);
|
colorType != LINES, colorType != AREAS);
|
||||||
|
@ -1023,29 +1036,29 @@ void fillAreaWithUndo(const TImageP &img, const TRectD &area, TStroke *stroke,
|
||||||
delete tileSet;
|
delete tileSet;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
|
} else {
|
||||||
filler.strokeFill(stroke, cs, onlyUnfilled, colorType != LINES,
|
filler.strokeFill(stroke, cs, onlyUnfilled, colorType != LINES,
|
||||||
colorType != AREAS, rasterFillArea);
|
colorType != AREAS, rasterFillArea);
|
||||||
|
}
|
||||||
|
|
||||||
if (fillGaps) {
|
TPixelCM32 *tempPix = tempRaster->pixels();
|
||||||
TPixelCM32 *tempPix = tempRaster->pixels();
|
TPixelCM32 *keepPix = ras->pixels();
|
||||||
TPixelCM32 *keepPix = ras->pixels();
|
|
||||||
for (int tempY = 0; tempY < tempRaster->getLy(); tempY++) {
|
|
||||||
for (int tempX = 0; tempX < tempRaster->getLx();
|
finishGapLines(tempRaster, rasterFillArea, ras, ras, ti->getPalette(), 0,
|
||||||
tempX++, tempPix++, keepPix++) {
|
cs, closeStyleIndex, closeGaps);
|
||||||
keepPix->setPaint(tempPix->getPaint());
|
|
||||||
if (tempPix->getInk() != styleIndex) {
|
for (int tempY = 0; tempY < tempRaster->getLy(); tempY++) {
|
||||||
if (colorType == AREAS && closeGaps && tempPix->getInk() == 4095) {
|
for (int tempX = 0; tempX < tempRaster->getLx();
|
||||||
keepPix->setInk(closeStyleIndex);
|
tempX++, tempPix++, keepPix++) {
|
||||||
keepPix->setTone(tempPix->getTone());
|
if (tempPix->getInk() < IGNORECOLORSTYLE) {
|
||||||
} else if (colorType != AREAS && tempPix->getInk() == 4095) {
|
keepPix->setInk(tempPix->getInk());
|
||||||
keepPix->setInk(cs);
|
|
||||||
keepPix->setTone(tempPix->getTone());
|
|
||||||
} else if (tempPix->getInk() != 4095) {
|
|
||||||
keepPix->setInk(tempPix->getInk());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (tempPix->getPaint() < IGNORECOLORSTYLE) {
|
||||||
|
keepPix->setPaint(tempPix->getPaint());
|
||||||
|
}
|
||||||
|
keepPix->setTone(tempPix->getTone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1185,7 +1198,7 @@ void doFill(const TImageP &img, const TPointD &pos, FillParameters ¶ms,
|
||||||
|
|
||||||
if (tileSaver.getTileSet()->getTileCount() != 0) {
|
if (tileSaver.getTileSet()->getTileCount() != 0) {
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
TSystem::outputDebug("FILL" + std::to_string(count++) + "\n");
|
TSystem::outputDebug("FILL" + std::to_string(count++));
|
||||||
if (offs != TPoint())
|
if (offs != TPoint())
|
||||||
for (int i = 0; i < tileSet->getTileCount(); i++) {
|
for (int i = 0; i < tileSet->getTileCount(); i++) {
|
||||||
TTileSet::Tile *t = tileSet->editTile(i);
|
TTileSet::Tile *t = tileSet->editTile(i);
|
||||||
|
@ -2000,7 +2013,14 @@ void AreaFillTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e,
|
||||||
m_enabled = m_active = false;
|
m_enabled = m_active = false;
|
||||||
if (!isValid || m_track.isEmpty()) return;
|
if (!isValid || m_track.isEmpty()) return;
|
||||||
double pixelSize2 = m_parent->getPixelSize() * m_parent->getPixelSize();
|
double pixelSize2 = m_parent->getPixelSize() * m_parent->getPixelSize();
|
||||||
|
|
||||||
|
if (m_type == FREEPICK){
|
||||||
|
//strip off the first n points to allow the stroke to begin away from the initial click point where the color style will be selected.
|
||||||
|
TPointD firstPoint = m_track.getFirstPoint();
|
||||||
|
}
|
||||||
|
// add the first point as also the last point, to form a complete loop.
|
||||||
m_track.add(TThickPoint(m_firstPos, m_thick), pixelSize2);
|
m_track.add(TThickPoint(m_firstPos, m_thick), pixelSize2);
|
||||||
|
|
||||||
m_track.filterPoints();
|
m_track.filterPoints();
|
||||||
double error = (m_isPath ? 20.0 : 30.0 / 11) * sqrt(pixelSize2);
|
double error = (m_isPath ? 20.0 : 30.0 / 11) * sqrt(pixelSize2);
|
||||||
TStroke *stroke = m_track.makeStroke(error);
|
TStroke *stroke = m_track.makeStroke(error);
|
||||||
|
@ -2587,8 +2607,8 @@ void FillTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
|
||||||
invalidate();
|
invalidate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TSystem::outputDebug("ok. pix=" + std::to_string(pix.getTone()) + "," +
|
//TSystem::outputDebug("ok. pix=" + std::to_string(pix.getTone()) + "," +
|
||||||
std::to_string(pix.getPaint()) + "\n");
|
// std::to_string(pix.getPaint()));
|
||||||
} else
|
} else
|
||||||
return;
|
return;
|
||||||
int closeStyleIndex = m_closeStyleIndex.getStyleIndex();
|
int closeStyleIndex = m_closeStyleIndex.getStyleIndex();
|
||||||
|
|
|
@ -1799,7 +1799,7 @@ void FullColorFillToolOptionsBox::onGapSettingChanged(int index) {
|
||||||
m_styleIndex->hide();
|
m_styleIndex->hide();
|
||||||
m_styleIndexLabel->hide();
|
m_styleIndexLabel->hide();
|
||||||
m_rasterGapSlider->show();
|
m_rasterGapSlider->show();
|
||||||
m_gapSliderLabel->hide();
|
m_gapSliderLabel->show();
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
m_styleIndex->show();
|
m_styleIndex->show();
|
||||||
m_styleIndexLabel->show();
|
m_styleIndexLabel->show();
|
||||||
|
|
|
@ -20,11 +20,17 @@
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "tsystem.h"
|
||||||
|
|
||||||
extern TEnv::DoubleVar AutocloseDistance;
|
extern TEnv::DoubleVar AutocloseDistance;
|
||||||
extern TEnv::DoubleVar AutocloseAngle;
|
extern TEnv::DoubleVar AutocloseAngle;
|
||||||
extern TEnv::IntVar AutocloseInk;
|
extern TEnv::IntVar AutocloseInk;
|
||||||
extern TEnv::IntVar AutocloseOpacity;
|
extern TEnv::IntVar AutocloseOpacity;
|
||||||
|
|
||||||
|
#define IGNORECOLORSTYLE 4093
|
||||||
|
#define GAP_CLOSE_TEMP 4094
|
||||||
|
#define GAP_CLOSE_USED 4095
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
namespace { // Utility Function
|
namespace { // Utility Function
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -47,14 +53,14 @@ inline TPoint nearestInkNotDiagonal(const TRasterCM32P &r, const TPoint &p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// from point x, y expands to the rightand left.
|
// from point x, y expands to the right and left.
|
||||||
// the redrawn line goes from* xa to* xb inclusive
|
// the redrawn line goes from* xa to* xb inclusive
|
||||||
// x1 <= *xa <= *xb <= x2
|
// x1 <= *xa <= *xb <= x2
|
||||||
// N.B. if not even one pixel is drawn* xa > * xb
|
// N.B. if not even one pixel is drawn* xa > * xb
|
||||||
//
|
//
|
||||||
// "prevailing" is set to false on revert-filling the border of
|
// "prevailing" is set to false on revert-filling the border of
|
||||||
// region in the Rectangular, Freehand and Polyline fill procedures
|
// region in the Rectangular, Freehand and Polyline fill procedures
|
||||||
// in order to make the paint to protlude behind the line.
|
// in order to make the paint extend behind the line.
|
||||||
|
|
||||||
// Calculates the endpoints for the line of pixels in which to fill
|
// Calculates the endpoints for the line of pixels in which to fill
|
||||||
bool calcFillRow(const TRasterCM32P &r, const TPoint &p, int &xa, int &xb,
|
bool calcFillRow(const TRasterCM32P &r, const TPoint &p, int &xa, int &xb,
|
||||||
|
@ -72,10 +78,16 @@ bool calcFillRow(const TRasterCM32P &r, const TPoint &p, int &xa, int &xb,
|
||||||
oldtone = pix->getTone();
|
oldtone = pix->getTone();
|
||||||
tone = oldtone;
|
tone = oldtone;
|
||||||
for (; pix <= limit; pix++) {
|
for (; pix <= limit; pix++) {
|
||||||
if (pix->getPaint() == paint) break;
|
if (pix->getPaint() == paint) {
|
||||||
if (emptyOnly && pix->getPaint() != 0) break;
|
//break;
|
||||||
|
}
|
||||||
|
if (emptyOnly && pix->getPaint() != 0) {
|
||||||
|
//break;
|
||||||
|
}
|
||||||
tone = pix->getTone();
|
tone = pix->getTone();
|
||||||
if (tone == 0) break;
|
if (tone == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
// prevent fill area from protruding behind the colored line
|
// prevent fill area from protruding behind the colored line
|
||||||
if (tone > oldtone) {
|
if (tone > oldtone) {
|
||||||
// not-yet-colored line case
|
// not-yet-colored line case
|
||||||
|
@ -94,8 +106,7 @@ bool calcFillRow(const TRasterCM32P &r, const TPoint &p, int &xa, int &xb,
|
||||||
TPixelCM32 *upPix = pix - r->getWrap();
|
TPixelCM32 *upPix = pix - r->getWrap();
|
||||||
TPixelCM32 *downPix = pix + r->getWrap();
|
TPixelCM32 *downPix = pix + r->getWrap();
|
||||||
if (upPix->getTone() > pix->getTone() &&
|
if (upPix->getTone() > pix->getTone() &&
|
||||||
downPix->getTone() > pix->getTone())
|
downPix->getTone() > pix->getTone()) continue;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -109,12 +120,14 @@ bool calcFillRow(const TRasterCM32P &r, const TPoint &p, int &xa, int &xb,
|
||||||
tmp_limit = pix + 10; // edge stop fill == 10 per default
|
tmp_limit = pix + 10; // edge stop fill == 10 per default
|
||||||
if (limit > tmp_limit) limit = tmp_limit;
|
if (limit > tmp_limit) limit = tmp_limit;
|
||||||
for (; pix <= limit; pix++) {
|
for (; pix <= limit; pix++) {
|
||||||
if (pix->getPaint() == paint) break;
|
//if (pix->getPaint() == paint) break; // commented out for issue 1151
|
||||||
if (pix->getTone() != 0) break;
|
if (pix->getTone() != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xb = p.x + pix - pix0 - 1;
|
xb = p.x + pix - pix0 - 1; //go backward one pixel from the current pixel which triggered the boundary condition.
|
||||||
|
|
||||||
/* go left */
|
/* go left */
|
||||||
|
|
||||||
|
@ -123,15 +136,22 @@ bool calcFillRow(const TRasterCM32P &r, const TPoint &p, int &xa, int &xb,
|
||||||
oldtone = pix->getTone();
|
oldtone = pix->getTone();
|
||||||
tone = oldtone;
|
tone = oldtone;
|
||||||
for (pix--; pix >= limit; pix--) {
|
for (pix--; pix >= limit; pix--) {
|
||||||
if (pix->getPaint() == paint) break;
|
if (pix->getPaint() == paint) {
|
||||||
if (emptyOnly && pix->getPaint() != 0) break;
|
break;
|
||||||
|
}
|
||||||
|
if (emptyOnly && pix->getPaint() != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
tone = pix->getTone();
|
tone = pix->getTone();
|
||||||
if (tone == 0) break;
|
if (tone == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
// prevent fill area from protruding behind the colored line
|
// prevent fill area from protruding behind the colored line
|
||||||
if (tone > oldtone) {
|
if (tone > oldtone) {
|
||||||
// not-yet-colored line case
|
// not-yet-colored line case
|
||||||
if (prevailing && !pix->isPurePaint() && pix->getInk() != pix->getPaint())
|
if (prevailing && !pix->isPurePaint() && pix->getInk() != pix->getPaint()){
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
while (pix != pix0) {
|
while (pix != pix0) {
|
||||||
// iterate forward in order to leave the pixel with the lowest tone
|
// iterate forward in order to leave the pixel with the lowest tone
|
||||||
// unpainted
|
// unpainted
|
||||||
|
@ -145,8 +165,9 @@ bool calcFillRow(const TRasterCM32P &r, const TPoint &p, int &xa, int &xb,
|
||||||
TPixelCM32 *upPix = pix - r->getWrap();
|
TPixelCM32 *upPix = pix - r->getWrap();
|
||||||
TPixelCM32 *downPix = pix + r->getWrap();
|
TPixelCM32 *downPix = pix + r->getWrap();
|
||||||
if (upPix->getTone() > pix->getTone() &&
|
if (upPix->getTone() > pix->getTone() &&
|
||||||
downPix->getTone() > pix->getTone())
|
downPix->getTone() > pix->getTone()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -160,12 +181,14 @@ bool calcFillRow(const TRasterCM32P &r, const TPoint &p, int &xa, int &xb,
|
||||||
tmp_limit = pix - 10;
|
tmp_limit = pix - 10;
|
||||||
if (limit < tmp_limit) limit = tmp_limit;
|
if (limit < tmp_limit) limit = tmp_limit;
|
||||||
for (; pix >= limit; pix--) {
|
for (; pix >= limit; pix--) {
|
||||||
if (pix->getPaint() == paint) break;
|
//if (pix->getPaint() == paint) break; // commented out for issue 1151
|
||||||
if (pix->getTone() != 0) break;
|
if (pix->getTone() != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xa = p.x + pix - pix0 + 1;
|
xa = p.x + pix - pix0 + 1; //go backward one pixel from the current pixel which triggered the boundary condition.
|
||||||
|
|
||||||
return (xb >= xa);
|
return (xb >= xa);
|
||||||
}
|
}
|
||||||
|
@ -430,6 +453,44 @@ TRasterCM32P convertRaster2CM(const TRasterP &inputRaster) {
|
||||||
return rout;
|
return rout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void outputPixels(const std::string _str, const TRasterCM32P &r) {
|
||||||
|
r->lock();
|
||||||
|
TPixelCM32* tempPix = r->pixels(0);
|
||||||
|
std::cout << "\noutputPixels for:";
|
||||||
|
std::cout << _str;
|
||||||
|
std::cout << ", bbox is y : ";
|
||||||
|
std::cout << r->getLy();
|
||||||
|
std::cout << ",x:";
|
||||||
|
std::cout << r->getLx();
|
||||||
|
std::cout << "----";
|
||||||
|
tempPix = tempPix + ((r->getLy()-1) * r->getLx());
|
||||||
|
for (int tempY = r->getLy()-1; tempY >= 0; tempY--) {
|
||||||
|
if (tempY < r->getLy() - 1) {
|
||||||
|
tempPix = tempPix - 2 * r->getLx();
|
||||||
|
}
|
||||||
|
std::cout << "\ny:";
|
||||||
|
std::cout << tempY;
|
||||||
|
for (int tempX = 0; tempX < r->getLx();
|
||||||
|
tempX++, tempPix++) {
|
||||||
|
std::cout << "|x:";
|
||||||
|
std::cout << tempX;
|
||||||
|
std::cout << ":";
|
||||||
|
std::cout << tempPix->getInk();
|
||||||
|
std::cout << ".";
|
||||||
|
std::cout << tempPix->getPaint();
|
||||||
|
std::cout << ".";
|
||||||
|
std::cout << tempPix->getTone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r->unlock();
|
||||||
|
std::cout << "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*-- The return value is whether the saveBox has been updated or not. --*/
|
/*-- The return value is whether the saveBox has been updated or not. --*/
|
||||||
bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
||||||
TTileSaverCM32 *saver, bool fillGaps, bool closeGaps,
|
TTileSaverCM32 *saver, bool fillGaps, bool closeGaps,
|
||||||
|
@ -449,9 +510,9 @@ bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
||||||
int paint = params.m_styleId;
|
int paint = params.m_styleId;
|
||||||
int fillDepth =
|
int fillDepth =
|
||||||
params.m_shiftFill ? params.m_maxFillDepth : params.m_minFillDepth;
|
params.m_shiftFill ? params.m_maxFillDepth : params.m_minFillDepth;
|
||||||
TRasterCM32P tempRaster;
|
TRasterCM32P tempRaster, cr, refCMRaster;
|
||||||
int styleIndex = 4094;
|
int styleIndex = GAP_CLOSE_TEMP;
|
||||||
int fakeStyleIndex = 4095;
|
int fakeStyleIndex = GAP_CLOSE_USED;
|
||||||
if (autoCloseDistance < 0.0) autoCloseDistance = AutocloseDistance;
|
if (autoCloseDistance < 0.0) autoCloseDistance = AutocloseDistance;
|
||||||
|
|
||||||
bool gapsClosed = false, refGapsClosed = false;
|
bool gapsClosed = false, refGapsClosed = false;
|
||||||
|
@ -473,7 +534,10 @@ bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
||||||
if (!bbbox.contains(p)) return false;
|
if (!bbbox.contains(p)) return false;
|
||||||
/*- If the same color has already been painted, return -*/
|
/*- If the same color has already been painted, return -*/
|
||||||
int paintAtClickedPos = (tempRaster->pixels(p.y) + p.x)->getPaint();
|
int paintAtClickedPos = (tempRaster->pixels(p.y) + p.x)->getPaint();
|
||||||
if (paintAtClickedPos == paint) return false;
|
|
||||||
|
if (paintAtClickedPos == paint) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/*- If the "paint only transparent areas" option is enabled and the area is
|
/*- If the "paint only transparent areas" option is enabled and the area is
|
||||||
* already colored, return
|
* already colored, return
|
||||||
* -*/
|
* -*/
|
||||||
|
@ -511,8 +575,8 @@ bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fillGaps) {
|
if (fillGaps) {
|
||||||
TRasterCM32P cr = convertRaster2CM(refRaster);
|
cr = convertRaster2CM(refRaster);
|
||||||
TRasterCM32P refCMRaster = cr->clone();
|
refCMRaster = cr->clone();
|
||||||
|
|
||||||
refGapsClosed = TAutocloser(refCMRaster, autoCloseDistance,
|
refGapsClosed = TAutocloser(refCMRaster, autoCloseDistance,
|
||||||
AutocloseAngle, styleIndex, AutocloseOpacity)
|
AutocloseAngle, styleIndex, AutocloseOpacity)
|
||||||
|
@ -529,7 +593,7 @@ bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
||||||
refCMX++, refCMPix++, refPix++, tempPix++) {
|
refCMX++, refCMPix++, refPix++, tempPix++) {
|
||||||
if (refCMPix->getInk() != styleIndex) continue;
|
if (refCMPix->getInk() != styleIndex) continue;
|
||||||
*refPix = color;
|
*refPix = color;
|
||||||
if (closeGaps) {
|
if (fillGaps) {
|
||||||
tempPix->setInk(refCMPix->getInk());
|
tempPix->setInk(refCMPix->getInk());
|
||||||
tempPix->setTone(refCMPix->getTone());
|
tempPix->setTone(refCMPix->getTone());
|
||||||
}
|
}
|
||||||
|
@ -539,7 +603,9 @@ bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fillGaps && !gapsClosed && !refGapsClosed) fillGaps = false;
|
if (fillGaps && !gapsClosed && !refGapsClosed) {
|
||||||
|
fillGaps = false;
|
||||||
|
}
|
||||||
|
|
||||||
assert(fillDepth >= 0 && fillDepth < 16);
|
assert(fillDepth >= 0 && fillDepth < 16);
|
||||||
|
|
||||||
|
@ -580,23 +646,11 @@ bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
||||||
params.m_prevailing, params.m_emptyOnly)
|
params.m_prevailing, params.m_emptyOnly)
|
||||||
: calcRefFillRow(refRaster, p, xa, xb, color, clickedPosColor,
|
: calcRefFillRow(refRaster, p, xa, xb, color, clickedPosColor,
|
||||||
fillDepth);
|
fillDepth);
|
||||||
|
|
||||||
if (fillIt) fillRow(tempRaster, p, xa, xb, paint, params.m_palette, saver);
|
if (fillIt) fillRow(tempRaster, p, xa, xb, paint, params.m_palette, saver);
|
||||||
if (xsheet) segments[y].push_back(std::pair<int, int>(xa, xb));
|
if (xsheet) segments[y].push_back(std::pair<int, int>(xa, xb));
|
||||||
seeds.push(FillSeed(xa, xb, y, 1));
|
seeds.push(FillSeed(xa, xb, y, 1));
|
||||||
seeds.push(FillSeed(xa, xb, y, -1));
|
seeds.push(FillSeed(xa, xb, y, -1));
|
||||||
// Set the ink on gaps that were used to 4095
|
|
||||||
{
|
|
||||||
TPixelCM32 *tempPix = tempRaster->pixels(0);
|
|
||||||
tempPix += (y * tempRaster->getLx()) + xa - 1;
|
|
||||||
int i = xa;
|
|
||||||
while (i <= xb) {
|
|
||||||
if (tempPix->getInk() == styleIndex) {
|
|
||||||
tempPix->setInk(fakeStyleIndex);
|
|
||||||
}
|
|
||||||
tempPix++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!seeds.empty()) {
|
while (!seeds.empty()) {
|
||||||
FillSeed fs = seeds.top();
|
FillSeed fs = seeds.top();
|
||||||
|
@ -647,19 +701,7 @@ bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
||||||
fillRow(tempRaster, TPoint(x, y), xc, xd, paint, params.m_palette,
|
fillRow(tempRaster, TPoint(x, y), xc, xd, paint, params.m_palette,
|
||||||
saver);
|
saver);
|
||||||
if (xsheet) insertSegment(segments[y], std::pair<int, int>(xc, xd));
|
if (xsheet) insertSegment(segments[y], std::pair<int, int>(xc, xd));
|
||||||
// Set the ink on gaps that were used to 4095
|
|
||||||
{
|
|
||||||
TPixelCM32 *tempPix = tempRaster->pixels(0);
|
|
||||||
tempPix += (y * tempRaster->getLx()) + xa - 1;
|
|
||||||
int i = xa;
|
|
||||||
while (i <= xb) {
|
|
||||||
if (tempPix->getInk() == styleIndex) {
|
|
||||||
tempPix->setInk(fakeStyleIndex);
|
|
||||||
}
|
|
||||||
tempPix++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xc < xa) seeds.push(FillSeed(xc, xa - 1, y, -dy));
|
if (xc < xa) seeds.push(FillSeed(xc, xa - 1, y, -dy));
|
||||||
if (xd > xb) seeds.push(FillSeed(xb + 1, xd, y, -dy));
|
if (xd > xb) seeds.push(FillSeed(xb + 1, xd, y, -dy));
|
||||||
if (oldxd >= xc - 1)
|
if (oldxd >= xc - 1)
|
||||||
|
@ -703,26 +745,27 @@ bool fill(const TRasterCM32P &r, const FillParameters ¶ms,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fillGaps) {
|
if (fillGaps) {
|
||||||
TPixelCM32 *tempPix = tempRaster->pixels();
|
finishGapLines(tempRaster, bbbox, r, refCMRaster, params.m_palette, paintAtClickedPos, paint, closeStyleIndex, closeGaps);
|
||||||
TPixelCM32 *keepPix = r->pixels();
|
TPixelCM32 *tempPix, *tempPixRestart;
|
||||||
|
tempPixRestart = tempPix = tempRaster->pixels();
|
||||||
|
TPixelCM32 *keepPix, *keepPixRestart;
|
||||||
|
keepPixRestart = keepPix = r->pixels();
|
||||||
|
int fillNeighbors = 0;
|
||||||
|
int paintableNeighbors = 0;
|
||||||
|
|
||||||
for (int tempY = 0; tempY < tempRaster->getLy(); tempY++) {
|
for (int tempY = 0; tempY < tempRaster->getLy(); tempY++) {
|
||||||
for (int tempX = 0; tempX < tempRaster->getLx();
|
for (int tempX = 0; tempX < tempRaster->getLx();
|
||||||
tempX++, tempPix++, keepPix++) {
|
tempX++, tempPix++, keepPix++) {
|
||||||
if (tempPix->getInk() != styleIndex &&
|
if (tempPix->getInk() >= IGNORECOLORSTYLE || tempPix->getPaint() >= IGNORECOLORSTYLE) {
|
||||||
tempPix->getInk() != fakeStyleIndex)
|
continue;
|
||||||
keepPix->setPaint(tempPix->getPaint());
|
|
||||||
// This next line takes care of autopaint lines
|
|
||||||
if (tempPix->getInk() != styleIndex) {
|
|
||||||
if (closeGaps && tempPix->getInk() == fakeStyleIndex) {
|
|
||||||
keepPix->setInk(closeStyleIndex);
|
|
||||||
keepPix->setTone(tempPix->getTone());
|
|
||||||
} else if (tempPix->getInk() != fakeStyleIndex) {
|
|
||||||
keepPix->setInk(tempPix->getInk());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
keepPix->setInk(tempPix->getInk());
|
||||||
|
keepPix->setPaint(tempPix->getPaint());
|
||||||
|
keepPix->setTone(tempPix->getTone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return saveBoxChanged;
|
return saveBoxChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,8 +992,8 @@ void fullColorFill(const TRaster32P &ras, const FillParameters ¶ms,
|
||||||
TRaster32P refRas(bbbox.getSize());
|
TRaster32P refRas(bbbox.getSize());
|
||||||
|
|
||||||
TPixel32 gapColor = plt->getStyle(closeStyleIndex)->getMainColor();
|
TPixel32 gapColor = plt->getStyle(closeStyleIndex)->getMainColor();
|
||||||
int styleIndex = 4094;
|
int styleIndex = GAP_CLOSE_TEMP;
|
||||||
int fakeStyleIndex = 4095;
|
int fakeStyleIndex = GAP_CLOSE_USED;
|
||||||
|
|
||||||
if (xsheet) {
|
if (xsheet) {
|
||||||
ToonzScene *scene = xsheet->getScene();
|
ToonzScene *scene = xsheet->getScene();
|
||||||
|
@ -975,9 +1018,10 @@ void fullColorFill(const TRaster32P &ras, const FillParameters ¶ms,
|
||||||
}
|
}
|
||||||
|
|
||||||
TRasterCM32P refCMRaster;
|
TRasterCM32P refCMRaster;
|
||||||
|
TRasterCM32P cr;
|
||||||
|
|
||||||
if (fillGaps) {
|
if (fillGaps) {
|
||||||
TRasterCM32P cr = convertRaster2CM(refRas);
|
cr = convertRaster2CM(refRas);
|
||||||
refCMRaster = cr->clone();
|
refCMRaster = cr->clone();
|
||||||
fillGaps = TAutocloser(refCMRaster, autoCloseDistance, AutocloseAngle,
|
fillGaps = TAutocloser(refCMRaster, autoCloseDistance, AutocloseAngle,
|
||||||
styleIndex, AutocloseOpacity)
|
styleIndex, AutocloseOpacity)
|
||||||
|
@ -1019,20 +1063,6 @@ void fullColorFill(const TRaster32P &ras, const FillParameters ¶ms,
|
||||||
seeds.push(FillSeed(xa, xb, y, 1));
|
seeds.push(FillSeed(xa, xb, y, 1));
|
||||||
seeds.push(FillSeed(xa, xb, y, -1));
|
seeds.push(FillSeed(xa, xb, y, -1));
|
||||||
|
|
||||||
if (fillGaps && closeGaps) {
|
|
||||||
// Set the ink on gaps that were used to 4095
|
|
||||||
TPixelCM32 *tempPix = refCMRaster->pixels(0);
|
|
||||||
tempPix += (y * refCMRaster->getLx()) + xa - 1;
|
|
||||||
int i = xa;
|
|
||||||
while (i <= xb) {
|
|
||||||
if (tempPix->getInk() == styleIndex) {
|
|
||||||
tempPix->setInk(fakeStyleIndex);
|
|
||||||
}
|
|
||||||
tempPix++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!seeds.empty()) {
|
while (!seeds.empty()) {
|
||||||
FillSeed fs = seeds.top();
|
FillSeed fs = seeds.top();
|
||||||
seeds.pop();
|
seeds.pop();
|
||||||
|
@ -1083,19 +1113,6 @@ void fullColorFill(const TRaster32P &ras, const FillParameters ¶ms,
|
||||||
clickedPosColor, fillDepth);
|
clickedPosColor, fillDepth);
|
||||||
// insert segment to be filled
|
// insert segment to be filled
|
||||||
insertSegment(segments[y], std::pair<int, int>(xc, xd));
|
insertSegment(segments[y], std::pair<int, int>(xc, xd));
|
||||||
if (fillGaps && closeGaps) {
|
|
||||||
// Set the ink on gaps that were used to 4095
|
|
||||||
TPixelCM32 *tempPix = refCMRaster->pixels(0);
|
|
||||||
tempPix += (y * refCMRaster->getLx()) + xa - 1;
|
|
||||||
int i = xa;
|
|
||||||
while (i <= xb) {
|
|
||||||
if (tempPix->getInk() == styleIndex) {
|
|
||||||
tempPix->setInk(fakeStyleIndex);
|
|
||||||
}
|
|
||||||
tempPix++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// create new fillSeed to invert direction, if needed
|
// create new fillSeed to invert direction, if needed
|
||||||
if (xc < xa) seeds.push(FillSeed(xc, xa - 1, y, -dy));
|
if (xc < xa) seeds.push(FillSeed(xc, xa - 1, y, -dy));
|
||||||
|
@ -1158,14 +1175,59 @@ void fullColorFill(const TRaster32P &ras, const FillParameters ¶ms,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fillGaps && closeGaps) {
|
// final check for close gap pixels
|
||||||
|
if (fillGaps) {
|
||||||
|
|
||||||
TPixelCM32 *tempPix = refCMRaster->pixels();
|
TPixelCM32 *tempPix = refCMRaster->pixels();
|
||||||
TPixel32 *keepPix = ras->pixels();
|
TPixel32 *keepPix = ras->pixels();
|
||||||
|
int fillNeighbors;
|
||||||
for (int tempY = 0; tempY < refCMRaster->getLy(); tempY++) {
|
for (int tempY = 0; tempY < refCMRaster->getLy(); tempY++) {
|
||||||
for (int tempX = 0; tempX < refCMRaster->getLx();
|
for (int tempX = 0; tempX < refCMRaster->getLx();
|
||||||
tempX++, tempPix++, keepPix++) {
|
tempX++, tempPix++, keepPix++) {
|
||||||
if (tempPix->getInk() == fakeStyleIndex) {
|
// if (tempPix->getInk() == fakeStyleIndex) {
|
||||||
*keepPix = gapColor;
|
if (tempPix->getInk() == styleIndex) {
|
||||||
|
// how many fill pixel neighbors for the current pixel?
|
||||||
|
fillNeighbors = 0;
|
||||||
|
if ((tempX > 0) && *(keepPix - 1) == color) fillNeighbors++; // west
|
||||||
|
if (tempX < ras->getLx() - 1 && *(keepPix + 1) == color)
|
||||||
|
fillNeighbors++; // east
|
||||||
|
if (tempY < ras->getLy() - 1 && *(keepPix + ras->getWrap()) == color)
|
||||||
|
fillNeighbors++; // north
|
||||||
|
if (tempY > 0 && *(keepPix - ras->getWrap()) == color)
|
||||||
|
fillNeighbors++; // south
|
||||||
|
if (fillNeighbors < 1) {
|
||||||
|
// no neighboring fill pixels, this is an unused gap close pixel
|
||||||
|
continue;
|
||||||
|
} else if (fillNeighbors > 3) {
|
||||||
|
// too many neighboring fill pixels to be a gap close pixel
|
||||||
|
// , convert it to a fill pixel
|
||||||
|
*keepPix = color;
|
||||||
|
} else {
|
||||||
|
// does it have at least one unpainted pixel neighbor?
|
||||||
|
if (((tempX > 0) && (tempPix - 1)->getInk() == 0 &&
|
||||||
|
(*(keepPix - 1) == clickedPosColor)) // west
|
||||||
|
|| (tempX < refCMRaster->getLx() - 1 &&
|
||||||
|
(tempPix + 1)->getInk() == 0 &&
|
||||||
|
*(keepPix + 1) == clickedPosColor) // east
|
||||||
|
|| (tempY < refCMRaster->getLy() - 1 &&
|
||||||
|
(tempPix + refCMRaster->getWrap())->getInk() == 0 &&
|
||||||
|
*(keepPix + ras->getWrap()) == clickedPosColor) // north
|
||||||
|
|| (tempY > 0 &&
|
||||||
|
(tempPix - refCMRaster->getWrap())->getInk() == 0 &&
|
||||||
|
*(keepPix - ras->getWrap()) == clickedPosColor) // south
|
||||||
|
) {
|
||||||
|
// yes, persist it as a gap close pixel
|
||||||
|
if (closeGaps) {
|
||||||
|
*keepPix = gapColor;
|
||||||
|
} else {
|
||||||
|
*keepPix = color;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// it is not acting as a border pixel so convert it to a fill
|
||||||
|
// pixel
|
||||||
|
*keepPix = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
#include "tpixelutils.h"
|
#include "tpixelutils.h"
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <tsystem.h>
|
||||||
|
|
||||||
|
#define IGNORECOLORSTYLE 4093
|
||||||
|
#define GAP_CLOSE_TEMP 4094
|
||||||
|
#define GAP_CLOSE_USED 4095
|
||||||
|
|
||||||
using namespace SkeletonLut;
|
using namespace SkeletonLut;
|
||||||
|
|
||||||
|
@ -79,8 +84,7 @@ void fillArea(const TRasterCM32P &ras, TRegion *r, int colorId,
|
||||||
for (int k = from; k < to; k++, pix++) {
|
for (int k = from; k < to; k++, pix++) {
|
||||||
if (fillPaints && (!onlyUnfilled || pix->getPaint() == 0))
|
if (fillPaints && (!onlyUnfilled || pix->getPaint() == 0))
|
||||||
pix->setPaint(colorId);
|
pix->setPaint(colorId);
|
||||||
if (fillInks && pix->getInk() != 4094) pix->setInk(colorId);
|
if (fillInks && pix->getInk() != GAP_CLOSE_TEMP) pix->setInk(colorId);
|
||||||
if (pix->getInk() == 4094) pix->setInk(4095);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,11 +96,12 @@ void fillArea(const TRasterCM32P &ras, TRegion *r, int colorId,
|
||||||
void restoreColors(const TRasterCM32P &r,
|
void restoreColors(const TRasterCM32P &r,
|
||||||
const std::vector<std::pair<TPoint, int>> &seeds) {
|
const std::vector<std::pair<TPoint, int>> &seeds) {
|
||||||
FillParameters params;
|
FillParameters params;
|
||||||
// in order to make the paint to protlude behind the line
|
// in order to make the paint to protrude behind the line
|
||||||
params.m_prevailing = false;
|
params.m_prevailing = false;
|
||||||
for (UINT i = 0; i < seeds.size(); i++) {
|
for (UINT i = 0; i < seeds.size(); i++) {
|
||||||
params.m_p = seeds[i].first;
|
params.m_p = seeds[i].first;
|
||||||
params.m_styleId = seeds[i].second;
|
// params.m_styleId = seeds[i].second;
|
||||||
|
params.m_styleId = IGNORECOLORSTYLE;
|
||||||
fill(r, params);
|
fill(r, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +142,171 @@ bool areRectPixelsTransparent(TPixel32 *pixels, TRect rect, int wrap) {
|
||||||
} // namespace
|
} // namespace
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void finishGapLine(const TRasterCM32P &r, const TRasterCM32P &combined,
|
||||||
|
const TPoint &pin, int clickedColorStyle, int fillColorStyle,
|
||||||
|
int closeColorStyle, int searchRay, TRect *insideRect,
|
||||||
|
bool closeGaps) {
|
||||||
|
r->lock();
|
||||||
|
|
||||||
|
TRasterCM32P myCombined;
|
||||||
|
if (!combined.getPointer() || combined->isEmpty()) {
|
||||||
|
myCombined = r;
|
||||||
|
} else {
|
||||||
|
myCombined = combined;
|
||||||
|
}
|
||||||
|
|
||||||
|
TPixelCM32 *pixels = (TPixelCM32 *)r->getRawData();
|
||||||
|
TPixelCM32 *combinedPixels = (TPixelCM32 *)myCombined->getRawData();
|
||||||
|
;
|
||||||
|
TPoint p = pin;
|
||||||
|
int filledNeighbor = 0;
|
||||||
|
int unfilledNeighbor = 0;
|
||||||
|
int inkStyle = 0;
|
||||||
|
int paintStyle = 0;
|
||||||
|
int toneValue = 0;
|
||||||
|
|
||||||
|
TPixelCM32 *pix = pixels + (p.y * r->getWrap() + p.x);
|
||||||
|
TPixelCM32 *pixc = combinedPixels + (p.y * myCombined->getWrap() + p.x);
|
||||||
|
|
||||||
|
std::stack<TPoint> gapLinePixels;
|
||||||
|
std::stack<TPoint> seeds;
|
||||||
|
seeds.push(p);
|
||||||
|
|
||||||
|
while (!seeds.empty()) {
|
||||||
|
p = seeds.top();
|
||||||
|
seeds.pop();
|
||||||
|
|
||||||
|
if (!r->getBounds().contains(p)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (insideRect && !insideRect->contains(p)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TPixelCM32 *pix = pixels + (p.y * r->getWrap() + p.x);
|
||||||
|
TPixelCM32 *pixc = combinedPixels + (p.y * myCombined->getWrap() + p.x);
|
||||||
|
|
||||||
|
// handle gap close pixel
|
||||||
|
if (pix->getInk() == GAP_CLOSE_USED) continue;
|
||||||
|
if (pix->getInk() == GAP_CLOSE_TEMP) {
|
||||||
|
pix->setInk(GAP_CLOSE_USED);
|
||||||
|
// push to the gapLinePixels collection for later processing as a line
|
||||||
|
gapLinePixels.push(p);
|
||||||
|
|
||||||
|
// push neighboring pixels into the seeds queue
|
||||||
|
seeds.push(TPoint(p.x - 1, p.y - 1)); // sw
|
||||||
|
seeds.push(TPoint(p.x - 1, p.y)); // west
|
||||||
|
seeds.push(TPoint(p.x - 1, p.y + 1)); // nw
|
||||||
|
seeds.push(TPoint(p.x, p.y - 1)); // south
|
||||||
|
seeds.push(TPoint(p.x, p.y + 1)); // north
|
||||||
|
seeds.push(TPoint(p.x + 1, p.y - 1)); // se
|
||||||
|
seeds.push(TPoint(p.x + 1, p.y)); // east
|
||||||
|
seeds.push(TPoint(p.x + 1, p.y + 1)); // ne
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// a neighboring filled pixel
|
||||||
|
if (pix->getTone() > 0 && pix->getPaint() == fillColorStyle) {
|
||||||
|
filledNeighbor++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// a neighboring fillable but unfilled pixel
|
||||||
|
if ((pix->getTone() == 255 &&
|
||||||
|
((pix->getPaint() == clickedColorStyle) || (pix->getPaint() == 0) ||
|
||||||
|
(pix->getPaint() == IGNORECOLORSTYLE))) &&
|
||||||
|
(pixc->getTone() == 255 && ((pixc->getPaint() == clickedColorStyle) ||
|
||||||
|
(pixc->getPaint() == 0)))) {
|
||||||
|
unfilledNeighbor++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine the final disposition of the gap line
|
||||||
|
if (filledNeighbor > 0) {
|
||||||
|
if (unfilledNeighbor > 0) {
|
||||||
|
if (closeGaps) {
|
||||||
|
inkStyle = closeColorStyle;
|
||||||
|
paintStyle = fillColorStyle;
|
||||||
|
toneValue = 0;
|
||||||
|
} else {
|
||||||
|
inkStyle = 0;
|
||||||
|
paintStyle = fillColorStyle;
|
||||||
|
toneValue = 255;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inkStyle = 0;
|
||||||
|
paintStyle = fillColorStyle;
|
||||||
|
toneValue = 255;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inkStyle = IGNORECOLORSTYLE;
|
||||||
|
paintStyle = 0;
|
||||||
|
toneValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// process the stored gap close line pixels
|
||||||
|
while (!gapLinePixels.empty()) {
|
||||||
|
p = gapLinePixels.top();
|
||||||
|
gapLinePixels.pop();
|
||||||
|
|
||||||
|
TPixelCM32 *pix = pixels + (p.y * r->getWrap() + p.x);
|
||||||
|
|
||||||
|
pix->setInk(inkStyle);
|
||||||
|
pix->setPaint(paintStyle);
|
||||||
|
pix->setTone(toneValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
r->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// This function finishes candidate gap lines that were created
|
||||||
|
// during a fill process.
|
||||||
|
// combined is the levels combined as is done for the "use visible" tool option
|
||||||
|
void finishGapLines(TRasterCM32P &rin, TRect &rect, const TRasterCM32P &rbefore,
|
||||||
|
const TRasterCM32P &combined, TPalette *plt,
|
||||||
|
int clickedColorStyle, int fillIndex, int closeColorStyle,
|
||||||
|
bool closeGaps) {
|
||||||
|
assert(plt);
|
||||||
|
TRasterCM32P r = rin->extract(rect);
|
||||||
|
assert(r->getSize() == rbefore->getSize());
|
||||||
|
assert(r->getSize() == combined->getSize());
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < r->getLy(); i++) {
|
||||||
|
TPixelCM32 *pix = r->pixels(i);
|
||||||
|
TPixelCM32 *pixb = rbefore->pixels(i);
|
||||||
|
for (j = 0; j < r->getLx(); j++, pix++, pixb++) {
|
||||||
|
int paint = pix->getPaint();
|
||||||
|
int tone = pix->getTone();
|
||||||
|
int ink = pix->getInk();
|
||||||
|
|
||||||
|
if (ink == GAP_CLOSE_TEMP &&
|
||||||
|
(
|
||||||
|
// north
|
||||||
|
(i < rin->getLy() - 1 &&
|
||||||
|
(pix + rin->getWrap())->getPaint() == fillIndex &&
|
||||||
|
(pix + rin->getWrap())->getPaint() !=
|
||||||
|
(pixb + rbefore->getWrap())->getPaint())
|
||||||
|
// south
|
||||||
|
|| (i > 0 && (pix - rin->getWrap())->getPaint() == fillIndex &&
|
||||||
|
(pix - rin->getWrap())->getPaint() !=
|
||||||
|
(pixb - rbefore->getWrap())->getPaint())
|
||||||
|
// east
|
||||||
|
|| (j < rin->getLx() - 1 && (pix + 1)->getPaint() == fillIndex &&
|
||||||
|
(pix + 1)->getPaint() != (pixb + 1)->getPaint())
|
||||||
|
// west
|
||||||
|
|| (j > 0 && (pix - 1)->getPaint() == fillIndex &&
|
||||||
|
(pix - 1)->getPaint() != (pixb - 1)->getPaint()))) {
|
||||||
|
finishGapLine(rin, combined, TPoint(j, i) + rect.getP00(),
|
||||||
|
clickedColorStyle, fillIndex, closeColorStyle, 0, &rect,
|
||||||
|
closeGaps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// AreaFiller
|
// AreaFiller
|
||||||
|
|
||||||
|
@ -154,10 +324,9 @@ AreaFiller::AreaFiller(const TRasterCM32P &ras)
|
||||||
AreaFiller::~AreaFiller() { m_ras->unlock(); }
|
AreaFiller::~AreaFiller() { m_ras->unlock(); }
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// questa funzione viene chiamata dopo il fill rect delle aree, e colora gli
|
// This function is called after rect fill of the areas, and colors the
|
||||||
// inchiostri di tipo "autoink"
|
// "autoink" type inks bordering the areas just filled with the rect.
|
||||||
// che confinano con le aree appena fillate con il rect. rbefore e' il rect del
|
// rbefore is the rect of the raster before rectfill.
|
||||||
// raster prima del rectfill.
|
|
||||||
void fillautoInks(TRasterCM32P &rin, TRect &rect, const TRasterCM32P &rbefore,
|
void fillautoInks(TRasterCM32P &rin, TRect &rect, const TRasterCM32P &rbefore,
|
||||||
TPalette *plt, int fillIndex) {
|
TPalette *plt, int fillIndex) {
|
||||||
assert(plt);
|
assert(plt);
|
||||||
|
@ -172,9 +341,36 @@ void fillautoInks(TRasterCM32P &rin, TRect &rect, const TRasterCM32P &rbefore,
|
||||||
int paint = pix->getPaint();
|
int paint = pix->getPaint();
|
||||||
int tone = pix->getTone();
|
int tone = pix->getTone();
|
||||||
int ink = pix->getInk();
|
int ink = pix->getInk();
|
||||||
if (paint != pixb->getPaint() && paint == fillIndex && ink != paint &&
|
|
||||||
plt->getStyle(ink)->getFlags() != 0)
|
/* new
|
||||||
inkFill(rin, TPoint(j, i) + rect.getP00(), paint, 0, NULL, &rect);
|
* Pseudocode:
|
||||||
|
* Start the inkFill procedure at the current pixel if:
|
||||||
|
* The ink colorstyle has autopaint enabled
|
||||||
|
* The ink colorstyle is not already the same as the fill colorstyle
|
||||||
|
* The paint colorstyle of a neighboring pixel:
|
||||||
|
* is the same as the fill colorstyle
|
||||||
|
* has changed from its prior version
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (plt->getStyle(ink)->getFlags() != 0 && ink != fillIndex &&
|
||||||
|
(
|
||||||
|
// north
|
||||||
|
(i < r->getLy() - 1 &&
|
||||||
|
(pix + r->getWrap())->getPaint() == fillIndex &&
|
||||||
|
(pix + r->getWrap())->getPaint() !=
|
||||||
|
(pixb + rbefore->getWrap())->getPaint())
|
||||||
|
// south
|
||||||
|
|| (i > 0 && (pix - r->getWrap())->getPaint() == fillIndex &&
|
||||||
|
(pix - r->getWrap())->getPaint() !=
|
||||||
|
(pixb - rbefore->getWrap())->getPaint())
|
||||||
|
// east
|
||||||
|
|| (j < r->getLx() - 1 && (pix + 1)->getPaint() == fillIndex &&
|
||||||
|
(pix + 1)->getPaint() != (pixb + 1)->getPaint())
|
||||||
|
// west
|
||||||
|
|| (j > 0 && (pix - 1)->getPaint() == fillIndex &&
|
||||||
|
(pix - 1)->getPaint() != (pixb - 1)->getPaint()))) {
|
||||||
|
inkFill(rin, TPoint(j, i) + rect.getP00(), fillIndex, 0, NULL, &rect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,19 +380,21 @@ void fillautoInks(TRasterCM32P &rin, TRect &rect, const TRasterCM32P &rbefore,
|
||||||
bool AreaFiller::rectFill(const TRect &rect, int color, bool onlyUnfilled,
|
bool AreaFiller::rectFill(const TRect &rect, int color, bool onlyUnfilled,
|
||||||
bool fillPaints, bool fillInks) {
|
bool fillPaints, bool fillInks) {
|
||||||
// Synopsis:
|
// Synopsis:
|
||||||
// This gets the color of the pixes at the edge of the rect
|
// This gets the color of the pixels at the edge of the rect
|
||||||
// Then fills in EVERYTHING with 'color'
|
// Then fills in EVERYTHING with 'color'
|
||||||
// Then uses the fill command to fill in the edges with their original color
|
// Then uses the fill command to fill in the edges with their original color
|
||||||
// This makes sure only the enclosed areas not on the edge get filled.
|
// This makes sure only the enclosed areas not on the edge get filled.
|
||||||
/*- In case of FillInk only -*/
|
/*- In case of FillInk only -*/
|
||||||
|
|
||||||
if (!fillPaints) {
|
if (!fillPaints) {
|
||||||
assert(fillInks);
|
assert(fillInks);
|
||||||
assert(m_ras->getBounds().contains(rect));
|
assert(m_ras->getBounds().contains(rect));
|
||||||
for (int y = rect.y0; y <= rect.y1; y++) {
|
for (int y = rect.y0; y <= rect.y1; y++) {
|
||||||
TPixelCM32 *pix = m_ras->pixels(y) + rect.x0;
|
TPixelCM32 *pix = m_ras->pixels(y) + rect.x0;
|
||||||
for (int x = rect.x0; x <= rect.x1; x++, pix++) {
|
for (int x = rect.x0; x <= rect.x1; x++, pix++) {
|
||||||
if (pix->getInk() == 4094)
|
if (pix->getInk() == GAP_CLOSE_TEMP)
|
||||||
pix->setInk(4095);
|
//pix->setInk(TEMP_GAP_CLOSE_WAS_USED);
|
||||||
|
continue;
|
||||||
else
|
else
|
||||||
pix->setInk(color);
|
pix->setInk(color);
|
||||||
}
|
}
|
||||||
|
@ -249,18 +447,16 @@ bool AreaFiller::rectFill(const TRect &rect, int color, bool onlyUnfilled,
|
||||||
for (x = r.x0; x <= r.x1; x++, pix++) {
|
for (x = r.x0; x <= r.x1; x++, pix++) {
|
||||||
if (pix->getPaint() == 0) // BackgroundStyle
|
if (pix->getPaint() == 0) // BackgroundStyle
|
||||||
pix->setPaint(color);
|
pix->setPaint(color);
|
||||||
if (fillInks && (pix->getInk() != 4094 && pix->getInk() != 4095))
|
if (fillInks && (pix->getInk() != GAP_CLOSE_TEMP && pix->getInk() != GAP_CLOSE_USED))
|
||||||
pix->setInk(color);
|
pix->setInk(color);
|
||||||
if (pix->getInk() == 4094) pix->setInk(4095);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
for (y = r.y0; y <= r.y1; y++, pix += m_wrap - dx - 1) {
|
for (y = r.y0; y <= r.y1; y++, pix += m_wrap - dx - 1) {
|
||||||
for (x = r.x0; x <= r.x1; x++, pix++) {
|
for (x = r.x0; x <= r.x1; x++, pix++) {
|
||||||
pix->setPaint(color);
|
pix->setPaint(color);
|
||||||
if (fillInks && (pix->getInk() != 4094 && pix->getInk() != 4095))
|
if (fillInks && (pix->getInk() != GAP_CLOSE_TEMP && pix->getInk() != GAP_CLOSE_USED))
|
||||||
pix->setInk(color);
|
pix->setInk(color);
|
||||||
if (pix->getInk() == 4094) pix->setInk(4095);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,14 +519,26 @@ void AreaFiller::strokeFill(TStroke *stroke, int colorId, bool onlyUnfilled,
|
||||||
|
|
||||||
TVectorImage app;
|
TVectorImage app;
|
||||||
app.addStroke(stroke);
|
app.addStroke(stroke);
|
||||||
|
|
||||||
app.findRegions();
|
app.findRegions();
|
||||||
|
|
||||||
|
//std::cout << "\nAreaFiller::strokeFill().fillArea()";
|
||||||
|
|
||||||
for (UINT i = 0; i < app.getRegionCount(); i++)
|
for (UINT i = 0; i < app.getRegionCount(); i++)
|
||||||
fillArea(m_ras, app.getRegion(i), colorId, onlyUnfilled, fillPaints,
|
fillArea(m_ras, app.getRegion(i), colorId, onlyUnfilled, fillPaints,
|
||||||
fillInks);
|
fillInks);
|
||||||
|
|
||||||
|
//std::cout << "\nAreaFiller::strokeFill(), after fillArea()";
|
||||||
|
//outputPixels("tempRaster", m_ras); // issue 1151
|
||||||
|
|
||||||
app.removeStroke(0);
|
app.removeStroke(0);
|
||||||
|
|
||||||
stroke->transform(TTranslation(convert(-m_ras->getCenter())));
|
stroke->transform(TTranslation(convert(-m_ras->getCenter())));
|
||||||
restoreColors(m_ras, seeds);
|
restoreColors(m_ras, seeds);
|
||||||
|
|
||||||
|
//std::cout << "\nAreaFiller::strokeFill(), after restoreColors()";
|
||||||
|
//outputPixels("tempRaster", m_ras); // issue 1151
|
||||||
|
|
||||||
m_ras->unlock();
|
m_ras->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,7 +620,7 @@ void FullColorAreaFiller::rectFill(const TRect &rect,
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// InkSegmenter
|
// InkSegmenter
|
||||||
|
|
||||||
const int damInk = 4094;
|
const int damInk = 4094; //same value as the tempoary gap close lines?
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -57,12 +57,15 @@ void StrokeGenerator::filterPoints() {
|
||||||
|
|
||||||
// filtra m_points iniziali: generalmente elevate variazioni di thickness
|
// filtra m_points iniziali: generalmente elevate variazioni di thickness
|
||||||
// si hanno tra m_points[0] (al massimo m_points[1]) e i successivi)
|
// si hanno tra m_points[0] (al massimo m_points[1]) e i successivi)
|
||||||
|
// filter initial m_points: usually large thickness variations
|
||||||
|
// you have between m_points[0] (at most m_points[1]) and the following ones)
|
||||||
int size1 = m_points.size();
|
int size1 = m_points.size();
|
||||||
int kMin = 0;
|
int kMin = 0;
|
||||||
int kMax = std::min(
|
int kMax = std::min(
|
||||||
4,
|
4,
|
||||||
size1 -
|
size1 -
|
||||||
2); // confronta 5 m_points iniziali con i successivi corrispondenti
|
2); // confronta 5 m_points iniziali con i successivi corrispondenti
|
||||||
|
// compare initial 5 m_points with subsequent matched ones
|
||||||
int k = kMax;
|
int k = kMax;
|
||||||
for (k = kMax; k >= kMin; --k) {
|
for (k = kMax; k >= kMin; --k) {
|
||||||
TThickPoint currPoint = m_points[k];
|
TThickPoint currPoint = m_points[k];
|
||||||
|
@ -72,10 +75,12 @@ void StrokeGenerator::filterPoints() {
|
||||||
if (deltaThick > 0.6 * dist) // deltaThick <= dist (condizione
|
if (deltaThick > 0.6 * dist) // deltaThick <= dist (condizione
|
||||||
// approssimata di non-autocontenimento per
|
// approssimata di non-autocontenimento per
|
||||||
// TTQ)
|
// TTQ)
|
||||||
|
// deltaThick <= dist (approximate non-self-contained condition for TTQ)
|
||||||
{
|
{
|
||||||
vector<TThickPoint>::iterator it1 = m_points.begin();
|
vector<TThickPoint>::iterator it1 = m_points.begin();
|
||||||
vector<TThickPoint>::iterator it2 = it1 + k + 1;
|
vector<TThickPoint>::iterator it2 = it1 + k + 1;
|
||||||
m_points.erase(it1, it2); // cancella da m_points[0] a m_points[k]
|
m_points.erase(it1, it2); // cancella da m_points[0] a m_points[k]
|
||||||
|
// delete from m_points[0] to m_points[k]
|
||||||
assert((int)m_points.size() == size1 - k - 1);
|
assert((int)m_points.size() == size1 - k - 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -83,11 +88,15 @@ void StrokeGenerator::filterPoints() {
|
||||||
// filtra m_points finali: generalmente elevate variazioni di thickness
|
// filtra m_points finali: generalmente elevate variazioni di thickness
|
||||||
// si hanno tra m_points[size - 1] (al massimo m_points[size - 2]) e i
|
// si hanno tra m_points[size - 1] (al massimo m_points[size - 2]) e i
|
||||||
// predecessori)
|
// predecessori)
|
||||||
|
// filter final m_points: usually large thickness variations
|
||||||
|
// have between m_points[size - 1] (at most m_points[size - 2]) and i
|
||||||
|
// predecessors)
|
||||||
int size2 = m_points.size();
|
int size2 = m_points.size();
|
||||||
kMax = size2 - 1;
|
kMax = size2 - 1;
|
||||||
kMin = std::max(
|
kMin = std::max(
|
||||||
kMax - 4,
|
kMax - 4,
|
||||||
1); // confronta 5 m_points finali con i predecessori corrispondenti
|
1); // confronta 5 m_points finali con i predecessori corrispondenti
|
||||||
|
// compare final 5 m_points with matching ancestors
|
||||||
k = kMin;
|
k = kMin;
|
||||||
for (k = kMin; k <= kMax; ++k) {
|
for (k = kMin; k <= kMax; ++k) {
|
||||||
TThickPoint currPoint = m_points[k];
|
TThickPoint currPoint = m_points[k];
|
||||||
|
@ -100,6 +109,7 @@ void StrokeGenerator::filterPoints() {
|
||||||
{
|
{
|
||||||
int kTmp = k;
|
int kTmp = k;
|
||||||
while (k <= kMax) // cancella da m_points[k] a m_points[size2 - 1]
|
while (k <= kMax) // cancella da m_points[k] a m_points[size2 - 1]
|
||||||
|
// delete from m_points[k] to m_points[size2 - 1]
|
||||||
{
|
{
|
||||||
m_points.pop_back();
|
m_points.pop_back();
|
||||||
++k;
|
++k;
|
||||||
|
|
Loading…
Reference in a new issue