Add back the old perspective tool

Add perspective correction method chooser to allow choice between the
original perspective tool (simple) and the new one (camera-based).
This commit is contained in:
Lawrence 2019-12-28 17:18:59 -08:00
parent f514a69104
commit f83a62be5b
13 changed files with 263 additions and 48 deletions

View File

@ -732,7 +732,9 @@ HISTORY_MSG_497;Perspective - Camera
HISTORY_MSG_498;Perspective - Recovery HISTORY_MSG_498;Perspective - Recovery
HISTORY_MSG_499;Perspective - PCA - Rotation HISTORY_MSG_499;Perspective - PCA - Rotation
HISTORY_MSG_500;Perspective - PCA - Scale HISTORY_MSG_500;Perspective - PCA - Scale
HISTORY_MSG_501;Perspective - PCA - Shift HISTORY_MSG_501;Perspective - PCA
HISTORY_MSG_502;Perspective - Camera
HISTORY_MSG_503;Perspective - Method
HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors
HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction
HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction
@ -1812,10 +1814,15 @@ TP_PDSHARPENING_LABEL;Capture Sharpening
TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Crop factor TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Crop factor
TP_PERSPECTIVE_CAMERA_FRAME;Correction TP_PERSPECTIVE_CAMERA_FRAME;Correction
TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Focal length TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Focal length
TP_PERSPECTIVE_CAMERA_PITCH;Vertical
TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontal shift TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontal shift
TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Vertical shift TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Vertical shift
TP_PERSPECTIVE_CAMERA_YAW;Horizontal
TP_PERSPECTIVE_HORIZONTAL;Horizontal TP_PERSPECTIVE_HORIZONTAL;Horizontal
TP_PERSPECTIVE_LABEL;Perspective TP_PERSPECTIVE_LABEL;Perspective
TP_PERSPECTIVE_METHOD;Method
TP_PERSPECTIVE_METHOD_SIMPLE;Simple
TP_PERSPECTIVE_METHOD_CAMERA_BASED;Camera-based
TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Post-correction adjustment TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Post-correction adjustment
TP_PERSPECTIVE_PROJECTION_PITCH;Vertical TP_PERSPECTIVE_PROJECTION_PITCH;Vertical
TP_PERSPECTIVE_PROJECTION_ROTATE;Rotation TP_PERSPECTIVE_PROJECTION_ROTATE;Rotation

View File

