tahoma2d/toonz/sources/toonzlib/cleanupparameters.cpp
Shinya Kitaoka fd19c4eedf Support Visual Studio 2015 (#544)
* Small changes, for some reason VS 2015 can't link cprintf and they added a second function std::map::count and bind couldn't resolve the function. Substituted with a lambda-expression.

* Created all 64bit version of the 3rd party libs.

* Cleanup popup opens CleanupSettings instead of CleanupSettingsPane. Not finished, panel is wrong now (also uses CleanupSettings).

* Tried to get Twain working, failed.

* When there are more then 3 peg holes create additional holes.

* When a hole touches the boundary it should still be considered a hole.

* Do not compare dot size against fixed size. Will not work in some scan resolutions. Used the same value (PERCENT * max dot size) as later in the code in compare_dots.

* When there are more than three peg holes the code looked for the best fit and used that. The problem was, that the middle hole was used as center for auto center. For three peg holes that is correct, but does not work for more than three. Now the best fit is calculated and from there the offset of the middle of the three best fit holes is calculated and applied.

* One of the last changes broke VS2015 compatibility, it chocked on a missing include.

* fix for msvs2013

* revert autopos.cpp

* apply clang-format

* use GIT-LFS
2016-07-04 17:50:30 +09:00

457 lines
15 KiB
C++

#include "toonz/cleanupparameters.h"
#include "tstream.h"
#include "texception.h"
#include "toonz/toonzscene.h"
#include "toonz/sceneproperties.h"
#include "toonz/txshleveltypes.h"
#include "tsystem.h"
#include "tenv.h"
#include "tconvert.h"
#include "cleanuppalette.h"
#include "tpalette.h"
#ifdef _WIN32
#pragma warning(disable : 4996)
#endif
using namespace CleanupTypes;
#define FDG_VERSION_FILE "VERSION_1.0"
CleanupParameters CleanupParameters::GlobalParameters;
CleanupParameters CleanupParameters::LastSavedParameters;
//=========================================================
namespace {
//=========================================================
class FdgManager { // singleton
std::map<std::string, FDG_INFO> m_infos;
void loadFieldGuideInfo();
FdgManager() { loadFieldGuideInfo(); }
public:
static FdgManager *instance() {
static FdgManager _instance;
return &_instance;
}
const FDG_INFO *getFdg(std::string name) const {
std::map<std::string, FDG_INFO>::const_iterator it;
it = m_infos.find(name);
if (it == m_infos.end())
return 0;
else
return &it->second;
}
void getFdgNames(std::vector<std::string> &names) const {
std::map<std::string, FDG_INFO>::const_iterator it;
for (it = m_infos.begin(); it != m_infos.end(); ++it)
names.push_back(it->first);
}
};
//---------------------------------------------------------
#define REMOVE_CR(s) \
{ \
while (*(s) && *(s) != '\n' && *(s) != '\r') (s)++; \
*(s) = '\0'; \
}
#define SKIP_BLANKS(s) \
{ \
while (*(s) && (*(s) == ' ' || *(s) == '\t')) (s)++; \
}
#define STR_EQ(s1, s2) (!strcmp((s1), (s2)))
//---------------------------------------------------------
void FdgManager::loadFieldGuideInfo() {
FILE *fp;
char *s, buffer[256], label[100], arg[100];
int i, version = 0, cnt;
try {
TFilePathSet fps =
TSystem::readDirectory(TEnv::getConfigDir() + "fdg", false);
for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); ++it) {
TFilePath fname = *it;
if (fname.getType() != "fdg") continue;
fp = fopen(::to_string(fname.getWideString()).c_str(), "r");
if (!fp) continue;
FDG_INFO fdg_info;
// memset(&fdg_info,0, sizeof(FDG_INFO));
fdg_info.dots.resize(3);
cnt = 0;
while (fgets(buffer, 256, fp)) {
s = buffer;
if (*s == '#' || *s == '*') continue;
REMOVE_CR(s)
s = buffer;
SKIP_BLANKS(s)
if (!*s) continue;
for (i = 0; *s && *s != ' ' && *s != '\t'; i++, s++) label[i] = *s;
label[i] = '\0';
SKIP_BLANKS(s)
for (i = 0; *s && *s != ' ' && *s != '\t'; i++, s++) arg[i] = *s;
arg[i] = '\0';
/* suppongo ci siano sempre 3 dots */
if (STR_EQ(label, FDG_VERSION_FILE))
version = 1;
else if (STR_EQ(label, "CTRX"))
sscanf(arg, "%lf", &fdg_info.ctr_x), fdg_info.ctr_type = 1;
else if (STR_EQ(label, "CTRY"))
sscanf(arg, "%lf", &fdg_info.ctr_y), fdg_info.ctr_type = 1;
else if (STR_EQ(label, "ANGLE"))
sscanf(arg, "%lf", &fdg_info.ctr_angle), fdg_info.ctr_type = 1;
else if (STR_EQ(label, "SKEW"))
sscanf(arg, "%lf", &fdg_info.ctr_skew), fdg_info.ctr_type = 1;
else if (STR_EQ(label, "HOLE")) {
sscanf(arg, "%d", &cnt);
if (cnt >= (int)fdg_info.dots.size()) {
fdg_info.dots.push_back(CleanupTypes::DOT());
}
} else if (STR_EQ(label, "X0"))
sscanf(arg, "%d", &fdg_info.dots[cnt].x1);
else if (STR_EQ(label, "Y0"))
sscanf(arg, "%d", &fdg_info.dots[cnt].y1);
else if (STR_EQ(label, "X1"))
sscanf(arg, "%d", &fdg_info.dots[cnt].x2);
else if (STR_EQ(label, "Y1"))
sscanf(arg, "%d", &fdg_info.dots[cnt].y2);
else if (STR_EQ(label, "X"))
sscanf(arg, "%f", &fdg_info.dots[cnt].x);
else if (STR_EQ(label, "Y"))
sscanf(arg, "%f", &fdg_info.dots[cnt].y);
else if (STR_EQ(label, "XSIZE"))
sscanf(arg, "%d", &fdg_info.dots[cnt].lx);
else if (STR_EQ(label, "YSIZE"))
sscanf(arg, "%d", &fdg_info.dots[cnt].ly);
else if (STR_EQ(label, "AREA"))
sscanf(arg, "%d", &fdg_info.dots[cnt].area);
else if (STR_EQ(label, "END")) {
} else if (STR_EQ(label, "DIST_CTR_TO_CTR_HOLE"))
sscanf(arg, "%lf", &fdg_info.dist_ctr_to_ctr_hole);
else if (STR_EQ(label, "DIST_CTR_HOLE_TO_EDGE"))
sscanf(arg, "%lf", &fdg_info.dist_ctr_hole_to_edge);
}
fclose(fp);
if (!fdg_info.ctr_type && version != 1) {
// tmsg_error("load field guide info: bad file or old version");
// return FALSE;
} else {
fdg_info.m_name = fname.getName();
m_infos[fdg_info.m_name] = fdg_info;
}
}
} catch (...) {
}
// return TRUE;
}
} // namespace
//=========================================================
CleanupParameters::CleanupParameters()
: m_autocenterType(AUTOCENTER_NONE)
, m_pegSide(PEGS_BOTTOM)
, m_fdgInfo()
, m_rotate(0)
, m_flipx(false)
, m_flipy(false)
, m_offx(0)
, m_offy(0)
//, m_scale(1)
, m_lineProcessingMode(lpGrey)
, m_noAntialias(false)
, m_postAntialias(false)
, m_despeckling(2)
, m_aaValue(70)
, m_closestField(10.)
, m_sharpness(90.)
, m_autoAdjustMode(AUTO_ADJ_NONE)
, m_transparencyCheckEnabled(false)
, m_colors()
, m_path()
, m_cleanupPalette(createStandardCleanupPalette())
, m_camera()
, m_dirtyFlag(false)
//, m_resName("")
, m_offx_lock(false)
, m_offy_lock(false) {}
//---------------------------------------------------------
bool CleanupParameters::setFdgByName(std::string name) {
const FDG_INFO *info = FdgManager::instance()->getFdg(name);
if (info) {
m_fdgInfo = *info;
return true;
} else {
m_fdgInfo = FDG_INFO();
return false;
}
}
//---------------------------------------------------------
void CleanupParameters::getFdgNames(std::vector<std::string> &names) {
FdgManager::instance()->getFdgNames(names);
}
//---------------------------------------------------------
TFilePath CleanupParameters::getPath(ToonzScene *scene) const {
if (m_path == TFilePath()) {
int levelType =
(m_lineProcessingMode != lpNone) ? TZP_XSHLEVEL : OVL_XSHLEVEL;
TFilePath fp = scene->getDefaultLevelPath(levelType);
return fp.getParentDir();
} else
return scene->decodeSavePath(m_path);
}
//---------------------------------------------------------
void CleanupParameters::setPath(ToonzScene *scene, TFilePath fp) {
if (fp == scene->getDefaultLevelPath(TZP_XSHLEVEL).getParentDir())
m_path = TFilePath();
else
m_path = scene->codeSavePath(fp);
}
//------------------------------------------------------------------------------
void CleanupParameters::getOutputImageInfo(TDimension &outDim, double &outDpiX,
double &outDpiY) const {
double lq_nozoom, lp_nozoom;
double zoom_factor;
// Retrieve camera infos
const TDimensionD &cameraSize = m_camera.getSize();
const TDimension &cameraRes = m_camera.getRes();
// Camera resolution
lp_nozoom = cameraRes.lx;
lq_nozoom = cameraRes.ly;
// Zoom factor due to the 'closest field' parameter
if (m_closestField < cameraSize.lx)
zoom_factor = cameraSize.lx / m_closestField;
else
zoom_factor = 1.0;
// Output image resolution (considering the closest field)
// apart from any rotation (eg m_parameters.m_rotate == 90 or 270)
outDim.lx = troundp(zoom_factor * lp_nozoom);
outDim.ly = troundp(zoom_factor * lq_nozoom);
// output image dpi
outDpiX = zoom_factor * cameraRes.lx / cameraSize.lx;
outDpiY = zoom_factor * cameraRes.ly / cameraSize.ly;
}
//------------------------------------------------------------------------------------
void CleanupParameters::assign(const CleanupParameters *param,
bool clonePalette) {
// m_resName = param->m_resName;
m_camera = param->m_camera;
m_autocenterType = param->m_autocenterType;
m_pegSide = param->m_pegSide;
m_fdgInfo = param->m_fdgInfo;
m_rotate = param->m_rotate;
m_flipx = param->m_flipx;
m_flipy = param->m_flipy;
// m_scale = param->m_scale;
m_offx = param->m_offx;
m_offy = param->m_offy;
m_closestField = param->m_closestField;
m_autoAdjustMode = param->m_autoAdjustMode;
m_sharpness = param->m_sharpness;
m_path = param->m_path;
m_colors = param->m_colors;
m_dirtyFlag = param->m_dirtyFlag;
m_transparencyCheckEnabled = param->m_transparencyCheckEnabled;
m_lineProcessingMode = param->m_lineProcessingMode;
m_noAntialias = param->m_noAntialias;
m_postAntialias = param->m_postAntialias;
m_despeckling = param->m_despeckling;
m_aaValue = param->m_aaValue;
// In modern Toonz scenes, there always is a cleanup palette.
// In older Toonz scenes, it may be missing. In this case, leave the current
// one.
if (clonePalette && param->m_cleanupPalette)
m_cleanupPalette = param->m_cleanupPalette->clone();
m_offx_lock = param->m_offx_lock;
m_offy_lock = param->m_offy_lock;
}
//---------------------------------------------------------
void CleanupParameters::saveData(TOStream &os) const {
CleanupParameters::LastSavedParameters.assign(this);
os.openChild("cleanupCamera");
m_camera.saveData(os);
os.closeChild();
os.openChild("cleanupPalette");
m_cleanupPalette->saveData(os);
os.closeChild();
std::map<std::string, std::string> attr;
if (m_autocenterType != AUTOCENTER_NONE) {
attr.clear();
attr["type"] = std::to_string(m_autocenterType);
attr["pegHoles"] = std::to_string(m_pegSide);
os.openCloseChild("autoCenter", attr);
}
if (m_flipx || m_flipy || m_rotate != 0 //|| m_scale!=1
|| m_offx != 0 || m_offy != 0) {
attr.clear();
std::string flip =
std::string(m_flipx ? "x" : "") + std::string(m_flipy ? "y" : "");
if (flip != "") attr["flip"] = flip;
if (m_rotate != 0) attr["rotate"] = std::to_string(m_rotate);
if (m_offx != 0.0) attr["xoff"] = std::to_string(m_offx);
if (m_offy != 0.0) attr["yoff"] = std::to_string(m_offy);
os.openCloseChild("transform", attr);
}
if (m_lineProcessingMode != lpNone) {
attr.clear();
attr["sharpness"] = std::to_string(m_sharpness);
attr["autoAdjust"] = std::to_string(m_autoAdjustMode);
attr["mode"] = (m_lineProcessingMode == lpGrey ? "grey" : "color");
os.openCloseChild("lineProcessing", attr);
}
if (m_noAntialias) {
attr.clear();
os.openCloseChild("noAntialias", attr);
}
if (m_postAntialias) {
attr.clear();
os.openCloseChild("MLAA", attr);
}
attr.clear();
attr["value"] = std::to_string(m_despeckling);
os.openCloseChild("despeckling", attr);
attr.clear();
attr["value"] = std::to_string(m_aaValue);
os.openCloseChild("aaValue", attr);
attr.clear();
attr["value"] = std::to_string(m_closestField);
os.openCloseChild("closestField", attr);
attr.clear();
attr["name"] = m_fdgInfo.m_name;
os.openCloseChild("fdg", attr);
attr.clear();
if (m_path != TFilePath()) os.child("path") << m_path;
}
//---------------------------------------------------------
void CleanupParameters::loadData(TIStream &is, bool globalParams) {
if (globalParams) {
CleanupParameters cp;
assign(&cp);
}
std::string tagName;
m_lineProcessingMode = lpNone;
m_noAntialias = false;
m_postAntialias = false;
while (is.matchTag(tagName)) {
if (tagName == "cleanupPalette") {
m_cleanupPalette->loadData(is);
m_cleanupPalette->setIsCleanupPalette(true);
is.closeChild();
} else if (tagName == "cleanupCamera") {
m_camera.loadData(is);
is.closeChild();
} else if (tagName == "autoCenter") {
m_autocenterType = AUTOCENTER_FDG;
std::string s = is.getTagAttribute("type");
if (s != "" && isInt(s)) m_autocenterType = (AUTOCENTER_TYPE)std::stoi(s);
s = is.getTagAttribute("pegHoles");
if (s != "" && isInt(s)) m_pegSide = (PEGS_SIDE)std::stoi(s);
} else if (tagName == "transform") {
std::string s = is.getTagAttribute("flip");
m_flipx = (s.find("x") != std::string::npos);
m_flipy = (s.find("y") != std::string::npos);
s = is.getTagAttribute("rotate");
if (s != "" && isInt(s)) m_rotate = std::stoi(s);
s = is.getTagAttribute("xoff");
if (s != "" && isDouble(s)) m_offx = std::stod(s);
s = is.getTagAttribute("yoff");
if (s != "" && isDouble(s)) m_offy = std::stod(s);
} else if (tagName == "lineProcessing") {
m_lineProcessingMode = lpGrey;
std::string s = is.getTagAttribute("sharpness");
if (s != "" && isDouble(s)) m_sharpness = std::stod(s);
s = is.getTagAttribute("autoAdjust");
if (s != "" && isDouble(s))
m_autoAdjustMode = (CleanupTypes::AUTO_ADJ_MODE)std::stoi(s);
s = is.getTagAttribute("mode");
if (s != "" && s == "color") m_lineProcessingMode = lpColor;
} else if (tagName == "despeckling") {
std::string s = is.getTagAttribute("value");
if (s != "" && isInt(s)) m_despeckling = std::stoi(s);
} else if (tagName == "aaValue") {
std::string s = is.getTagAttribute("value");
if (s != "" && isInt(s)) m_aaValue = std::stoi(s);
} else if (tagName == "noAntialias")
m_noAntialias = true;
else if (tagName == "MLAA")
m_postAntialias = true;
else if (tagName == "closestField") {
std::string s = is.getTagAttribute("value");
if (s != "" && isDouble(s)) m_closestField = std::stod(s);
} else if (tagName == "fdg") {
std::string s = is.getTagAttribute("name");
if (s != "") setFdgByName(s);
} else if (tagName == "path") {
is >> m_path;
is.closeChild();
} else
is.skipCurrentTag();
}
CleanupParameters::LastSavedParameters.assign(this);
if (globalParams) CleanupParameters::GlobalParameters.assign(this);
}
//---------------------------------------------------------
const CleanupTypes::FDG_INFO &CleanupParameters::getFdgInfo() {
if (m_fdgInfo.m_name == "") {
std::vector<std::string> names;
FdgManager::instance()->getFdgNames(names);
if (names.size() > 1) {
const CleanupTypes::FDG_INFO *info =
FdgManager::instance()->getFdg(names[0]);
if (info) m_fdgInfo = *info;
}
}
return m_fdgInfo;
}