[Bf-blender-cvs] [ecc37c7] soc-2016-uv_tools: WIP: Select shortest path - Computing the shortest path using regular Dijkstra algorithm
Phil Gosch
noreply at git.blender.org
Thu Jun 2 11:45:36 CEST 2016
Commit: ecc37c77f8274ea37523f20a41f5958c5c5bd94a
Author: Phil Gosch
Date: Thu Jun 2 11:44:55 2016 +0200
Branches: soc-2016-uv_tools
https://developer.blender.org/rBecc37c77f8274ea37523f20a41f5958c5c5bd94a
WIP: Select shortest path - Computing the shortest path using regular Dijkstra algorithm
===================================================================
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 81cbe56..eb8f595 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -34,6 +34,7 @@
#include "BLI_heap.h"
#include "BLI_boxpack2d.h"
#include "BLI_convexhull2d.h"
+#include "BLI_linklist.h"
#include "uvedit_parametrizer.h"
@@ -4705,9 +4706,134 @@ void param_scale_bounds(ParamHandle *handle)
}
}
-void param_shortest_path(ParamHandle *handle)
+void p_verttag_add_adjacent(Heap *heap, PChart *chart, PVert *v_a, PVert **v_prev, float *cost)
{
- /* TODO (SaphireS): Shortest Path computation here */
+ const int v_a_index = v_a->u.id;
+ PEdge *e;
+ e = v_a->edge->next;
+
+ do {
+ PVert *v_b = e->vert;
+
+ if (!(v_b->flag & PVERT_MARKED)) {
+ /* v_b not visited yet, check it out! */
+ const int v_b_index = v_b->u.id;
+ const float cost_cut = len_v2v2(v_a->uv, v_b->uv); /* params->use_topology_distance ? 1.0f : len_v2v2(v_a->uv, v_b->uv); */
+ const float cost_new = cost[v_a_index] + cost_cut;
+
+ if (cost[v_b_index] > cost_new) {
+ cost[v_b_index] = cost_new;
+ v_prev[v_b_index] = v_a;
+ BLI_heap_insert(heap, cost_new, v_b);
+ }
+ }
+
+ e = p_wheel_edge_next(e);
+ } while (e && (e != v_a->edge));
+}
+
+LinkNode* p_calc_path_vert(PChart *chart, PVert *src, PVert *dst)
+{
+ LinkNode *path = NULL;
+ Heap *heap;
+ PVert *vert;
+ PVert **verts_prev;
+ float *cost;
+ int totvert, index;
+
+ /* Clear flags */
+ for (vert = chart->verts, index = 0; vert; vert = vert->nextlink, index++) {
+ vert->flag &= ~PVERT_MARKED;
+ vert->u.id = index; /* Abuse lscm id field */
+ }
+
+ //src->flag &= ~PVERT_MARKED;
+ //printf(" src unmarked, index: %i \n", src->u.id);
+ //dst->flag &= ~PVERT_MARKED;
+ //printf(" src unmarked, index: %i \n", dst->u.id);
+
+ /* alloc */
+ totvert = chart->nverts;
+ verts_prev = MEM_callocN(sizeof(*verts_prev) * totvert, __func__);
+ cost = MEM_mallocN(sizeof(*cost) * totvert, __func__);
+
+ copy_vn_fl(cost, totvert, 1e20f);
+
+ /* regular dijkstra shortest path */
+ heap = BLI_heap_new();
+ BLI_heap_insert(heap, 0.0f, src);
+ cost[src->u.id] = 0.0f;
+
+ while (!BLI_heap_is_empty(heap)) {
+ vert = BLI_heap_popmin(heap);
+
+ if (vert == dst) {
+ break;
+ }
+
+ if (!(vert->flag & PVERT_MARKED)) {
+ vert->flag |= PVERT_MARKED;
+ p_verttag_add_adjacent(heap, chart, vert, verts_prev, cost);
+ }
+ }
+
+ if (vert == dst) {
+ do {
+ BLI_linklist_prepend(&path, vert);
+ } while (vert = verts_prev[vert->u.id]);
+ }
+
+ MEM_freeN(verts_prev);
+ MEM_freeN(cost);
+ BLI_heap_free(heap, NULL);
+
+ return path;
+}
+
+void param_shortest_path(ParamHandle *handle, bool *p_found)
+{
+ PHandle *phandle = (PHandle *)handle;
+ PChart *chart, *current_chart;
+ PVert *v, *vert_src = NULL, *vert_dst = NULL;
+ int i, j;
+ bool success = false;
+
+ if (phandle->ncharts == 0)
+ return;
+
+ /* Get src and dst */
+ for (i = 0; i < phandle->ncharts; i++) {
+ chart = phandle->charts[i];
+
+ for (v = chart->verts; v; v = v->nextlink) {
+
+ if (v->flag & PVERT_SELECT) {
+
+ if (vert_src == NULL) {
+ vert_src = v;
+ current_chart = chart;
+ }
+ else if (vert_dst == NULL) {
+ if (current_chart == chart) {
+ vert_dst = v;
+ }
+ }
+ }
+ }
+ }
+
+ /* Connect src and dst */
+
+ LinkNode* path = NULL;
+ if (vert_src && vert_dst){
+ path = p_calc_path_vert(current_chart, vert_src, vert_dst);
+ if (path) {
+ /* TODO (SaphireS): Set *_SELECT tag for verts/edges */
+ success = true;
+ }
+ }
+
+ *p_found = success;
}
void param_flush(ParamHandle *handle)
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.h b/source/blender/editors/uvedit/uvedit_parametrizer.h
index 7f0a77e..2ce7fe1 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.h
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.h
@@ -115,7 +115,7 @@ void param_scale_bounds(ParamHandle *handle);
/* Select shortest Path */
-void param_shortest_path(ParamHandle *handle);
+void param_shortest_path(ParamHandle *handle, bool *p_found);
/* Flushing */
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index aff3136..3aefb61 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -716,11 +716,12 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
bool ED_uvedit_shortest_path_select(Scene *scene, Object *ob, BMesh *bm)
{
ParamHandle *handle;
+ bool path_found = false;
handle = construct_param_handle(scene, ob, bm, false, false, false, true);
- param_shortest_path(handle);
+ param_shortest_path(handle, &path_found);
param_flush(handle);
param_delete(handle);
- return true; /* TODO (SaphireS): WIP Code, return true only if a valid path was found*/
+ return path_found; /* TODO (SaphireS): WIP Code, return true only if a valid path was found*/
}
/* ******************** Pack Islands operator **************** */
More information about the Bf-blender-cvs
mailing list