@ -286,6 +286,10 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector<Coord2D> &src,
const LensCorrection *pLCPMap) const const LensCorrection *pLCPMap) const
{ {
enum PerspType { NONE, SIMPLE, CAMERA_BASED };
const PerspType perspectiveType = needsPerspective() ? (
(params->perspective.method == "camera_based") ?
PerspType::CAMERA_BASED : PerspType::SIMPLE ) : PerspType::NONE;
bool clipped = false; bool clipped = false;
red.clear (); red.clear ();
@ -318,11 +322,21 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector<Coord2D> &src,
double ascale = ascaleDef > 0 ? ascaleDef : (params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0); double ascale = ascaleDef > 0 ? ascaleDef : (params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0);
// auxiliary variables for perspective correction // auxiliary variables for perspective correction
// Simple.
double vpdeg = params->perspective.vertical / 100.0 * 45.0;
double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI;
double vpteta = fabs (vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((vpdeg > 0 ? 1.0 : -1.0) * sqrt ((-oW * oW * tan (vpalpha) * tan (vpalpha) + (vpdeg > 0 ? 1.0 : -1.0) * oW * tan (vpalpha) * sqrt (16 * maxRadius * maxRadius + oW * oW * tan (vpalpha) * tan (vpalpha))) / (maxRadius * maxRadius * 8)));
double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI;
double hpteta = fabs (hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((hpdeg > 0 ? 1.0 : -1.0) * sqrt ((-oH * oH * tan (hpalpha) * tan (hpalpha) + (hpdeg > 0 ? 1.0 : -1.0) * oH * tan (hpalpha) * sqrt (16 * maxRadius * maxRadius + oH * oH * tan (hpalpha) * tan (hpalpha))) / (maxRadius * maxRadius * 8)));
double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
// Camera-based.
const double f = params->perspective.camera_focal_length * const double f = params->perspective.camera_focal_length *
params->perspective.camera_crop_factor * (maxRadius / sqrt(18.0*18.0 + params->perspective.camera_crop_factor * (maxRadius / sqrt(18.0*18.0 +
12.0*12.0)); 12.0*12.0));
const double p_camera_yaw = params->perspective.horizontal / 180.0 * rtengine::RT_PI; const double p_camera_yaw = params->perspective.camera_yaw / 180.0 * rtengine::RT_PI;
const double p_camera_pitch = params->perspective.vertical / 180.0 * rtengine::RT_PI; const double p_camera_pitch = params->perspective.camera_pitch / 180.0 * rtengine::RT_PI;
const double p_camera_shift_horiz = oW / 100.0 * params->perspective.camera_shift_horiz; const double p_camera_shift_horiz = oW / 100.0 * params->perspective.camera_shift_horiz;
const double p_camera_shift_vert = oH / -100.0 * params->perspective.camera_shift_vert; const double p_camera_shift_vert = oH / -100.0 * params->perspective.camera_shift_vert;
const double p_projection_shift_horiz = oW / 100.0 * params->perspective.projection_shift_horiz; const double p_projection_shift_horiz = oW / 100.0 * params->perspective.projection_shift_horiz;
@ -350,12 +364,25 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector<Coord2D> &src,
x_d += ascale * (0 - w2); // centering x coord & scale x_d += ascale * (0 - w2); // centering x coord & scale
y_d += ascale * (0 - h2); // centering y coord & scale y_d += ascale * (0 - h2); // centering y coord & scale
if (needsPerspective()) { switch (perspectiveType) {
const double w = p_matrix[3][0] * x_d + p_matrix[3][1] * y_d + p_matrix[3][3]; case PerspType::NONE:
const double xw = p_matrix[0][0] * x_d + p_matrix[0][1] * y_d + p_matrix[0][3]; break;
const double yw = p_matrix[1][0] * x_d + p_matrix[1][1] * y_d + p_matrix[1][3]; case PerspType::SIMPLE:
x_d = xw / w; // horizontal perspective transformation
y_d = yw / w; y_d *= maxRadius / (maxRadius + x_d * hptanpt);
x_d *= maxRadius * hpcospt / (maxRadius + x_d * hptanpt);
// vertical perspective transformation
x_d *= maxRadius / (maxRadius - y_d * vptanpt);
y_d *= maxRadius * vpcospt / (maxRadius - y_d * vptanpt);
break;
case PerspType::CAMERA_BASED:
const double w = p_matrix[3][0] * x_d + p_matrix[3][1] * y_d + p_matrix[3][3];
const double xw = p_matrix[0][0] * x_d + p_matrix[0][1] * y_d + p_matrix[0][3];
const double yw = p_matrix[1][0] * x_d + p_matrix[1][1] * y_d + p_matrix[1][3];
x_d = xw / w;
y_d = yw / w;
break;
} }
// rotate // rotate
@ -933,13 +960,16 @@ void ImProcFunctions::transformLuminanceOnly (Imagefloat* original, Imagefloat*
void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap) void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap)
{ {
// set up stuff, depending on the mode we are // set up stuff, depending on the mode we are
enum PerspType { NONE, SIMPLE, CAMERA_BASED };
const bool enableLCPDist = pLCPMap && params->lensProf.useDist; const bool enableLCPDist = pLCPMap && params->lensProf.useDist;
const bool enableCA = highQuality && needsCA(); const bool enableCA = highQuality && needsCA();
const bool enableGradient = needsGradient(); const bool enableGradient = needsGradient();
const bool enablePCVignetting = needsPCVignetting(); const bool enablePCVignetting = needsPCVignetting();
const bool enableVignetting = needsVignetting(); const bool enableVignetting = needsVignetting();
const bool enablePerspective = needsPerspective();
const bool enableDistortion = needsDistortion(); const bool enableDistortion = needsDistortion();
const PerspType perspectiveType = needsPerspective() ? (
(params->perspective.method == "camera_based") ?
PerspType::CAMERA_BASED : PerspType::SIMPLE ) : PerspType::NONE;
const double w2 = static_cast<double>(oW) / 2.0 - 0.5; const double w2 = static_cast<double>(oW) / 2.0 - 0.5;
const double h2 = static_cast<double>(oH) / 2.0 - 0.5; const double h2 = static_cast<double>(oH) / 2.0 - 0.5;
@ -995,11 +1025,25 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
const double centerFactory = cy - h2; const double centerFactory = cy - h2;
// auxiliary variables for perspective correction // auxiliary variables for perspective correction
// Simple.
const double vpdeg = params->perspective.vertical / 100.0 * 45.0;
const double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI;
const double vpteta = fabs(vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos((vpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oW * tan(vpalpha)) + (vpdeg > 0 ? 1.0 : -1.0) *
oW * tan(vpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oW * tan(vpalpha)))) / (SQR(maxRadius) * 8)));
const double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos(vpteta);
const double vptanpt = tan(vpteta);
const double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
const double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI;
const double hpteta = fabs(hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos((hpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oH * tan(hpalpha)) + (hpdeg > 0 ? 1.0 : -1.0) *
oH * tan(hpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oH * tan(hpalpha)))) / (SQR(maxRadius) * 8)));
const double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos(hpteta);
const double hptanpt = tan(hpteta);
// Camera-based.
const double f = params->perspective.camera_focal_length * const double f = params->perspective.camera_focal_length *
params->perspective.camera_crop_factor * (maxRadius / sqrt(18.0*18.0 + params->perspective.camera_crop_factor * (maxRadius / sqrt(18.0*18.0 +
12.0*12.0)); 12.0*12.0));
const double p_camera_yaw = params->perspective.horizontal / 180.0 * rtengine::RT_PI; const double p_camera_yaw = params->perspective.camera_yaw / 180.0 * rtengine::RT_PI;
const double p_camera_pitch = params->perspective.vertical / 180.0 * rtengine::RT_PI; const double p_camera_pitch = params->perspective.camera_pitch / 180.0 * rtengine::RT_PI;
const double p_camera_shift_horiz = oW / 100.0 * params->perspective.camera_shift_horiz; const double p_camera_shift_horiz = oW / 100.0 * params->perspective.camera_shift_horiz;
const double p_camera_shift_vert = oH / -100.0 * params->perspective.camera_shift_vert; const double p_camera_shift_vert = oH / -100.0 * params->perspective.camera_shift_vert;
const double p_projection_shift_horiz = oW / 100.0 * params->perspective.projection_shift_horiz; const double p_projection_shift_horiz = oW / 100.0 * params->perspective.projection_shift_horiz;
@ -1034,12 +1078,25 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
x_d += ascale * centerFactorx; // centering x coord & scale x_d += ascale * centerFactorx; // centering x coord & scale
y_d += ascale * centerFactory; // centering y coord & scale y_d += ascale * centerFactory; // centering y coord & scale
if (enablePerspective) { switch (perspectiveType) {
const double w = p_matrix[3][0] * x_d + p_matrix[3][1] * y_d + p_matrix[3][3]; case PerspType::NONE:
const double xw = p_matrix[0][0] * x_d + p_matrix[0][1] * y_d + p_matrix[0][3]; break;
const double yw = p_matrix[1][0] * x_d + p_matrix[1][1] * y_d + p_matrix[1][3]; case PerspType::SIMPLE:
x_d = xw / w; // horizontal perspective transformation
y_d = yw / w; y_d *= maxRadius / (maxRadius + x_d * hptanpt);
x_d *= maxRadius * hpcospt / (maxRadius + x_d * hptanpt);
// vertical perspective transformation
x_d *= maxRadius / (maxRadius - y_d * vptanpt);
y_d *= maxRadius * vpcospt / (maxRadius - y_d * vptanpt);
break;
case PerspType::CAMERA_BASED:
const double w = p_matrix[3][0] * x_d + p_matrix[3][1] * y_d + p_matrix[3][3];
const double xw = p_matrix[0][0] * x_d + p_matrix[0][1] * y_d + p_matrix[0][3];
const double yw = p_matrix[1][0] * x_d + p_matrix[1][1] * y_d + p_matrix[1][3];
x_d = xw / w;
y_d = yw / w;
break;
} }
// rotate // rotate
@ -1237,15 +1294,19 @@ bool ImProcFunctions::needsRotation () const
bool ImProcFunctions::needsPerspective () const bool ImProcFunctions::needsPerspective () const
{ {
return params->perspective.horizontal || params->perspective.vertical || return ( (params->perspective.method == "simple") &&
params->perspective.camera_shift_horiz || (params->perspective.horizontal || params->perspective.vertical) )
params->perspective.camera_shift_vert || || ( (params->perspective.method == "camera_based") && (
params->perspective.projection_pitch || params->perspective.camera_pitch ||
params->perspective.projection_rotate || params->perspective.camera_shift_horiz ||
params->perspective.projection_scale != 1.0 || params->perspective.camera_shift_vert ||
params->perspective.projection_shift_horiz || params->perspective.camera_yaw ||
params->perspective.projection_shift_vert || params->perspective.projection_pitch ||
params->perspective.projection_yaw; params->perspective.projection_rotate ||
params->perspective.projection_scale != 1.0 ||
params->perspective.projection_shift_horiz ||
params->perspective.projection_shift_vert ||
params->perspective.projection_yaw) );
} }
bool ImProcFunctions::needsGradient () const bool ImProcFunctions::needsGradient () const

View File

@ -524,6 +524,8 @@ enum ProcEventCode {
EvPerspProjRotate = 498, EvPerspProjRotate = 498,
EvPerspProjScale = 499, EvPerspProjScale = 499,
EvPerspProjShift = 500, EvPerspProjShift = 500,
EvPerspCamAngle = 501,
EvPerspMethod = 502,
NUMOFEVENTS NUMOFEVENTS

View File

@ -1850,12 +1850,15 @@ LensProfParams::LcMode LensProfParams::getMethodNumber(const Glib::ustring& mode
} }
PerspectiveParams::PerspectiveParams() : PerspectiveParams::PerspectiveParams() :
method("simple"),
horizontal(0.0), horizontal(0.0),
vertical(0.0), vertical(0.0),
camera_crop_factor(1.0), camera_crop_factor(1.0),
camera_focal_length(24.0), camera_focal_length(24.0),
camera_pitch(0.0),
camera_shift_horiz(0.0), camera_shift_horiz(0.0),
camera_shift_vert(0.0), camera_shift_vert(0.0),
camera_yaw(0.0),
projection_pitch(0.0), projection_pitch(0.0),
projection_rotate(0.0), projection_rotate(0.0),
projection_scale(1.0), projection_scale(1.0),
@ -1868,12 +1871,15 @@ PerspectiveParams::PerspectiveParams() :
bool PerspectiveParams::operator ==(const PerspectiveParams& other) const bool PerspectiveParams::operator ==(const PerspectiveParams& other) const
{ {
return return
horizontal == other.horizontal method == other.method
&& horizontal == other.horizontal
&& vertical == other.vertical && vertical == other.vertical
&& camera_focal_length == other.camera_focal_length && camera_focal_length == other.camera_focal_length
&& camera_crop_factor == other.camera_crop_factor && camera_crop_factor == other.camera_crop_factor
&& camera_pitch == other.camera_pitch
&& camera_shift_horiz == other.camera_shift_horiz && camera_shift_horiz == other.camera_shift_horiz
&& camera_shift_vert == other.camera_shift_vert && camera_shift_vert == other.camera_shift_vert
&& camera_yaw == other.camera_yaw
&& projection_shift_horiz == other.projection_shift_horiz && projection_shift_horiz == other.projection_shift_horiz
&& projection_shift_vert == other.projection_shift_vert && projection_shift_vert == other.projection_shift_vert
&& projection_scale == other.projection_scale && projection_scale == other.projection_scale
@ -3361,12 +3367,16 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->lensProf.lfLens, "LensProfile", "LFLens", lensProf.lfLens, keyFile); saveToKeyfile(!pedited || pedited->lensProf.lfLens, "LensProfile", "LFLens", lensProf.lfLens, keyFile);
// Perspective correction // Perspective correction
saveToKeyfile(!pedited || pedited->perspective.method, "Perspective", "Method", perspective.method, keyFile);
saveToKeyfile(!pedited || pedited->perspective.horizontal, "Perspective", "Horizontal", perspective.horizontal, keyFile); saveToKeyfile(!pedited || pedited->perspective.horizontal, "Perspective", "Horizontal", perspective.horizontal, keyFile);
saveToKeyfile(!pedited || pedited->perspective.vertical, "Perspective", "Vertical", perspective.vertical, keyFile); saveToKeyfile(!pedited || pedited->perspective.vertical, "Perspective", "Vertical", perspective.vertical, keyFile);
saveToKeyfile(!pedited || pedited->perspective.camera_crop_factor, "Perspective", "CameraCropFactor", perspective.camera_crop_factor, keyFile); saveToKeyfile(!pedited || pedited->perspective.camera_crop_factor, "Perspective", "CameraCropFactor", perspective.camera_crop_factor, keyFile);
saveToKeyfile(!pedited || pedited->perspective.camera_focal_length, "Perspective", "CameraFocalLength", perspective.camera_focal_length, keyFile); saveToKeyfile(!pedited || pedited->perspective.camera_focal_length, "Perspective", "CameraFocalLength", perspective.camera_focal_length, keyFile);
saveToKeyfile(!pedited || pedited->perspective.camera_pitch, "Perspective", "CameraPitch", perspective.camera_pitch, keyFile);
saveToKeyfile(!pedited || pedited->perspective.camera_shift_horiz, "Perspective", "CameraShiftHorizontal", perspective.camera_shift_horiz, keyFile); saveToKeyfile(!pedited || pedited->perspective.camera_shift_horiz, "Perspective", "CameraShiftHorizontal", perspective.camera_shift_horiz, keyFile);
saveToKeyfile(!pedited || pedited->perspective.camera_shift_vert, "Perspective", "CameraShiftVertical", perspective.camera_shift_vert, keyFile); saveToKeyfile(!pedited || pedited->perspective.camera_shift_vert, "Perspective", "CameraShiftVertical", perspective.camera_shift_vert, keyFile);
saveToKeyfile(!pedited || pedited->perspective.camera_yaw, "Perspective", "CameraYaw", perspective.camera_yaw, keyFile);
saveToKeyfile(!pedited || pedited->perspective.projection_shift_horiz, "Perspective", "ProjectionShiftHorizontal", perspective.projection_shift_horiz, keyFile);
saveToKeyfile(!pedited || pedited->perspective.projection_pitch, "Perspective", "ProjectionPitch", perspective.projection_pitch, keyFile); saveToKeyfile(!pedited || pedited->perspective.projection_pitch, "Perspective", "ProjectionPitch", perspective.projection_pitch, keyFile);
saveToKeyfile(!pedited || pedited->perspective.projection_rotate, "Perspective", "ProjectionRotate", perspective.projection_rotate, keyFile); saveToKeyfile(!pedited || pedited->perspective.projection_rotate, "Perspective", "ProjectionRotate", perspective.projection_rotate, keyFile);
saveToKeyfile(!pedited || pedited->perspective.projection_scale, "Perspective", "ProjectionScale", perspective.projection_scale, keyFile); saveToKeyfile(!pedited || pedited->perspective.projection_scale, "Perspective", "ProjectionScale", perspective.projection_scale, keyFile);
@ -4448,12 +4458,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
} }
if (keyFile.has_group("Perspective")) { if (keyFile.has_group("Perspective")) {
assignFromKeyfile(keyFile, "Perspective", "Method", pedited, perspective.method, pedited->perspective.method);
assignFromKeyfile(keyFile, "Perspective", "Horizontal", pedited, perspective.horizontal, pedited->perspective.horizontal); assignFromKeyfile(keyFile, "Perspective", "Horizontal", pedited, perspective.horizontal, pedited->perspective.horizontal);
assignFromKeyfile(keyFile, "Perspective", "Vertical", pedited, perspective.vertical, pedited->perspective.vertical); assignFromKeyfile(keyFile, "Perspective", "Vertical", pedited, perspective.vertical, pedited->perspective.vertical);
assignFromKeyfile(keyFile, "Perspective", "CameraShiftHorizontal", pedited, perspective.camera_shift_horiz, pedited->perspective.camera_shift_horiz); assignFromKeyfile(keyFile, "Perspective", "CameraShiftHorizontal", pedited, perspective.camera_shift_horiz, pedited->perspective.camera_shift_horiz);
assignFromKeyfile(keyFile, "Perspective", "CameraShiftVertical", pedited, perspective.camera_shift_vert, pedited->perspective.camera_shift_vert); assignFromKeyfile(keyFile, "Perspective", "CameraShiftVertical", pedited, perspective.camera_shift_vert, pedited->perspective.camera_shift_vert);
assignFromKeyfile(keyFile, "Perspective", "CameraPitch", pedited, perspective.camera_pitch, pedited->perspective.camera_pitch);
assignFromKeyfile(keyFile, "Perspective", "CameraCropFactor", pedited, perspective.camera_crop_factor, pedited->perspective.camera_crop_factor); assignFromKeyfile(keyFile, "Perspective", "CameraCropFactor", pedited, perspective.camera_crop_factor, pedited->perspective.camera_crop_factor);
assignFromKeyfile(keyFile, "Perspective", "CameraFocalLength", pedited, perspective.camera_focal_length, pedited->perspective.camera_focal_length); assignFromKeyfile(keyFile, "Perspective", "CameraFocalLength", pedited, perspective.camera_focal_length, pedited->perspective.camera_focal_length);
assignFromKeyfile(keyFile, "Perspective", "CameraYaw", pedited, perspective.camera_yaw, pedited->perspective.camera_yaw);
assignFromKeyfile(keyFile, "Perspective", "ProjectionPitch", pedited, perspective.projection_pitch, pedited->perspective.projection_pitch); assignFromKeyfile(keyFile, "Perspective", "ProjectionPitch", pedited, perspective.projection_pitch, pedited->perspective.projection_pitch);
assignFromKeyfile(keyFile, "Perspective", "ProjectionRotate", pedited, perspective.projection_rotate, pedited->perspective.projection_rotate); assignFromKeyfile(keyFile, "Perspective", "ProjectionRotate", pedited, perspective.projection_rotate, pedited->perspective.projection_rotate);
assignFromKeyfile(keyFile, "Perspective", "ProjectionScale", pedited, perspective.projection_scale, pedited->perspective.projection_scale); assignFromKeyfile(keyFile, "Perspective", "ProjectionScale", pedited, perspective.projection_scale, pedited->perspective.projection_scale);

View File

@ -905,12 +905,15 @@ struct LensProfParams {
* Parameters of the perspective correction * Parameters of the perspective correction
*/ */
struct PerspectiveParams { struct PerspectiveParams {
Glib::ustring method;
double horizontal; double horizontal;
double vertical; double vertical;
double camera_crop_factor; double camera_crop_factor;
double camera_focal_length; double camera_focal_length;
double camera_pitch;
double camera_shift_horiz; double camera_shift_horiz;
double camera_shift_vert; double camera_shift_vert;
double camera_yaw;
double projection_pitch; double projection_pitch;
double projection_rotate; double projection_rotate;
double projection_scale; double projection_scale;

View File

@ -527,7 +527,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
TRANSFORM, // EvPerspProjAngle TRANSFORM, // EvPerspProjAngle
TRANSFORM, // EvPerspProjRotate TRANSFORM, // EvPerspProjRotate
TRANSFORM, // EvPerspProjScale TRANSFORM, // EvPerspProjScale
TRANSFORM // EvPerspProjShift TRANSFORM, // EvPerspProjShift
TRANSFORM, // EvPerspCamAngle
TRANSFORM // EvPerspMethod
}; };

View File

@ -18,6 +18,7 @@ enum {
ADDSET_ROTATE_DEGREE, ADDSET_ROTATE_DEGREE,
ADDSET_DIST_AMOUNT, ADDSET_DIST_AMOUNT,
ADDSET_PERSPECTIVE, ADDSET_PERSPECTIVE,
ADDSET_PERSP_CAM_ANGLE,
ADDSET_PERSP_CAM_FOCAL_LENGTH, ADDSET_PERSP_CAM_FOCAL_LENGTH,
ADDSET_PERSP_CAM_SHIFT, ADDSET_PERSP_CAM_SHIFT,
ADDSET_PERSP_PROJ_ANGLE, ADDSET_PERSP_PROJ_ANGLE,

View File

@ -151,7 +151,7 @@ void BatchToolPanelCoordinator::initSession ()
rotate->setAdjusterBehavior (false); rotate->setAdjusterBehavior (false);
resize->setAdjusterBehavior (false); resize->setAdjusterBehavior (false);
distortion->setAdjusterBehavior (false); distortion->setAdjusterBehavior (false);
perspective->setAdjusterBehavior (false, false, false, false, false, false, false); perspective->setAdjusterBehavior (false, false, false, false, false, false, false, false);
gradient->setAdjusterBehavior (false, false, false, false); gradient->setAdjusterBehavior (false, false, false, false);
pcvignette->setAdjusterBehavior (false, false, false); pcvignette->setAdjusterBehavior (false, false, false);
cacorrection->setAdjusterBehavior (false); cacorrection->setAdjusterBehavior (false);
@ -196,7 +196,7 @@ void BatchToolPanelCoordinator::initSession ()
rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]); rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]);
resize->setAdjusterBehavior (options.baBehav[ADDSET_RESIZE_SCALE]); resize->setAdjusterBehavior (options.baBehav[ADDSET_RESIZE_SCALE]);
distortion->setAdjusterBehavior (options.baBehav[ADDSET_DIST_AMOUNT]); distortion->setAdjusterBehavior (options.baBehav[ADDSET_DIST_AMOUNT]);
perspective->setAdjusterBehavior (options.baBehav[ADDSET_PERSPECTIVE], options.baBehav[ADDSET_PERSP_CAM_FOCAL_LENGTH], options.baBehav[ADDSET_PERSP_CAM_SHIFT], options.baBehav[ADDSET_PERSP_PROJ_ANGLE], options.baBehav[ADDSET_PERSP_PROJ_SHIFT], options.baBehav[ADDSET_PERSP_PROJ_ROTATE], options.baBehav[ADDSET_PERSP_PROJ_SCALE]); perspective->setAdjusterBehavior (options.baBehav[ADDSET_PERSPECTIVE], options.baBehav[ADDSET_PERSP_CAM_FOCAL_LENGTH], options.baBehav[ADDSET_PERSP_CAM_SHIFT], options.baBehav[ADDSET_PERSP_CAM_ANGLE], options.baBehav[ADDSET_PERSP_PROJ_ANGLE], options.baBehav[ADDSET_PERSP_PROJ_SHIFT], options.baBehav[ADDSET_PERSP_PROJ_ROTATE], options.baBehav[ADDSET_PERSP_PROJ_SCALE]);
gradient->setAdjusterBehavior (options.baBehav[ADDSET_GRADIENT_DEGREE], options.baBehav[ADDSET_GRADIENT_FEATHER], options.baBehav[ADDSET_GRADIENT_STRENGTH], options.baBehav[ADDSET_GRADIENT_CENTER]); gradient->setAdjusterBehavior (options.baBehav[ADDSET_GRADIENT_DEGREE], options.baBehav[ADDSET_GRADIENT_FEATHER], options.baBehav[ADDSET_GRADIENT_STRENGTH], options.baBehav[ADDSET_GRADIENT_CENTER]);
pcvignette->setAdjusterBehavior (options.baBehav[ADDSET_PCVIGNETTE_STRENGTH], options.baBehav[ADDSET_PCVIGNETTE_FEATHER], options.baBehav[ADDSET_PCVIGNETTE_ROUNDNESS]); pcvignette->setAdjusterBehavior (options.baBehav[ADDSET_PCVIGNETTE_STRENGTH], options.baBehav[ADDSET_PCVIGNETTE_FEATHER], options.baBehav[ADDSET_PCVIGNETTE_ROUNDNESS]);
cacorrection->setAdjusterBehavior (options.baBehav[ADDSET_CA]); cacorrection->setAdjusterBehavior (options.baBehav[ADDSET_CA]);
@ -310,6 +310,7 @@ void BatchToolPanelCoordinator::initSession ()
if (options.baBehav[ADDSET_PERSPECTIVE]) { pparams.perspective.horizontal = pparams.perspective.vertical = 0; } if (options.baBehav[ADDSET_PERSPECTIVE]) { pparams.perspective.horizontal = pparams.perspective.vertical = 0; }
if (options.baBehav[ADDSET_PERSP_CAM_FOCAL_LENGTH]) { pparams.perspective.camera_focal_length = pparams.perspective.camera_crop_factor = 0; } if (options.baBehav[ADDSET_PERSP_CAM_FOCAL_LENGTH]) { pparams.perspective.camera_focal_length = pparams.perspective.camera_crop_factor = 0; }
if (options.baBehav[ADDSET_PERSP_CAM_SHIFT]) { pparams.perspective.camera_shift_horiz = pparams.perspective.camera_shift_vert = 0; } if (options.baBehav[ADDSET_PERSP_CAM_SHIFT]) { pparams.perspective.camera_shift_horiz = pparams.perspective.camera_shift_vert = 0; }
if (options.baBehav[ADDSET_PERSP_CAM_ANGLE]) { pparams.perspective.camera_yaw = pparams.perspective.camera_pitch = 0; }
if (options.baBehav[ADDSET_PERSP_PROJ_ANGLE]) { pparams.perspective.projection_yaw = pparams.perspective.projection_pitch = 0; } if (options.baBehav[ADDSET_PERSP_PROJ_ANGLE]) { pparams.perspective.projection_yaw = pparams.perspective.projection_pitch = 0; }
if (options.baBehav[ADDSET_PERSP_PROJ_SHIFT]) { pparams.perspective.projection_shift_horiz = pparams.perspective.projection_shift_vert = 0; } if (options.baBehav[ADDSET_PERSP_PROJ_SHIFT]) { pparams.perspective.projection_shift_horiz = pparams.perspective.projection_shift_vert = 0; }
if (options.baBehav[ADDSET_PERSP_PROJ_ROTATE]) { pparams.perspective.projection_rotate = 0; } if (options.baBehav[ADDSET_PERSP_PROJ_ROTATE]) { pparams.perspective.projection_rotate = 0; }

