1035 lines
37 KiB
C
1035 lines
37 KiB
C
/* PIKA - Photo and Image Kooker Application
|
|
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
|
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
|
*
|
|
* Original copyright, applying to most contents (license remains unchanged):
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <gegl.h>
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "libpikabase/pikabase.h"
|
|
#include "libpikamath/pikamath.h"
|
|
#include "libpikawidgets/pikawidgets.h"
|
|
|
|
#include "tools-types.h"
|
|
|
|
#include "core/pika-transform-3d-utils.h"
|
|
#include "core/pikaimage.h"
|
|
|
|
#include "widgets/pikahelp-ids.h"
|
|
#include "widgets/pikapivotselector.h"
|
|
#include "widgets/pikawidgets-utils.h"
|
|
|
|
#include "display/pikadisplay.h"
|
|
#include "display/pikadisplayshell.h"
|
|
#include "display/pikadisplayshell-transform.h"
|
|
#include "display/pikatoolgui.h"
|
|
#include "display/pikatooltransform3dgrid.h"
|
|
|
|
#include "pikatoolcontrol.h"
|
|
#include "pikatransform3doptions.h"
|
|
#include "pikatransform3dtool.h"
|
|
|
|
#include "pika-intl.h"
|
|
|
|
|
|
/* index into trans_info array */
|
|
enum
|
|
{
|
|
VANISHING_POINT_X,
|
|
VANISHING_POINT_Y,
|
|
LENS_MODE,
|
|
LENS_VALUE,
|
|
OFFSET_X,
|
|
OFFSET_Y,
|
|
OFFSET_Z,
|
|
ROTATION_ORDER,
|
|
ANGLE_X,
|
|
ANGLE_Y,
|
|
ANGLE_Z,
|
|
PIVOT_X,
|
|
PIVOT_Y,
|
|
PIVOT_Z
|
|
};
|
|
|
|
|
|
/* local function prototypes */
|
|
|
|
static void pika_transform_3d_tool_modifier_key (PikaTool *tool,
|
|
GdkModifierType key,
|
|
gboolean press,
|
|
GdkModifierType state,
|
|
PikaDisplay *display);
|
|
|
|
static gboolean pika_transform_3d_tool_info_to_matrix (PikaTransformGridTool *tg_tool,
|
|
PikaMatrix3 *transform);
|
|
static void pika_transform_3d_tool_dialog (PikaTransformGridTool *tg_tool);
|
|
static void pika_transform_3d_tool_dialog_update (PikaTransformGridTool *tg_tool);
|
|
static void pika_transform_3d_tool_prepare (PikaTransformGridTool *tg_tool);
|
|
static PikaToolWidget * pika_transform_3d_tool_get_widget (PikaTransformGridTool *tg_tool);
|
|
static void pika_transform_3d_tool_update_widget (PikaTransformGridTool *tg_tool);
|
|
static void pika_transform_3d_tool_widget_changed (PikaTransformGridTool *tg_tool);
|
|
|
|
static void pika_transform_3d_tool_dialog_changed (GObject *object,
|
|
PikaTransform3DTool *t3d);
|
|
static void pika_transform_3d_tool_lens_mode_changed (GtkComboBox *combo,
|
|
PikaTransform3DTool *t3d);
|
|
static void pika_transform_3d_tool_rotation_order_clicked (GtkButton *button,
|
|
PikaTransform3DTool *t3d);
|
|
static void pika_transform_3d_tool_pivot_changed (PikaPivotSelector *selector,
|
|
PikaTransform3DTool *t3d);
|
|
|
|
static gdouble pika_transform_3d_tool_get_focal_length (PikaTransform3DTool *t3d);
|
|
|
|
|
|
G_DEFINE_TYPE (PikaTransform3DTool, pika_transform_3d_tool, PIKA_TYPE_TRANSFORM_GRID_TOOL)
|
|
|
|
#define parent_class pika_transform_3d_tool_parent_class
|
|
|
|
|
|
void
|
|
pika_transform_3d_tool_register (PikaToolRegisterCallback callback,
|
|
gpointer data)
|
|
{
|
|
(* callback) (PIKA_TYPE_TRANSFORM_3D_TOOL,
|
|
PIKA_TYPE_TRANSFORM_3D_OPTIONS,
|
|
pika_transform_3d_options_gui,
|
|
PIKA_CONTEXT_PROP_MASK_BACKGROUND,
|
|
"pika-transform-3d-tool",
|
|
_("3D Transform"),
|
|
_("3D Transform Tool: Apply a 3D transformation to the layer, selection or path"),
|
|
N_("_3D Transform"), "<shift>W",
|
|
NULL, PIKA_HELP_TOOL_TRANSFORM_3D,
|
|
PIKA_ICON_TOOL_TRANSFORM_3D,
|
|
data);
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_class_init (PikaTransform3DToolClass *klass)
|
|
{
|
|
PikaToolClass *tool_class = PIKA_TOOL_CLASS (klass);
|
|
PikaTransformToolClass *tr_class = PIKA_TRANSFORM_TOOL_CLASS (klass);
|
|
PikaTransformGridToolClass *tg_class = PIKA_TRANSFORM_GRID_TOOL_CLASS (klass);
|
|
|
|
tool_class->modifier_key = pika_transform_3d_tool_modifier_key;
|
|
|
|
tg_class->info_to_matrix = pika_transform_3d_tool_info_to_matrix;
|
|
tg_class->dialog = pika_transform_3d_tool_dialog;
|
|
tg_class->dialog_update = pika_transform_3d_tool_dialog_update;
|
|
tg_class->prepare = pika_transform_3d_tool_prepare;
|
|
tg_class->get_widget = pika_transform_3d_tool_get_widget;
|
|
tg_class->update_widget = pika_transform_3d_tool_update_widget;
|
|
tg_class->widget_changed = pika_transform_3d_tool_widget_changed;
|
|
|
|
tr_class->undo_desc = C_("undo-type", "3D Transform");
|
|
tr_class->progress_text = _("3D transformation");
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_init (PikaTransform3DTool *t3d)
|
|
{
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_modifier_key (PikaTool *tool,
|
|
GdkModifierType key,
|
|
gboolean press,
|
|
GdkModifierType state,
|
|
PikaDisplay *display)
|
|
{
|
|
PikaTransform3DOptions *options = PIKA_TRANSFORM_3D_TOOL_GET_OPTIONS (tool);
|
|
|
|
if (key == pika_get_extend_selection_mask ())
|
|
{
|
|
g_object_set (options,
|
|
"constrain-axis", ! options->constrain_axis,
|
|
NULL);
|
|
}
|
|
else if (key == pika_get_constrain_behavior_mask ())
|
|
{
|
|
g_object_set (options,
|
|
"z-axis", ! options->z_axis,
|
|
NULL);
|
|
}
|
|
else if (key == GDK_MOD1_MASK)
|
|
{
|
|
g_object_set (options,
|
|
"local-frame", ! options->local_frame,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
static gboolean
|
|
pika_transform_3d_tool_info_to_matrix (PikaTransformGridTool *tg_tool,
|
|
PikaMatrix3 *transform)
|
|
{
|
|
PikaTransform3DTool *t3d = PIKA_TRANSFORM_3D_TOOL (tg_tool);
|
|
|
|
pika_transform_3d_matrix (transform,
|
|
|
|
tg_tool->trans_info[VANISHING_POINT_X],
|
|
tg_tool->trans_info[VANISHING_POINT_Y],
|
|
-pika_transform_3d_tool_get_focal_length (t3d),
|
|
|
|
tg_tool->trans_info[OFFSET_X],
|
|
tg_tool->trans_info[OFFSET_Y],
|
|
tg_tool->trans_info[OFFSET_Z],
|
|
|
|
tg_tool->trans_info[ROTATION_ORDER],
|
|
tg_tool->trans_info[ANGLE_X],
|
|
tg_tool->trans_info[ANGLE_Y],
|
|
tg_tool->trans_info[ANGLE_Z],
|
|
|
|
tg_tool->trans_info[PIVOT_X],
|
|
tg_tool->trans_info[PIVOT_Y],
|
|
tg_tool->trans_info[PIVOT_Z]);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_dialog (PikaTransformGridTool *tg_tool)
|
|
{
|
|
PikaTransform3DTool *t3d = PIKA_TRANSFORM_3D_TOOL (tg_tool);
|
|
PikaTransform3DOptions *options = PIKA_TRANSFORM_3D_TOOL_GET_OPTIONS (tg_tool);
|
|
GtkWidget *notebook;
|
|
GtkWidget *label;
|
|
GtkWidget *vbox;
|
|
GtkWidget *frame;
|
|
GtkWidget *vbox2;
|
|
GtkWidget *se;
|
|
GtkWidget *spinbutton;
|
|
GtkWidget *combo;
|
|
GtkWidget *scale;
|
|
GtkWidget *grid;
|
|
GtkWidget *button;
|
|
GtkWidget *selector;
|
|
gint i;
|
|
|
|
/* main notebook */
|
|
notebook = gtk_notebook_new ();
|
|
gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_LEFT);
|
|
gtk_box_pack_start (GTK_BOX (pika_tool_gui_get_vbox (tg_tool->gui)),
|
|
notebook, FALSE, FALSE, 0);
|
|
gtk_widget_show (notebook);
|
|
|
|
t3d->notebook = notebook;
|
|
|
|
/* camera page */
|
|
label = gtk_image_new_from_icon_name (PIKA_ICON_TRANSFORM_3D_CAMERA,
|
|
GTK_ICON_SIZE_MENU);
|
|
pika_help_set_help_data (label, _("Camera"), NULL);
|
|
gtk_widget_show (label);
|
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
|
|
gtk_widget_show (vbox);
|
|
|
|
/* vanishing-point frame */
|
|
frame = pika_frame_new (_("Vanishing Point"));
|
|
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
|
gtk_widget_show (frame);
|
|
|
|
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
|
gtk_container_add (GTK_CONTAINER (frame), vbox2);
|
|
gtk_widget_show (vbox2);
|
|
|
|
/* vanishing-point size entry */
|
|
se = pika_size_entry_new (1, PIKA_UNIT_PIXEL, "%a", TRUE, TRUE, FALSE, 6,
|
|
PIKA_SIZE_ENTRY_UPDATE_SIZE);
|
|
gtk_grid_set_row_spacing (GTK_GRID (se), 2);
|
|
gtk_grid_set_column_spacing (GTK_GRID (se), 2);
|
|
gtk_box_pack_start (GTK_BOX (vbox2), se, FALSE, FALSE, 0);
|
|
gtk_widget_show (se);
|
|
|
|
t3d->vanishing_point_se = se;
|
|
|
|
spinbutton = pika_spin_button_new_with_range (0.0, 0.0, 1.0);
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 6);
|
|
pika_size_entry_add_field (PIKA_SIZE_ENTRY (se),
|
|
GTK_SPIN_BUTTON (spinbutton), NULL);
|
|
gtk_grid_attach (GTK_GRID (se), spinbutton, 1, 0, 1, 1);
|
|
gtk_widget_show (spinbutton);
|
|
|
|
pika_size_entry_attach_label (PIKA_SIZE_ENTRY (se), _("_X:"), 0, 0, 0.0);
|
|
pika_size_entry_attach_label (PIKA_SIZE_ENTRY (se), _("_Y:"), 1, 0, 0.0);
|
|
|
|
pika_size_entry_set_refval_digits (PIKA_SIZE_ENTRY (se), 0, 2);
|
|
pika_size_entry_set_refval_digits (PIKA_SIZE_ENTRY (se), 1, 2);
|
|
|
|
g_signal_connect (se, "value-changed",
|
|
G_CALLBACK (pika_transform_3d_tool_dialog_changed),
|
|
t3d);
|
|
|
|
/* lens frame */
|
|
frame = pika_frame_new (NULL);
|
|
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
|
gtk_widget_show (frame);
|
|
|
|
/* lens-mode combo */
|
|
combo = pika_enum_combo_box_new (PIKA_TYPE_TRANSFORM_3D_LENS_MODE);
|
|
gtk_frame_set_label_widget (GTK_FRAME (frame), combo);
|
|
gtk_widget_show (combo);
|
|
|
|
t3d->lens_mode_combo = combo;
|
|
|
|
g_signal_connect (combo, "changed",
|
|
G_CALLBACK (pika_transform_3d_tool_lens_mode_changed),
|
|
t3d);
|
|
|
|
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
|
gtk_container_add (GTK_CONTAINER (frame), vbox2);
|
|
gtk_widget_show (vbox2);
|
|
|
|
/* focal-length size entry */
|
|
se = pika_size_entry_new (1, PIKA_UNIT_PIXEL, "%a", TRUE, FALSE, FALSE, 6,
|
|
PIKA_SIZE_ENTRY_UPDATE_SIZE);
|
|
gtk_grid_set_row_spacing (GTK_GRID (se), 2);
|
|
gtk_box_pack_start (GTK_BOX (vbox2), se, FALSE, FALSE, 0);
|
|
|
|
t3d->focal_length_se = se;
|
|
|
|
pika_size_entry_set_refval_digits (PIKA_SIZE_ENTRY (se), 0, 2);
|
|
|
|
pika_size_entry_set_value_boundaries (PIKA_SIZE_ENTRY (se), 0,
|
|
0.0, G_MAXDOUBLE);
|
|
|
|
g_signal_connect (se, "value-changed",
|
|
G_CALLBACK (pika_transform_3d_tool_dialog_changed),
|
|
t3d);
|
|
|
|
/* angle-of-view spin scale */
|
|
t3d->angle_of_view_adj = (GtkAdjustment *)
|
|
gtk_adjustment_new (0, 0, 180, 1, 10, 0);
|
|
scale = pika_spin_scale_new (t3d->angle_of_view_adj,
|
|
_("Angle"), 2);
|
|
gtk_box_pack_start (GTK_BOX (vbox2), scale, FALSE, FALSE, 0);
|
|
gtk_widget_show (scale);
|
|
|
|
t3d->angle_of_view_scale = scale;
|
|
|
|
g_signal_connect (t3d->angle_of_view_adj, "value-changed",
|
|
G_CALLBACK (pika_transform_3d_tool_dialog_changed),
|
|
t3d);
|
|
|
|
/* move page */
|
|
label = gtk_image_new_from_icon_name (PIKA_ICON_TRANSFORM_3D_MOVE,
|
|
GTK_ICON_SIZE_MENU);
|
|
pika_help_set_help_data (label, _("Move"), NULL);
|
|
gtk_widget_show (label);
|
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
|
|
gtk_widget_show (vbox);
|
|
|
|
/* offset frame */
|
|
frame = pika_frame_new (_("Offset"));
|
|
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
|
gtk_widget_show (frame);
|
|
|
|
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
|
gtk_container_add (GTK_CONTAINER (frame), vbox2);
|
|
gtk_widget_show (vbox2);
|
|
|
|
/* offset size entry */
|
|
se = pika_size_entry_new (1, PIKA_UNIT_PIXEL, "%a", TRUE, TRUE, FALSE, 6,
|
|
PIKA_SIZE_ENTRY_UPDATE_SIZE);
|
|
gtk_grid_set_row_spacing (GTK_GRID (se), 2);
|
|
gtk_grid_set_column_spacing (GTK_GRID (se), 2);
|
|
gtk_box_pack_start (GTK_BOX (vbox2), se, FALSE, FALSE, 0);
|
|
gtk_widget_show (se);
|
|
|
|
t3d->offset_se = se;
|
|
|
|
grid = gtk_grid_new ();
|
|
gtk_grid_set_row_spacing (GTK_GRID (grid), 2);
|
|
gtk_grid_set_column_spacing (GTK_GRID (grid), 2);
|
|
gtk_grid_attach (GTK_GRID (se), grid, 0, 0, 2, 1);
|
|
gtk_widget_show (grid);
|
|
|
|
spinbutton = pika_spin_button_new_with_range (0.0, 0.0, 1.0);
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 6);
|
|
pika_size_entry_add_field (PIKA_SIZE_ENTRY (se),
|
|
GTK_SPIN_BUTTON (spinbutton), NULL);
|
|
gtk_grid_attach (GTK_GRID (grid), spinbutton, 1, 1, 1, 1);
|
|
gtk_widget_show (spinbutton);
|
|
|
|
spinbutton = pika_spin_button_new_with_range (0.0, 0.0, 1.0);
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 6);
|
|
pika_size_entry_add_field (PIKA_SIZE_ENTRY (se),
|
|
GTK_SPIN_BUTTON (spinbutton), NULL);
|
|
gtk_grid_attach (GTK_GRID (grid), spinbutton, 1, 0, 1, 1);
|
|
gtk_widget_show (spinbutton);
|
|
|
|
label = gtk_label_new_with_mnemonic (_("_X:"));
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
|
gtk_widget_show (label);
|
|
|
|
label = gtk_label_new_with_mnemonic (_("_Y:"));
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
|
|
gtk_widget_show (label);
|
|
|
|
label = gtk_label_new_with_mnemonic (_("_Z:"));
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_grid_attach (GTK_GRID (se), label, 0, 1, 1, 1);
|
|
gtk_widget_show (label);
|
|
|
|
pika_size_entry_set_refval_boundaries (PIKA_SIZE_ENTRY (se), 0,
|
|
-PIKA_MAX_IMAGE_SIZE,
|
|
PIKA_MAX_IMAGE_SIZE);
|
|
pika_size_entry_set_refval_boundaries (PIKA_SIZE_ENTRY (se), 1,
|
|
-PIKA_MAX_IMAGE_SIZE,
|
|
PIKA_MAX_IMAGE_SIZE);
|
|
pika_size_entry_set_refval_boundaries (PIKA_SIZE_ENTRY (se), 2,
|
|
-PIKA_MAX_IMAGE_SIZE,
|
|
PIKA_MAX_IMAGE_SIZE);
|
|
|
|
pika_size_entry_set_refval_digits (PIKA_SIZE_ENTRY (se), 0, 2);
|
|
pika_size_entry_set_refval_digits (PIKA_SIZE_ENTRY (se), 1, 2);
|
|
pika_size_entry_set_refval_digits (PIKA_SIZE_ENTRY (se), 2, 2);
|
|
|
|
g_signal_connect (se, "value-changed",
|
|
G_CALLBACK (pika_transform_3d_tool_dialog_changed),
|
|
t3d);
|
|
|
|
/* rotate page */
|
|
label = gtk_image_new_from_icon_name (PIKA_ICON_TRANSFORM_3D_ROTATE,
|
|
GTK_ICON_SIZE_MENU);
|
|
pika_help_set_help_data (label, _("Rotate"), NULL);
|
|
gtk_widget_show (label);
|
|
|
|
/* angle frame */
|
|
frame = pika_frame_new (_("Angle"));
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
|
|
gtk_widget_show (frame);
|
|
|
|
grid = gtk_grid_new ();
|
|
gtk_grid_set_row_spacing (GTK_GRID (grid), 2);
|
|
gtk_grid_set_column_spacing (GTK_GRID (grid), 2);
|
|
gtk_container_add (GTK_CONTAINER (frame), grid);
|
|
gtk_widget_show (grid);
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
const gchar *labels[3] = {_("X"), _("Y"), _("Z")};
|
|
|
|
/* rotation-order button */
|
|
button = gtk_button_new ();
|
|
pika_help_set_help_data (button, _("Rotation axis order"), NULL);
|
|
gtk_grid_attach (GTK_GRID (grid), button, 0, i, 1, 1);
|
|
gtk_widget_show (button);
|
|
|
|
t3d->rotation_order_buttons[i] = button;
|
|
|
|
g_signal_connect (button, "clicked",
|
|
G_CALLBACK (pika_transform_3d_tool_rotation_order_clicked),
|
|
t3d);
|
|
|
|
/* angle spin scale */
|
|
t3d->angle_adj[i] = (GtkAdjustment *)
|
|
gtk_adjustment_new (0, -180, 180, 1, 10, 0);
|
|
scale = pika_spin_scale_new (t3d->angle_adj[i],
|
|
labels[i], 2);
|
|
gtk_widget_set_hexpand (GTK_WIDGET (scale), TRUE);
|
|
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (scale), TRUE);
|
|
gtk_grid_attach (GTK_GRID (grid), scale, 1, i, 1, 1);
|
|
gtk_widget_show (scale);
|
|
|
|
g_signal_connect (t3d->angle_adj[i], "value-changed",
|
|
G_CALLBACK (pika_transform_3d_tool_dialog_changed),
|
|
t3d);
|
|
}
|
|
|
|
/* pivot selector */
|
|
selector = pika_pivot_selector_new (0.0, 0.0, 0.0, 0.0);
|
|
gtk_grid_attach (GTK_GRID (grid), selector, 2, 0, 1, 3);
|
|
gtk_widget_show (selector);
|
|
|
|
t3d->pivot_selector = selector;
|
|
|
|
g_signal_connect (selector, "changed",
|
|
G_CALLBACK (pika_transform_3d_tool_pivot_changed),
|
|
t3d);
|
|
|
|
g_object_bind_property (options, "mode",
|
|
t3d->notebook, "page",
|
|
G_BINDING_SYNC_CREATE |
|
|
G_BINDING_BIDIRECTIONAL);
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_dialog_update (PikaTransformGridTool *tg_tool)
|
|
{
|
|
PikaTransform3DTool *t3d = PIKA_TRANSFORM_3D_TOOL (tg_tool);
|
|
Pika3DTransformLensMode lens_mode;
|
|
gint permutation[3];
|
|
gint i;
|
|
|
|
t3d->updating = TRUE;
|
|
|
|
/* vanishing-point size entry */
|
|
pika_size_entry_set_refval (PIKA_SIZE_ENTRY (t3d->vanishing_point_se),
|
|
0, tg_tool->trans_info[VANISHING_POINT_X]);
|
|
pika_size_entry_set_refval (PIKA_SIZE_ENTRY (t3d->vanishing_point_se),
|
|
1, tg_tool->trans_info[VANISHING_POINT_Y]);
|
|
|
|
lens_mode = tg_tool->trans_info[LENS_MODE];
|
|
|
|
/* lens-mode combo */
|
|
pika_int_combo_box_set_active (PIKA_INT_COMBO_BOX (t3d->lens_mode_combo),
|
|
lens_mode);
|
|
|
|
/* focal-length size entry / angle-of-view spin scale */
|
|
gtk_widget_set_visible (t3d->focal_length_se,
|
|
lens_mode ==
|
|
PIKA_TRANSFORM_3D_LENS_MODE_FOCAL_LENGTH);
|
|
gtk_widget_set_visible (t3d->angle_of_view_scale,
|
|
lens_mode !=
|
|
PIKA_TRANSFORM_3D_LENS_MODE_FOCAL_LENGTH);
|
|
|
|
switch (lens_mode)
|
|
{
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOCAL_LENGTH:
|
|
pika_size_entry_set_refval (PIKA_SIZE_ENTRY (t3d->focal_length_se),
|
|
0, tg_tool->trans_info[LENS_VALUE]);
|
|
break;
|
|
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOV_IMAGE:
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOV_ITEM:
|
|
gtk_adjustment_set_value (
|
|
t3d->angle_of_view_adj,
|
|
pika_rad_to_deg (tg_tool->trans_info[LENS_VALUE]));
|
|
break;
|
|
}
|
|
|
|
/* offset size entry */
|
|
pika_size_entry_set_refval (PIKA_SIZE_ENTRY (t3d->offset_se),
|
|
0, tg_tool->trans_info[OFFSET_X]);
|
|
pika_size_entry_set_refval (PIKA_SIZE_ENTRY (t3d->offset_se),
|
|
1, tg_tool->trans_info[OFFSET_Y]);
|
|
pika_size_entry_set_refval (PIKA_SIZE_ENTRY (t3d->offset_se),
|
|
2, tg_tool->trans_info[OFFSET_Z]);
|
|
|
|
/* rotation-order buttons */
|
|
pika_transform_3d_rotation_order_to_permutation (
|
|
tg_tool->trans_info[ROTATION_ORDER], permutation);
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
gchar *label;
|
|
|
|
label = g_strdup_printf ("%d", i + 1);
|
|
|
|
gtk_button_set_label (
|
|
GTK_BUTTON (t3d->rotation_order_buttons[permutation[i]]), label);
|
|
|
|
g_free (label);
|
|
}
|
|
|
|
/* angle spin scales */
|
|
gtk_adjustment_set_value (t3d->angle_adj[0],
|
|
pika_rad_to_deg (tg_tool->trans_info[ANGLE_X]));
|
|
gtk_adjustment_set_value (t3d->angle_adj[1],
|
|
pika_rad_to_deg (tg_tool->trans_info[ANGLE_Y]));
|
|
gtk_adjustment_set_value (t3d->angle_adj[2],
|
|
pika_rad_to_deg (tg_tool->trans_info[ANGLE_Z]));
|
|
|
|
/* pivot selector */
|
|
pika_pivot_selector_set_position (PIKA_PIVOT_SELECTOR (t3d->pivot_selector),
|
|
tg_tool->trans_info[PIVOT_X],
|
|
tg_tool->trans_info[PIVOT_Y]);
|
|
|
|
t3d->updating = FALSE;
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_prepare (PikaTransformGridTool *tg_tool)
|
|
{
|
|
PikaTool *tool = PIKA_TOOL (tg_tool);
|
|
PikaTransformTool *tr_tool = PIKA_TRANSFORM_TOOL (tg_tool);
|
|
PikaTransform3DTool *t3d = PIKA_TRANSFORM_3D_TOOL (tg_tool);
|
|
PikaDisplay *display = tool->display;
|
|
PikaDisplayShell *shell = pika_display_get_shell (display);
|
|
PikaImage *image = pika_display_get_image (display);
|
|
PikaSizeEntry *se;
|
|
gdouble xres;
|
|
gdouble yres;
|
|
gint width;
|
|
gint height;
|
|
|
|
pika_image_get_resolution (image, &xres, &yres);
|
|
|
|
width = pika_image_get_width (image);
|
|
height = pika_image_get_height (image);
|
|
|
|
tg_tool->trans_info[VANISHING_POINT_X] = (tr_tool->x1 + tr_tool->x2) / 2.0;
|
|
tg_tool->trans_info[VANISHING_POINT_Y] = (tr_tool->y1 + tr_tool->y2) / 2.0;
|
|
|
|
tg_tool->trans_info[LENS_MODE] = PIKA_TRANSFORM_3D_LENS_MODE_FOV_ITEM;
|
|
tg_tool->trans_info[LENS_VALUE] = pika_deg_to_rad (45.0);
|
|
|
|
tg_tool->trans_info[OFFSET_X] = 0.0;
|
|
tg_tool->trans_info[OFFSET_Y] = 0.0;
|
|
tg_tool->trans_info[OFFSET_Z] = 0.0;
|
|
|
|
tg_tool->trans_info[ROTATION_ORDER] =
|
|
pika_transform_3d_permutation_to_rotation_order ((const gint[]) {0, 1, 2});
|
|
tg_tool->trans_info[ANGLE_X] = 0.0;
|
|
tg_tool->trans_info[ANGLE_Y] = 0.0;
|
|
tg_tool->trans_info[ANGLE_Z] = 0.0;
|
|
|
|
tg_tool->trans_info[PIVOT_X] = (tr_tool->x1 + tr_tool->x2) / 2.0;
|
|
tg_tool->trans_info[PIVOT_Y] = (tr_tool->y1 + tr_tool->y2) / 2.0;
|
|
tg_tool->trans_info[PIVOT_Z] = 0.0;
|
|
|
|
t3d->updating = TRUE;
|
|
|
|
/* vanishing-point size entry */
|
|
se = PIKA_SIZE_ENTRY (t3d->vanishing_point_se);
|
|
|
|
pika_size_entry_set_unit (se, shell->unit);
|
|
|
|
pika_size_entry_set_resolution (se, 0, xres, FALSE);
|
|
pika_size_entry_set_resolution (se, 1, yres, FALSE);
|
|
|
|
pika_size_entry_set_refval_boundaries (se, 0,
|
|
-PIKA_MAX_IMAGE_SIZE,
|
|
PIKA_MAX_IMAGE_SIZE);
|
|
pika_size_entry_set_refval_boundaries (se, 1,
|
|
-PIKA_MAX_IMAGE_SIZE,
|
|
PIKA_MAX_IMAGE_SIZE);
|
|
|
|
pika_size_entry_set_size (se, 0, tr_tool->x1, tr_tool->x2);
|
|
pika_size_entry_set_size (se, 1, tr_tool->y1, tr_tool->y2);
|
|
|
|
/* focal-length size entry */
|
|
se = PIKA_SIZE_ENTRY (t3d->focal_length_se);
|
|
|
|
pika_size_entry_set_unit (se, shell->unit);
|
|
|
|
pika_size_entry_set_resolution (se, 0, width >= height ? xres : yres, FALSE);
|
|
|
|
/* offset size entry */
|
|
se = PIKA_SIZE_ENTRY (t3d->offset_se);
|
|
|
|
pika_size_entry_set_unit (se, shell->unit);
|
|
|
|
pika_size_entry_set_resolution (se, 0, xres, FALSE);
|
|
pika_size_entry_set_resolution (se, 1, yres, FALSE);
|
|
pika_size_entry_set_resolution (se, 2, width >= height ? xres : yres, FALSE);
|
|
|
|
pika_size_entry_set_size (se, 0, 0, width);
|
|
pika_size_entry_set_size (se, 1, 0, height);
|
|
pika_size_entry_set_size (se, 2, 0, MAX (width, height));
|
|
|
|
/* pivot selector */
|
|
pika_pivot_selector_set_bounds (PIKA_PIVOT_SELECTOR (t3d->pivot_selector),
|
|
tr_tool->x1, tr_tool->y1,
|
|
tr_tool->x2, tr_tool->y2);
|
|
|
|
t3d->updating = FALSE;
|
|
}
|
|
|
|
static PikaToolWidget *
|
|
pika_transform_3d_tool_get_widget (PikaTransformGridTool *tg_tool)
|
|
{
|
|
PikaTool *tool = PIKA_TOOL (tg_tool);
|
|
PikaTransformTool *tr_tool = PIKA_TRANSFORM_TOOL (tg_tool);
|
|
PikaTransform3DTool *t3d = PIKA_TRANSFORM_3D_TOOL (tg_tool);
|
|
PikaTransform3DOptions *options = PIKA_TRANSFORM_3D_TOOL_GET_OPTIONS (tg_tool);
|
|
PikaDisplayShell *shell = pika_display_get_shell (tool->display);
|
|
PikaToolWidget *widget;
|
|
gint i;
|
|
|
|
static const gchar *bound_properties[] =
|
|
{
|
|
"mode",
|
|
"unified",
|
|
"constrain-axis",
|
|
"z-axis",
|
|
"local-frame",
|
|
};
|
|
|
|
widget = pika_tool_transform_3d_grid_new (
|
|
shell,
|
|
tr_tool->x1,
|
|
tr_tool->y1,
|
|
tr_tool->x2,
|
|
tr_tool->y2,
|
|
tg_tool->trans_info[VANISHING_POINT_X],
|
|
tg_tool->trans_info[VANISHING_POINT_Y],
|
|
-pika_transform_3d_tool_get_focal_length (t3d));
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (bound_properties); i++)
|
|
{
|
|
g_object_bind_property (options, bound_properties[i],
|
|
widget, bound_properties[i],
|
|
G_BINDING_SYNC_CREATE |
|
|
G_BINDING_BIDIRECTIONAL);
|
|
}
|
|
|
|
return widget;
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_update_widget (PikaTransformGridTool *tg_tool)
|
|
{
|
|
PikaTransformTool *tr_tool = PIKA_TRANSFORM_TOOL (tg_tool);
|
|
PikaTransform3DTool *t3d = PIKA_TRANSFORM_3D_TOOL (tg_tool);
|
|
PikaMatrix3 transform;
|
|
|
|
PIKA_TRANSFORM_GRID_TOOL_CLASS (parent_class)->update_widget (tg_tool);
|
|
|
|
pika_transform_grid_tool_info_to_matrix (tg_tool, &transform);
|
|
|
|
g_object_set (
|
|
tg_tool->widget,
|
|
|
|
"x1", (gdouble) tr_tool->x1,
|
|
"y1", (gdouble) tr_tool->y1,
|
|
"x2", (gdouble) tr_tool->x2,
|
|
"y2", (gdouble) tr_tool->y2,
|
|
|
|
"camera-x", tg_tool->trans_info[VANISHING_POINT_X],
|
|
"camera-y", tg_tool->trans_info[VANISHING_POINT_Y],
|
|
"camera-z", -pika_transform_3d_tool_get_focal_length (t3d),
|
|
|
|
"offset-x", tg_tool->trans_info[OFFSET_X],
|
|
"offset-y", tg_tool->trans_info[OFFSET_Y],
|
|
"offset-z", tg_tool->trans_info[OFFSET_Z],
|
|
|
|
"rotation-order", (gint) tg_tool->trans_info[ROTATION_ORDER],
|
|
"angle-x", tg_tool->trans_info[ANGLE_X],
|
|
"angle-y", tg_tool->trans_info[ANGLE_Y],
|
|
"angle-z", tg_tool->trans_info[ANGLE_Z],
|
|
|
|
"pivot-3d-x", tg_tool->trans_info[PIVOT_X],
|
|
"pivot-3d-y", tg_tool->trans_info[PIVOT_Y],
|
|
"pivot-3d-z", tg_tool->trans_info[PIVOT_Z],
|
|
|
|
"transform", &transform,
|
|
|
|
NULL);
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_widget_changed (PikaTransformGridTool *tg_tool)
|
|
{
|
|
g_object_get (
|
|
tg_tool->widget,
|
|
|
|
"camera-x", &tg_tool->trans_info[VANISHING_POINT_X],
|
|
"camera-y", &tg_tool->trans_info[VANISHING_POINT_Y],
|
|
|
|
"offset-x", &tg_tool->trans_info[OFFSET_X],
|
|
"offset-y", &tg_tool->trans_info[OFFSET_Y],
|
|
"offset-z", &tg_tool->trans_info[OFFSET_Z],
|
|
|
|
"angle-x", &tg_tool->trans_info[ANGLE_X],
|
|
"angle-y", &tg_tool->trans_info[ANGLE_Y],
|
|
"angle-z", &tg_tool->trans_info[ANGLE_Z],
|
|
|
|
NULL);
|
|
|
|
PIKA_TRANSFORM_GRID_TOOL_CLASS (parent_class)->widget_changed (tg_tool);
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_dialog_changed (GObject *object,
|
|
PikaTransform3DTool *t3d)
|
|
{
|
|
PikaTool *tool = PIKA_TOOL (t3d);
|
|
PikaTransformTool *tr_tool = PIKA_TRANSFORM_TOOL (t3d);
|
|
PikaTransformGridTool *tg_tool = PIKA_TRANSFORM_GRID_TOOL (t3d);
|
|
|
|
if (t3d->updating)
|
|
return;
|
|
|
|
/* vanishing-point size entry */
|
|
tg_tool->trans_info[VANISHING_POINT_X] = pika_size_entry_get_refval (
|
|
PIKA_SIZE_ENTRY (t3d->vanishing_point_se), 0);
|
|
tg_tool->trans_info[VANISHING_POINT_Y] = pika_size_entry_get_refval (
|
|
PIKA_SIZE_ENTRY (t3d->vanishing_point_se), 1);
|
|
|
|
/* focal-length size entry / angle-of-view spin scale */
|
|
switch ((gint) tg_tool->trans_info[LENS_MODE])
|
|
{
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOCAL_LENGTH:
|
|
tg_tool->trans_info[LENS_VALUE] = pika_size_entry_get_refval (
|
|
PIKA_SIZE_ENTRY (t3d->focal_length_se), 0);
|
|
break;
|
|
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOV_IMAGE:
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOV_ITEM:
|
|
tg_tool->trans_info[LENS_VALUE] = pika_deg_to_rad (
|
|
gtk_adjustment_get_value (t3d->angle_of_view_adj));
|
|
break;
|
|
}
|
|
|
|
/* offset size entry */
|
|
tg_tool->trans_info[OFFSET_X] = pika_size_entry_get_refval (
|
|
PIKA_SIZE_ENTRY (t3d->offset_se), 0);
|
|
tg_tool->trans_info[OFFSET_Y] = pika_size_entry_get_refval (
|
|
PIKA_SIZE_ENTRY (t3d->offset_se), 1);
|
|
tg_tool->trans_info[OFFSET_Z] = pika_size_entry_get_refval (
|
|
PIKA_SIZE_ENTRY (t3d->offset_se), 2);
|
|
|
|
/* angle spin scales */
|
|
tg_tool->trans_info[ANGLE_X] = pika_deg_to_rad (gtk_adjustment_get_value (
|
|
t3d->angle_adj[0]));
|
|
tg_tool->trans_info[ANGLE_Y] = pika_deg_to_rad (gtk_adjustment_get_value (
|
|
t3d->angle_adj[1]));
|
|
tg_tool->trans_info[ANGLE_Z] = pika_deg_to_rad (gtk_adjustment_get_value (
|
|
t3d->angle_adj[2]));
|
|
|
|
pika_transform_grid_tool_push_internal_undo (tg_tool, TRUE);
|
|
|
|
pika_transform_tool_recalc_matrix (tr_tool, tool->display);
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_lens_mode_changed (GtkComboBox *combo,
|
|
PikaTransform3DTool *t3d)
|
|
{
|
|
PikaTool *tool = PIKA_TOOL (t3d);
|
|
PikaTransformTool *tr_tool = PIKA_TRANSFORM_TOOL (t3d);
|
|
PikaTransformGridTool *tg_tool = PIKA_TRANSFORM_GRID_TOOL (t3d);
|
|
PikaDisplay *display = tool->display;
|
|
PikaImage *image = pika_display_get_image (display);
|
|
gdouble x1 = 0.0;
|
|
gdouble y1 = 0.0;
|
|
gdouble x2 = 0.0;
|
|
gdouble y2 = 0.0;
|
|
gint width;
|
|
gint height;
|
|
gint lens_mode;
|
|
gdouble focal_length;
|
|
|
|
if (t3d->updating)
|
|
return;
|
|
|
|
if (! pika_int_combo_box_get_active (PIKA_INT_COMBO_BOX (combo), &lens_mode))
|
|
return;
|
|
|
|
width = pika_image_get_width (image);
|
|
height = pika_image_get_height (image);
|
|
|
|
focal_length = pika_transform_3d_tool_get_focal_length (t3d);
|
|
|
|
tg_tool->trans_info[LENS_MODE] = lens_mode;
|
|
|
|
switch (lens_mode)
|
|
{
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOCAL_LENGTH:
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOV_IMAGE:
|
|
x1 = 0.0;
|
|
y1 = 0.0;
|
|
|
|
x2 = width;
|
|
y2 = height;
|
|
break;
|
|
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOV_ITEM:
|
|
x1 = tr_tool->x1;
|
|
y1 = tr_tool->y1;
|
|
|
|
x2 = tr_tool->x2;
|
|
y2 = tr_tool->y2;
|
|
break;
|
|
}
|
|
|
|
switch (lens_mode)
|
|
{
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOCAL_LENGTH:
|
|
tg_tool->trans_info[LENS_VALUE] = focal_length;
|
|
break;
|
|
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOV_IMAGE:
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOV_ITEM:
|
|
tg_tool->trans_info[LENS_VALUE] =
|
|
pika_transform_3d_focal_length_to_angle_of_view (
|
|
focal_length, x2 - x1, y2 - y1);
|
|
break;
|
|
}
|
|
|
|
/* vanishing-point size entry */
|
|
pika_size_entry_set_size (PIKA_SIZE_ENTRY (t3d->vanishing_point_se), 0,
|
|
x1, x2);
|
|
pika_size_entry_set_size (PIKA_SIZE_ENTRY (t3d->vanishing_point_se), 1,
|
|
y1, y2);
|
|
|
|
pika_transform_grid_tool_push_internal_undo (tg_tool, TRUE);
|
|
|
|
pika_transform_tool_recalc_matrix (tr_tool, tool->display);
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_rotation_order_clicked (GtkButton *button,
|
|
PikaTransform3DTool *t3d)
|
|
{
|
|
PikaTool *tool = PIKA_TOOL (t3d);
|
|
PikaTransformTool *tr_tool = PIKA_TRANSFORM_TOOL (t3d);
|
|
PikaTransformGridTool *tg_tool = PIKA_TRANSFORM_GRID_TOOL (t3d);
|
|
PikaMatrix4 matrix;
|
|
gint permutation[3];
|
|
gint b;
|
|
gint i;
|
|
|
|
for (b = 0; b < 3; b++)
|
|
{
|
|
if (GTK_BUTTON (t3d->rotation_order_buttons[b]) == button)
|
|
break;
|
|
}
|
|
|
|
pika_transform_3d_rotation_order_to_permutation (
|
|
tg_tool->trans_info[ROTATION_ORDER], permutation);
|
|
|
|
if (permutation[0] == b)
|
|
{
|
|
gint temp;
|
|
|
|
temp = permutation[1];
|
|
permutation[1] = permutation[2];
|
|
permutation[2] = temp;
|
|
}
|
|
else
|
|
{
|
|
gint temp;
|
|
|
|
temp = permutation[0];
|
|
permutation[0] = b;
|
|
|
|
for (i = 1; i < 3; i++)
|
|
{
|
|
if (permutation[i] == b)
|
|
{
|
|
permutation[i] = temp;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
pika_matrix4_identity (&matrix);
|
|
|
|
pika_transform_3d_matrix4_rotate_euler (&matrix,
|
|
tg_tool->trans_info[ROTATION_ORDER],
|
|
tg_tool->trans_info[ANGLE_X],
|
|
tg_tool->trans_info[ANGLE_Y],
|
|
tg_tool->trans_info[ANGLE_Z],
|
|
0.0, 0.0, 0.0);
|
|
|
|
tg_tool->trans_info[ROTATION_ORDER] =
|
|
pika_transform_3d_permutation_to_rotation_order (permutation);
|
|
|
|
pika_transform_3d_matrix4_rotate_euler_decompose (
|
|
&matrix,
|
|
tg_tool->trans_info[ROTATION_ORDER],
|
|
&tg_tool->trans_info[ANGLE_X],
|
|
&tg_tool->trans_info[ANGLE_Y],
|
|
&tg_tool->trans_info[ANGLE_Z]);
|
|
|
|
pika_transform_grid_tool_push_internal_undo (tg_tool, TRUE);
|
|
|
|
pika_transform_tool_recalc_matrix (tr_tool, tool->display);
|
|
}
|
|
|
|
static void
|
|
pika_transform_3d_tool_pivot_changed (PikaPivotSelector *selector,
|
|
PikaTransform3DTool *t3d)
|
|
{
|
|
PikaTool *tool = PIKA_TOOL (t3d);
|
|
PikaTransformTool *tr_tool = PIKA_TRANSFORM_TOOL (t3d);
|
|
PikaTransformGridTool *tg_tool = PIKA_TRANSFORM_GRID_TOOL (t3d);
|
|
PikaMatrix4 matrix;
|
|
gdouble offset_x;
|
|
gdouble offset_y;
|
|
gdouble offset_z;
|
|
|
|
if (t3d->updating)
|
|
return;
|
|
|
|
pika_matrix4_identity (&matrix);
|
|
|
|
pika_transform_3d_matrix4_rotate_euler (&matrix,
|
|
tg_tool->trans_info[ROTATION_ORDER],
|
|
tg_tool->trans_info[ANGLE_X],
|
|
tg_tool->trans_info[ANGLE_Y],
|
|
tg_tool->trans_info[ANGLE_Z],
|
|
tg_tool->trans_info[PIVOT_X],
|
|
tg_tool->trans_info[PIVOT_Y],
|
|
tg_tool->trans_info[PIVOT_Z]);
|
|
|
|
pika_pivot_selector_get_position (PIKA_PIVOT_SELECTOR (t3d->pivot_selector),
|
|
&tg_tool->trans_info[PIVOT_X],
|
|
&tg_tool->trans_info[PIVOT_Y]);
|
|
|
|
pika_matrix4_transform_point (&matrix,
|
|
tg_tool->trans_info[PIVOT_X],
|
|
tg_tool->trans_info[PIVOT_Y],
|
|
tg_tool->trans_info[PIVOT_Z],
|
|
&offset_x, &offset_y, &offset_z);
|
|
|
|
tg_tool->trans_info[OFFSET_X] += offset_x - tg_tool->trans_info[PIVOT_X];
|
|
tg_tool->trans_info[OFFSET_Y] += offset_y - tg_tool->trans_info[PIVOT_Y];
|
|
tg_tool->trans_info[OFFSET_Z] += offset_z - tg_tool->trans_info[PIVOT_Z];
|
|
|
|
pika_transform_grid_tool_push_internal_undo (tg_tool, TRUE);
|
|
|
|
pika_transform_tool_recalc_matrix (tr_tool, tool->display);
|
|
}
|
|
|
|
static gdouble
|
|
pika_transform_3d_tool_get_focal_length (PikaTransform3DTool *t3d)
|
|
{
|
|
PikaTool *tool = PIKA_TOOL (t3d);
|
|
PikaTransformTool *tr_tool = PIKA_TRANSFORM_TOOL (t3d);
|
|
PikaTransformGridTool *tg_tool = PIKA_TRANSFORM_GRID_TOOL (t3d);
|
|
PikaImage *image = pika_display_get_image (tool->display);
|
|
gdouble width = 0.0;
|
|
gdouble height = 0.0;
|
|
|
|
switch ((int) tg_tool->trans_info[LENS_MODE])
|
|
{
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOCAL_LENGTH:
|
|
return tg_tool->trans_info[LENS_VALUE];
|
|
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOV_IMAGE:
|
|
width = pika_image_get_width (image);
|
|
height = pika_image_get_height (image);
|
|
break;
|
|
|
|
case PIKA_TRANSFORM_3D_LENS_MODE_FOV_ITEM:
|
|
width = tr_tool->x2 - tr_tool->x1;
|
|
height = tr_tool->y2 - tr_tool->y1;
|
|
break;
|
|
}
|
|
|
|
return pika_transform_3d_angle_of_view_to_focal_length (
|
|
tg_tool->trans_info[LENS_VALUE], width, height);
|
|
}
|