[Bf-blender-cvs] [aac3466] soc-2016-uv_tools: Some groundwork for packing improvements
Phil Gosch
noreply at git.blender.org
Wed Jun 22 18:29:53 CEST 2016
Commit: aac346662d120fc90630e0eacd9c80d92c75fdbc
Author: Phil Gosch
Date: Wed Jun 22 18:29:03 2016 +0200
Branches: soc-2016-uv_tools
https://developer.blender.org/rBaac346662d120fc90630e0eacd9c80d92c75fdbc
Some groundwork for packing improvements
Implemented a modal operator for packing, actual implementation of the algorithm left as "ToDo"
===================================================================
M source/blender/editors/uvedit/uvedit_intern.h
M source/blender/editors/uvedit/uvedit_ops.c
M source/blender/editors/uvedit/uvedit_parametrizer.c
M source/blender/editors/uvedit/uvedit_parametrizer.h
M source/blender/editors/uvedit/uvedit_unwrap_ops.c
===================================================================
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 5d50ed2..5d02c68 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -85,6 +85,7 @@ void UV_OT_cylinder_project(struct wmOperatorType *ot);
void UV_OT_project_from_view(struct wmOperatorType *ot);
void UV_OT_minimize_stretch(struct wmOperatorType *ot);
void UV_OT_pack_islands(struct wmOperatorType *ot);
+void UV_OT_irregular_pack_islands(struct wmOperatorType *ot);
void UV_OT_reset(struct wmOperatorType *ot);
void UV_OT_sphere_project(struct wmOperatorType *ot);
void UV_OT_unwrap(struct wmOperatorType *ot);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index d3d94d6..20bcfc5 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -4666,6 +4666,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_project_from_view);
WM_operatortype_append(UV_OT_minimize_stretch);
WM_operatortype_append(UV_OT_pack_islands);
+ WM_operatortype_append(UV_OT_irregular_pack_islands);
WM_operatortype_append(UV_OT_reset);
WM_operatortype_append(UV_OT_sphere_project);
WM_operatortype_append(UV_OT_unwrap);
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 02ca0b3..0ce0dab 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -217,7 +217,8 @@ enum PHandleState {
PHANDLE_STATE_ALLOCATED,
PHANDLE_STATE_CONSTRUCTED,
PHANDLE_STATE_LSCM,
- PHANDLE_STATE_STRETCH
+ PHANDLE_STATE_STRETCH,
+ PHANDLE_STATE_PACK
};
typedef struct PHandle {
@@ -4642,6 +4643,72 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate)
param_scale(handle, phandle->aspx, phandle->aspy);
}
+void param_irregular_pack_begin(ParamHandle *handle)
+{
+ PHandle *phandle = (PHandle *)handle;
+ PChart *chart;
+ PFace *f;
+ int i;
+
+ param_assert(phandle->state == PHANDLE_STATE_CONSTRUCTED);
+ phandle->state = PHANDLE_STATE_PACK;
+
+ unsigned int seed = 31415926;
+ phandle->rng = BLI_rng_new(seed);
+
+ /* Back up UVs */
+ for (i = 0; i < phandle->ncharts; i++) {
+ chart = phandle->charts[i];
+
+ for (f = chart->faces; f; f = f->nextlink) {
+ p_face_backup_uvs(f);
+ }
+ }
+
+ /* ToDo (SaphireS) */
+
+ /* Initializations */
+}
+
+void param_irregular_pack_iter(ParamHandle *handle, float *w_area)
+{
+ PHandle *phandle = (PHandle *)handle;
+
+ param_assert(phandle->state == PHANDLE_STATE_PACK);
+
+ /* ToDo (SaphireS): packing solution computation */
+
+ /* Compute inner fit polygon (this probably only needs to be done once) */
+
+ /* For every chart: */
+
+ /* Compute no-fit polygon for current chart against all placed charts so far */
+ /* This includes a decomposition of non-convex shapes into convex ones */
+
+ /* Compute collision-free area for current chart */
+
+ /* Place chart according to parameters from simulated annealing algorithm */
+
+ float used_area = p_face_uv_area_combined(handle);
+
+ /* ToDo(SaphireS): Account for aspect ratio != 1 */
+ *w_area = 1.0f - used_area;
+
+}
+
+void param_irregular_pack_end(ParamHandle *handle)
+{
+ PHandle *phandle = (PHandle *)handle;
+
+ param_assert(phandle->state == PHANDLE_STATE_PACK);
+ phandle->state = PHANDLE_STATE_CONSTRUCTED;
+
+ /* ToDo? (SaphireS) */
+
+ BLI_rng_free(phandle->rng);
+ phandle->rng = NULL;
+}
+
void param_average(ParamHandle *handle)
{
PChart *chart;
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.h b/source/blender/editors/uvedit/uvedit_parametrizer.h
index 1ae5902..5e48ff4 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.h
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.h
@@ -102,6 +102,12 @@ void param_smooth_area(ParamHandle *handle);
void param_pack(ParamHandle *handle, float margin, bool do_rotate);
+/* Packing 2.0 */
+
+void param_irregular_pack_begin(ParamHandle *handle);
+void param_irregular_pack_iter(ParamHandle *handle, float *w_area);
+void param_irregular_pack_end(ParamHandle *handle);
+
/* Average area for all charts */
void param_average(ParamHandle *handle);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 051b1f5..7b03258 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -815,6 +815,197 @@ void UV_OT_pack_islands(wmOperatorType *ot)
RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
+/* ******************** Pack Islands operator 2.0 **************** */
+
+typedef struct PackIslands {
+ Scene *scene;
+ Object *obedit;
+ BMEditMesh *em;
+ ParamHandle *handle;
+ double lasttime;
+ int i, iterations;
+ wmTimer *timer;
+ float wasted_area_last;
+} PackIslands;
+
+static bool irregular_pack_islands_init(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ PackIslands *pi;
+
+ /* Keep for now, needed when making packing work with current selection */
+ /*if (!uvedit_have_selection(scene, em, implicit)) {
+ return false;
+ }*/
+
+ int hparams = set_handle_params(true, false, false, false, true);
+
+ pi = MEM_callocN(sizeof(PackIslands), "PackIslands");
+ pi->scene = scene;
+ pi->obedit = obedit;
+ pi->em = em;
+ pi->iterations = RNA_int_get(op->ptr, "iterations");
+ pi->i = 0;
+ pi->handle = construct_param_handle(scene, obedit, em->bm, hparams);
+ pi->lasttime = PIL_check_seconds_timer();
+
+ param_irregular_pack_begin(pi->handle);
+
+ op->customdata = pi;
+
+ return true;
+}
+
+static void irregular_pack_islands_iteration(bContext *C, wmOperator *op, bool interactive)
+{
+ PackIslands *pi = op->customdata;
+ ScrArea *sa = CTX_wm_area(C);
+ float wasted_area = 0.0f;
+
+ param_irregular_pack_iter(pi->handle, &wasted_area);
+
+ /* ToDo (SaphireS): simulated annealing, based on wasted areas ("temperature") of last and current solution */
+
+
+
+ pi->wasted_area_last = wasted_area;
+
+ pi->i++;
+ RNA_int_set(op->ptr, "iterations", pi->i);
+
+ if (interactive && (PIL_check_seconds_timer() - pi->lasttime > 0.5)) {
+ char str[UI_MAX_DRAW_STR];
+
+ param_flush(pi->handle);
+
+ if (sa) {
+ BLI_snprintf(str, sizeof(str),
+ IFACE_("Pack Islands (irregular). Iteration: %i, Wasted UV Area: %f"), pi->i, pi->wasted_area_last);
+ ED_area_headerprint(sa, str);
+ }
+
+ pi->lasttime = PIL_check_seconds_timer();
+
+ DAG_id_tag_update(pi->obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, pi->obedit->data);
+ }
+}
+
+static void irregular_pack_islands_exit(bContext *C, wmOperator *op, bool cancel)
+{
+ PackIslands *pi = op->customdata;
+ ScrArea *sa = CTX_wm_area(C);
+
+ if (sa)
+ ED_area_headerprint(sa, NULL);
+ if (pi->timer)
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), pi->timer);
+
+ if (cancel)
+ param_flush_restore(pi->handle); /* Restore UVs */
+ else
+ param_flush(pi->handle); /* Keep new UVs */
+
+ param_irregular_pack_end(pi->handle);
+ param_delete(pi->handle);
+
+ DAG_id_tag_update(pi->obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, pi->obedit->data);
+
+ MEM_freeN(pi);
+ op->customdata = NULL;
+}
+
+static int irregular_pack_islands_exec(bContext *C, wmOperator *op)
+{
+ int i, iterations;
+
+ if (!irregular_pack_islands_init(C, op))
+ return OPERATOR_CANCELLED;
+
+ iterations = RNA_int_get(op->ptr, "iterations");
+ for (i = 0; i < iterations; i++)
+ irregular_pack_islands_iteration(C, op, false);
+ irregular_pack_islands_exit(C, op, false);
+
+ return OPERATOR_FINISHED;
+}
+
+static int irregular_pack_islands_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ PackIslands *pi;
+
+ if (!irregular_pack_islands_init(C, op))
+ return OPERATOR_CANCELLED;
+
+ irregular_pack_islands_iteration(C, op, true);
+
+ pi = op->customdata;
+ WM_event_add_modal_handler(C, op);
+ pi->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int irregular_pack_islands_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ PackIslands *pi = op->customdata;
+
+ switch (event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ irregular_pack_islands_exit(C, op, true);
+ return OPERATOR_CANCELLED;
+ case RETKEY:
+ case PADENTER:
+ case LEFTMOUSE:
+ irregular_pack_islands_exit(C, op, false);
+ return OPERATOR_FINISHED;
+ case TIMER:
+ if (pi->timer == event->customdata) {
+ double start = PIL_check_seconds_timer();
+
+ do {
+ irregular_pack_islands_iteration(C, op, true);
+ } while (PIL_check_seconds_timer() - start < 0.01);
+ }
+ break;
+ }
+
+ if (pi->iterations && pi->i >= pi->iterations) {
+ irregular_pack_islands_exit(C, op, false);
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static void irregular_pack_islands_cancel(bContext *C, wmOperator *op)
+{
+ irregular_pack_islands_exit(C, op, true);
+}
+
+void UV_OT_irregular_pack_islands(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Pack Islands (irregular)";
+ ot->idname = "UV_OT_irregular_pack_islands";
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_CURSOR | OPTYPE_BLOCKING;
+ ot->description = "New and improved packing taking into account irregular uv shapes";
+
+ /* api callbacks */
+ ot->exec = irregular_pack_islands_exec;
+ ot->invoke = irregular_pack_islands_invoke;
+ ot->modal = irregular_pack_islands_modal;
+ ot->cancel = irregular_pack_islands_cancel;
+ ot->poll = ED_operator_uvedit;
+
+ /* properties */
+ RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", "Number of iterations to run, 0 is unlimited when run interactively", 0, 100);
+}
+
/* ******************** XXX (SaphireS): DEBUG-TEST operator **************** */
/* XXX (SaphireS): Remove */
More information about the Bf-blender-cvs
mailing list