View File

@ -334,12 +334,15 @@ void ParamsEdited::set(bool v)
lensProf.lfCameraMake = v; lensProf.lfCameraMake = v;
lensProf.lfCameraModel = v; lensProf.lfCameraModel = v;
lensProf.lfLens = v; lensProf.lfLens = v;
perspective.method = v;
perspective.horizontal = v; perspective.horizontal = v;
perspective.vertical = v; perspective.vertical = v;
perspective.camera_crop_factor = v; perspective.camera_crop_factor = v;
perspective.camera_focal_length = v; perspective.camera_focal_length = v;
perspective.camera_pitch = v;
perspective.camera_shift_horiz = v; perspective.camera_shift_horiz = v;
perspective.camera_shift_vert = v; perspective.camera_shift_vert = v;
perspective.camera_yaw = v;
perspective.projection_pitch = v; perspective.projection_pitch = v;
perspective.projection_rotate = v; perspective.projection_rotate = v;
perspective.projection_scale = v; perspective.projection_scale = v;
@ -927,13 +930,16 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
lensProf.lfCameraMake = lensProf.lfCameraMake && p.lensProf.lfCameraMake == other.lensProf.lfCameraMake; lensProf.lfCameraMake = lensProf.lfCameraMake && p.lensProf.lfCameraMake == other.lensProf.lfCameraMake;
lensProf.lfCameraModel = lensProf.lfCameraModel && p.lensProf.lfCameraModel == other.lensProf.lfCameraModel; lensProf.lfCameraModel = lensProf.lfCameraModel && p.lensProf.lfCameraModel == other.lensProf.lfCameraModel;
lensProf.lfLens = lensProf.lfLens && p.lensProf.lfLens == other.lensProf.lfLens; lensProf.lfLens = lensProf.lfLens && p.lensProf.lfLens == other.lensProf.lfLens;
perspective.method = perspective.method && p.perspective.method == other.perspective.method;
perspective.horizontal = perspective.horizontal && p.perspective.horizontal == other.perspective.horizontal; perspective.horizontal = perspective.horizontal && p.perspective.horizontal == other.perspective.horizontal;
perspective.vertical = perspective.vertical && p.perspective.vertical == other.perspective.vertical; perspective.vertical = perspective.vertical && p.perspective.vertical == other.perspective.vertical;
perspective.camera_crop_factor = perspective.camera_crop_factor && p.perspective.camera_crop_factor == other.perspective.camera_crop_factor; perspective.camera_crop_factor = perspective.camera_crop_factor && p.perspective.camera_crop_factor == other.perspective.camera_crop_factor;
perspective.camera_focal_length = perspective.camera_focal_length && p.perspective.camera_focal_length == other.perspective.camera_focal_length; perspective.camera_focal_length = perspective.camera_focal_length && p.perspective.camera_focal_length == other.perspective.camera_focal_length;
perspective.camera_pitch = perspective.camera_pitch && p.perspective.camera_pitch == other.perspective.camera_pitch;
perspective.camera_shift_horiz = perspective.camera_shift_horiz && p.perspective.camera_shift_horiz == other.perspective.camera_shift_horiz; perspective.camera_shift_horiz = perspective.camera_shift_horiz && p.perspective.camera_shift_horiz == other.perspective.camera_shift_horiz;
perspective.camera_shift_vert = perspective.camera_shift_vert && p.perspective.camera_shift_vert == other.perspective.camera_shift_vert; perspective.camera_shift_vert = perspective.camera_shift_vert && p.perspective.camera_shift_vert == other.perspective.camera_shift_vert;
perspective.projection_pitch = perspective.projection_pitch && p.perspective.projection_pitch == other.perspective.projection_pitch; perspective.projection_pitch = perspective.projection_pitch && p.perspective.projection_pitch == other.perspective.projection_pitch;
perspective.camera_yaw = perspective.camera_yaw && p.perspective.camera_yaw == other.perspective.camera_yaw;
perspective.projection_rotate = perspective.projection_rotate && p.perspective.projection_rotate == other.perspective.projection_rotate; perspective.projection_rotate = perspective.projection_rotate && p.perspective.projection_rotate == other.perspective.projection_rotate;
perspective.projection_scale = perspective.projection_scale && p.perspective.projection_scale == other.perspective.projection_scale; perspective.projection_scale = perspective.projection_scale && p.perspective.projection_scale == other.perspective.projection_scale;
perspective.projection_shift_horiz = perspective.projection_shift_horiz && p.perspective.projection_shift_horiz == other.perspective.projection_shift_horiz; perspective.projection_shift_horiz = perspective.projection_shift_horiz && p.perspective.projection_shift_horiz == other.perspective.projection_shift_horiz;
@ -2329,6 +2335,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.lensProf.lfLens = mods.lensProf.lfLens; toEdit.lensProf.lfLens = mods.lensProf.lfLens;
} }
if (perspective.method) {
toEdit.perspective.method = mods.perspective.method;
}
if (perspective.horizontal) { if (perspective.horizontal) {
toEdit.perspective.horizontal = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.horizontal + mods.perspective.horizontal : mods.perspective.horizontal; toEdit.perspective.horizontal = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.horizontal + mods.perspective.horizontal : mods.perspective.horizontal;
} }
@ -2345,6 +2355,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.perspective.camera_focal_length = dontforceSet && options.baBehav[ADDSET_PERSP_CAM_FOCAL_LENGTH] ? toEdit.perspective.camera_focal_length + mods.perspective.camera_focal_length : mods.perspective.camera_focal_length; toEdit.perspective.camera_focal_length = dontforceSet && options.baBehav[ADDSET_PERSP_CAM_FOCAL_LENGTH] ? toEdit.perspective.camera_focal_length + mods.perspective.camera_focal_length : mods.perspective.camera_focal_length;
} }
if (perspective.camera_pitch) {
toEdit.perspective.camera_pitch = dontforceSet && options.baBehav[ADDSET_PERSP_CAM_ANGLE] ? toEdit.perspective.camera_pitch + mods.perspective.camera_pitch : mods.perspective.camera_pitch;
}
if (perspective.camera_shift_horiz) { if (perspective.camera_shift_horiz) {
toEdit.perspective.camera_shift_horiz = dontforceSet && options.baBehav[ADDSET_PERSP_CAM_SHIFT] ? toEdit.perspective.camera_shift_horiz + mods.perspective.camera_shift_horiz : mods.perspective.camera_shift_horiz; toEdit.perspective.camera_shift_horiz = dontforceSet && options.baBehav[ADDSET_PERSP_CAM_SHIFT] ? toEdit.perspective.camera_shift_horiz + mods.perspective.camera_shift_horiz : mods.perspective.camera_shift_horiz;
} }
@ -2353,6 +2367,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.perspective.camera_shift_vert = dontforceSet && options.baBehav[ADDSET_PERSP_CAM_SHIFT] ? toEdit.perspective.camera_shift_vert + mods.perspective.camera_shift_vert : mods.perspective.camera_shift_vert; toEdit.perspective.camera_shift_vert = dontforceSet && options.baBehav[ADDSET_PERSP_CAM_SHIFT] ? toEdit.perspective.camera_shift_vert + mods.perspective.camera_shift_vert : mods.perspective.camera_shift_vert;
} }
if (perspective.camera_yaw) {
toEdit.perspective.camera_yaw = dontforceSet && options.baBehav[ADDSET_PERSP_CAM_ANGLE] ? toEdit.perspective.camera_yaw + mods.perspective.camera_yaw : mods.perspective.camera_yaw;
}
if (perspective.projection_pitch) { if (perspective.projection_pitch) {
toEdit.perspective.projection_pitch = dontforceSet && options.baBehav[ADDSET_PERSP_PROJ_ANGLE] ? toEdit.perspective.projection_pitch + mods.perspective.projection_pitch : mods.perspective.projection_pitch; toEdit.perspective.projection_pitch = dontforceSet && options.baBehav[ADDSET_PERSP_PROJ_ANGLE] ? toEdit.perspective.projection_pitch + mods.perspective.projection_pitch : mods.perspective.projection_pitch;
} }

