|
| 1 | +/* This file is an image processing operation for GEGL |
| 2 | + * |
| 3 | + * GEGL is free software; you can redistribute it and/or |
| 4 | + * modify it under the terms of the GNU Lesser General Public |
| 5 | + * License as published by the Free Software Foundation; either |
| 6 | + * version 3 of the License, or (at your option) any later version. |
| 7 | + * |
| 8 | + * GEGL is distributed in the hope that it will be useful, |
| 9 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 11 | + * Lesser General Public License for more details. |
| 12 | + * |
| 13 | + * You should have received a copy of the GNU Lesser General Public |
| 14 | + * License along with GEGL; if not, see <https://www.gnu.org/licenses/>. |
| 15 | + * |
| 16 | + * Copyright 2006 Øyvind Kolås <pippin@gimp.org> |
| 17 | + * 2022 Beaver (GEGL Bevel) *2023 Beaver (GEGL Bevel 2 for GEGL Effects Continual Edition) |
| 18 | + */ |
| 19 | + |
| 20 | +#include "config.h" |
| 21 | +#include <glib/gi18n-lib.h> |
| 22 | + |
| 23 | +#ifdef GEGL_PROPERTIES |
| 24 | + |
| 25 | +property_boolean (effectsswitchbevel, _("Enable Bevel (FOR GEGL EFFECTS ONLY)"), TRUE) |
| 26 | + description (_("This switch exist for GEGL Effects. You won't find it in stand alone bevel'")) |
| 27 | + ui_meta ("role", "output-extent") |
| 28 | + |
| 29 | +property_boolean (embossmode, _("Emboss Mode (use Gimp's layer Grain Merge blend mode)"), FALSE) |
| 30 | + description (_("Make an embossed bevel'")) |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | + |
| 38 | + |
| 39 | +property_double (radius, _("Radius Normal Bevel"), 7.0) |
| 40 | + value_range (1.0, 40.0) |
| 41 | + ui_range (1.0, 12) |
| 42 | + ui_gamma (1.5) |
| 43 | + |
| 44 | +property_int (radiussharp, _("Radius Sharp Bevel"), 0) |
| 45 | + description(_("Box Blur -0 means disabled by default")) |
| 46 | + value_range (0, 8) |
| 47 | + ui_range (0, 8) |
| 48 | + ui_gamma (1.5) |
| 49 | + |
| 50 | + |
| 51 | +property_double (elevation, _("Depth Angle"), 90.0) |
| 52 | + description (_("Elevation angle (degrees)")) |
| 53 | + value_range (0, 180) |
| 54 | + ui_meta ("unit", "degree") |
| 55 | + |
| 56 | +property_int (depth, _("Depth"), 40) |
| 57 | + description (_("Filter width")) |
| 58 | + value_range (1, 100) |
| 59 | + |
| 60 | + |
| 61 | +property_double (th, _("Threshold of the Bevel's Transparency'"), 0.100) |
| 62 | + value_range (0.0, 1.0) |
| 63 | + ui_range (0.0, 0.5) |
| 64 | + |
| 65 | +property_double (azimuth, _("Rotate Lighting"), 40.0) |
| 66 | + description (_("Light angle (degrees)")) |
| 67 | + value_range (0, 350) |
| 68 | + ui_meta ("unit", "degree") |
| 69 | + ui_meta ("direction", "ccw") |
| 70 | + |
| 71 | + |
| 72 | +#else |
| 73 | + |
| 74 | +#define GEGL_OP_META |
| 75 | +#define GEGL_OP_NAME bevelbump |
| 76 | +#define GEGL_OP_C_SOURCE bevelbump.c |
| 77 | + |
| 78 | +#include "gegl-op.h" |
| 79 | + |
| 80 | + |
| 81 | +typedef struct |
| 82 | +{ |
| 83 | + GeglNode *input; |
| 84 | + GeglNode *blur; |
| 85 | + GeglNode *boxblur; |
| 86 | + GeglNode *emb; |
| 87 | + GeglNode *th; |
| 88 | + GeglNode *output; |
| 89 | +} State; |
| 90 | + |
| 91 | + |
| 92 | +static void attach (GeglOperation *operation) |
| 93 | +{ |
| 94 | + GeglNode *gegl = operation->node; |
| 95 | + GeglProperties *o = GEGL_PROPERTIES (operation); |
| 96 | + GeglNode *input, *output, *boxblur, *blur, *emb, *th; |
| 97 | + |
| 98 | + input = gegl_node_get_input_proxy (gegl, "input"); |
| 99 | + output = gegl_node_get_output_proxy (gegl, "output"); |
| 100 | + |
| 101 | + blur = gegl_node_new_child (gegl, |
| 102 | + "operation", "gegl:gaussian-blur", |
| 103 | + NULL); |
| 104 | + |
| 105 | + boxblur = gegl_node_new_child (gegl, |
| 106 | + "operation", "gegl:box-blur", |
| 107 | + NULL); |
| 108 | + |
| 109 | + |
| 110 | + |
| 111 | + |
| 112 | + emb = gegl_node_new_child (gegl, |
| 113 | + "operation", "gegl:emboss", |
| 114 | + NULL); |
| 115 | + |
| 116 | + th = gegl_node_new_child (gegl, |
| 117 | + "operation", "gimp:threshold-alpha", |
| 118 | + NULL); |
| 119 | + |
| 120 | + |
| 121 | + |
| 122 | + gegl_node_link_many (input, blur, boxblur, emb, th, output, NULL); |
| 123 | + gegl_operation_meta_redirect (operation, "radius", blur, "std-dev-x"); |
| 124 | + gegl_operation_meta_redirect (operation, "radius", blur, "std-dev-y"); |
| 125 | + gegl_operation_meta_redirect (operation, "elevation", emb, "elevation"); |
| 126 | + gegl_operation_meta_redirect (operation, "depth", emb, "depth"); |
| 127 | + gegl_operation_meta_redirect (operation, "azimuth", emb, "azimuth"); |
| 128 | + gegl_operation_meta_redirect (operation, "radiussharp", boxblur, "radius"); |
| 129 | + gegl_operation_meta_redirect (operation, "th", th, "value"); |
| 130 | + |
| 131 | + |
| 132 | + |
| 133 | + |
| 134 | + /* Now save points to the various gegl nodes so we can rewire them in |
| 135 | + * update_graph() later |
| 136 | + */ |
| 137 | + State *state = g_malloc0 (sizeof (State)); |
| 138 | + state->input = input; |
| 139 | + state->blur = blur; |
| 140 | + state->boxblur = boxblur; |
| 141 | + state->emb = emb; |
| 142 | + state->th = th; |
| 143 | + state->output = output; |
| 144 | + o->user_data = state; |
| 145 | +} |
| 146 | + |
| 147 | +static void |
| 148 | +update_graph (GeglOperation *operation) |
| 149 | +{ |
| 150 | + GeglProperties *o = GEGL_PROPERTIES (operation); |
| 151 | + State *state = o->user_data; |
| 152 | + if (!state) return; |
| 153 | + |
| 154 | + if (o->effectsswitchbevel) |
| 155 | + if (o->embossmode) |
| 156 | + { |
| 157 | + gegl_node_link_many (state->blur, state->boxblur, state->emb, state->output, NULL); |
| 158 | + } |
| 159 | +else |
| 160 | + { |
| 161 | + gegl_node_link_many (state->blur, state->boxblur, state->emb, state->th, state->output, NULL); |
| 162 | + } |
| 163 | +else |
| 164 | + { |
| 165 | + gegl_node_link_many (state->input, state->output, NULL); |
| 166 | + } |
| 167 | +} |
| 168 | + |
| 169 | + |
| 170 | + |
| 171 | + |
| 172 | + |
| 173 | +static void |
| 174 | +gegl_op_class_init (GeglOpClass *klass) |
| 175 | +{ |
| 176 | + GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass); |
| 177 | + GeglOperationMetaClass *operation_meta_class = GEGL_OPERATION_META_CLASS (klass); |
| 178 | + |
| 179 | + operation_class->attach = attach; |
| 180 | + operation_meta_class->update = update_graph; |
| 181 | + |
| 182 | + gegl_operation_class_set_keys (operation_class, |
| 183 | + "name", "gegl:bevelbump", |
| 184 | + "title", _("Bevel 2"), |
| 185 | + "categories", "Aristic", |
| 186 | + "reference-hash", "bev45ed5656a28a512570f0f25sb2ac", |
| 187 | + "description", _("GEGL Effects Continual Edition REQUIRES Bevel 2. Many other Beaver Plugins (chrome, goo, and default GEGL Effects) require Bevel. So you have to keep both bevel plugins if you want everything to work. Bevel 2 has new abilities such as the sharp bevel mode and emboss mode. Works best wiht blend modes multiply and grain merge." |
| 188 | + ""), |
| 189 | + NULL); |
| 190 | +} |
| 191 | + |
| 192 | +#endif |
0 commit comments