added stroke stabilizer for toonz raster level.

This commit is contained in:
walkerka 2016-06-11 18:16:00 +08:00
parent 2e244a2acf
commit 611fd32a6f

View file

@ -753,6 +753,7 @@ BrushTool::BrushTool(std::string name, int targetType)
if (targetType & TTool::ToonzImage) { if (targetType & TTool::ToonzImage) {
m_prop[0].bind(m_rasThickness); m_prop[0].bind(m_rasThickness);
m_prop[0].bind(m_smooth);
m_prop[0].bind(m_hardness); m_prop[0].bind(m_hardness);
m_prop[0].bind(m_selective); m_prop[0].bind(m_selective);
m_prop[0].bind(m_pencil); m_prop[0].bind(m_pencil);
@ -1058,12 +1059,18 @@ void BrushTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e)
/*-- Pencilモードでなく、Hardness=100 の場合のブラシサイズを1段階下げる --*/ /*-- Pencilモードでなく、Hardness=100 の場合のブラシサイズを1段階下げる --*/
if (!m_pencil.getValue()) if (!m_pencil.getValue())
thickness -= 1.0; thickness -= 1.0;
TThickPoint thickPoint(pos + convert(ras->getCenter()), thickness);
m_rasterTrack = new RasterStrokeGenerator(ras, BRUSH, NONE, m_styleId, m_rasterTrack = new RasterStrokeGenerator(ras, BRUSH, NONE, m_styleId,
TThickPoint(pos + convert(ras->getCenter()), thickness), thickPoint,
m_selective.getValue(), 0, !m_pencil.getValue()); m_selective.getValue(), 0, !m_pencil.getValue());
m_tileSaver->save(m_rasterTrack->getLastRect()); m_tileSaver->save(m_rasterTrack->getLastRect());
m_rasterTrack->generateLastPieceOfStroke(m_pencil.getValue()); m_rasterTrack->generateLastPieceOfStroke(m_pencil.getValue());
m_smoothStroke.beginStroke(m_smooth.getValue());
m_smoothStroke.addPoint(thickPoint);
std::vector<TThickPoint> pts;
m_smoothStroke.getSmoothPoints(pts);// skip first point because it has been outputted
} else { } else {
m_points.clear(); m_points.clear();
TThickPoint point(pos + rasCenter, thickness); TThickPoint point(pos + rasCenter, thickness);
@ -1076,6 +1083,11 @@ void BrushTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e)
m_bluredBrush->addPoint(point, 1); m_bluredBrush->addPoint(point, 1);
m_bluredBrush->updateDrawing(ri->getRaster(), m_backupRas, m_strokeRect, m_styleId, m_selective.getValue()); m_bluredBrush->updateDrawing(ri->getRaster(), m_backupRas, m_strokeRect, m_styleId, m_selective.getValue());
m_lastRect = m_strokeRect; m_lastRect = m_strokeRect;
m_smoothStroke.beginStroke(m_smooth.getValue());
m_smoothStroke.addPoint(point);
std::vector<TThickPoint> pts;
m_smoothStroke.getSmoothPoints(pts);// skip first point because it has been outputted
} }
/*-- 作業中のFidを登録 --*/ /*-- 作業中のFidを登録 --*/
m_workingFrameId = getFrameId(); m_workingFrameId = getFrameId();
@ -1115,63 +1127,96 @@ void BrushTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e)
/*-- Pencilモードでなく、Hardness=100 の場合のブラシサイズを1段階下げる --*/ /*-- Pencilモードでなく、Hardness=100 の場合のブラシサイズを1段階下げる --*/
if (!m_pencil.getValue()) if (!m_pencil.getValue())
thickness -= 1.0; thickness -= 1.0;
isAdded = m_rasterTrack->add(TThickPoint(pos + rasCenter, thickness)); TThickPoint thickPoint(pos + rasCenter, thickness);
if (isAdded) { m_smoothStroke.addPoint(thickPoint);
m_tileSaver->save(m_rasterTrack->getLastRect()); std::vector<TThickPoint> pts;
m_rasterTrack->generateLastPieceOfStroke(m_pencil.getValue()); m_smoothStroke.getSmoothPoints(pts);
std::vector<TThickPoint> brushPoints = m_rasterTrack->getPointsSequence(); for (size_t i = 0; i < pts.size(); ++i)
int m = (int)brushPoints.size(); {
std::vector<TThickPoint> points; const TThickPoint& thickPoint = pts[i];
if (m == 3) { isAdded = m_rasterTrack->add(thickPoint);
points.push_back(brushPoints[0]); if (isAdded) {
points.push_back(brushPoints[1]); m_tileSaver->save(m_rasterTrack->getLastRect());
} else { m_rasterTrack->generateLastPieceOfStroke(m_pencil.getValue());
points.push_back(brushPoints[m - 4]); std::vector<TThickPoint> brushPoints = m_rasterTrack->getPointsSequence();
points.push_back(brushPoints[m - 3]); int m = (int)brushPoints.size();
points.push_back(brushPoints[m - 2]); std::vector<TThickPoint> points;
} if (m == 3) {
invalidateRect = ToolUtils::getBounds(points, maxThickness) - rasCenter; points.push_back(brushPoints[0]);
} points.push_back(brushPoints[1]);
}
else {
points.push_back(brushPoints[m - 4]);
points.push_back(brushPoints[m - 3]);
points.push_back(brushPoints[m - 2]);
}
if (i == 0)
{
invalidateRect = ToolUtils::getBounds(points, maxThickness) - rasCenter;
}
else
{
invalidateRect += ToolUtils::getBounds(points, maxThickness) - rasCenter;
}
}
}
} else { } else {
//antialiased brush //antialiased brush
assert(m_workRas.getPointer() && m_backupRas.getPointer()); assert(m_workRas.getPointer() && m_backupRas.getPointer());
TThickPoint thickPoint(pos + rasCenter, thickness);
m_smoothStroke.addPoint(thickPoint);
std::vector<TThickPoint> pts;
m_smoothStroke.getSmoothPoints(pts);
bool rectUpdated = false;
for (size_t i = 0; i < pts.size(); ++i)
{
TThickPoint old = m_points.back();
if (norm2(pos - old) < 4)
continue;
TThickPoint old = m_points.back(); const TThickPoint& point = pts[i];
if (norm2(pos - old) < 4) TThickPoint mid((old + point) * 0.5, (point.thick + old.thick) * 0.5);
return; m_points.push_back(mid);
m_points.push_back(point);
TThickPoint point(pos + rasCenter, thickness); TRect bbox;
TThickPoint mid((old + point) * 0.5, (point.thick + old.thick) * 0.5); int m = (int)m_points.size();
m_points.push_back(mid); std::vector<TThickPoint> points;
m_points.push_back(point); if (m == 3) {
// ho appena cominciato. devo disegnare un segmento
TRect bbox; TThickPoint pa = m_points.front();
int m = (int)m_points.size(); points.push_back(pa);
std::vector<TThickPoint> points; points.push_back(mid);
if (m == 3) { bbox = m_bluredBrush->getBoundFromPoints(points);
// ho appena cominciato. devo disegnare un segmento updateWorkAndBackupRasters(bbox + m_lastRect);
TThickPoint pa = m_points.front(); m_tileSaver->save(bbox);
points.push_back(pa); m_bluredBrush->addArc(pa, (mid + pa) * 0.5, mid, 1, 1);
points.push_back(mid); m_lastRect += bbox;
bbox = m_bluredBrush->getBoundFromPoints(points); }
updateWorkAndBackupRasters(bbox + m_lastRect); else {
m_tileSaver->save(bbox); points.push_back(m_points[m - 4]);
m_bluredBrush->addArc(pa, (mid + pa) * 0.5, mid, 1, 1); points.push_back(old);
m_lastRect += bbox; points.push_back(mid);
} else { bbox = m_bluredBrush->getBoundFromPoints(points);
points.push_back(m_points[m - 4]); updateWorkAndBackupRasters(bbox + m_lastRect);
points.push_back(old); m_tileSaver->save(bbox);
points.push_back(mid); m_bluredBrush->addArc(m_points[m - 4], old, mid, 1, 1);
bbox = m_bluredBrush->getBoundFromPoints(points); m_lastRect += bbox;
updateWorkAndBackupRasters(bbox + m_lastRect); }
m_tileSaver->save(bbox); if (!rectUpdated)
m_bluredBrush->addArc(m_points[m - 4], old, mid, 1, 1); {
m_lastRect += bbox; invalidateRect = ToolUtils::getBounds(points, maxThickness) - rasCenter;
} rectUpdated = true;
invalidateRect = ToolUtils::getBounds(points, maxThickness) - rasCenter; }
m_bluredBrush->updateDrawing(ti->getRaster(), m_backupRas, bbox, m_styleId, m_selective.getValue()); else
m_strokeRect += bbox; {
invalidateRect += ToolUtils::getBounds(points, maxThickness) - rasCenter;
}
m_bluredBrush->updateDrawing(ti->getRaster(), m_backupRas, bbox, m_styleId, m_selective.getValue());
m_strokeRect += bbox;
}
} }
invalidate(invalidateRect.enlarge(2)); invalidate(invalidateRect.enlarge(2));
} else { } else {
@ -1190,12 +1235,10 @@ void BrushTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e)
if (!isValid) if (!isValid)
return; return;
flushTrackPoint();
if (m_isPath) { if (m_isPath) {
double error = 20.0 * getPixelSize(); double error = 20.0 * getPixelSize();
flushTrackPoint();
TStroke *stroke = m_track.makeStroke(error); TStroke *stroke = m_track.makeStroke(error);
int points = stroke->getControlPointCount(); int points = stroke->getControlPointCount();
@ -1243,6 +1286,7 @@ void BrushTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e)
double error = 30.0 / (1 + 0.5 * m_accuracy.getValue()); double error = 30.0 / (1 + 0.5 * m_accuracy.getValue());
error *= getPixelSize(); error *= getPixelSize();
flushTrackPoint();
TStroke *stroke = m_track.makeStroke(error); TStroke *stroke = m_track.makeStroke(error);
stroke->setStyle(m_styleId); stroke->setStyle(m_styleId);
{ {
@ -1322,26 +1366,45 @@ void BrushTool::finishRasterBrush(const TPointD &pos, int pressureVal)
/*-- Pencilモードでなく、Hardness=100 の場合のブラシサイズを1段階下げる --*/ /*-- Pencilモードでなく、Hardness=100 の場合のブラシサイズを1段階下げる --*/
if (!m_pencil.getValue()) if (!m_pencil.getValue())
thickness -= 1.0; thickness -= 1.0;
TRectD invalidateRect;
TThickPoint thickPoint(pos + rasCenter, thickness);
m_smoothStroke.addPoint(thickPoint);
m_smoothStroke.endStroke();
std::vector<TThickPoint> pts;
m_smoothStroke.getSmoothPoints(pts);
for (size_t i = 0; i < pts.size(); ++i)
{
const TThickPoint& thickPoint = pts[i];
bool isAdded = m_rasterTrack->add(thickPoint);
if (isAdded) {
m_tileSaver->save(m_rasterTrack->getLastRect());
m_rasterTrack->generateLastPieceOfStroke(m_pencil.getValue(), true);
bool isAdded = m_rasterTrack->add(TThickPoint(pos + convert(ti->getRaster()->getCenter()), thickness)); std::vector<TThickPoint> brushPoints = m_rasterTrack->getPointsSequence();
if (isAdded) { int m = (int)brushPoints.size();
m_tileSaver->save(m_rasterTrack->getLastRect()); std::vector<TThickPoint> points;
m_rasterTrack->generateLastPieceOfStroke(m_pencil.getValue(), true); if (m == 3) {
points.push_back(brushPoints[0]);
std::vector<TThickPoint> brushPoints = m_rasterTrack->getPointsSequence(); points.push_back(brushPoints[1]);
int m = (int)brushPoints.size(); }
std::vector<TThickPoint> points; else {
if (m == 3) { points.push_back(brushPoints[m - 4]);
points.push_back(brushPoints[0]); points.push_back(brushPoints[m - 3]);
points.push_back(brushPoints[1]); points.push_back(brushPoints[m - 2]);
} else { }
points.push_back(brushPoints[m - 4]); int maxThickness = m_rasThickness.getValue().second;
points.push_back(brushPoints[m - 3]); if (i == 0)
points.push_back(brushPoints[m - 2]); {
} invalidateRect = ToolUtils::getBounds(points, maxThickness) - rasCenter;
int maxThickness = m_rasThickness.getValue().second; }
invalidate(ToolUtils::getBounds(points, maxThickness).enlarge(2) - rasCenter); else
} {
invalidateRect += ToolUtils::getBounds(points, maxThickness) - rasCenter;
}
}
}
invalidate(invalidateRect.enlarge(2));
if (m_tileSet->getTileCount() > 0) { if (m_tileSet->getTileCount() > 0) {
TUndoManager::manager()->add(new RasterBrushUndo(m_tileSet, TUndoManager::manager()->add(new RasterBrushUndo(m_tileSet,
@ -1361,21 +1424,88 @@ void BrushTool::finishRasterBrush(const TPointD &pos, int pressureVal)
double thickness = (m_pressure.getValue() || m_isPath) ? computeThickness(pressureVal, m_rasThickness, m_isPath) double thickness = (m_pressure.getValue() || m_isPath) ? computeThickness(pressureVal, m_rasThickness, m_isPath)
: maxThickness; : maxThickness;
TPointD rasCenter = ti->getRaster()->getCenterD(); TPointD rasCenter = ti->getRaster()->getCenterD();
TThickPoint point(pos + rasCenter, thickness); TRectD invalidateRect;
m_points.push_back(point); bool rectUpdated = false;
int m = m_points.size(); TThickPoint thickPoint(pos + rasCenter, thickness);
std::vector<TThickPoint> points; m_smoothStroke.addPoint(thickPoint);
points.push_back(m_points[m - 3]); m_smoothStroke.endStroke();
points.push_back(m_points[m - 2]); std::vector<TThickPoint> pts;
points.push_back(m_points[m - 1]); m_smoothStroke.getSmoothPoints(pts);
TRect bbox = m_bluredBrush->getBoundFromPoints(points); for (size_t i = 0; i < pts.size() - 1; ++i)
updateWorkAndBackupRasters(bbox); {
m_tileSaver->save(bbox); TThickPoint old = m_points.back();
m_bluredBrush->addArc(points[0], points[1], points[2], 1, 1); if (norm2(pos - old) < 4)
m_bluredBrush->updateDrawing(ti->getRaster(), m_backupRas, bbox, m_styleId, m_selective.getValue()); continue;
TRectD invalidateRect = ToolUtils::getBounds(points, maxThickness);
invalidate(invalidateRect.enlarge(2) - rasCenter); const TThickPoint& point = pts[i];
m_strokeRect += bbox; TThickPoint mid((old + point) * 0.5, (point.thick + old.thick) * 0.5);
m_points.push_back(mid);
m_points.push_back(point);
TRect bbox;
int m = (int)m_points.size();
std::vector<TThickPoint> points;
if (m == 3) {
// ho appena cominciato. devo disegnare un segmento
TThickPoint pa = m_points.front();
points.push_back(pa);
points.push_back(mid);
bbox = m_bluredBrush->getBoundFromPoints(points);
updateWorkAndBackupRasters(bbox + m_lastRect);
m_tileSaver->save(bbox);
m_bluredBrush->addArc(pa, (mid + pa) * 0.5, mid, 1, 1);
m_lastRect += bbox;
}
else {
points.push_back(m_points[m - 4]);
points.push_back(old);
points.push_back(mid);
bbox = m_bluredBrush->getBoundFromPoints(points);
updateWorkAndBackupRasters(bbox + m_lastRect);
m_tileSaver->save(bbox);
m_bluredBrush->addArc(m_points[m - 4], old, mid, 1, 1);
m_lastRect += bbox;
}
if (!rectUpdated)
{
invalidateRect = ToolUtils::getBounds(points, maxThickness) - rasCenter;
rectUpdated = true;
}
else
{
invalidateRect += ToolUtils::getBounds(points, maxThickness) - rasCenter;
}
m_bluredBrush->updateDrawing(ti->getRaster(), m_backupRas, bbox, m_styleId, m_selective.getValue());
m_strokeRect += bbox;
}
if (pts.size() > 0)
{
TThickPoint point = pts.back();
m_points.push_back(point);
int m = m_points.size();
std::vector<TThickPoint> points;
points.push_back(m_points[m - 3]);
points.push_back(m_points[m - 2]);
points.push_back(m_points[m - 1]);
TRect bbox = m_bluredBrush->getBoundFromPoints(points);
updateWorkAndBackupRasters(bbox);
m_tileSaver->save(bbox);
m_bluredBrush->addArc(points[0], points[1], points[2], 1, 1);
m_bluredBrush->updateDrawing(ti->getRaster(), m_backupRas, bbox, m_styleId, m_selective.getValue());
if (!rectUpdated)
{
invalidateRect = ToolUtils::getBounds(points, maxThickness) - rasCenter;
}
else
{
invalidateRect += ToolUtils::getBounds(points, maxThickness) - rasCenter;
}
m_lastRect += bbox;
m_strokeRect += bbox;
}
invalidate(invalidateRect.enlarge(2));
m_lastRect.empty(); m_lastRect.empty();
} }
delete m_bluredBrush; delete m_bluredBrush;
@ -1722,7 +1852,8 @@ void BrushTool::loadPreset()
} else { } else {
m_rasThickness.setValue(TDoublePairProperty::Value(std::max(preset.m_min, 1.0), preset.m_max)); m_rasThickness.setValue(TDoublePairProperty::Value(std::max(preset.m_min, 1.0), preset.m_max));
m_brushPad = ToolUtils::getBrushPad(preset.m_max, preset.m_hardness * 0.01); m_brushPad = ToolUtils::getBrushPad(preset.m_max, preset.m_hardness * 0.01);
m_hardness.setValue(preset.m_hardness, true); m_smooth.setValue(preset.m_smooth, true);
m_hardness.setValue(preset.m_hardness, true);
m_selective.setValue(preset.m_selective); m_selective.setValue(preset.m_selective);
m_pencil.setValue(preset.m_pencil); m_pencil.setValue(preset.m_pencil);
m_pressure.setValue(preset.m_pressure); m_pressure.setValue(preset.m_pressure);