View File

@ -394,12 +394,15 @@ struct LensProfParamsEdited {
}; };
struct PerspectiveParamsEdited { struct PerspectiveParamsEdited {
bool method;
bool horizontal; bool horizontal;
bool vertical; bool vertical;
bool camera_crop_factor; bool camera_crop_factor;
bool camera_focal_length; bool camera_focal_length;
bool camera_pitch;
bool camera_shift_horiz; bool camera_shift_horiz;
bool camera_shift_vert; bool camera_shift_vert;
bool camera_yaw;
bool projection_pitch; bool projection_pitch;
bool projection_rotate; bool projection_rotate;
bool projection_scale; bool projection_scale;

View File

@ -33,6 +33,10 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("
Gtk::Image* ipersVL = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png")); Gtk::Image* ipersVL = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png"));
Gtk::Image* ipersVR = Gtk::manage (new RTImage ("perspective-vertical-top-small.png")); Gtk::Image* ipersVR = Gtk::manage (new RTImage ("perspective-vertical-top-small.png"));
Gtk::Image* ipers_cam_yaw_left = Gtk::manage (new RTImage ("perspective-horizontal-left-small.png"));
Gtk::Image* ipers_cam_yaw_right = Gtk::manage (new RTImage ("perspective-horizontal-right-small.png"));
Gtk::Image* ipers_cam_pitch_left = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png"));
Gtk::Image* ipers_cam_pitch_right = Gtk::manage (new RTImage ("perspective-vertical-top-small.png"));
Gtk::Image* ipers_proj_yaw_left = Gtk::manage (new RTImage ("perspective-horizontal-left-small.png")); Gtk::Image* ipers_proj_yaw_left = Gtk::manage (new RTImage ("perspective-horizontal-left-small.png"));
Gtk::Image* ipers_proj_yaw_right = Gtk::manage (new RTImage ("perspective-horizontal-right-small.png")); Gtk::Image* ipers_proj_yaw_right = Gtk::manage (new RTImage ("perspective-horizontal-right-small.png"));
Gtk::Image* ipers_proj_pitch_left = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png")); Gtk::Image* ipers_proj_pitch_left = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png"));
@ -40,18 +44,31 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("
Gtk::Image* ipers_rotate_left = Gtk::manage(new RTImage("rotate-right-small.png")); Gtk::Image* ipers_rotate_left = Gtk::manage(new RTImage("rotate-right-small.png"));
Gtk::Image* ipers_rotate_right = Gtk::manage(new RTImage("rotate-left-small.png")); Gtk::Image* ipers_rotate_right = Gtk::manage(new RTImage("rotate-left-small.png"));
Gtk::HBox* method_hbox = Gtk::manage (new Gtk::HBox());
Gtk::Label* method_label = Gtk::manage (new Gtk::Label (M("TP_PERSPECTIVE_METHOD") + ": "));
method = Gtk::manage (new MyComboBoxText ());
method->append (M("TP_PERSPECTIVE_METHOD_SIMPLE"));
method->append (M("TP_PERSPECTIVE_METHOD_CAMERA_BASED"));
method_hbox->pack_start(*method_label, Gtk::PACK_SHRINK);
method_hbox->pack_start(*method);
pack_start(*method_hbox);
simple = Gtk::manage( new Gtk::VBox() );
vert = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_VERTICAL"), -100, 100, 0.1, 0, ipersVL, ipersVR));
vert->setAdjusterListener (this);
horiz = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_HORIZONTAL"), -100, 100, 0.1, 0, ipersHL, ipersHR));
horiz->setAdjusterListener (this);
camera_based = Gtk::manage( new Gtk::VBox() );
Gtk::Frame* camera_frame = Gtk::manage (new Gtk::Frame Gtk::Frame* camera_frame = Gtk::manage (new Gtk::Frame
(M("TP_PERSPECTIVE_CAMERA_FRAME"))); (M("TP_PERSPECTIVE_CAMERA_FRAME")));
camera_frame->set_label_align(0.025, 0.5); camera_frame->set_label_align(0.025, 0.5);
Gtk::VBox* camera_vbox = Gtk::manage (new Gtk::VBox()); Gtk::VBox* camera_vbox = Gtk::manage (new Gtk::VBox());
vert = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_VERTICAL"), -85, 85, 0.1, 0, ipersVL, ipersVR));
vert->setAdjusterListener (this);
horiz = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_HORIZONTAL"), -85, 85, 0.1, 0, ipersHL, ipersHR));
horiz->setAdjusterListener (this);
camera_focal_length = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH"), 0.5, 2000, 0.01, 24)); camera_focal_length = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH"), 0.5, 2000, 0.01, 24));
camera_focal_length->setAdjusterListener (this); camera_focal_length->setAdjusterListener (this);
@ -64,6 +81,14 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("
camera_shift_vert = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL"), -100, 100, 0.01, 0)); camera_shift_vert = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL"), -100, 100, 0.01, 0));
camera_shift_vert->setAdjusterListener (this); camera_shift_vert->setAdjusterListener (this);
camera_pitch = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_PITCH"),
-85, 85, 0.1, 0, ipers_cam_pitch_left, ipers_cam_pitch_right));
camera_pitch->setAdjusterListener (this);
camera_yaw = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_YAW"),
-85, 85, 0.1, 0, ipers_cam_yaw_left, ipers_cam_yaw_right));
camera_yaw->setAdjusterListener (this);
Gtk::Frame* pca_frame = Gtk::manage (new Gtk::Frame Gtk::Frame* pca_frame = Gtk::manage (new Gtk::Frame
(M("TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME"))); (M("TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME")));
pca_frame->set_label_align(0.025, 0.5); pca_frame->set_label_align(0.025, 0.5);
@ -94,26 +119,32 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("
projection_yaw = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_PROJECTION_YAW"), -85, 85, 0.1, 0, ipers_proj_yaw_left, ipers_proj_yaw_right)); projection_yaw = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_PROJECTION_YAW"), -85, 85, 0.1, 0, ipers_proj_yaw_left, ipers_proj_yaw_right));
projection_yaw->setAdjusterListener (this); projection_yaw->setAdjusterListener (this);
camera_vbox->pack_start (*vert); simple->pack_start (*horiz);
camera_vbox->pack_start (*horiz); simple->pack_start (*vert);
camera_vbox->pack_start (*camera_focal_length); camera_vbox->pack_start (*camera_focal_length);
camera_vbox->pack_start (*camera_crop_factor); camera_vbox->pack_start (*camera_crop_factor);
camera_vbox->pack_start (*camera_shift_horiz); camera_vbox->pack_start (*camera_shift_horiz);
camera_vbox->pack_start (*camera_shift_vert); camera_vbox->pack_start (*camera_shift_vert);
camera_vbox->pack_start (*camera_pitch);
camera_vbox->pack_start (*camera_yaw);
camera_frame->add(*camera_vbox); camera_frame->add(*camera_vbox);
pack_start(*camera_frame); camera_based->pack_start(*camera_frame);
pca_vbox->pack_start (*projection_shift_horiz); pca_vbox->pack_start (*projection_shift_horiz);
pca_vbox->pack_start (*projection_shift_vert); pca_vbox->pack_start (*projection_shift_vert);
pca_vbox->pack_start (*projection_rotate); pca_vbox->pack_start (*projection_rotate);
pca_vbox->pack_start (*projection_scale); pca_vbox->pack_start (*projection_scale);
pca_frame->add(*pca_vbox); pca_frame->add(*pca_vbox);
pack_start(*pca_frame); camera_based->pack_start(*pca_frame);
recovery_vbox->pack_start (*projection_yaw); recovery_vbox->pack_start (*projection_yaw);
recovery_vbox->pack_start (*projection_pitch); recovery_vbox->pack_start (*projection_pitch);
recovery_frame->add(*recovery_vbox); recovery_frame->add(*recovery_vbox);
pack_start(*recovery_frame); camera_based->pack_start(*recovery_frame);
pack_start(*simple);
pack_start(*camera_based);
horiz->setLogScale(2, 0); horiz->setLogScale(2, 0);
vert->setLogScale(2, 0); vert->setLogScale(2, 0);
@ -121,6 +152,8 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("
camera_crop_factor->setLogScale(300, 0.1); camera_crop_factor->setLogScale(300, 0.1);
projection_scale->setLogScale(4, 0.5); projection_scale->setLogScale(4, 0.5);
method->signal_changed().connect(sigc::mem_fun(*this, &PerspCorrection::methodChanged));
show_all(); show_all();
} }
@ -134,8 +167,10 @@ void PerspCorrection::read (const ProcParams* pp, const ParamsEdited* pedited)
vert->setEditedState (pedited->perspective.vertical ? Edited : UnEdited); vert->setEditedState (pedited->perspective.vertical ? Edited : UnEdited);
camera_crop_factor->setEditedState (pedited->perspective.camera_crop_factor ? Edited : UnEdited); camera_crop_factor->setEditedState (pedited->perspective.camera_crop_factor ? Edited : UnEdited);
camera_focal_length->setEditedState (pedited->perspective.camera_focal_length ? Edited : UnEdited); camera_focal_length->setEditedState (pedited->perspective.camera_focal_length ? Edited : UnEdited);
camera_pitch->setEditedState (pedited->perspective.camera_pitch ? Edited : UnEdited);
camera_shift_horiz->setEditedState (pedited->perspective.camera_shift_horiz ? Edited : UnEdited); camera_shift_horiz->setEditedState (pedited->perspective.camera_shift_horiz ? Edited : UnEdited);
camera_shift_vert->setEditedState (pedited->perspective.camera_shift_vert ? Edited : UnEdited); camera_shift_vert->setEditedState (pedited->perspective.camera_shift_vert ? Edited : UnEdited);
camera_yaw->setEditedState (pedited->perspective.camera_yaw ? Edited : UnEdited);
projection_pitch->setEditedState (pedited->perspective.projection_pitch ? Edited : UnEdited); projection_pitch->setEditedState (pedited->perspective.projection_pitch ? Edited : UnEdited);
projection_rotate->setEditedState (pedited->perspective.projection_rotate ? Edited : UnEdited); projection_rotate->setEditedState (pedited->perspective.projection_rotate ? Edited : UnEdited);
projection_scale->setEditedState (pedited->perspective.projection_scale ? Edited : UnEdited); projection_scale->setEditedState (pedited->perspective.projection_scale ? Edited : UnEdited);
@ -148,8 +183,10 @@ void PerspCorrection::read (const ProcParams* pp, const ParamsEdited* pedited)
vert->setValue (pp->perspective.vertical); vert->setValue (pp->perspective.vertical);
camera_crop_factor->setValue (pp->perspective.camera_crop_factor); camera_crop_factor->setValue (pp->perspective.camera_crop_factor);
camera_focal_length->setValue (pp->perspective.camera_focal_length); camera_focal_length->setValue (pp->perspective.camera_focal_length);
camera_pitch->setValue (pp->perspective.camera_pitch);
camera_shift_horiz->setValue (pp->perspective.camera_shift_horiz); camera_shift_horiz->setValue (pp->perspective.camera_shift_horiz);
camera_shift_vert->setValue (pp->perspective.camera_shift_vert); camera_shift_vert->setValue (pp->perspective.camera_shift_vert);
camera_yaw->setValue (pp->perspective.camera_yaw);
projection_pitch->setValue (pp->perspective.projection_pitch); projection_pitch->setValue (pp->perspective.projection_pitch);
projection_rotate->setValue (pp->perspective.projection_rotate); projection_rotate->setValue (pp->perspective.projection_rotate);
projection_scale->setValue (pp->perspective.projection_scale); projection_scale->setValue (pp->perspective.projection_scale);
@ -157,6 +194,14 @@ void PerspCorrection::read (const ProcParams* pp, const ParamsEdited* pedited)
projection_shift_vert->setValue (pp->perspective.projection_shift_vert); projection_shift_vert->setValue (pp->perspective.projection_shift_vert);
projection_yaw->setValue (pp->perspective.projection_yaw); projection_yaw->setValue (pp->perspective.projection_yaw);
if (pedited && !pedited->perspective.method) {
method->set_active (2);
} else if (pp->perspective.method == "simple") {
method->set_active (0);
} else if (pp->perspective.method == "camera_based") {
method->set_active (1);
}
enableListener (); enableListener ();
} }
@ -167,8 +212,10 @@ void PerspCorrection::write (ProcParams* pp, ParamsEdited* pedited)
pp->perspective.vertical = vert->getValue (); pp->perspective.vertical = vert->getValue ();
pp->perspective.camera_crop_factor= camera_crop_factor->getValue (); pp->perspective.camera_crop_factor= camera_crop_factor->getValue ();
pp->perspective.camera_focal_length = camera_focal_length->getValue (); pp->perspective.camera_focal_length = camera_focal_length->getValue ();
pp->perspective.camera_pitch = camera_pitch->getValue ();
pp->perspective.camera_shift_horiz = camera_shift_horiz->getValue (); pp->perspective.camera_shift_horiz = camera_shift_horiz->getValue ();
pp->perspective.camera_shift_vert = camera_shift_vert->getValue (); pp->perspective.camera_shift_vert = camera_shift_vert->getValue ();
pp->perspective.camera_yaw = camera_yaw->getValue ();
pp->perspective.projection_pitch = projection_pitch->getValue (); pp->perspective.projection_pitch = projection_pitch->getValue ();
pp->perspective.projection_rotate = projection_rotate->getValue (); pp->perspective.projection_rotate = projection_rotate->getValue ();
pp->perspective.projection_scale = projection_scale->getValue (); pp->perspective.projection_scale = projection_scale->getValue ();
@ -176,13 +223,22 @@ void PerspCorrection::write (ProcParams* pp, ParamsEdited* pedited)
pp->perspective.projection_shift_vert = projection_shift_vert->getValue (); pp->perspective.projection_shift_vert = projection_shift_vert->getValue ();
pp->perspective.projection_yaw = projection_yaw->getValue (); pp->perspective.projection_yaw = projection_yaw->getValue ();
if (method->get_active_row_number() == 0) {
pp->perspective.method = "simple";
} else if (method->get_active_row_number() == 1) {
pp->perspective.method = "camera_based";
}
if (pedited) { if (pedited) {
pedited->perspective.method = method->get_active_row_number() != 2;
pedited->perspective.horizontal = horiz->getEditedState (); pedited->perspective.horizontal = horiz->getEditedState ();
pedited->perspective.vertical = vert->getEditedState (); pedited->perspective.vertical = vert->getEditedState ();
pedited->perspective.camera_crop_factor= camera_crop_factor->getEditedState (); pedited->perspective.camera_crop_factor= camera_crop_factor->getEditedState ();
pedited->perspective.camera_focal_length = camera_focal_length->getEditedState (); pedited->perspective.camera_focal_length = camera_focal_length->getEditedState ();
pedited->perspective.camera_pitch = camera_pitch->getEditedState();
pedited->perspective.camera_shift_horiz = camera_shift_horiz->getEditedState(); pedited->perspective.camera_shift_horiz = camera_shift_horiz->getEditedState();
pedited->perspective.camera_shift_vert = camera_shift_vert->getEditedState(); pedited->perspective.camera_shift_vert = camera_shift_vert->getEditedState();
pedited->perspective.camera_yaw = camera_yaw->getEditedState();
pedited->perspective.projection_pitch = projection_pitch->getEditedState(); pedited->perspective.projection_pitch = projection_pitch->getEditedState();
pedited->perspective.projection_rotate = projection_rotate->getEditedState(); pedited->perspective.projection_rotate = projection_rotate->getEditedState();
pedited->perspective.projection_scale = projection_scale->getEditedState(); pedited->perspective.projection_scale = projection_scale->getEditedState();
@ -199,8 +255,10 @@ void PerspCorrection::setDefaults (const ProcParams* defParams, const ParamsEdit
vert->setDefault (defParams->perspective.vertical); vert->setDefault (defParams->perspective.vertical);
camera_crop_factor->setDefault (defParams->perspective.camera_crop_factor); camera_crop_factor->setDefault (defParams->perspective.camera_crop_factor);
camera_focal_length->setDefault (defParams->perspective.camera_focal_length); camera_focal_length->setDefault (defParams->perspective.camera_focal_length);
camera_pitch->setDefault (defParams->perspective.camera_pitch);
camera_shift_horiz->setDefault (defParams->perspective.camera_shift_horiz); camera_shift_horiz->setDefault (defParams->perspective.camera_shift_horiz);
camera_shift_vert->setDefault (defParams->perspective.camera_shift_vert); camera_shift_vert->setDefault (defParams->perspective.camera_shift_vert);
camera_yaw->setDefault (defParams->perspective.camera_yaw);
projection_pitch->setDefault (defParams->perspective.projection_pitch); projection_pitch->setDefault (defParams->perspective.projection_pitch);
projection_rotate->setDefault (defParams->perspective.projection_rotate); projection_rotate->setDefault (defParams->perspective.projection_rotate);
projection_scale->setDefault (defParams->perspective.projection_scale); projection_scale->setDefault (defParams->perspective.projection_scale);
@ -213,8 +271,10 @@ void PerspCorrection::setDefaults (const ProcParams* defParams, const ParamsEdit
vert->setDefaultEditedState (pedited->perspective.vertical ? Edited : UnEdited); vert->setDefaultEditedState (pedited->perspective.vertical ? Edited : UnEdited);
camera_crop_factor->setDefaultEditedState (pedited->perspective.camera_crop_factor ? Edited : UnEdited); camera_crop_factor->setDefaultEditedState (pedited->perspective.camera_crop_factor ? Edited : UnEdited);
camera_focal_length->setDefaultEditedState (pedited->perspective.camera_focal_length ? Edited : UnEdited); camera_focal_length->setDefaultEditedState (pedited->perspective.camera_focal_length ? Edited : UnEdited);
camera_pitch->setDefaultEditedState (pedited->perspective.camera_pitch ? Edited : UnEdited);
camera_shift_horiz->setDefaultEditedState (pedited->perspective.camera_shift_horiz ? Edited : UnEdited); camera_shift_horiz->setDefaultEditedState (pedited->perspective.camera_shift_horiz ? Edited : UnEdited);
camera_shift_vert->setDefaultEditedState (pedited->perspective.camera_shift_vert ? Edited : UnEdited); camera_shift_vert->setDefaultEditedState (pedited->perspective.camera_shift_vert ? Edited : UnEdited);
camera_yaw->setDefaultEditedState (pedited->perspective.camera_yaw ? Edited : UnEdited);
projection_pitch->setDefaultEditedState (pedited->perspective.projection_pitch ? Edited : UnEdited); projection_pitch->setDefaultEditedState (pedited->perspective.projection_pitch ? Edited : UnEdited);
projection_rotate->setDefaultEditedState (pedited->perspective.projection_rotate ? Edited : UnEdited); projection_rotate->setDefaultEditedState (pedited->perspective.projection_rotate ? Edited : UnEdited);
projection_scale->setDefaultEditedState (pedited->perspective.projection_scale ? Edited : UnEdited); projection_scale->setDefaultEditedState (pedited->perspective.projection_scale ? Edited : UnEdited);
@ -226,8 +286,10 @@ void PerspCorrection::setDefaults (const ProcParams* defParams, const ParamsEdit
vert->setDefaultEditedState (Irrelevant); vert->setDefaultEditedState (Irrelevant);
camera_crop_factor->setDefaultEditedState (Irrelevant); camera_crop_factor->setDefaultEditedState (Irrelevant);
camera_focal_length->setDefaultEditedState (Irrelevant); camera_focal_length->setDefaultEditedState (Irrelevant);
camera_pitch->setDefaultEditedState (Irrelevant);
camera_shift_horiz->setDefaultEditedState (Irrelevant); camera_shift_horiz->setDefaultEditedState (Irrelevant);
camera_shift_vert->setDefaultEditedState (Irrelevant); camera_shift_vert->setDefaultEditedState (Irrelevant);
camera_yaw->setDefaultEditedState (Irrelevant);
projection_pitch->setDefaultEditedState (Irrelevant); projection_pitch->setDefaultEditedState (Irrelevant);
projection_rotate->setDefaultEditedState (Irrelevant); projection_rotate->setDefaultEditedState (Irrelevant);
projection_scale->setDefaultEditedState (Irrelevant); projection_scale->setDefaultEditedState (Irrelevant);
@ -261,6 +323,13 @@ void PerspCorrection::adjusterChanged(Adjuster* a, double newval)
camera_shift_horiz->getValue(), camera_shift_horiz->getValue(),
M("TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL"), M("TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL"),
camera_shift_vert->getValue())); camera_shift_vert->getValue()));
} else if (a == camera_pitch || a == camera_yaw) {
listener->panelChanged (EvPerspCamAngle,
Glib::ustring::compose("%1=%2\n%3=%4",
M("TP_PERSPECTIVE_CAMERA_YAW"),
camera_yaw->getValue(),
M("TP_PERSPECTIVE_CAMERA_PITCH"),
camera_pitch->getValue()));
} else if (a == projection_shift_horiz || a == projection_shift_vert) { } else if (a == projection_shift_horiz || a == projection_shift_vert) {
listener->panelChanged (EvPerspProjShift, listener->panelChanged (EvPerspProjShift,
Glib::ustring::compose("%1=%2\n%3=%4", Glib::ustring::compose("%1=%2\n%3=%4",
@ -285,15 +354,37 @@ void PerspCorrection::adjusterChanged(Adjuster* a, double newval)
} }
} }
void PerspCorrection::setAdjusterBehavior (bool badd, bool camera_focal_length_add, bool camera_shift_add, bool projection_angle_add, bool projection_shift_add, bool projection_rotate_add, bool projection_scale_add) void PerspCorrection::methodChanged (void)
{
if (!batchMode) {
removeIfThere (this, simple, false);
removeIfThere (this, camera_based, false);
if (method->get_active_row_number() == 0) {
pack_start (*simple);
} else if (method->get_active_row_number() == 1) {
pack_start (*camera_based);
}
}
if (listener) {
listener->panelChanged (EvPerspMethod, method->get_active_text ());
}
}
void PerspCorrection::setAdjusterBehavior (bool badd, bool camera_focal_length_add, bool camera_shift_add, bool camera_angle_add, bool projection_angle_add, bool projection_shift_add, bool projection_rotate_add, bool projection_scale_add)
{ {
horiz->setAddMode(badd); horiz->setAddMode(badd);
vert->setAddMode(badd); vert->setAddMode(badd);
camera_crop_factor->setAddMode(camera_focal_length_add); camera_crop_factor->setAddMode(camera_focal_length_add);
camera_focal_length->setAddMode(camera_focal_length_add); camera_focal_length->setAddMode(camera_focal_length_add);
camera_pitch->setAddMode(camera_angle_add);
camera_shift_horiz->setAddMode(camera_shift_add); camera_shift_horiz->setAddMode(camera_shift_add);
camera_shift_vert->setAddMode(camera_shift_add); camera_shift_vert->setAddMode(camera_shift_add);
camera_yaw->setAddMode(camera_angle_add);
projection_pitch->setAddMode(projection_angle_add); projection_pitch->setAddMode(projection_angle_add);
projection_rotate->setAddMode(projection_rotate_add); projection_rotate->setAddMode(projection_rotate_add);
projection_scale->setAddMode(projection_scale_add); projection_scale->setAddMode(projection_scale_add);
@ -309,8 +400,10 @@ void PerspCorrection::trimValues (rtengine::procparams::ProcParams* pp)
vert->trimValue(pp->perspective.vertical); vert->trimValue(pp->perspective.vertical);
camera_crop_factor->trimValue(pp->perspective.camera_crop_factor); camera_crop_factor->trimValue(pp->perspective.camera_crop_factor);
camera_focal_length->trimValue(pp->perspective.camera_focal_length); camera_focal_length->trimValue(pp->perspective.camera_focal_length);
camera_pitch->trimValue(pp->perspective.camera_pitch);
camera_shift_horiz->trimValue(pp->perspective.camera_shift_horiz); camera_shift_horiz->trimValue(pp->perspective.camera_shift_horiz);
camera_shift_vert->trimValue(pp->perspective.camera_shift_vert); camera_shift_vert->trimValue(pp->perspective.camera_shift_vert);
camera_yaw->trimValue(pp->perspective.camera_yaw);
projection_pitch->trimValue(pp->perspective.projection_pitch); projection_pitch->trimValue(pp->perspective.projection_pitch);
projection_rotate->trimValue(pp->perspective.projection_rotate); projection_rotate->trimValue(pp->perspective.projection_rotate);
projection_scale->trimValue(pp->perspective.projection_scale); projection_scale->trimValue(pp->perspective.projection_scale);
@ -327,12 +420,16 @@ void PerspCorrection::setBatchMode (bool batchMode)
vert->showEditedCB (); vert->showEditedCB ();
camera_crop_factor->showEditedCB (); camera_crop_factor->showEditedCB ();
camera_focal_length->showEditedCB (); camera_focal_length->showEditedCB ();
camera_pitch->showEditedCB ();
camera_shift_horiz->showEditedCB (); camera_shift_horiz->showEditedCB ();
camera_shift_vert->showEditedCB (); camera_shift_vert->showEditedCB ();
camera_yaw->showEditedCB ();
projection_pitch->showEditedCB (); projection_pitch->showEditedCB ();
projection_rotate->showEditedCB (); projection_rotate->showEditedCB ();
projection_scale->showEditedCB (); projection_scale->showEditedCB ();
projection_shift_horiz->showEditedCB (); projection_shift_horiz->showEditedCB ();
projection_shift_vert->showEditedCB (); projection_shift_vert->showEditedCB ();
projection_yaw->showEditedCB (); projection_yaw->showEditedCB ();
method->append (M("GENERAL_UNCHANGED"));
} }

View File

@ -30,12 +30,17 @@ class PerspCorrection final :
{ {
protected: protected:
MyComboBoxText* method;
Gtk::VBox* simple;
Adjuster* horiz; Adjuster* horiz;
Adjuster* vert; Adjuster* vert;
Gtk::VBox* camera_based;
Adjuster* camera_crop_factor; Adjuster* camera_crop_factor;
Adjuster* camera_focal_length; Adjuster* camera_focal_length;
Adjuster* camera_pitch;
Adjuster* camera_shift_horiz; Adjuster* camera_shift_horiz;
Adjuster* camera_shift_vert; Adjuster* camera_shift_vert;
Adjuster* camera_yaw;
Adjuster* projection_pitch; Adjuster* projection_pitch;
Adjuster* projection_rotate; Adjuster* projection_rotate;
Adjuster* projection_scale; Adjuster* projection_scale;
@ -53,6 +58,7 @@ public:
void setBatchMode (bool batchMode) override; void setBatchMode (bool batchMode) override;
void adjusterChanged (Adjuster* a, double newval) override; void adjusterChanged (Adjuster* a, double newval) override;
void setAdjusterBehavior (bool badd, bool camera_focal_length_add, bool camera_shift_add, bool projection_angle_add, bool projection_shift_add, bool projection_rotate_add, bool projection_scale_add); void methodChanged (void);
void setAdjusterBehavior (bool badd, bool camera_focal_length_add, bool camera_shift_add, bool camera_angle_add, bool projection_angle_add, bool projection_shift_add, bool projection_rotate_add, bool projection_scale_add);
void trimValues (rtengine::procparams::ProcParams* pp) override; void trimValues (rtengine::procparams::ProcParams* pp) override;
}; };

View File

@ -343,13 +343,14 @@ Gtk::Widget* Preferences::getBatchProcPanel ()
mi = behModel->append (); mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_PERSPECTIVE_LABEL")); mi->set_value (behavColumns.label, M ("TP_PERSPECTIVE_LABEL"));
appendBehavList (mi, M ("TP_PERSPECTIVE_HORIZONTAL") + ", " + M ("TP_PERSPECTIVE_VERTICAL"), ADDSET_PERSPECTIVE, false); appendBehavList (mi, M ("TP_PERSPECTIVE_METHOD_SIMPLE") + " - " + M ("TP_PERSPECTIVE_HORIZONTAL") + ", " + M ("TP_PERSPECTIVE_VERTICAL"), ADDSET_PERSPECTIVE, false);
appendBehavList (mi, M ("TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH") + ", " + M ("TP_PERSPECTIVE_CAMERA_CROP_FACTOR"), ADDSET_PERSP_CAM_FOCAL_LENGTH, false); appendBehavList (mi, M ("TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH") + ", " + M ("TP_PERSPECTIVE_CAMERA_CROP_FACTOR"), ADDSET_PERSP_CAM_FOCAL_LENGTH, false);
appendBehavList (mi, M ("TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL") + ", " + M ("TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL"), ADDSET_PERSP_CAM_SHIFT, false); appendBehavList (mi, M ("TP_PERSPECTIVE_CAMERA_FRAME") + " - " + M ("TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL") + ", " + M ("TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL"), ADDSET_PERSP_CAM_SHIFT, false);
appendBehavList (mi, M ("TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL") + ", " + M ("TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL"), ADDSET_PERSP_PROJ_SHIFT, false); appendBehavList (mi, M ("TP_PERSPECTIVE_CAMERA_FRAME") + " - " + M ("TP_PERSPECTIVE_CAMERA_YAW") + ", " + M ("TP_PERSPECTIVE_CAMERA_PITCH"), ADDSET_PERSP_CAM_ANGLE, false);
appendBehavList (mi, M ("TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME") + " - " + M ("TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL") + ", " + M ("TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL"), ADDSET_PERSP_PROJ_SHIFT, false);
appendBehavList (mi, M ("TP_PERSPECTIVE_PROJECTION_ROTATE"), ADDSET_PERSP_PROJ_ROTATE, false); appendBehavList (mi, M ("TP_PERSPECTIVE_PROJECTION_ROTATE"), ADDSET_PERSP_PROJ_ROTATE, false);
appendBehavList (mi, M ("TP_PERSPECTIVE_PROJECTION_SCALE"), ADDSET_PERSP_PROJ_SCALE, false); appendBehavList (mi, M ("TP_PERSPECTIVE_PROJECTION_SCALE"), ADDSET_PERSP_PROJ_SCALE, false);
appendBehavList (mi, M ("TP_PERSPECTIVE_PROJECTION_YAW") + ", " + M ("TP_PERSPECTIVE_PROJECTION_PITCH"), ADDSET_PERSP_PROJ_ANGLE, false); appendBehavList (mi, M ("TP_PERSPECTIVE_RECOVERY_FRAME") + " - " + M ("TP_PERSPECTIVE_PROJECTION_YAW") + ", " + M ("TP_PERSPECTIVE_PROJECTION_PITCH"), ADDSET_PERSP_PROJ_ANGLE, false);
mi = behModel->append (); mi = behModel->append ();
mi->set_value (behavColumns.label, M ("TP_GRADIENT_LABEL")); mi->set_value (behavColumns.label, M ("TP_GRADIENT_LABEL"));