diff --git a/rtdata/languages/default b/rtdata/languages/default index 376eb6072..776074d5e 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -727,6 +727,12 @@ HISTORY_MSG_491;White Balance HISTORY_MSG_492;RGB Curves HISTORY_MSG_493;L*a*b* Adjustments HISTORY_MSG_494;Capture Sharpening +HISTORY_MSG_496;Perspective - Camera +HISTORY_MSG_497;Perspective - Camera +HISTORY_MSG_498;Perspective - Recovery +HISTORY_MSG_499;Perspective - PCA - Rotation +HISTORY_MSG_500;Perspective - PCA - Scale +HISTORY_MSG_501;Perspective - PCA - Shift HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1803,11 +1809,19 @@ TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse, TP_PCVIGNETTE_STRENGTH;Strength TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). TP_PDSHARPENING_LABEL;Capture Sharpening -TP_PERSPECTIVE_FOV;Field of view +TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Crop factor +TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Focal length +TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontal shift +TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Vertical shift TP_PERSPECTIVE_HORIZONTAL;Horizontal TP_PERSPECTIVE_LABEL;Perspective +TP_PERSPECTIVE_PROJECTION_PITCH;Vertical +TP_PERSPECTIVE_PROJECTION_ROTATE;Rotation +TP_PERSPECTIVE_PROJECTION_SCALE;Scale +TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL;Horizontal shift +TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL;Vertical shift +TP_PERSPECTIVE_PROJECTION_YAW;Horizontal TP_PERSPECTIVE_VERTICAL;Vertical -TP_PERSPECTIVE_VERTICAL_BIAS;Vertical bias TP_PFCURVE_CURVEEDITOR_CH;Hue TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. TP_PREPROCESS_DEADPIXFILT;Dead pixel filter diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 7e509d584..46c0601e0 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -21,6 +21,7 @@ #include "imagefloat.h" #include "improcfun.h" +#include "homogeneouscoordinates.h" #include "procparams.h" #include "rt_math.h" #include "rtengine.h" @@ -203,6 +204,84 @@ namespace rtengine #define CLIPTOC(a,b,c,d) ((a)>=(b)?((a)<=(c)?(a):(d=true,(c))):(d=true,(b))) +/** + * Creates an inverse transformation matrix for camera-geometry-based + * perspective correction. Unless otherwise specified, units are the same as the + * units of the vectors which the matrix will transform. The projection_* + * parameters are applied in the order they appear. + * @param camera_focal_length Camera's focal length. + * @param camera_shift_horiz Camera lens's shift to the right. + * @param camera_shift_vert Camera lens's shift upwards. + * @param camera_pitch Camera's pitch in radians. Up is positive. + * @param camera_yaw Camera's yaw in radians. Right is positive. + * Up is positive. + * @param projection_shift_horiz Shift of perspective-corrected image to the + * right. + * @param projection_shift_vert Shift of perspective-corrected image upwards. + * @param projection_rotate Rotation of perspective-corrected image + * counter-clockwise in radians. + * @param projection_yaw Yaw in radians of simulated perspective distortion. + * Right is positive. + * @param projection_pitch Pitch in radians of simulated perspective distortion. + * Up is positive. + * @param projection_scale Scale factor of perspective-corrected image. + */ +homogeneous::Matrix perspectiveMatrix(double camera_focal_length, double + camera_shift_horiz, double camera_shift_vert, double camera_pitch, + double camera_yaw, double projection_yaw, double projection_pitch, + double projection_rotate, double projection_shift_horiz, double + projection_shift_vert, double projection_scale) +{ + const double projection_scale_inverse = 1.0 / projection_scale; + homogeneous::Vector center; + center[0] = 0; + center[1] = 0; + center[2] = camera_focal_length; + center[3] = 1; + + // Locations of image center after rotations. + const homogeneous::Vector camera_center_yaw_pitch = + homogeneous::rotationMatrix(camera_yaw, homogeneous::Axis::Y) * + homogeneous::rotationMatrix(camera_pitch, homogeneous::Axis::X) * + center; + const homogeneous::Vector projection_center_yaw_pitch = + homogeneous::rotationMatrix(-projection_yaw, homogeneous::Axis::Y) * + homogeneous::rotationMatrix(-projection_pitch, homogeneous::Axis::X) * + center; + + // The following comments refer to the forward transformation. + const homogeneous::Matrix matrix = + // Lens/sensor shift and move to z == camera_focal_length. + homogeneous::translationMatrix(-camera_shift_horiz, + -camera_shift_vert, -camera_focal_length) * + // Perspective correction. + homogeneous::projectionMatrix(camera_focal_length, homogeneous::Axis::Z) * + homogeneous::rotationMatrix(-camera_pitch, homogeneous::Axis::X) * + homogeneous::rotationMatrix(-camera_yaw, homogeneous::Axis::Y) * + // Re-center after perspective rotation. + homogeneous::translationMatrix(camera_center_yaw_pitch[0], + camera_center_yaw_pitch[1], camera_center_yaw_pitch[2] - camera_focal_length) * + // Translate corrected image. + homogeneous::translationMatrix(-projection_shift_horiz, + -projection_shift_vert, 0) * + // Rotate corrected image. + homogeneous::rotationMatrix(projection_rotate, homogeneous::Axis::Z) * + // Un-center for perspective rotation. + homogeneous::translationMatrix(projection_center_yaw_pitch[0], + projection_center_yaw_pitch[1], camera_focal_length - projection_center_yaw_pitch[2]) * + // Simulate perspective transformation. + homogeneous::projectionMatrix(projection_center_yaw_pitch[2], homogeneous::Axis::Z) * + homogeneous::rotationMatrix(projection_yaw, homogeneous::Axis::Y) * + homogeneous::rotationMatrix(projection_pitch, homogeneous::Axis::X) * + // Move to z == 0. + homogeneous::translationMatrix(0, 0, camera_focal_length) * + // Scale corrected image. + homogeneous::scaleMatrix(projection_scale_inverse, + projection_scale_inverse, 1); + + return matrix; +} + bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef, const LensCorrection *pLCPMap) const { @@ -239,34 +318,24 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, double ascale = ascaleDef > 0 ? ascaleDef : (params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0); // auxiliary variables for perspective correction - const double f = maxRadius / tan(params->perspective.fov / 360.0 * rtengine::RT_PI); - const double phtheta = params->perspective.horizontal / -180.0 * rtengine::RT_PI; - const double pvtheta = params->perspective.vertical / -180.0 * rtengine::RT_PI; - const double pbtheta = params->perspective.vBias / -180.0 * rtengine::RT_PI; - const double phcos = cos(phtheta); - const double pvcos = cos(pvtheta); - const double pbcos = cos(pbtheta); - const double phsin = sin(phtheta); - const double pvsin = sin(pvtheta); - const double pbsin = sin(pbtheta); - // Coordinates of distorted image center. - const double pxoffset = f * phsin * pvcos; - const double pyoffset = -f * (phcos * pvcos * pbsin + pvsin * pbcos); - const double pz = f * (phcos * pvcos * pbcos - pvsin * pbsin); - // Inverse transformation matrix. - const double p_xx = f * phcos; - const double p_xy = f * phsin * pbsin; - const double p_xz = f * phsin * pbcos; - const double p_yx = f * phsin * pvsin; - const double p_yy = f * (pvcos * pbcos - phcos * pvsin * pbsin); - const double p_yz = f * (-pvcos * pbsin - phcos * pvsin * pbcos); - const double p_zx = -phsin * pvcos; - const double p_zy = phcos * pvcos * pbsin + pvsin * pbcos; - const double p_zz = phcos * pvcos * pbcos - pvsin * pbsin; - // z is known, can calculate these in advance. - const double pz_xz = pz * p_xz; - const double pz_yz = pz * p_yz; - const double pz_zz = pz * p_zz; + const double f = params->perspective.camera_focal_length * + params->perspective.camera_crop_factor * (maxRadius / sqrt(18.0*18.0 + + 12.0*12.0)); + const double p_camera_yaw = params->perspective.horizontal / 180.0 * rtengine::RT_PI; + const double p_camera_pitch = params->perspective.vertical / 180.0 * rtengine::RT_PI; + 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_projection_shift_horiz = oW / 100.0 * params->perspective.projection_shift_horiz; + const double p_projection_shift_vert = oH / -100.0 * params->perspective.projection_shift_vert; + const double p_projection_rotate = params->perspective.projection_rotate * rtengine::RT_PI_180; + const double p_projection_yaw = -params->perspective.projection_yaw * rtengine::RT_PI_180; + const double p_projection_pitch = -params->perspective.projection_pitch * rtengine::RT_PI_180; + const double p_projection_scale = params->perspective.projection_scale; + const homogeneous::Matrix p_matrix = perspectiveMatrix(f, + p_camera_shift_horiz, p_camera_shift_vert, p_camera_pitch, + p_camera_yaw, p_projection_yaw, p_projection_pitch, + p_projection_rotate, p_projection_shift_horiz, + p_projection_shift_vert, p_projection_scale); for (size_t i = 0; i < src.size(); i++) { double x_d = src[i].x, y_d = src[i].y; @@ -282,13 +351,11 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, y_d += ascale * (0 - h2); // centering y coord & scale if (needsPerspective()) { - x_d -= pxoffset; - y_d -= pyoffset; - const double normalizer = p_zx * x_d + p_zy * y_d + pz_zz; - const double x_d_new = p_xx * x_d + p_xy * y_d + pz_xz; - y_d = p_yx * x_d + p_yy * y_d + pz_yz; - x_d = x_d_new / normalizer; - y_d /= normalizer; + 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; } // rotate @@ -928,34 +995,24 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I const double centerFactory = cy - h2; // auxiliary variables for perspective correction - const double f = maxRadius / tan(params->perspective.fov / 360.0 * rtengine::RT_PI); - const double phtheta = params->perspective.horizontal / -180.0 * rtengine::RT_PI; - const double pvtheta = params->perspective.vertical / -180.0 * rtengine::RT_PI; - const double pbtheta = params->perspective.vBias / -180.0 * rtengine::RT_PI; - const double phcos = cos(phtheta); - const double pvcos = cos(pvtheta); - const double pbcos = cos(pbtheta); - const double phsin = sin(phtheta); - const double pvsin = sin(pvtheta); - const double pbsin = sin(pbtheta); - // Coordinates of distorted image center. - const double pxoffset = f * phsin * pvcos; - const double pyoffset = -f * (phcos * pvcos * pbsin + pvsin * pbcos); - const double pz = f * (phcos * pvcos * pbcos - pvsin * pbsin); - // Inverse transformation matrix. - const double p_xx = f * phcos; - const double p_xy = f * phsin * pbsin; - const double p_xz = f * phsin * pbcos; - const double p_yx = f * phsin * pvsin; - const double p_yy = f * (pvcos * pbcos - phcos * pvsin * pbsin); - const double p_yz = f * (-pvcos * pbsin - phcos * pvsin * pbcos); - const double p_zx = -phsin * pvcos; - const double p_zy = phcos * pvcos * pbsin + pvsin * pbcos; - const double p_zz = phcos * pvcos * pbcos - pvsin * pbsin; - // z is known, can calculate these in advance. - const double pz_xz = pz * p_xz; - const double pz_yz = pz * p_yz; - const double pz_zz = pz * p_zz; + const double f = params->perspective.camera_focal_length * + params->perspective.camera_crop_factor * (maxRadius / sqrt(18.0*18.0 + + 12.0*12.0)); + const double p_camera_yaw = params->perspective.horizontal / 180.0 * rtengine::RT_PI; + const double p_camera_pitch = params->perspective.vertical / 180.0 * rtengine::RT_PI; + 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_projection_shift_horiz = oW / 100.0 * params->perspective.projection_shift_horiz; + const double p_projection_shift_vert = oH / -100.0 * params->perspective.projection_shift_vert; + const double p_projection_rotate = params->perspective.projection_rotate * rtengine::RT_PI_180; + const double p_projection_yaw = -params->perspective.projection_yaw * rtengine::RT_PI_180; + const double p_projection_pitch = -params->perspective.projection_pitch * rtengine::RT_PI_180; + const double p_projection_scale = params->perspective.projection_scale; + const homogeneous::Matrix p_matrix = perspectiveMatrix(f, + p_camera_shift_horiz, p_camera_shift_vert, p_camera_pitch, + p_camera_yaw, p_projection_yaw, p_projection_pitch, + p_projection_rotate, p_projection_shift_horiz, + p_projection_shift_vert, p_projection_scale); // main cycle #ifdef _OPENMP @@ -978,13 +1035,11 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I y_d += ascale * centerFactory; // centering y coord & scale if (enablePerspective) { - x_d -= pxoffset; - y_d -= pyoffset; - const double normalizer = p_zx * x_d + p_zy * y_d + pz_zz; - const double x_d_new = p_xx * x_d + p_xy * y_d + pz_xz; - y_d = p_yx * x_d + p_yy * y_d + pz_yz; - x_d = x_d_new / normalizer; - y_d /= normalizer; + 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; } // rotate @@ -1182,7 +1237,15 @@ bool ImProcFunctions::needsRotation () const bool ImProcFunctions::needsPerspective () const { - return params->perspective.horizontal || params->perspective.vertical || params->perspective.vBias; + return params->perspective.horizontal || params->perspective.vertical || + params->perspective.camera_shift_horiz || + params->perspective.camera_shift_vert || + params->perspective.projection_pitch || + 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 diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 1b00d4218..dddfdea30 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -518,6 +518,12 @@ enum ProcEventCode { EvLEnabled = 492, EvPdShrEnabled = 493, EvPdShrMaskToggled = 494, + EvPerspCamFocalLength = 495, + EvPerspCamShift = 496, + EvPerspProjAngle = 497, + EvPerspProjRotate = 498, + EvPerspProjScale = 499, + EvPerspProjShift = 500, NUMOFEVENTS diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 16f06b71f..dbabc9165 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1852,8 +1852,16 @@ LensProfParams::LcMode LensProfParams::getMethodNumber(const Glib::ustring& mode PerspectiveParams::PerspectiveParams() : horizontal(0.0), vertical(0.0), - vBias(0.0), - fov(65.0) + camera_crop_factor(1.0), + camera_focal_length(24.0), + camera_shift_horiz(0.0), + camera_shift_vert(0.0), + projection_pitch(0.0), + projection_rotate(0.0), + projection_scale(1.0), + projection_shift_horiz(0.0), + projection_shift_vert(0.0), + projection_yaw(0.0) { } @@ -1862,8 +1870,16 @@ bool PerspectiveParams::operator ==(const PerspectiveParams& other) const return horizontal == other.horizontal && vertical == other.vertical - && vBias == other.vBias - && fov == other.fov; + && camera_focal_length == other.camera_focal_length + && camera_crop_factor == other.camera_crop_factor + && camera_shift_horiz == other.camera_shift_horiz + && camera_shift_vert == other.camera_shift_vert + && projection_shift_horiz == other.projection_shift_horiz + && projection_shift_vert == other.projection_shift_vert + && projection_scale == other.projection_scale + && projection_rotate == other.projection_rotate + && projection_pitch == other.projection_pitch + && projection_yaw == other.projection_yaw; } bool PerspectiveParams::operator !=(const PerspectiveParams& other) const @@ -3347,8 +3363,16 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Perspective correction saveToKeyfile(!pedited || pedited->perspective.horizontal, "Perspective", "Horizontal", perspective.horizontal, keyFile); saveToKeyfile(!pedited || pedited->perspective.vertical, "Perspective", "Vertical", perspective.vertical, keyFile); - saveToKeyfile(!pedited || pedited->perspective.vBias, "Perspective", "VerticalBias", perspective.vBias, keyFile); - saveToKeyfile(!pedited || pedited->perspective.fov, "Perspective", "FOV", perspective.fov, 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_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.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_scale, "Perspective", "ProjectionScale", perspective.projection_scale, keyFile); + saveToKeyfile(!pedited || pedited->perspective.projection_shift_horiz, "Perspective", "ProjectionShiftHorizontal", perspective.projection_shift_horiz, keyFile); + saveToKeyfile(!pedited || pedited->perspective.projection_shift_vert, "Perspective", "ProjectionShiftVertical", perspective.projection_shift_vert, keyFile); + saveToKeyfile(!pedited || pedited->perspective.projection_yaw, "Perspective", "ProjectionYaw", perspective.projection_yaw, keyFile); // Gradient saveToKeyfile(!pedited || pedited->gradient.enabled, "Gradient", "Enabled", gradient.enabled, keyFile); @@ -4426,8 +4450,16 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("Perspective")) { assignFromKeyfile(keyFile, "Perspective", "Horizontal", pedited, perspective.horizontal, pedited->perspective.horizontal); assignFromKeyfile(keyFile, "Perspective", "Vertical", pedited, perspective.vertical, pedited->perspective.vertical); - assignFromKeyfile(keyFile, "Perspective", "VerticalBias", pedited, perspective.vBias, pedited->perspective.vBias); - assignFromKeyfile(keyFile, "Perspective", "FOV", pedited, perspective.fov, pedited->perspective.fov); + 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", "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", "ProjectionPitch", pedited, perspective.projection_pitch, pedited->perspective.projection_pitch); + 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", "ProjectionShiftHorizontal", pedited, perspective.projection_shift_horiz, pedited->perspective.projection_shift_horiz); + assignFromKeyfile(keyFile, "Perspective", "ProjectionShiftVertical", pedited, perspective.projection_shift_vert, pedited->perspective.projection_shift_vert); + assignFromKeyfile(keyFile, "Perspective", "ProjectionYaw", pedited, perspective.projection_yaw, pedited->perspective.projection_yaw); } if (keyFile.has_group("Gradient")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 956a0ac0c..eb251a9d0 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -907,8 +907,16 @@ struct LensProfParams { struct PerspectiveParams { double horizontal; double vertical; - double vBias; - double fov; + double camera_crop_factor; + double camera_focal_length; + double camera_shift_horiz; + double camera_shift_vert; + double projection_pitch; + double projection_rotate; + double projection_scale; + double projection_shift_horiz; + double projection_shift_vert; + double projection_yaw; PerspectiveParams(); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index b77eac29c..aeb783ae5 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -521,7 +521,13 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RGBCURVE, // EvRGBEnabled LUMINANCECURVE, // EvLEnabled DEMOSAIC, // EvPdShrEnabled - CAPTURESHARPEN // EvPdShrMaskToggled + CAPTURESHARPEN, // EvPdShrMaskToggled + TRANSFORM, // EvPerspCamFocalLength + TRANSFORM, // EvPerspCamShift + TRANSFORM, // EvPerspProjAngle + TRANSFORM, // EvPerspProjRotate + TRANSFORM, // EvPerspProjScale + TRANSFORM // EvPerspProjShift }; diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 05150517f..dd21f9a89 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -18,6 +18,12 @@ enum { ADDSET_ROTATE_DEGREE, ADDSET_DIST_AMOUNT, ADDSET_PERSPECTIVE, + ADDSET_PERSP_CAM_FOCAL_LENGTH, + ADDSET_PERSP_CAM_SHIFT, + ADDSET_PERSP_PROJ_ANGLE, + ADDSET_PERSP_PROJ_ROTATE, + ADDSET_PERSP_PROJ_SCALE, + ADDSET_PERSP_PROJ_SHIFT, ADDSET_CA, ADDSET_VIGN_AMOUNT, ADDSET_VIGN_RADIUS, diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 2824a285c..da7073b71 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -151,7 +151,7 @@ void BatchToolPanelCoordinator::initSession () rotate->setAdjusterBehavior (false); resize->setAdjusterBehavior (false); distortion->setAdjusterBehavior (false); - perspective->setAdjusterBehavior (false); + perspective->setAdjusterBehavior (false, false, false, false, false, false, false); gradient->setAdjusterBehavior (false, false, false, false); pcvignette->setAdjusterBehavior (false, false, false); cacorrection->setAdjusterBehavior (false); @@ -196,7 +196,7 @@ void BatchToolPanelCoordinator::initSession () rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]); resize->setAdjusterBehavior (options.baBehav[ADDSET_RESIZE_SCALE]); distortion->setAdjusterBehavior (options.baBehav[ADDSET_DIST_AMOUNT]); - perspective->setAdjusterBehavior (options.baBehav[ADDSET_PERSPECTIVE]); + 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]); 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]); cacorrection->setAdjusterBehavior (options.baBehav[ADDSET_CA]); @@ -308,6 +308,12 @@ void BatchToolPanelCoordinator::initSession () if (options.baBehav[ADDSET_RESIZE_SCALE]) { pparams.resize.scale = 0; } if (options.baBehav[ADDSET_DIST_AMOUNT]) { pparams.distortion.amount = 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_SHIFT]) { pparams.perspective.camera_shift_horiz = pparams.perspective.camera_shift_vert = 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_ROTATE]) { pparams.perspective.projection_rotate = 0; } + if (options.baBehav[ADDSET_PERSP_PROJ_SCALE]) { pparams.perspective.projection_scale = 0; } if (options.baBehav[ADDSET_GRADIENT_DEGREE]) { pparams.gradient.degree = 0; } if (options.baBehav[ADDSET_GRADIENT_FEATHER]) { pparams.gradient.feather = 0; } if (options.baBehav[ADDSET_GRADIENT_STRENGTH]) { pparams.gradient.strength = 0; } diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ce7f3400c..ddd6146a3 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -336,8 +336,16 @@ void ParamsEdited::set(bool v) lensProf.lfLens = v; perspective.horizontal = v; perspective.vertical = v; - perspective.vBias = v; - perspective.fov = v; + perspective.camera_crop_factor = v; + perspective.camera_focal_length = v; + perspective.camera_shift_horiz = v; + perspective.camera_shift_vert = v; + perspective.projection_pitch = v; + perspective.projection_rotate = v; + perspective.projection_scale = v; + perspective.projection_shift_horiz = v; + perspective.projection_shift_vert = v; + perspective.projection_yaw = v; gradient.enabled = v; gradient.degree = v; gradient.feather = v; @@ -921,8 +929,16 @@ void ParamsEdited::initFrom(const std::vector& lensProf.lfLens = lensProf.lfLens && p.lensProf.lfLens == other.lensProf.lfLens; perspective.horizontal = perspective.horizontal && p.perspective.horizontal == other.perspective.horizontal; perspective.vertical = perspective.vertical && p.perspective.vertical == other.perspective.vertical; - perspective.vBias = perspective.vBias && p.perspective.vBias == other.perspective.vBias; - perspective.fov = perspective.fov && p.perspective.fov == other.perspective.fov; + 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_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.projection_pitch = perspective.projection_pitch && p.perspective.projection_pitch == other.perspective.projection_pitch; + 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_shift_horiz = perspective.projection_shift_horiz && p.perspective.projection_shift_horiz == other.perspective.projection_shift_horiz; + perspective.projection_shift_vert = perspective.projection_shift_vert && p.perspective.projection_shift_vert == other.perspective.projection_shift_vert; + perspective.projection_yaw = perspective.projection_yaw && p.perspective.projection_yaw == other.perspective.projection_yaw; gradient.enabled = gradient.enabled && p.gradient.enabled == other.gradient.enabled; gradient.degree = gradient.degree && p.gradient.degree == other.gradient.degree; gradient.feather = gradient.feather && p.gradient.feather == other.gradient.feather; @@ -2321,12 +2337,44 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.perspective.vertical = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.vertical + mods.perspective.vertical : mods.perspective.vertical; } - if (perspective.vBias) { - toEdit.perspective.vBias = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.vBias + mods.perspective.vBias : mods.perspective.vBias; + if (perspective.camera_crop_factor) { + toEdit.perspective.camera_crop_factor = dontforceSet && options.baBehav[ADDSET_PERSP_CAM_FOCAL_LENGTH] ? toEdit.perspective.camera_crop_factor + mods.perspective.camera_crop_factor : mods.perspective.camera_crop_factor; } - if (perspective.fov) { - toEdit.perspective.fov = dontforceSet && options.baBehav[ADDSET_PERSPECTIVE] ? toEdit.perspective.fov + mods.perspective.fov : mods.perspective.fov; + if (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_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; + } + + if (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.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; + } + + if (perspective.projection_rotate) { + toEdit.perspective.projection_rotate = dontforceSet && options.baBehav[ADDSET_PERSP_PROJ_ROTATE] ? toEdit.perspective.projection_rotate + mods.perspective.projection_rotate : mods.perspective.projection_rotate; + } + + if (perspective.projection_scale) { + toEdit.perspective.projection_scale = dontforceSet && options.baBehav[ADDSET_PERSP_PROJ_SCALE] ? toEdit.perspective.projection_scale + mods.perspective.projection_scale : mods.perspective.projection_scale; + } + + if (perspective.projection_shift_horiz) { + toEdit.perspective.projection_shift_horiz = dontforceSet && options.baBehav[ADDSET_PERSP_PROJ_SHIFT] ? toEdit.perspective.projection_shift_horiz + mods.perspective.projection_shift_horiz : mods.perspective.projection_shift_horiz; + } + + if (perspective.projection_shift_vert) { + toEdit.perspective.projection_shift_vert = dontforceSet && options.baBehav[ADDSET_PERSP_PROJ_SHIFT] ? toEdit.perspective.projection_shift_vert + mods.perspective.projection_shift_vert : mods.perspective.projection_shift_vert; + } + + if (perspective.projection_yaw) { + toEdit.perspective.projection_yaw = dontforceSet && options.baBehav[ADDSET_PERSP_PROJ_ANGLE] ? toEdit.perspective.projection_yaw + mods.perspective.projection_yaw : mods.perspective.projection_yaw; } if (gradient.enabled) { diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index aa1e10698..6403eba3b 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -396,8 +396,16 @@ struct LensProfParamsEdited { struct PerspectiveParamsEdited { bool horizontal; bool vertical; - bool vBias; - bool fov; + bool camera_crop_factor; + bool camera_focal_length; + bool camera_shift_horiz; + bool camera_shift_vert; + bool projection_pitch; + bool projection_rotate; + bool projection_scale; + bool projection_shift_horiz; + bool projection_shift_vert; + bool projection_yaw; }; struct GradientParamsEdited { diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc index 19bef6de6..a7c3900ad 100644 --- a/rtgui/perspective.cc +++ b/rtgui/perspective.cc @@ -32,8 +32,13 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M(" Gtk::Image* ipersHR = Gtk::manage (new RTImage ("perspective-horizontal-right-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* ipersBL = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png")); - Gtk::Image* ipersBR = 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_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_right = Gtk::manage (new RTImage ("perspective-vertical-top-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")); vert = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_VERTICAL"), -85, 85, 0.1, 0, ipersVL, ipersVR)); vert->setAdjusterListener (this); @@ -41,21 +46,54 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M(" horiz = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_HORIZONTAL"), -85, 85, 0.1, 0, ipersHL, ipersHR)); horiz->setAdjusterListener (this); - vBias = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_VERTICAL_BIAS"), -85, 85, 0.1, 0, ipersBL, ipersBR)); - vBias->setAdjusterListener (this); + camera_focal_length = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH"), 0.5, 2000, 0.01, 24)); + camera_focal_length->setAdjusterListener (this); - fov = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_FOV"), 0.1, 150, 0.1, 65)); - fov->setAdjusterListener (this); + camera_crop_factor = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_CROP_FACTOR"), 0.1, 30, 0.01, 1)); + camera_crop_factor->setAdjusterListener (this); + + camera_shift_horiz = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL"), -100, 100, 0.01, 0)); + camera_shift_horiz->setAdjusterListener (this); + + camera_shift_vert = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL"), -100, 100, 0.01, 0)); + camera_shift_vert->setAdjusterListener (this); + + projection_shift_horiz = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL"), -100, 100, 0.01, 0)); + projection_shift_horiz->setAdjusterListener (this); + + projection_shift_vert = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL"), -100, 100, 0.01, 0)); + projection_shift_vert->setAdjusterListener (this); + + projection_rotate = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_PROJECTION_ROTATE"), -180, 180, 0.01, 0, ipers_rotate_left, ipers_rotate_right)); + projection_rotate->setAdjusterListener (this); + + projection_scale = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_PROJECTION_SCALE"), 0.5, 2, 0.01, 1)); + projection_scale->setAdjusterListener (this); + + projection_pitch = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_PROJECTION_PITCH"), -85, 85, 0.1, 0, ipers_proj_pitch_left, ipers_proj_pitch_right)); + projection_pitch->setAdjusterListener (this); + + 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); pack_start (*vert); pack_start (*horiz); - pack_start (*vBias); - pack_start (*fov); + pack_start (*camera_focal_length); + pack_start (*camera_crop_factor); + pack_start (*camera_shift_horiz); + pack_start (*camera_shift_vert); + pack_start (*projection_shift_horiz); + pack_start (*projection_shift_vert); + pack_start (*projection_rotate); + pack_start (*projection_scale); + pack_start (*projection_yaw); + pack_start (*projection_pitch); horiz->setLogScale(2, 0); vert->setLogScale(2, 0); - vBias->setLogScale(2, 0); - fov->setLogScale(2, 0); + camera_focal_length->setLogScale(4000, 0.5); + camera_crop_factor->setLogScale(300, 0.1); + projection_scale->setLogScale(4, 0.5); show_all(); } @@ -68,14 +106,30 @@ void PerspCorrection::read (const ProcParams* pp, const ParamsEdited* pedited) if (pedited) { horiz->setEditedState (pedited->perspective.horizontal ? Edited : UnEdited); vert->setEditedState (pedited->perspective.vertical ? Edited : UnEdited); - vBias->setEditedState (pedited->perspective.vBias ? Edited : UnEdited); - fov->setEditedState (pedited->perspective.fov ? 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_shift_horiz->setEditedState (pedited->perspective.camera_shift_horiz ? Edited : UnEdited); + camera_shift_vert->setEditedState (pedited->perspective.camera_shift_vert ? Edited : UnEdited); + projection_pitch->setEditedState (pedited->perspective.projection_pitch ? Edited : UnEdited); + projection_rotate->setEditedState (pedited->perspective.projection_rotate ? Edited : UnEdited); + projection_scale->setEditedState (pedited->perspective.projection_scale ? Edited : UnEdited); + projection_shift_horiz->setEditedState (pedited->perspective.projection_shift_horiz ? Edited : UnEdited); + projection_shift_vert->setEditedState (pedited->perspective.projection_shift_vert ? Edited : UnEdited); + projection_yaw->setEditedState (pedited->perspective.projection_yaw ? Edited : UnEdited); } horiz->setValue (pp->perspective.horizontal); vert->setValue (pp->perspective.vertical); - vBias->setValue (pp->perspective.vBias); - fov->setValue (pp->perspective.fov); + camera_crop_factor->setValue (pp->perspective.camera_crop_factor); + camera_focal_length->setValue (pp->perspective.camera_focal_length); + camera_shift_horiz->setValue (pp->perspective.camera_shift_horiz); + camera_shift_vert->setValue (pp->perspective.camera_shift_vert); + projection_pitch->setValue (pp->perspective.projection_pitch); + projection_rotate->setValue (pp->perspective.projection_rotate); + projection_scale->setValue (pp->perspective.projection_scale); + projection_shift_horiz->setValue (pp->perspective.projection_shift_horiz); + projection_shift_vert->setValue (pp->perspective.projection_shift_vert); + projection_yaw->setValue (pp->perspective.projection_yaw); enableListener (); } @@ -85,14 +139,30 @@ void PerspCorrection::write (ProcParams* pp, ParamsEdited* pedited) pp->perspective.horizontal = horiz->getValue (); pp->perspective.vertical = vert->getValue (); - pp->perspective.vBias = vBias->getValue (); - pp->perspective.fov = fov->getValue (); + pp->perspective.camera_crop_factor= camera_crop_factor->getValue (); + pp->perspective.camera_focal_length = camera_focal_length->getValue (); + pp->perspective.camera_shift_horiz = camera_shift_horiz->getValue (); + pp->perspective.camera_shift_vert = camera_shift_vert->getValue (); + pp->perspective.projection_pitch = projection_pitch->getValue (); + pp->perspective.projection_rotate = projection_rotate->getValue (); + pp->perspective.projection_scale = projection_scale->getValue (); + pp->perspective.projection_shift_horiz = projection_shift_horiz->getValue (); + pp->perspective.projection_shift_vert = projection_shift_vert->getValue (); + pp->perspective.projection_yaw = projection_yaw->getValue (); if (pedited) { pedited->perspective.horizontal = horiz->getEditedState (); pedited->perspective.vertical = vert->getEditedState (); - pedited->perspective.vBias = vBias->getEditedState (); - pedited->perspective.fov = fov->getEditedState (); + pedited->perspective.camera_crop_factor= camera_crop_factor->getEditedState (); + pedited->perspective.camera_focal_length = camera_focal_length->getEditedState (); + pedited->perspective.camera_shift_horiz = camera_shift_horiz->getEditedState(); + pedited->perspective.camera_shift_vert = camera_shift_vert->getEditedState(); + pedited->perspective.projection_pitch = projection_pitch->getEditedState(); + pedited->perspective.projection_rotate = projection_rotate->getEditedState(); + pedited->perspective.projection_scale = projection_scale->getEditedState(); + pedited->perspective.projection_shift_horiz = projection_shift_horiz->getEditedState(); + pedited->perspective.projection_shift_vert = projection_shift_vert->getEditedState(); + pedited->perspective.projection_yaw = projection_yaw->getEditedState(); } } @@ -101,36 +171,109 @@ void PerspCorrection::setDefaults (const ProcParams* defParams, const ParamsEdit horiz->setDefault (defParams->perspective.horizontal); vert->setDefault (defParams->perspective.vertical); - vBias->setDefault (defParams->perspective.vBias); - fov->setDefault (defParams->perspective.fov); + camera_crop_factor->setDefault (defParams->perspective.camera_crop_factor); + camera_focal_length->setDefault (defParams->perspective.camera_focal_length); + camera_shift_horiz->setDefault (defParams->perspective.camera_shift_horiz); + camera_shift_vert->setDefault (defParams->perspective.camera_shift_vert); + projection_pitch->setDefault (defParams->perspective.projection_pitch); + projection_rotate->setDefault (defParams->perspective.projection_rotate); + projection_scale->setDefault (defParams->perspective.projection_scale); + projection_shift_horiz->setDefault (defParams->perspective.projection_shift_horiz); + projection_shift_vert->setDefault (defParams->perspective.projection_shift_vert); + projection_yaw->setDefault (defParams->perspective.projection_yaw); if (pedited) { horiz->setDefaultEditedState (pedited->perspective.horizontal ? Edited : UnEdited); vert->setDefaultEditedState (pedited->perspective.vertical ? Edited : UnEdited); - vBias->setDefaultEditedState (pedited->perspective.vBias ? Edited : UnEdited); - fov->setDefaultEditedState (pedited->perspective.fov ? 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_shift_horiz->setDefaultEditedState (pedited->perspective.camera_shift_horiz ? Edited : UnEdited); + camera_shift_vert->setDefaultEditedState (pedited->perspective.camera_shift_vert ? Edited : UnEdited); + projection_pitch->setDefaultEditedState (pedited->perspective.projection_pitch ? Edited : UnEdited); + projection_rotate->setDefaultEditedState (pedited->perspective.projection_rotate ? Edited : UnEdited); + projection_scale->setDefaultEditedState (pedited->perspective.projection_scale ? Edited : UnEdited); + projection_shift_horiz->setDefaultEditedState (pedited->perspective.projection_shift_horiz ? Edited : UnEdited); + projection_shift_vert->setDefaultEditedState (pedited->perspective.projection_shift_vert ? Edited : UnEdited); + projection_yaw->setDefaultEditedState (pedited->perspective.projection_yaw ? Edited : UnEdited); } else { horiz->setDefaultEditedState (Irrelevant); vert->setDefaultEditedState (Irrelevant); - vBias->setDefaultEditedState (Irrelevant); - fov->setDefaultEditedState (Irrelevant); + camera_crop_factor->setDefaultEditedState (Irrelevant); + camera_focal_length->setDefaultEditedState (Irrelevant); + camera_shift_horiz->setDefaultEditedState (Irrelevant); + camera_shift_vert->setDefaultEditedState (Irrelevant); + projection_pitch->setDefaultEditedState (Irrelevant); + projection_rotate->setDefaultEditedState (Irrelevant); + projection_scale->setDefaultEditedState (Irrelevant); + projection_shift_horiz->setDefaultEditedState (Irrelevant); + projection_shift_vert->setDefaultEditedState (Irrelevant); + projection_yaw->setDefaultEditedState (Irrelevant); } } void PerspCorrection::adjusterChanged(Adjuster* a, double newval) { if (listener) { - listener->panelChanged (EvPerspCorr, Glib::ustring::compose ("%1=%5\n%2=%6\n%3=%7\n%4=%8", M("TP_PERSPECTIVE_HORIZONTAL"), M("TP_PERSPECTIVE_VERTICAL"), M("TP_PERSPECTIVE_VERTICAL_BIAS"), M("TP_PERSPECTIVE_FOV"), horiz->getValue(), vert->getValue(), vBias->getValue(), fov->getValue())); + if (a == horiz || a == vert) { + listener->panelChanged (EvPerspCorr, + Glib::ustring::compose("%1=%2\n%3=%4", + M("TP_PERSPECTIVE_HORIZONTAL"), + horiz->getValue(), + M("TP_PERSPECTIVE_VERTICAL"), + vert->getValue())); + } else if (a == camera_focal_length || a == camera_crop_factor) { + listener->panelChanged (EvPerspCamFocalLength, + Glib::ustring::compose("%1=%2\n%3=%4", + M("TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH"), + camera_focal_length->getValue(), + M("TP_PERSPECTIVE_CAMERA_CROP_FACTOR"), + camera_crop_factor->getValue())); + } else if (a == camera_shift_horiz || a == camera_shift_vert) { + listener->panelChanged (EvPerspCamShift, + Glib::ustring::compose("%1=%2\n%3=%4", + M("TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL"), + camera_shift_horiz->getValue(), + M("TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL"), + camera_shift_vert->getValue())); + } else if (a == projection_shift_horiz || a == projection_shift_vert) { + listener->panelChanged (EvPerspProjShift, + Glib::ustring::compose("%1=%2\n%3=%4", + M("TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL"), + projection_shift_horiz->getValue(), + M("TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL"), + projection_shift_vert->getValue())); + } else if (a == projection_rotate) { + listener->panelChanged (EvPerspProjRotate, + Glib::ustring::format(projection_rotate->getValue())); + } else if (a == projection_scale) { + listener->panelChanged (EvPerspProjScale, + Glib::ustring::format(projection_scale->getValue())); + } else if (a == projection_pitch || a == projection_yaw) { + listener->panelChanged (EvPerspProjAngle, + Glib::ustring::compose("%1=%2\n%3=%4", + M("TP_PERSPECTIVE_PROJECTION_PITCH"), + projection_pitch->getValue(), + M("TP_PERSPECTIVE_PROJECTION_YAW"), + projection_yaw->getValue())); + } } } -void PerspCorrection::setAdjusterBehavior (bool badd) +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) { horiz->setAddMode(badd); vert->setAddMode(badd); - vBias->setAddMode(badd); - fov->setAddMode(badd); + camera_crop_factor->setAddMode(camera_focal_length_add); + camera_focal_length->setAddMode(camera_focal_length_add); + camera_shift_horiz->setAddMode(camera_shift_add); + camera_shift_vert->setAddMode(camera_shift_add); + projection_pitch->setAddMode(projection_angle_add); + projection_rotate->setAddMode(projection_rotate_add); + projection_scale->setAddMode(projection_scale_add); + projection_shift_horiz->setAddMode(projection_shift_add); + projection_shift_vert->setAddMode(projection_shift_add); + projection_yaw->setAddMode(projection_angle_add); } void PerspCorrection::trimValues (rtengine::procparams::ProcParams* pp) @@ -138,8 +281,16 @@ void PerspCorrection::trimValues (rtengine::procparams::ProcParams* pp) horiz->trimValue(pp->perspective.horizontal); vert->trimValue(pp->perspective.vertical); - vBias->trimValue(pp->perspective.vBias); - fov->trimValue(pp->perspective.fov); + camera_crop_factor->trimValue(pp->perspective.camera_crop_factor); + camera_focal_length->trimValue(pp->perspective.camera_focal_length); + camera_shift_horiz->trimValue(pp->perspective.camera_shift_horiz); + camera_shift_vert->trimValue(pp->perspective.camera_shift_vert); + projection_pitch->trimValue(pp->perspective.projection_pitch); + projection_rotate->trimValue(pp->perspective.projection_rotate); + projection_scale->trimValue(pp->perspective.projection_scale); + projection_shift_horiz->trimValue(pp->perspective.projection_shift_horiz); + projection_shift_vert->trimValue(pp->perspective.projection_shift_vert); + projection_yaw->trimValue(pp->perspective.projection_yaw); } void PerspCorrection::setBatchMode (bool batchMode) @@ -148,6 +299,14 @@ void PerspCorrection::setBatchMode (bool batchMode) ToolPanel::setBatchMode (batchMode); horiz->showEditedCB (); vert->showEditedCB (); - vBias->showEditedCB (); - fov->showEditedCB (); + camera_crop_factor->showEditedCB (); + camera_focal_length->showEditedCB (); + camera_shift_horiz->showEditedCB (); + camera_shift_vert->showEditedCB (); + projection_pitch->showEditedCB (); + projection_rotate->showEditedCB (); + projection_scale->showEditedCB (); + projection_shift_horiz->showEditedCB (); + projection_shift_vert->showEditedCB (); + projection_yaw->showEditedCB (); } diff --git a/rtgui/perspective.h b/rtgui/perspective.h index 2b56f2727..bf443f430 100644 --- a/rtgui/perspective.h +++ b/rtgui/perspective.h @@ -32,8 +32,16 @@ class PerspCorrection final : protected: Adjuster* horiz; Adjuster* vert; - Adjuster* vBias; - Adjuster* fov; + Adjuster* camera_crop_factor; + Adjuster* camera_focal_length; + Adjuster* camera_shift_horiz; + Adjuster* camera_shift_vert; + Adjuster* projection_pitch; + Adjuster* projection_rotate; + Adjuster* projection_scale; + Adjuster* projection_shift_horiz; + Adjuster* projection_shift_vert; + Adjuster* projection_yaw; public: @@ -45,6 +53,6 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void setAdjusterBehavior (bool badd); + 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 trimValues (rtengine::procparams::ProcParams* pp) override; }; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4bbeb345d..a66cfd7d7 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -343,7 +343,13 @@ Gtk::Widget* Preferences::getBatchProcPanel () mi = behModel->append (); mi->set_value (behavColumns.label, M ("TP_PERSPECTIVE_LABEL")); - appendBehavList (mi, M ("TP_PERSPECTIVE_HORIZONTAL") + ", " + M ("TP_PERSPECTIVE_VERTICAL") + ", " + M ("TP_PERSPECTIVE_VERTICAL_BIAS") + ", " + M ("TP_PERSPECTIVE_FOV"), ADDSET_PERSPECTIVE, false); + appendBehavList (mi, 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_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_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_YAW") + ", " + M ("TP_PERSPECTIVE_PROJECTION_PITCH"), ADDSET_PERSP_PROJ_ANGLE, false); mi = behModel->append (); mi->set_value (behavColumns.label, M ("TP_GRADIENT_LABEL"));