Commit 520af4d2 authored by Marek Dvoroznak's avatar Marek Dvoroznak Committed by Mikael Magnusson

libs: npd: add MLS-like deformation

parent bc4ddf9f
......@@ -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;
......@@ -130,6 +130,7 @@ void
npd_compute_ARSAP_transformations (NPDHiddenModel *hidden_model)
{
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);
}
}
......
......@@ -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);
......
......@@ -32,7 +32,8 @@ npd_init_model (NPDModel *model)
/* init hidden model */
hidden_model = g_new (NPDHiddenModel, 1);
model->hidden_model = hidden_model;
hidden_model->ARAP = TRUE;
hidden_model->ASAP = FALSE;
hidden_model->MLS_weights = FALSE;
hidden_model->num_of_bones = 0;
hidden_model->num_of_overlapping_points = 0;
......@@ -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);
......@@ -156,6 +160,10 @@ npd_remove_control_point (NPDModel *model,
{
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)
......
......@@ -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
......@@ -104,23 +103,19 @@ 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,
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,
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,
void add_point_to_suitable_cluster (GHashTable *coords_to_cluster,
NPDPoint *point,
GPtrArray *list_of_overlapping_points);
void npd_set_overlapping_points_weight
......@@ -128,12 +123,17 @@ void npd_set_overlapping_points_weight
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);
void npd_print_overlapping_points (NPDOverlappingPoints *op);
#endif /* __NPD_COMMON_H__ */
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment