Commit: 97c2b665ad13efdc31cd24c5639f76385316d1a8 Author: Phil Gosch Date: Mon Jul 18 17:28:13 2016 +0200 Branches: soc-2016-uv_tools https://developer.blender.org/rB97c2b665ad13efdc31cd24c5639f76385316d1a8
WIP: Simulated Annealing Basics of the simulated annealing approach to iteratively find the optimal packing solution =================================================================== 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_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index c03580d..e64c292 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -5304,7 +5304,8 @@ bool p_chart_pack_individual(PHandle *phandle, PChart *item) } MEM_freeN(nfps); printf("-freeing stuff done!\n"); - /* p_flush_uvs(phandle, item); */ /* ToDo SaphireS: Needs update to work ... */ + p_flush_uvs(phandle, item); /* ToDo SaphireS: Needs update to work ... */ + return found; } @@ -5386,6 +5387,12 @@ bool p_compute_packing_solution(PHandle *phandle /* ToDo SaphireS: Simulated Ann } } + /* Un-set placed property of charts so next iteration works as expected */ + for (i = 0; i < phandle->ncharts; i++) { + chart = phandle->charts[i]; + chart->u.ipack.convex_hull->placed = false; + } + return true; } @@ -5414,6 +5421,9 @@ void param_irregular_pack_begin(ParamHandle *handle) p_face_backup_uvs(f); } + /* Set initial scale of charts */ + /* ToDo SaphireS: Idea: set initial scale so that combined chart area is about 1.0 of UV area */ + /* Compute convex hull for each chart -> CW */ chart->u.ipack.convex_hull = p_convex_hull_new(chart); @@ -5439,24 +5449,22 @@ void param_irregular_pack_begin(ParamHandle *handle) } -void param_irregular_pack_iter(ParamHandle *handle, float *w_area) +void param_irregular_pack_iter(ParamHandle *handle, float *w_area, unsigned int seed) { PHandle *phandle = (PHandle *)handle; - param_assert(phandle->state == PHANDLE_STATE_PACK); - - /* ToDo (SaphireS): packing solution computation */ + BLI_rng_seed(phandle->rng, seed); - /* Compute inner fit polygon */ + param_assert(phandle->state == PHANDLE_STATE_PACK); - /* For every chart: */ + /* Set initial scale of charts so finding a better solution is possible */ - /* 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 */ + /* ToDo (SaphireS): packing solution computation */ - /* Place chart according to parameters from simulated annealing algorithm */ + if (p_compute_packing_solution(phandle)) { + printf("packing solution found---------------------------------------------\n"); + } float used_area = p_face_uv_area_combined(handle); diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.h b/source/blender/editors/uvedit/uvedit_parametrizer.h index 1460b22..3698c52 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.h +++ b/source/blender/editors/uvedit/uvedit_parametrizer.h @@ -105,7 +105,7 @@ 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_iter(ParamHandle *handle, float *w_area, int seed); void param_irregular_pack_end(ParamHandle *handle); /* Average area for all charts */ diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 9f9cf7a..deeaca1 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -46,6 +46,7 @@ #include "BLI_utildefines.h" #include "BLI_alloca.h" #include "BLI_math.h" +#include "BLI_rand.h" #include "BLI_uvproject.h" #include "BLI_string.h" @@ -828,6 +829,15 @@ void UV_OT_pack_islands(wmOperatorType *ot) /* ******************** Pack Islands operator 2.0 **************** */ +typedef struct SimulatedAnnealing { + RNG *rng; + int seed; + float theta; + float f; + float r; + float temperature; +} SimulatedAnnealing; + typedef struct PackIslands { Scene *scene; Object *obedit; @@ -837,6 +847,7 @@ typedef struct PackIslands { int i, iterations; wmTimer *timer; float wasted_area_last; + SimulatedAnnealing *sa; } PackIslands; static bool irregular_pack_islands_init(bContext *C, wmOperator *op) @@ -845,6 +856,8 @@ static bool irregular_pack_islands_init(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); PackIslands *pi; + SimulatedAnnealing *simann; + unsigned int seed = 31415926; /* Keep for now, needed when making packing work with current selection */ /*if (!uvedit_have_selection(scene, em, implicit)) { @@ -862,6 +875,15 @@ static bool irregular_pack_islands_init(bContext *C, wmOperator *op) pi->handle = construct_param_handle(scene, obedit, em->bm, hparams); pi->lasttime = PIL_check_seconds_timer(); + simann = MEM_callocN(sizeof(SimulatedAnnealing), "SimulatedAnnealing"); + simann->rng = BLI_rng_new(seed); + simann->seed = seed; + simann->theta = 0.0f; + simann->f = 0.0f; + simann->r = 0.0f; + simann->temperature = 1.0f; + pi->sa = simann; + param_irregular_pack_begin(pi->handle); op->customdata = pi; @@ -873,17 +895,38 @@ static void irregular_pack_islands_iteration(bContext *C, wmOperator *op, bool i { PackIslands *pi = op->customdata; ScrArea *sa = CTX_wm_area(C); - float wasted_area = 0.0f; - - param_irregular_pack_iter(pi->handle, &wasted_area); + float wasted_area = 0.0f, dE, r1, r2; + float a = 0.95f; /*ToDo SaphireS: Make operator parameter for testing */ + float k = 5.670367e-8f; /* Stefan-Boltzman constant-like parameter */ + + pi->i++; + /* Cooling Schedule */ + pi->sa->temperature = pi->wasted_area_last * a; - /* ToDo (SaphireS): simulated annealing, based on wasted areas ("temperature") of last and current solution */ + /* Find neigbohring solution */ + /*ToDo Saphires: Pass SA parameters */ + param_irregular_pack_iter(pi->handle, &wasted_area, pi->i); + /* delta Energy */ + dE = wasted_area - pi->wasted_area_last; + if (dE < 0) { + /* Current solution is new best solution */ + /* ToDo SaphireS: Store last best solution */ + pi->wasted_area_last = wasted_area; + } + else { + r1 = BLI_rng_get_float(pi->sa->rng); - pi->wasted_area_last = wasted_area; + r2 = (float)exp(-dE/(k * pi->sa->temperature)); - pi->i++; + if (r1 < r2) { + /* Current solution is new best solution */ + /* ToDo SaphireS: Store last best solution */ + pi->wasted_area_last = wasted_area; + } + } + RNA_int_set(op->ptr, "iterations", pi->i); if (interactive && (PIL_check_seconds_timer() - pi->lasttime > 0.5)) { @@ -922,6 +965,9 @@ static void irregular_pack_islands_exit(bContext *C, wmOperator *op, bool cancel param_irregular_pack_end(pi->handle); param_delete(pi->handle); + BLI_rng_free(pi->sa->rng); + MEM_freeN(pi->sa); + DAG_id_tag_update(pi->obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, pi->obedit->data); _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs