[gimp/soc-2011-warp] gimpoperationwarp: add a hardness property, and use it to compute influence with a gaussian like cur
- From: Michael Murà <mmure src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/soc-2011-warp] gimpoperationwarp: add a hardness property, and use it to compute influence with a gaussian like cur
- Date: Tue, 5 Jul 2011 14:39:17 +0000 (UTC)
commit 7273faf7dee68a5bc8d3914b5efd1ae2e0b95a7a
Author: Michael Murà <batolettre gmail com>
Date: Tue Jul 5 16:35:32 2011 +0200
gimpoperationwarp: add a hardness property, and use it to compute influence with a gaussian like curve
implementation use a lookup table to speed things
gimpwarpoptions: add a hardness property and UI
app/gegl/gimpoperationwarp.c | 75 ++++++++++++++++++++++++++++++++++++++++-
app/gegl/gimpoperationwarp.h | 3 ++
app/tools/gimpwarpoptions.c | 28 +++++++++++++--
app/tools/gimpwarpoptions.h | 1 +
app/tools/gimpwarptool.c | 1 +
5 files changed, 102 insertions(+), 6 deletions(-)
---
diff --git a/app/gegl/gimpoperationwarp.c b/app/gegl/gimpoperationwarp.c
index e19c2da..ed95e0a 100644
--- a/app/gegl/gimpoperationwarp.c
+++ b/app/gegl/gimpoperationwarp.c
@@ -36,6 +36,7 @@ enum
PROP_0,
PROP_STRENGTH,
PROP_SIZE,
+ PROP_HARDNESS,
PROP_STROKE,
PROP_BEHAVIOR
};
@@ -60,6 +61,8 @@ static void gimp_operation_warp_stamp (GimpOperationWarp *ow
static gdouble gimp_operation_warp_get_influence (GimpOperationWarp *ow,
gdouble x,
gdouble y);
+static void gimp_operation_warp_calc_lut (GimpOperationWarp *ow);
+static gdouble gauss (gdouble f);
G_DEFINE_TYPE (GimpOperationWarp, gimp_operation_warp,
GEGL_TYPE_OPERATION_FILTER)
@@ -98,6 +101,11 @@ gimp_operation_warp_class_init (GimpOperationWarpClass *klass)
1.0, 10000.0, 40.0,
GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_HARDNESS,
+ "hardness", _("Effect Harness"),
+ 0.0, 1.0, 0.5,
+ GIMP_PARAM_STATIC_STRINGS);
+
GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, PROP_STROKE,
"stroke", _("Stroke"),
GEGL_TYPE_PATH,
@@ -128,6 +136,12 @@ gimp_operation_warp_finalize (GObject *object)
self->stroke = NULL;
}
+ if (self->lookup)
+ {
+ g_free (self->lookup);
+ self->lookup = NULL;
+ }
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -147,6 +161,9 @@ gimp_operation_warp_get_property (GObject *object,
case PROP_SIZE:
g_value_set_double (value, self->size);
break;
+ case PROP_HARDNESS:
+ g_value_set_double (value, self->hardness);
+ break;
case PROP_STROKE:
g_value_set_object (value, self->stroke);
break;
@@ -176,6 +193,9 @@ gimp_operation_warp_set_property (GObject *object,
case PROP_SIZE:
self->size = g_value_get_double (value);
break;
+ case PROP_HARDNESS:
+ self->hardness = g_value_get_double (value);
+ break;
case PROP_STROKE:
if (self->stroke)
g_object_unref (self->stroke);
@@ -367,7 +387,58 @@ gimp_operation_warp_get_influence (GimpOperationWarp *ow,
gdouble x,
gdouble y)
{
- gfloat radius = sqrt(x*x+y*y);
+ gfloat radius;
+
+ if (!ow->lookup)
+ {
+ gimp_operation_warp_calc_lut (ow);
+ }
+
+ radius = sqrt(x*x+y*y);
+
+ if (radius < 0.5 * ow->size + 1)
+ return ow->strength * ow->lookup[(gint) RINT (radius)];
+ else
+ return 0.0;
+}
+
+/* set up lookup table */
+static void
+gimp_operation_warp_calc_lut (GimpOperationWarp *ow)
+{
+ gint length;
+ gint x;
+ gdouble exponent;
+
+ length = ceil (0.5 * ow->size + 1.0);
+
+ ow->lookup = g_malloc (length * sizeof (gfloat));
+
+ if ((1.0 - ow->hardness) < 0.0000004)
+ exponent = 1000000.0;
+ else
+ exponent = 0.4 / (1.0 - ow->hardness);
+
+ for (x = 0; x < length; x++)
+ {
+ ow->lookup[x] = gauss (pow (2.0 * x / ow->size, exponent));
+ }
+}
+
+static gdouble
+gauss (gdouble f)
+{
+ /* This is not a real gauss function. */
+ /* Approximation is valid if -1 < f < 1 */
+ if (f < -0.5)
+ {
+ f = -1.0 - f;
+ return (2.0 * f*f);
+ }
+
+ if (f < 0.5)
+ return (1.0 - 2.0 * f*f);
- return (radius < ow->size / 2.0) ? ow->strength : 0.0;
+ f = 1.0 - f;
+ return (2.0 * f*f);
}
diff --git a/app/gegl/gimpoperationwarp.h b/app/gegl/gimpoperationwarp.h
index f34aa96..f581a33 100644
--- a/app/gegl/gimpoperationwarp.h
+++ b/app/gegl/gimpoperationwarp.h
@@ -41,6 +41,7 @@ struct _GimpOperationWarp
/* Properties of the operation */
gdouble strength;
gdouble size;
+ gdouble hardness;
GeglPath *stroke;
GimpWarpBehavior behavior;
@@ -51,6 +52,8 @@ struct _GimpOperationWarp
/* used to pass the temporary buffer to the function called by gegl_path_foreach */
GeglBuffer *buffer;
+
+ gfloat *lookup;
};
struct _GimpOperationWarpClass
diff --git a/app/tools/gimpwarpoptions.c b/app/tools/gimpwarpoptions.c
index 0ee2b96..c9bb508 100644
--- a/app/tools/gimpwarpoptions.c
+++ b/app/tools/gimpwarpoptions.c
@@ -41,6 +41,7 @@ enum
PROP_0,
PROP_EFFECT_STRENGTH,
PROP_EFFECT_SIZE,
+ PROP_EFFECT_HARDNESS,
PROP_BEHAVIOR
};
@@ -79,6 +80,11 @@ gimp_warp_options_class_init (GimpWarpOptionsClass *klass)
1.0, 10000.0, 40.0,
GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_EFFECT_HARDNESS,
+ "effect-hardness", _("Effect Hardness"),
+ 0.0, 1.0, 0.5,
+ GIMP_PARAM_STATIC_STRINGS);
+
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_BEHAVIOR,
"behavior",
N_("Behavior"),
@@ -108,6 +114,9 @@ gimp_warp_options_set_property (GObject *object,
case PROP_EFFECT_SIZE:
options->effect_size = g_value_get_double (value);
break;
+ case PROP_EFFECT_HARDNESS:
+ options->effect_hardness = g_value_get_double (value);
+ break;
case PROP_BEHAVIOR:
options->behavior = g_value_get_enum (value);
break;
@@ -134,6 +143,9 @@ gimp_warp_options_get_property (GObject *object,
case PROP_EFFECT_SIZE:
g_value_set_double (value, options->effect_size);
break;
+ case PROP_EFFECT_HARDNESS:
+ g_value_set_double (value, options->effect_hardness);
+ break;
case PROP_BEHAVIOR:
g_value_set_enum (value, options->behavior);
break;
@@ -152,24 +164,32 @@ gimp_warp_options_gui (GimpToolOptions *tool_options)
GtkWidget *behavior;
GtkWidget *strength;
GtkWidget *size;
+ GtkWidget *hardness;
behavior = gimp_prop_enum_combo_box_new (config, "behavior", 0, 0);
gtk_box_pack_start (GTK_BOX (vbox), behavior, FALSE, FALSE, 0);
gtk_widget_show (behavior);
strength = gimp_prop_spin_scale_new (config, "effect-strength",
- _("Strength"),
- 0.01, 1.0, 2);
+ _("Strength"),
+ 0.01, 1.0, 2);
gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (strength), 0.0, 1.0);
gtk_box_pack_start (GTK_BOX (vbox), strength, FALSE, FALSE, 0);
gtk_widget_show (strength);
size = gimp_prop_spin_scale_new (config, "effect-size",
- _("Size"),
- 0.01, 1.0, 2);
+ _("Size"),
+ 0.01, 1.0, 2);
gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (size), 1.0, 1000.0);
gtk_box_pack_start (GTK_BOX (vbox), size, FALSE, FALSE, 0);
gtk_widget_show (size);
+ hardness = gimp_prop_spin_scale_new (config, "effect-hardness",
+ _("Hardness"),
+ 0.01, 1.0, 2);
+ gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (hardness), 0.0, 1.0);
+ gtk_box_pack_start (GTK_BOX (vbox), hardness, FALSE, FALSE, 0);
+ gtk_widget_show (hardness);
+
return vbox;
}
diff --git a/app/tools/gimpwarpoptions.h b/app/tools/gimpwarpoptions.h
index d5d07a4..926197f 100644
--- a/app/tools/gimpwarpoptions.h
+++ b/app/tools/gimpwarpoptions.h
@@ -41,6 +41,7 @@ struct _GimpWarpOptions
gdouble effect_strength;
gdouble effect_size;
+ gdouble effect_hardness;
GimpWarpBehavior behavior;
};
diff --git a/app/tools/gimpwarptool.c b/app/tools/gimpwarptool.c
index 94f1a33..b2cc14c 100644
--- a/app/tools/gimpwarptool.c
+++ b/app/tools/gimpwarptool.c
@@ -561,6 +561,7 @@ gimp_warp_tool_add_op (GimpWarpTool *wt)
"behavior", options->behavior,
"strength", options->effect_strength,
"size", options->effect_size,
+ "hardness", options->effect_hardness,
"stroke", wt->current_stroke,
NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]