[gegl/soc-2013-n-point-deformation: 4/28] add part of n-point deformation library
- From: Marek Dvoroznak <dvoromar src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/soc-2013-n-point-deformation: 4/28] add part of n-point deformation library
- Date: Fri, 6 Dec 2013 05:01:27 +0000 (UTC)
commit ca0fb347c0d288e7dfe045dcc18bd448e65d51c3
Author: Marek Dvoroznak <dvoromar gmail com>
Date: Sun Jul 21 19:47:58 2013 +0200
add part of n-point deformation library
configure.ac | 14 ++
libs/Makefile.am | 2 +-
libs/npd/.gitignore | 6 +
libs/npd/Makefile.am | 16 ++
libs/npd/graphics.c | 355 +++++++++++++++++++++++++++++++++++++++
libs/npd/graphics.h | 93 ++++++++++
libs/npd/npd.h | 29 ++++
libs/npd/npd_common.c | 7 +
libs/npd/npd_common.h | 21 ++-
libs/npd/npd_gegl.c | 2 +-
libs/npd/npd_gegl.h | 2 +-
operations/external/Makefile.am | 6 +
operations/external/npd.c | 173 +++++++++++++++++++-
13 files changed, 714 insertions(+), 12 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index f567090..d75d11d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -246,6 +246,7 @@ case "$target_or_host" in
;;
x86_64-*-*)
have_x86=yes
+ have_64_bit=yes
AC_DEFINE(ARCH_X86, 1, [Define to 1 if you are compiling for ix86.])
AC_DEFINE(ARCH_X86_64, 1, [Define to 1 if you are compiling for amd64.])
;;
@@ -255,6 +256,7 @@ case "$target_or_host" in
;;
ppc64-*-* | powerpc64-*)
have_ppc=yes
+ have_64_bit=yes
AC_DEFINE(ARCH_PPC, 1, [Define to 1 if you are compiling for PowerPC.])
AC_DEFINE(ARCH_PPC64, 1, [Define to 1 if you are compiling for PowerPC64.])
;;
@@ -262,6 +264,8 @@ case "$target_or_host" in
;;
esac
+AM_CONDITIONAL(HAVE_64_BIT, test "x$have_64_bit" = "xyes")
+
####################################################
# Check how to generate plug-ins (with gcc at least)
@@ -1074,6 +1078,14 @@ if test "x$have_p2tc" != "xyes"; then
AC_SUBST(P2TC_LIBS, "-L\$(top_builddir)/libs/poly2tri-c/poly2tri-c -lpoly2tri-c")
fi
+##################
+# Check for libnpd
+##################
+have_libnpd="yes (internal)"
+
+AC_SUBST(NPD_CFLAGS, "-I\$(top_srcdir)/libs/npd")
+AC_SUBST(NPD_LIBS, "-L\$(top_builddir)/libs/npd -lnpd")
+
#######################
# Check for other items
#######################
@@ -1139,6 +1151,7 @@ gegl/property-types/Makefile
gegl/opencl/Makefile
libs/Makefile
libs/rgbe/Makefile
+libs/npd/Makefile
libs/poly2tri-c/Makefile
libs/poly2tri-c/poly2tri-c/Makefile
libs/poly2tri-c/poly2tri-c/render/Makefile
@@ -1225,4 +1238,5 @@ Optional dependencies:
umfpack: $have_umfpack
webp: $have_webp
poly2tri-c: $have_p2tc
+ libnpd: $have_libnpd
]);
diff --git a/libs/Makefile.am b/libs/Makefile.am
index 176d347..334cf56 100644
--- a/libs/Makefile.am
+++ b/libs/Makefile.am
@@ -1 +1 @@
-SUBDIRS = rgbe poly2tri-c
+SUBDIRS = rgbe poly2tri-c npd
diff --git a/libs/npd/.gitignore b/libs/npd/.gitignore
new file mode 100644
index 0000000..4e0b01c
--- /dev/null
+++ b/libs/npd/.gitignore
@@ -0,0 +1,6 @@
+/Makefile
+/Makefile.in
+/.deps/
+/.libs/
+/*.lo
+/*.la
\ No newline at end of file
diff --git a/libs/npd/Makefile.am b/libs/npd/Makefile.am
new file mode 100644
index 0000000..ffc55f9
--- /dev/null
+++ b/libs/npd/Makefile.am
@@ -0,0 +1,16 @@
+noinst_LTLIBRARIES = libnpd.la
+
+AM_CFLAGS = $(GLIB_CFLAGS) $(NPD_CFLAGS) -I$(top_builddir)/gegl -I$(top_srcdir)/gegl
+AM_LDFLAGS = $(GLIB_LIBS) $(NPD_LIBS)
+
+libnpd_la_SOURCES = \
+ npd_common.h \
+ npd_common.c \
+ deformation.h \
+ deformation.c \
+ npd_math.h \
+ npd_math.c \
+ graphics.h \
+ graphics.c \
+ npd_gegl.h \
+ npd_gegl.c
diff --git a/libs/npd/graphics.c b/libs/npd/graphics.c
new file mode 100644
index 0000000..e4f0878
--- /dev/null
+++ b/libs/npd/graphics.c
@@ -0,0 +1,355 @@
+/*
+ * This file is part of n-point image deformation library.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2013 Marek Dvoroznak <dvoromar gmail com>
+ */
+
+#include "graphics.h"
+#include "glib.h"
+#include <math.h>
+#include "npd_math.h"
+
+void
+npd_create_mesh_from_image (NPDModel *model,
+ gint width,
+ gint height,
+ gint position_x,
+ gint position_y)
+{
+ gint square_size = model->mesh_square_size;
+ NPDHiddenModel *hidden_model = model->hidden_model;
+ NPDImage *image = model->reference_image;
+ gint i, cy, cx, y, x;
+ NPDColor transparent = { 0, 0, 0, 0 };
+ NPDColor pixel_color = { 0, 0, 0, 0 };
+ GPtrArray *current_bones, *reference_bones;
+
+ /* create quadrilaterals above the image */
+ width = ceil ((gfloat) width / square_size);
+ height = ceil ((gfloat) height / square_size);
+
+ current_bones = g_ptr_array_new ();
+ reference_bones = g_ptr_array_new ();
+
+ for (cy = 0; cy < height; cy++)
+ {
+ for (cx = 0; cx < width; cx++)
+ {
+ gboolean is_empty = TRUE;
+
+ for (y = cy * square_size; y < (cy + 1) * square_size; y++)
+ {
+ for (x = cx * square_size; x < (cx + 1) * square_size; x++)
+ {
+ npd_get_pixel_color (image, x, y, &pixel_color);
+
+ if (!npd_compare_colors (&pixel_color, &transparent))
+ {
+ is_empty = FALSE;
+ goto not_empty;
+ }
+ }
+ }
+
+ not_empty:
+ if (!is_empty)
+ {
+ NPDBone *current_bone, *reference_bone;
+ NPDPoint *current_points, *ref_points;
+ gfloat *weights;
+ gint coords[8] = {cx, cx + 1, cx + 1, cx,
+ cy, cy, cy + 1, cy + 1};
+
+ current_bone = g_new (NPDBone, 1);
+ reference_bone = g_new (NPDBone, 1);
+ current_points = g_new (NPDPoint, 4);
+ ref_points = g_new (NPDPoint, 4);
+ weights = g_new (gfloat, 4);
+
+ for (i = 0; i < 4; i++)
+ {
+ weights[i] = 1.0;
+
+ current_points[i].x = position_x + (coords[i] * square_size);
+ current_points[i].y = position_y + (coords[i + 4] * square_size);
+ current_points[i].weight = &weights[i];
+ current_points[i].fixed = FALSE;
+ current_points[i].current_bone = current_bone;
+ current_points[i].reference_bone = reference_bone;
+ current_points[i].index = i;
+
+ ref_points[i].x = current_points[i].x - position_x;
+ ref_points[i].y = current_points[i].y - position_y;
+ ref_points[i].weight = &weights[i];
+ ref_points[i].fixed = current_points[i].fixed;
+ ref_points[i].current_bone = current_bone;
+ ref_points[i].reference_bone = reference_bone;
+ ref_points[i].index = i;
+
+ current_points[i].counterpart = &ref_points[i];
+ ref_points[i].counterpart = ¤t_points[i];
+ }
+
+ current_bone->points = current_points;
+ current_bone->num_of_points = 4;
+ current_bone->weights = weights;
+ g_ptr_array_add (current_bones, current_bone);
+
+ reference_bone->points = ref_points;
+ reference_bone->num_of_points = 4;
+ reference_bone->weights = weights;
+ g_ptr_array_add (reference_bones, reference_bone);
+
+ hidden_model->num_of_bones++;
+ }
+ }
+ }
+
+ hidden_model->current_bones = g_new (NPDBone, current_bones->len);
+ hidden_model->reference_bones = g_new (NPDBone, reference_bones->len);
+
+ for (i = 0; i < current_bones->len; i++)
+ {
+ hidden_model->current_bones[i] = *(NPDBone*) g_ptr_array_index (current_bones, i);
+ hidden_model->reference_bones[i] = *(NPDBone*) g_ptr_array_index (reference_bones, i);
+ }
+
+ g_ptr_array_free(current_bones, TRUE);
+ g_ptr_array_free(reference_bones, TRUE);
+}
+
+gboolean
+npd_compare_colors (NPDColor *c1,
+ NPDColor *c2)
+{
+ if (c1->r == c2->r &&
+ c1->g == c2->g &&
+ c1->b == c2->b &&
+ c1->a == c2->a)
+ return TRUE;
+
+ return FALSE;
+}
+
+gboolean
+npd_is_color_transparent (NPDColor *color)
+{
+ if (color->a == 0 &&
+ color->b == 0 &&
+ color->g == 0 &&
+ color->r == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+gint
+npd_bilinear_interpolation (gint I0,
+ gint I1,
+ gint I2,
+ gint I3,
+ gfloat dx,
+ gfloat dy)
+{
+ return floor ((I0 * (1 - dx) + I1 * dx) * (1 - dy)
+ + (I2 * (1 - dx) + I3 * dx) * dy);
+}
+
+void
+npd_bilinear_color_interpolation (NPDColor *I0,
+ NPDColor *I1,
+ NPDColor *I2,
+ NPDColor *I3,
+ gfloat dx,
+ gfloat dy,
+ NPDColor *out)
+{
+ out->r = npd_bilinear_interpolation (I0->r, I1->r, I2->r, I3->r, dx, dy);
+ out->g = npd_bilinear_interpolation (I0->g, I1->g, I2->g, I3->g, dx, dy);
+ out->b = npd_bilinear_interpolation (I0->b, I1->b, I2->b, I3->b, dx, dy);
+ out->a = npd_bilinear_interpolation (I0->a, I1->a, I2->a, I3->a, dx, dy);
+}
+
+void
+npd_texture_fill_triangle (gint x1,
+ gint y1,
+ gint x2,
+ gint y2,
+ gint x3,
+ gint y3,
+ NPDMatrix *A,
+ NPDImage *input_image,
+ NPDImage *output_image)
+{
+ gint yA, yB, yC, xA, xB, xC;
+ gint tmp, y;
+ gint deltaXAB, deltaYAB;
+ gint deltaXBC, deltaYBC;
+ gint deltaXAC, deltaYAC;
+
+ gfloat slopeAB;
+ gfloat slopeBC;
+ gfloat slopeAC;
+
+ gfloat k, l;
+ gfloat slope1, slope2, slope3, slope4;
+
+ if (y1 == y2 && x1 > x2) {
+ tmp = y1;y1 = y2;y2 = tmp;
+ tmp = x1;x1 = x2;x2 = tmp;
+ }
+ if (y1 == y3 && x1 > x3) {
+ tmp = y1;y1 = y3;y3 = tmp;
+ tmp = x1;x1 = x3;x3 = tmp;
+ }
+ if (y2 == y3 && x2 > x3) {
+ tmp = y2;y2 = y3;y3 = tmp;
+ tmp = x2;x2 = x3;x3 = tmp;
+ }
+
+ if (y1 <= y2) {
+ if (y2 <= y3) {
+ // y1 <= y2 <= y3
+ yA=y1;yB=y2;yC=y3;
+ xA=x1;xB=x2;xC=x3;
+ } else if (y1 <= y3) {
+ // y1 <= y3 < y2
+ yA=y1;yB=y3;yC=y2;
+ xA=x1;xB=x3;xC=x2;
+ } else {
+ // y3 < y1 < y2
+ yA=y3;yB=y1;yC=y2;
+ xA=x3;xB=x1;xC=x2;
+ }
+ } else {
+ if (y1 <= y3) {
+ // y2 < y1 <= y3
+ yA=y2;yB=y1;yC=y3;
+ xA=x2;xB=x1;xC=x3;
+ } else if (y2 <= y3) {
+ // y2 <= y3 < y1
+ yA=y2;yB=y3;yC=y1;
+ xA=x2;xB=x3;xC=x1;
+ } else {
+ // y3 < y2 < y1
+ yA=y3;yB=y2;yC=y1;
+ xA=x3;xB=x2;xC=x1;
+ }
+ }
+
+ deltaXAB = xB-xA, deltaYAB = yB-yA;
+ deltaXBC = xC-xB, deltaYBC = yC-yB;
+ deltaXAC = xC-xA, deltaYAC = yC-yA;
+
+ slopeBC = (deltaYBC == 0 ? 0 : (gfloat) deltaXBC/deltaYBC);
+ slopeAC = (deltaYAC == 0 ? 0 : (gfloat) deltaXAC/deltaYAC);
+
+ if (deltaYAB == 0) {
+ slopeAB = 0;
+ k = xA;
+ l = xB;
+
+ slope1 = slopeAB;
+ slope2 = slopeAC;
+ slope3 = slopeAC;
+ slope4 = slopeBC;
+ } else {
+ slopeAB = (gfloat) deltaXAB/deltaYAB;
+ k = xA;
+ l = xA;
+
+ if (slopeAB > slopeAC) {
+ slope1 = slopeAC;
+ slope2 = slopeAB;
+ slope3 = slopeAC;
+ slope4 = slopeBC;
+ } else {
+ slope1 = slopeAB;
+ slope2 = slopeAC;
+ slope3 = slopeBC;
+ slope4 = slopeAC;
+ }
+ }
+
+ for (y=yA; y<yB; ++y) {
+ npd_draw_texture_line((gint)round(k), (gint)round(l), y, A, input_image, output_image);
+ k += slope1;
+ l += slope2;
+ }
+
+ for (y=yB; y<=yC; ++y) {
+ npd_draw_texture_line((gint)round(k), (gint)round(l), y, A, input_image, output_image);
+ k += slope3;
+ l += slope4;
+ }
+}
+
+void
+npd_texture_quadrilateral (NPDBone *reference_bone,
+ NPDBone *current_bone,
+ NPDImage *input_image,
+ NPDImage *output_image)
+{
+ /* p1 are points of domain, p2 are points of codomain */
+ NPDPoint *p1 = current_bone->points;
+ NPDPoint *p2 = reference_bone->points;
+
+ NPDMatrix *A = NULL;
+ npd_new_matrix(&A);
+
+ npd_compute_affinity(&p1[0], &p1[1], &p1[2], &p2[0], &p2[1], &p2[2], A);
+ npd_texture_fill_triangle((int)p1[0].x, (int)p1[0].y, (int)p1[1].x, (int)p1[1].y, (int)p1[2].x,
(int)p1[2].y, A, input_image, output_image);
+
+ npd_compute_affinity(&p1[0], &p1[2], &p1[3], &p2[0], &p2[2], &p2[3], A);
+ npd_texture_fill_triangle((int)p1[0].x, (int)p1[0].y, (int)p1[2].x, (int)p1[2].y, (int)p1[3].x,
(int)p1[3].y, A, input_image, output_image);
+
+ npd_destroy_matrix(&A);
+}
+
+void
+npd_draw_texture_line (gint x1,
+ gint x2,
+ gint y,
+ NPDMatrix *A,
+ NPDImage *input_image,
+ NPDImage *output_image)
+{
+ gint x, fx, fy;
+ gfloat dx, dy;
+
+ for (x = x1; x <= x2; x++)
+ {
+ NPDPoint p, q;
+ NPDColor I0, I1, I2, I3, interpolated;
+
+ q.x = x; q.y = y;
+ npd_apply_transformation(A, &q, &p);
+
+ fx = (gint) floor(p.x);
+ fy = (gint) floor(p.y);
+ dx = p.x - floor(p.x);
+ dy = p.y - floor(p.y);
+
+ /* bilinear interpolation */
+ npd_get_pixel_color(input_image, fx, fy, &I0);
+ npd_get_pixel_color(input_image, fx+1, fy, &I1);
+ npd_get_pixel_color(input_image, fx, fy+1, &I2);
+ npd_get_pixel_color(input_image, fx+1, fy+1, &I3);
+ npd_bilinear_color_interpolation(&I0, &I1, &I2, &I3, dx, dy, &interpolated);
+
+ npd_set_pixel_color (output_image, x, y, &interpolated);
+ }
+}
diff --git a/libs/npd/graphics.h b/libs/npd/graphics.h
new file mode 100644
index 0000000..d27cd5f
--- /dev/null
+++ b/libs/npd/graphics.h
@@ -0,0 +1,93 @@
+/*
+ * This file is part of n-point image deformation library.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2013 Marek Dvoroznak <dvoromar gmail com>
+ */
+
+#ifndef __NPD_GRAPHICS_H__
+#define __NPD_GRAPHICS_H__
+
+#include "npd_common.h"
+
+struct _NPDColor {
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ unsigned char a;
+};
+
+void npd_create_model_from_image (NPDModel *model,
+ NPDImage *image,
+ gint square_size);
+void npd_create_mesh_from_image (NPDModel *model,
+ gint width,
+ gint height,
+ gint position_x,
+ gint position_y);
+void npd_draw_model (NPDModel *model,
+ NPDDisplay *display);
+
+gboolean npd_load_image (NPDImage *image,
+ const char *path);
+void npd_destroy_image (NPDImage *image);
+void npd_draw_image (NPDImage *image);
+void npd_texture_fill_triangle (gint x1,
+ gint y1,
+ gint x2,
+ gint y2,
+ gint x3,
+ gint y3,
+ NPDMatrix *A,
+ NPDImage *input_image,
+ NPDImage *output_image);
+void npd_texture_quadrilateral (NPDBone *reference_bone,
+ NPDBone *current_bone,
+ NPDImage *input_image,
+ NPDImage *output_image);
+void npd_draw_texture_line (gint x1,
+ gint x2,
+ gint y,
+ NPDMatrix *A,
+ NPDImage *input_image,
+ NPDImage *output_image);
+gint npd_bilinear_interpolation (gint I0,
+ gint I1,
+ gint I2,
+ gint I3,
+ gfloat dx,
+ gfloat dy);
+void npd_bilinear_color_interpolation (NPDColor *I0,
+ NPDColor *I1,
+ NPDColor *I2,
+ NPDColor *I3,
+ gfloat dx,
+ gfloat dy,
+ NPDColor *out);
+void npd_get_pixel_color (NPDImage *image,
+ gint x,
+ gint y,
+ NPDColor *color);
+void npd_set_pixel_color (NPDImage *image,
+ gint x,
+ gint y,
+ NPDColor *color);
+gboolean npd_compare_colors (NPDColor *c1,
+ NPDColor *c2);
+gboolean npd_is_color_transparent (NPDColor *color);
+gboolean npd_init_display (NPDDisplay *display);
+void npd_destroy_display (NPDDisplay *display);
+
+#endif /*__NPD_GRAPHICS_H__ */
\ No newline at end of file
diff --git a/libs/npd/npd.h b/libs/npd/npd.h
new file mode 100644
index 0000000..ae70e59
--- /dev/null
+++ b/libs/npd/npd.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of n-point image deformation library.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2013 Marek Dvoroznak <dvoromar gmail com>
+ */
+
+#ifndef __NPD_H__
+#define __NPD_H__
+
+#include "npd_common.h"
+#include "graphics.h"
+#include "deformation.h"
+#include "npd_math.h"
+
+#endif /* __NPD_H__ */
+
diff --git a/libs/npd/npd_common.c b/libs/npd/npd_common.c
index a79fb1a..1991491 100644
--- a/libs/npd/npd_common.c
+++ b/libs/npd/npd_common.c
@@ -236,6 +236,13 @@ npd_create_list_of_overlapping_points (NPDHiddenModel *hm)
hm->list_of_overlapping_points[i].num_of_points = op->len;
hm->list_of_overlapping_points[i].representative =
hm->list_of_overlapping_points[i].points[0];
+
+ for (j = 0; j < op->len; j++)
+ {
+ NPDPoint *p = hm->list_of_overlapping_points[i].points[j];
+ p->overlapping_points = &hm->list_of_overlapping_points[i];
+ p->counterpart->overlapping_points = &hm->list_of_overlapping_points[i];
+ }
g_ptr_array_free (op, FALSE); /* we want to preserve the underlying
array */
diff --git a/libs/npd/npd_common.h b/libs/npd/npd_common.h
index 27731d1..5ccadad 100644
--- a/libs/npd/npd_common.h
+++ b/libs/npd/npd_common.h
@@ -28,29 +28,38 @@ typedef struct _NPDColor NPDColor;
typedef struct _NPDDisplay NPDDisplay;
typedef struct _NPDMatrix NPDMatrix;
-typedef struct
+typedef struct _NPDPoint NPDPoint;
+typedef struct _NPDBone NPDBone;
+typedef struct _NPDOverlappingPoints NPDOverlappingPoints;
+
+struct _NPDPoint
{
gfloat x;
gfloat y;
gboolean fixed;
gfloat *weight; /* reference to weight in array
of weights */
-} NPDPoint;
+ gint index;
+ NPDBone *current_bone;
+ NPDBone *reference_bone;
+ NPDPoint *counterpart;
+ NPDOverlappingPoints *overlapping_points;
+};
-typedef struct
+struct _NPDBone
{
gint num_of_points;
NPDPoint *points; /* array of points */
gfloat *weights; /* array of weights */
-} NPDBone;
+};
-typedef struct
+struct _NPDOverlappingPoints
{
gint num_of_points;
NPDPoint *representative; /* reference to representative
of cluster */
NPDPoint **points; /* array of references to points */
-} NPDOverlappingPoints;
+};
typedef struct
{
diff --git a/libs/npd/npd_gegl.c b/libs/npd/npd_gegl.c
index e4f7234..f95d5d9 100644
--- a/libs/npd/npd_gegl.c
+++ b/libs/npd/npd_gegl.c
@@ -61,6 +61,6 @@ npd_apply_transformation (NPDMatrix *T,
NPDPoint *dest)
{
gdouble x = src->x, y = src->y;
- gegl_matrix3_transform_point (T, &x, &y);
+ gegl_matrix3_transform_point (&T->matrix, &x, &y);
dest->x = x; dest->y = y;
}
diff --git a/libs/npd/npd_gegl.h b/libs/npd/npd_gegl.h
index 3bb61f0..e56dbfb 100644
--- a/libs/npd/npd_gegl.h
+++ b/libs/npd/npd_gegl.h
@@ -21,7 +21,7 @@
#define __NPD_GEGL_H__
#include "npd_math.h"
-#include <gegl/gegl-matrix.h>
+#include <gegl-matrix.h>
struct _NPDMatrix
{
diff --git a/operations/external/Makefile.am b/operations/external/Makefile.am
index b929744..1de5fec 100644
--- a/operations/external/Makefile.am
+++ b/operations/external/Makefile.am
@@ -158,5 +158,11 @@ rgbe_save_la_SOURCES = rgbe-save.c
rgbe_save_la_CFLAGS = $(AM_CFLAGS) -I $(top_srcdir)/libs
rgbe_save_la_LIBADD = $(op_libs) $(top_builddir)/libs/rgbe/librgbe.la
+# Dependencies are in our source tree
+ops += npd.la
+npd_la_SOURCES = npd.c
+npd_la_CFLAGS = $(AM_CFLAGS) -I $(top_srcdir)/libs
+npd_la_LIBADD = $(op_libs) $(top_builddir)/libs/npd/libnpd.la
+
opdir = $(libdir)/gegl- GEGL_API_VERSION@
op_LTLIBRARIES = $(ops)
diff --git a/operations/external/npd.c b/operations/external/npd.c
index d343730..e41cf48 100644
--- a/operations/external/npd.c
+++ b/operations/external/npd.c
@@ -20,7 +20,6 @@
#include <glib/gi18n-lib.h>
#ifdef GEGL_CHANT_PROPERTIES
-
#else
#define GEGL_CHANT_TYPE_FILTER
@@ -29,11 +28,138 @@
#include "gegl-chant.h"
#include <stdio.h>
#include <math.h>
-#include "npd/npd_common.h"
+#include "npd/npd.h"
+#include "npd/npd_gegl.h"
+
+struct _NPDImage
+{
+ gint width;
+ gint height;
+ NPDPoint position;
+ guchar *buffer;
+};
+
+struct _NPDDisplay
+{
+ NPDImage image;
+};
+
+typedef struct
+{
+ gboolean first_run;
+ NPDModel model;
+} NPDProperties;
+
+void npd_create_image (NPDImage *image,
+ GeglBuffer *gegl_buffer,
+ const Babl *format);
+
+void
+npd_set_pixel_color (NPDImage *image,
+ gint x,
+ gint y,
+ NPDColor *color)
+{
+ gint position = 4 * (y * image->width + x);
+ gint max = 4 * image->width * image->height;
+
+ if (position > 0 && position < max)
+ {
+ image->buffer[position + 0] = color->r;
+ image->buffer[position + 1] = color->g;
+ image->buffer[position + 2] = color->b;
+ image->buffer[position + 3] = color->a;
+ }
+}
+
+void
+npd_get_pixel_color (NPDImage *image,
+ gint x,
+ gint y,
+ NPDColor *color)
+{
+ gint position = 4 * (y * image->width + x);
+ gint max = 4 * image->width * image->height;
+
+ if (position > 0 && position < max)
+ {
+ color->r = image->buffer[position + 0];
+ color->g = image->buffer[position + 1];
+ color->b = image->buffer[position + 2];
+ color->a = image->buffer[position + 3];
+ }
+ else
+ {
+ color->r = color->g = color->b = color->a = 0;
+ }
+}
+
+void
+npd_draw_model (NPDModel *model,
+ NPDDisplay *display)
+{
+ NPDHiddenModel *hidden_model = model->hidden_model;
+ NPDImage *image = model->reference_image;
+ gint i;
+
+ /* draw texture */
+ if (model->texture_visible)
+ {
+ for (i = 0; i < hidden_model->num_of_bones; i++)
+ {
+ npd_texture_quadrilateral(&hidden_model->reference_bones[i],
+ &hidden_model->current_bones[i],
+ image,
+ &display->image);
+ }
+ }
+}
+
+void
+npd_create_model_from_image (NPDModel *model,
+ NPDImage *image,
+ gint square_size)
+{
+ npd_init_model(model);
+ model->reference_image = image;
+ model->mesh_square_size = square_size;
+
+ npd_create_mesh_from_image(model, image->width, image->height, 0, 0);
+}
+
+void
+npd_create_image (NPDImage *image,
+ GeglBuffer *gegl_buffer,
+ const Babl *format)
+{
+ guchar *buffer;
+ buffer = g_new0 (guchar, gegl_buffer_get_pixel_count (gegl_buffer) * 4);
+ gegl_buffer_get (gegl_buffer, NULL, 1.0, format, buffer, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+
+ image->buffer = buffer;
+ image->width = gegl_buffer_get_width (gegl_buffer);
+ image->height = gegl_buffer_get_height (gegl_buffer);
+}
+
+void
+npd_destroy_image (NPDImage *image)
+{
+ g_free(image->buffer);
+}
static void
prepare (GeglOperation *operation)
{
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+ NPDProperties *props;
+
+ if (o->chant_data == NULL)
+ {
+ props = g_new (NPDProperties, 1);
+ props->first_run = TRUE;
+ o->chant_data = props;
+ }
+
gegl_operation_set_format (operation, "input",
babl_format ("RGBA float"));
gegl_operation_set_format (operation, "output",
@@ -48,7 +174,48 @@ process (GeglOperation *operation,
gint level)
{
GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
- const Babl *format = babl_format ("RGBA float");
+ const Babl *format = babl_format ("RGBA u8");
+ NPDProperties *props = o->chant_data;
+ NPDModel *model = &props->model;
+ NPDControlPoint *cp;
+ NPDPoint coord, new_coord;
+ guchar *output_buffer;
+
+ if (props->first_run)
+ {
+ gint width, height;
+ NPDImage input_image;
+ NPDDisplay display;
+
+ npd_create_image (&input_image, input, format);
+ width = input_image.width;
+ height = input_image.height;
+
+ output_buffer = g_new0 (guchar, gegl_buffer_get_pixel_count (input) * 4);
+ display.image.width = width;
+ display.image.height = height;
+ display.image.buffer = output_buffer;
+
+ npd_create_model_from_image(model, &input_image, 20);
+ npd_create_list_of_overlapping_points (model->hidden_model);
+
+ model->display = &display;
+ }
+ else
+ {
+ output_buffer = model->display->image.buffer;
+ }
+
+ coord.x = 20; coord.y = 200;
+ new_coord.x = 100; new_coord.y = 250;
+
+ cp = npd_add_control_point (model, &coord);
+ npd_set_point_coordinates (&cp->point, &new_coord);
+
+ npd_deform_model (model, 1000);
+ npd_draw_model (model, model->display);
+
+ gegl_buffer_set (output, NULL, 0, format, output_buffer, GEGL_AUTO_ROWSTRIDE);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]