[gegl] libs: npd: add MLS-like deformation
- From: Mikael Magnusson <mikachu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] libs: npd: add MLS-like deformation
- Date: Fri, 27 Feb 2015 17:39:30 +0000 (UTC)
commit 520af4d2dc6b1ec09e506837c4c9f41b2143e99e
Author: Marek Dvoroznak <dvoromar gmail com>
Date: Thu Aug 8 17:37:22 2013 +0200
libs: npd: add MLS-like deformation
libs/npd/deformation.c | 11 +++--
libs/npd/deformation.h | 2 +-
libs/npd/npd_common.c | 107 +++++++++++++++++++++++++++++++++++++++++++-----
libs/npd/npd_common.h | 94 +++++++++++++++++++++---------------------
4 files changed, 150 insertions(+), 64 deletions(-)
---
diff --git a/libs/npd/deformation.c b/libs/npd/deformation.c
index 415e53b..068e7d8 100644
--- a/libs/npd/deformation.c
+++ b/libs/npd/deformation.c
@@ -59,7 +59,7 @@ npd_compute_ARSAP_transformation (gint num_of_points,
NPDPoint reference_points[],
NPDPoint current_points[],
gfloat weights[],
- gboolean ARAP)
+ gboolean ASAP)
{
NPDPoint pc = {0, 0}, qc = {0, 0};
gfloat a = 0, b = 0, mu_part = 0, mu, r1, r2, x0, y0;
@@ -103,8 +103,8 @@ npd_compute_ARSAP_transformation (gint num_of_points,
}
mu = 1;
- if (ARAP) mu = sqrt(a * a + b * b);
- else mu = mu_part;
+ if (ASAP) mu = mu_part;
+ else mu = sqrt(a * a + b * b);
r1 = a / mu;
r2 = -b / mu;
@@ -129,7 +129,8 @@ npd_compute_ARSAP_transformation (gint num_of_points,
void
npd_compute_ARSAP_transformations (NPDHiddenModel *hidden_model)
{
- gint i;
+ gint i;
+
for (i = 0; i < hidden_model->num_of_bones; ++i)
{
NPDBone *reference_bones = &hidden_model->reference_bones[i];
@@ -138,7 +139,7 @@ npd_compute_ARSAP_transformations (NPDHiddenModel *hidden_model)
reference_bones->points,
current_bones->points,
current_bones->weights,
- hidden_model->ARAP);
+ hidden_model->ASAP);
}
}
diff --git a/libs/npd/deformation.h b/libs/npd/deformation.h
index 326d14f..6c5c746 100644
--- a/libs/npd/deformation.h
+++ b/libs/npd/deformation.h
@@ -36,7 +36,7 @@ void npd_compute_ARSAP_transformation (gint num_of_points,
NPDPoint reference_shape[],
NPDPoint current_shape[],
gfloat weights[],
- gboolean ARAP);
+ gboolean ASAP);
void npd_compute_ARSAP_transformations (NPDHiddenModel *model);
void npd_deform_model (NPDModel *model,
gint rigidity);
diff --git a/libs/npd/npd_common.c b/libs/npd/npd_common.c
index ee52825..e9f856e 100644
--- a/libs/npd/npd_common.c
+++ b/libs/npd/npd_common.c
@@ -30,21 +30,22 @@ npd_init_model (NPDModel *model)
GArray *control_points;
/* init hidden model */
- hidden_model = g_new (NPDHiddenModel, 1);
+ hidden_model = g_new (NPDHiddenModel, 1);
model->hidden_model = hidden_model;
- hidden_model->ARAP = TRUE;
- hidden_model->num_of_bones = 0;
+ hidden_model->ASAP = FALSE;
+ hidden_model->MLS_weights = FALSE;
+ hidden_model->num_of_bones = 0;
hidden_model->num_of_overlapping_points = 0;
/* init control points */
- control_points = g_array_new (FALSE, FALSE, sizeof (NPDControlPoint));
+ control_points = g_array_new (FALSE, FALSE, sizeof (NPDControlPoint));
model->control_points = control_points;
- model->control_point_radius = 6;
- model->control_points_visible = TRUE;
+ model->control_point_radius = 6;
+ model->control_points_visible = TRUE;
/* init other */
- model->mesh_visible = TRUE;
- model->texture_visible = TRUE;
+ model->mesh_visible = TRUE;
+ model->texture_visible = TRUE;
}
void
@@ -133,6 +134,9 @@ npd_add_control_point (NPDModel *model,
npd_set_point_coordinates (&cp.point, closest_point);
g_array_append_val (model->control_points, cp);
+ if (model->hidden_model->MLS_weights)
+ npd_compute_MLS_weights (model);
+
return &g_array_index (model->control_points,
NPDControlPoint,
model->control_points->len - 1);
@@ -147,15 +151,19 @@ npd_remove_control_point (NPDModel *model,
{
gint i;
NPDControlPoint *cp;
-
+
for (i = 0; i < model->control_points->len; i++)
{
cp = &g_array_index (model->control_points, NPDControlPoint, i);
-
+
if (cp == control_point)
{
npd_set_control_point_weight (cp, 1.0);
g_array_remove_index (model->control_points, i);
+
+ if (model->hidden_model->MLS_weights)
+ npd_compute_MLS_weights (model);
+
return;
}
}
@@ -334,6 +342,82 @@ npd_set_point_coordinates (NPDPoint *target,
target->y = source->y;
}
+/**
+ * Sets type of deformation. The function doesn't perform anything if supplied
+ * deformation type doesn't differ from currently set one.
+ *
+ * @param model
+ * @param ASAP TRUE = ASAP deformation, FALSE = ARAP deformation
+ * @param MLS_weights use weights from Moving Least Squares deformation method
+ */
+void
+npd_set_deformation_type (NPDModel *model,
+ gboolean ASAP,
+ gboolean MLS_weights)
+{
+ NPDHiddenModel *hm = model->hidden_model;
+
+ if (hm->ASAP == ASAP && hm->MLS_weights == MLS_weights) return;
+
+ if (MLS_weights)
+ npd_compute_MLS_weights (model);
+ else if (hm->MLS_weights)
+ npd_reset_weights (hm);
+
+ hm->ASAP = ASAP;
+ hm->MLS_weights = MLS_weights;
+}
+
+void
+npd_compute_MLS_weights (NPDModel *model)
+{
+ NPDHiddenModel *hm = model->hidden_model;
+ NPDControlPoint *cp;
+ NPDOverlappingPoints *op;
+ NPDPoint *cp_reference, *op_reference;
+ gfloat min, SED, MLS_weight;
+ gint i, j;
+
+ if (model->control_points->len == 0) return;
+
+ for (i = 0; i < hm->num_of_overlapping_points; i++)
+ {
+ op = &hm->list_of_overlapping_points[i];
+ op_reference = op->representative->counterpart;
+ min = INFINITY;
+
+ for (j = 0; j < model->control_points->len; j++)
+ {
+ cp = &g_array_index (model->control_points,
+ NPDControlPoint,
+ j);
+ cp_reference = cp->overlapping_points->representative->counterpart;
+
+ /* TODO - use geodetic distance */
+ SED = npd_SED (cp_reference,
+ op_reference);
+ if (SED < min) min = SED;
+ }
+
+ if (npd_equal_floats (min, 0.0)) min = 0.0000001;
+ MLS_weight = 1 / min;
+ npd_set_overlapping_points_weight (op, MLS_weight);
+ }
+}
+
+void
+npd_reset_weights (NPDHiddenModel *hm)
+{
+ NPDOverlappingPoints *op;
+ gint i;
+
+ for (i = 0; i < hm->num_of_overlapping_points; i++)
+ {
+ op = &hm->list_of_overlapping_points[i];
+ npd_set_overlapping_points_weight (op, 1.0);
+ }
+}
+
void
npd_print_hidden_model (NPDHiddenModel *hm,
gboolean print_bones,
@@ -342,7 +426,8 @@ npd_print_hidden_model (NPDHiddenModel *hm,
gint i;
g_printf ("NPDHiddenModel:\n");
g_printf ("number of bones: %d\n", hm->num_of_bones);
- g_printf ("ARAP: %d\n", hm->ARAP);
+ g_printf ("ASAP: %d\n", hm->ASAP);
+ g_printf ("MLS weights: %d\n", hm->MLS_weights);
g_printf ("number of overlapping points: %d\n", hm->num_of_overlapping_points);
if (print_bones)
diff --git a/libs/npd/npd_common.h b/libs/npd/npd_common.h
index 4414cc5..06f4bc8 100644
--- a/libs/npd/npd_common.h
+++ b/libs/npd/npd_common.h
@@ -37,8 +37,7 @@ struct _NPDPoint
gfloat x;
gfloat y;
gboolean fixed;
- gfloat *weight; /* reference to weight in array
- of weights */
+ gfloat *weight; /* pointer to weight in array of weights */
gint index;
NPDBone *current_bone;
NPDBone *reference_bone;
@@ -56,27 +55,27 @@ struct _NPDBone
struct _NPDOverlappingPoints
{
gint num_of_points;
- NPDPoint *representative; /* reference to representative
- of cluster */
- NPDPoint **points; /* array of references to points */
+ NPDPoint *representative; /* pointer to representative of cluster */
+ NPDPoint **points; /* array of pointers to points */
};
typedef struct
{
gint num_of_bones;
gint num_of_overlapping_points;
- gboolean ARAP;
+ gboolean ASAP; /* don't change directly!
+ * use npd_set_deformation_type function */
+ gboolean MLS_weights; /* don't change directly!
+ * use npd_set_deformation_type function */
NPDBone *current_bones; /* array of current bones */
NPDBone *reference_bones; /* array of reference bones */
- NPDOverlappingPoints *list_of_overlapping_points; /* array of overlapping
- points */
+ NPDOverlappingPoints *list_of_overlapping_points; /* array of overlapping points */
} NPDHiddenModel;
typedef struct
{
NPDPoint point;
- NPDOverlappingPoints *overlapping_points; /* reference to overlapping
- points */
+ NPDOverlappingPoints *overlapping_points; /* pointer to overlapping points */
} NPDControlPoint;
typedef struct
@@ -96,44 +95,45 @@ typedef struct
npd_set_pixel_color = set_pixel;\
npd_get_pixel_color = get_pixel
-void npd_init_model (NPDModel *model);
-void npd_destroy_hidden_model (NPDHiddenModel *model);
-void npd_destroy_model (NPDModel *model);
+void npd_init_model (NPDModel *model);
+void npd_destroy_hidden_model (NPDHiddenModel *model);
+void npd_destroy_model (NPDModel *model);
-NPDControlPoint *npd_add_control_point (NPDModel *model,
- NPDPoint *coord);
-void npd_remove_control_point (NPDModel *model,
- NPDControlPoint *control_point);
-void npd_remove_all_control_points
- (NPDModel *model);
-void npd_set_control_point_weight
- (NPDControlPoint *cp,
- gfloat weight);
-gboolean npd_equal_coordinates (NPDPoint *p1,
- NPDPoint *p2);
-gboolean npd_equal_coordinates_epsilon
- (NPDPoint *p1,
- NPDPoint *p2,
- gfloat epsilon);
-NPDControlPoint *npd_get_control_point_at (NPDModel *model,
- NPDPoint *coord);
+NPDControlPoint *npd_add_control_point (NPDModel *model,
+ NPDPoint *coord);
+void npd_remove_control_point (NPDModel *model,
+ NPDControlPoint *control_point);
+void npd_remove_all_control_points (NPDModel *model);
+void npd_set_control_point_weight (NPDControlPoint *cp,
+ gfloat weight);
+gboolean npd_equal_coordinates (NPDPoint *p1,
+ NPDPoint *p2);
+gboolean npd_equal_coordinates_epsilon (NPDPoint *p1,
+ NPDPoint *p2,
+ gfloat epsilon);
+NPDControlPoint *npd_get_control_point_at (NPDModel *model,
+ NPDPoint *coord);
void npd_create_list_of_overlapping_points
- (NPDHiddenModel *model);
-void add_point_to_suitable_cluster
- (GHashTable *coords_to_cluster,
- NPDPoint *point,
- GPtrArray *list_of_overlapping_points);
+ (NPDHiddenModel *model);
+void add_point_to_suitable_cluster (GHashTable *coords_to_cluster,
+ NPDPoint *point,
+ GPtrArray *list_of_overlapping_points);
void npd_set_overlapping_points_weight
- (NPDOverlappingPoints *op,
- gfloat weight);
-void npd_set_point_coordinates (NPDPoint *target,
- NPDPoint *source);
-void npd_print_hidden_model (NPDHiddenModel *hm,
- gboolean print_bones,
- gboolean print_overlapping_points);
-void npd_print_bone (NPDBone *bone);
-void npd_print_point (NPDPoint *point,
- gboolean print_details);
-void npd_print_overlapping_points
- (NPDOverlappingPoints *op);
+ (NPDOverlappingPoints *op,
+ gfloat weight);
+void npd_set_point_coordinates (NPDPoint *target,
+ NPDPoint *source);
+void npd_set_deformation_type (NPDModel *model,
+ gboolean ASAP,
+ gboolean MLS_weights);
+void npd_compute_MLS_weights (NPDModel *model);
+void npd_reset_weights (NPDHiddenModel *hidden_model);
+
+void npd_print_hidden_model (NPDHiddenModel *hm,
+ gboolean print_bones,
+ gboolean print_overlapping_points);
+void npd_print_bone (NPDBone *bone);
+void npd_print_point (NPDPoint *point,
+ gboolean print_details);
+void npd_print_overlapping_points (NPDOverlappingPoints *op);
#endif /* __NPD_COMMON_H__ */
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]