Merge pull request #2763 from manongjohn/support_mypaintbrush_v2

Support for MyPaint brush format version 2
This commit is contained in:
Rodney 2019-10-05 23:45:05 -05:00 committed by GitHub
commit 4aee5c0dd7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -13,13 +13,15 @@
#include "toonz/mypaintbrushstyle.h"
#include <QDebug>
#include <sstream>
//*************************************************************************************
// TMyPaintBrushStyle implementation
//*************************************************************************************
TMyPaintBrushStyle::TMyPaintBrushStyle()
{ }
TMyPaintBrushStyle::TMyPaintBrushStyle() {}
//-----------------------------------------------------------------------------
@ -29,28 +31,25 @@ TMyPaintBrushStyle::TMyPaintBrushStyle(const TFilePath &path) {
//-----------------------------------------------------------------------------
TMyPaintBrushStyle::TMyPaintBrushStyle(const TMyPaintBrushStyle &other):
TColorStyle(other),
m_path (other.m_path),
m_fullpath (other.m_fullpath),
m_brushOriginal (other.m_brushOriginal),
m_brushModified (other.m_brushModified),
m_preview (other.m_preview),
m_color (other.m_color),
m_baseValues (other.m_baseValues)
{ }
TMyPaintBrushStyle::TMyPaintBrushStyle(const TMyPaintBrushStyle &other)
: TColorStyle(other)
, m_path(other.m_path)
, m_fullpath(other.m_fullpath)
, m_brushOriginal(other.m_brushOriginal)
, m_brushModified(other.m_brushModified)
, m_preview(other.m_preview)
, m_color(other.m_color)
, m_baseValues(other.m_baseValues) {}
//-----------------------------------------------------------------------------
TMyPaintBrushStyle::~TMyPaintBrushStyle()
{ }
TMyPaintBrushStyle::~TMyPaintBrushStyle() {}
//-----------------------------------------------------------------------------
TColorStyle& TMyPaintBrushStyle::copy(const TColorStyle &other) {
TColorStyle &TMyPaintBrushStyle::copy(const TColorStyle &other) {
const TMyPaintBrushStyle *otherBrushStyle =
dynamic_cast<const TMyPaintBrushStyle*>(&other);
dynamic_cast<const TMyPaintBrushStyle *>(&other);
if (otherBrushStyle) {
m_path = otherBrushStyle->m_path;
m_fullpath = otherBrushStyle->m_fullpath;
@ -65,21 +64,23 @@ TColorStyle& TMyPaintBrushStyle::copy(const TColorStyle &other) {
//-----------------------------------------------------------------------------
QString TMyPaintBrushStyle::getDescription() const
{ return "MyPaintBrushStyle"; }
QString TMyPaintBrushStyle::getDescription() const {
return "MyPaintBrushStyle";
}
//-----------------------------------------------------------------------------
std::string TMyPaintBrushStyle::getBrushType()
{ return "myb"; }
std::string TMyPaintBrushStyle::getBrushType() { return "myb"; }
//-----------------------------------------------------------------------------
TFilePathSet TMyPaintBrushStyle::getBrushesDirs() {
TFilePathSet paths;
paths.push_back(m_libraryDir + "mypaint brushes");
QStringList genericLocations = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
for(QStringList::iterator i = genericLocations.begin(); i != genericLocations.end(); ++i)
QStringList genericLocations =
QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
for (QStringList::iterator i = genericLocations.begin();
i != genericLocations.end(); ++i)
paths.push_back(TFilePath(*i) + "mypaint" + "brushes");
return paths;
}
@ -87,48 +88,137 @@ TFilePathSet TMyPaintBrushStyle::getBrushesDirs() {
//-----------------------------------------------------------------------------
TFilePath TMyPaintBrushStyle::decodePath(const TFilePath &path) const {
if (path.isAbsolute())
return path;
if (path.isAbsolute()) return path;
if (m_currentScene) {
TFilePath p = m_currentScene->decodeFilePath(path);
TFileStatus fs(p);
if (fs.doesExist() && !fs.isDirectory())
return p;
if (fs.doesExist() && !fs.isDirectory()) return p;
}
TFilePathSet paths = getBrushesDirs();
for(TFilePathSet::iterator i = paths.begin(); i != paths.end(); ++i) {
for (TFilePathSet::iterator i = paths.begin(); i != paths.end(); ++i) {
TFilePath p = *i + path;
TFileStatus fs(p);
if (fs.doesExist() && !fs.isDirectory())
return p;
if (fs.doesExist() && !fs.isDirectory()) return p;
}
return path;
}
//-----------------------------------------------------------------------------
std::string mybToVersion3(std::string origStr) {
std::string outStr = "";
std::string comment = "";
bool settingsStarted = false;
std::stringstream strstream(origStr);
outStr += "{\n";
for (std::string line; std::getline(strstream, line);) {
std::replace(line.begin(), line.end(), '\r', ' ');
if (line.find("version 2") != std::string::npos)
continue; // Ignore version. We'll add version back later as version 3
if (line[0] == '#') {
comment = comment + line;
continue;
}
if (!settingsStarted) {
settingsStarted = true;
outStr += " \"comment\": \"" + comment + "\",\n";
outStr += " \"group\": \"\",\n";
outStr += " \"parent_brush_name\": \"\",\n";
outStr += " \"settings\": {\n";
} else
outStr += ",\n";
int startPos = 0;
int pipe = line.find("|");
std::string settingInfo = line.substr(startPos, pipe);
std::string setting = settingInfo.substr(startPos, line.find(" "));
std::string baseValue =
settingInfo.substr(setting.length(), settingInfo.find_last_not_of(" "));
outStr += " \"" + setting + "\": {\n";
outStr += " \"base_value\": " + baseValue + ",\n";
if (pipe == std::string::npos)
outStr += " \"inputs\": {}";
else {
outStr += " \"inputs\": {\n";
while (pipe != line.length()) {
if (startPos > 0) outStr += ",\n";
startPos = pipe + 1;
pipe = line.find("|", startPos);
if (pipe == std::string::npos) pipe = line.length();
settingInfo = line.substr(startPos, pipe - startPos);
int firstCharPos = settingInfo.find_first_not_of(" ");
setting = settingInfo.substr(firstCharPos,
settingInfo.find(" ", firstCharPos) - 1);
outStr += " \"" + setting + "\": [\n";
firstCharPos = settingInfo.find_first_not_of(" ", setting.length() + 1);
baseValue = settingInfo.substr(firstCharPos, pipe - startPos);
int comma = baseValue.find(", ");
if (comma == std::string::npos) comma = baseValue.length();
std::string value = baseValue.substr(0, comma);
std::replace(value.begin(), value.end(), '(', '[');
std::replace(value.begin(), value.end(), ')', ']');
std::replace(value.begin(), value.end(), ' ', ',');
outStr += " " + value;
int prevComma;
while (comma != baseValue.length()) {
outStr += ",\n";
prevComma = comma + 2;
comma = baseValue.find(", ", prevComma);
if (comma == std::string::npos) comma = baseValue.length();
value = baseValue.substr(prevComma, comma - prevComma);
std::replace(value.begin(), value.end(), '(', '[');
std::replace(value.begin(), value.end(), ')', ']');
std::replace(value.begin(), value.end(), ' ', ',');
outStr += " " + value;
}
outStr += "\n ]"; // Ends Input setting
}
outStr += "\n }"; // End Inputs
}
outStr += "\n }"; // End Setting
}
outStr += "\n";
if (settingsStarted) {
outStr += " },\n"; // End Settings
outStr += " \"version\": 3\n";
}
outStr += "}"; // Ends file
return outStr;
}
void TMyPaintBrushStyle::loadBrush(const TFilePath &path) {
m_path = path;
m_path = path;
m_fullpath = decodePath(path);
m_brushOriginal.fromDefaults();
Tifstream is(m_fullpath);
if (is) {
std::string str;
str.assign( std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>() );
str.assign(std::istreambuf_iterator<char>(is),
std::istreambuf_iterator<char>());
if (str.find("version 2") != std::string::npos) str = mybToVersion3(str);
m_brushOriginal.fromString(str);
}
m_brushModified = m_brushOriginal;
std::map<MyPaintBrushSetting, float> baseValuesCopy;
baseValuesCopy.swap(m_baseValues);
for(std::map<MyPaintBrushSetting, float>::const_iterator i = baseValuesCopy.begin(); i != baseValuesCopy.end(); ++i)
for (std::map<MyPaintBrushSetting, float>::const_iterator i =
baseValuesCopy.begin();
i != baseValuesCopy.end(); ++i)
setBaseValue(i->first, i->second);
TFilePath preview_path = m_fullpath.getParentDir() + (m_fullpath.getWideName() + L"_prev.png");
TFilePath preview_path =
m_fullpath.getParentDir() + (m_fullpath.getWideName() + L"_prev.png");
TImageReader::load(preview_path, m_preview);
invalidateIcon();
@ -136,7 +226,8 @@ void TMyPaintBrushStyle::loadBrush(const TFilePath &path) {
//-----------------------------------------------------------------------------
void TMyPaintBrushStyle::setBaseValue(MyPaintBrushSetting id, bool enable, float value) {
void TMyPaintBrushStyle::setBaseValue(MyPaintBrushSetting id, bool enable,
float value) {
float def = m_brushOriginal.getBaseValue(id);
if (enable && fabsf(value - def) > 0.01) {
m_baseValues[id] = value;
@ -150,38 +241,37 @@ void TMyPaintBrushStyle::setBaseValue(MyPaintBrushSetting id, bool enable, float
//-----------------------------------------------------------------------------
void TMyPaintBrushStyle::resetBaseValues() {
for(int i = 0; i < MYPAINT_BRUSH_SETTINGS_COUNT; ++i)
for (int i = 0; i < MYPAINT_BRUSH_SETTINGS_COUNT; ++i)
setBaseValueEnabled((MyPaintBrushSetting)i, false);
}
//-----------------------------------------------------------------------------
void TMyPaintBrushStyle::makeIcon(const TDimension &d) {
TFilePath path = m_fullpath.getParentDir() + (m_fullpath.getWideName() + L"_prev.png");
TFilePath path =
m_fullpath.getParentDir() + (m_fullpath.getWideName() + L"_prev.png");
if (!m_preview) {
m_icon = TRaster32P(d);
m_icon->fill(TPixel32::Red);
} else
if (m_preview->getSize() == d) {
} else if (m_preview->getSize() == d) {
m_icon = m_preview;
} else {
m_icon = TRaster32P(d);
double sx = (double)d.lx/(double)m_preview->getLx();
double sy = (double)d.ly/(double)m_preview->getLy();
m_icon = TRaster32P(d);
double sx = (double)d.lx / (double)m_preview->getLx();
double sy = (double)d.ly / (double)m_preview->getLy();
TRop::resample(m_icon, m_preview, TScale(sx, sy));
}
// paint color marker
if (d.lx > 0 && d.ly > 0) {
int size = std::min( 1 + std::min(d.lx, d.ly)*2/3,
1 + std::max(d.lx, d.ly)/2 );
int size = std::min(1 + std::min(d.lx, d.ly) * 2 / 3,
1 + std::max(d.lx, d.ly) / 2);
TPixel32 color = getMainColor();
for(int y = 0; y < size; ++y) {
TPixel32 *p = m_icon->pixels(d.ly - y - 1);
TPixel32 *endp = p + size - y - 1;
for( ;p != endp; ++p)
*p = color;
*p = blend(*p, color, 0.5);
for (int y = 0; y < size; ++y) {
TPixel32 *p = m_icon->pixels(d.ly - y - 1);
TPixel32 *endp = p + size - y - 1;
for (; p != endp; ++p) *p = color;
*p = blend(*p, color, 0.5);
}
}
}
@ -196,9 +286,9 @@ void TMyPaintBrushStyle::loadData(TInputStreamInterface &is) {
int baseSettingsCount = 0;
is >> baseSettingsCount;
for(int i = 0; i < baseSettingsCount; ++i) {
for (int i = 0; i < baseSettingsCount; ++i) {
std::string key;
double value = 0.0;
double value = 0.0;
int inputsCount = 0;
is >> key;
is >> value;
@ -217,7 +307,9 @@ void TMyPaintBrushStyle::saveData(TOutputStreamInterface &os) const {
os << m_color;
os << (int)m_baseValues.size();
for(std::map<MyPaintBrushSetting, float>::const_iterator i = m_baseValues.begin(); i != m_baseValues.end(); ++i) {
for (std::map<MyPaintBrushSetting, float>::const_iterator i =
m_baseValues.begin();
i != m_baseValues.end(); ++i) {
os << mypaint::Setting::byId(i->first).key;
os << (double)i->second;
}
@ -225,54 +317,63 @@ void TMyPaintBrushStyle::saveData(TOutputStreamInterface &os) const {
//-----------------------------------------------------------------------------
int TMyPaintBrushStyle::getParamCount() const
{ return MYPAINT_BRUSH_SETTINGS_COUNT; }
int TMyPaintBrushStyle::getParamCount() const {
return MYPAINT_BRUSH_SETTINGS_COUNT;
}
//-----------------------------------------------------------------------------
QString TMyPaintBrushStyle::getParamNames(int index) const
{ return QString::fromUtf8(mypaint::Setting::byId((MyPaintBrushSetting)index).name.c_str()); }
QString TMyPaintBrushStyle::getParamNames(int index) const {
return QString::fromUtf8(
mypaint::Setting::byId((MyPaintBrushSetting)index).name.c_str());
}
//-----------------------------------------------------------------------------
TColorStyle::ParamType TMyPaintBrushStyle::getParamType(int index) const
{ return DOUBLE; }
TColorStyle::ParamType TMyPaintBrushStyle::getParamType(int index) const {
return DOUBLE;
}
//-----------------------------------------------------------------------------
bool TMyPaintBrushStyle::hasParamDefault(int index) const
{ return true; }
bool TMyPaintBrushStyle::hasParamDefault(int index) const { return true; }
//-----------------------------------------------------------------------------
void TMyPaintBrushStyle::setParamDefault(int index)
{ setBaseValueEnabled((MyPaintBrushSetting)index, false); }
void TMyPaintBrushStyle::setParamDefault(int index) {
setBaseValueEnabled((MyPaintBrushSetting)index, false);
}
//-----------------------------------------------------------------------------
bool TMyPaintBrushStyle::isParamDefault(int index) const
{ return getBaseValueEnabled((MyPaintBrushSetting)index); }
bool TMyPaintBrushStyle::isParamDefault(int index) const {
return getBaseValueEnabled((MyPaintBrushSetting)index);
}
//-----------------------------------------------------------------------------
void TMyPaintBrushStyle::getParamRange(int index, double &min, double &max) const {
const mypaint::Setting &setting = mypaint::Setting::byId((MyPaintBrushSetting)index);
void TMyPaintBrushStyle::getParamRange(int index, double &min,
double &max) const {
const mypaint::Setting &setting =
mypaint::Setting::byId((MyPaintBrushSetting)index);
min = setting.min;
max = setting.max;
}
//-----------------------------------------------------------------------------
void TMyPaintBrushStyle::setParamValue(int index, double value)
{ setBaseValue((MyPaintBrushSetting)index, value); }
void TMyPaintBrushStyle::setParamValue(int index, double value) {
setBaseValue((MyPaintBrushSetting)index, value);
}
//-----------------------------------------------------------------------------
double TMyPaintBrushStyle::getParamValue(double_tag, int index) const
{ return getBaseValue((MyPaintBrushSetting)index); }
double TMyPaintBrushStyle::getParamValue(double_tag, int index) const {
return getBaseValue((MyPaintBrushSetting)index);
}
//-----------------------------------------------------------------------------
namespace {
TColorStyle::Declaration mypaintBrushStyle(new TMyPaintBrushStyle());
TColorStyle::Declaration mypaintBrushStyle(new TMyPaintBrushStyle());
}