[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [49569] branches/soc-2012-bratwurst/source /blender/editors/uvedit: Isomap Unwrapper
Antony Riakiotakis
kalast at gmail.com
Sun Aug 5 04:34:35 CEST 2012
Revision: 49569
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=49569
Author: psy-fi
Date: 2012-08-05 02:34:31 +0000 (Sun, 05 Aug 2012)
Log Message:
-----------
Isomap Unwrapper
=================
* Fix, pass squares of distances to eigen solver
* Use a heap instead of a stack to get the next vertex to iterate
through in Dijkstra graph search algorithm. This is needed because we
may follow a non-optimal path and not get the nearest path between
vertices. This introduces the O(n*log(n)) performance (was more like
simply O(n) till now, but unfortunately, it was incorrect).
Modified Paths:
--------------
branches/soc-2012-bratwurst/source/blender/editors/uvedit/uvedit_parametrizer.c
branches/soc-2012-bratwurst/source/blender/editors/uvedit/uvedit_parametrizer_isomap.cpp
Modified: branches/soc-2012-bratwurst/source/blender/editors/uvedit/uvedit_parametrizer.c
===================================================================
--- branches/soc-2012-bratwurst/source/blender/editors/uvedit/uvedit_parametrizer.c 2012-08-05 01:50:08 UTC (rev 49568)
+++ branches/soc-2012-bratwurst/source/blender/editors/uvedit/uvedit_parametrizer.c 2012-08-05 02:34:31 UTC (rev 49569)
@@ -3072,6 +3072,8 @@
static PBool p_chart_lscm_solve(PHandle *handle, PChart *chart)
{
+
+ //#define OLD_DIST_CONSTRUCTION
enum UnwrapMethods method = handle->method;
if (method == UNWRAP_ISOMAP) {
@@ -3082,9 +3084,10 @@
/* create matrix with squared edge distances */
float *dist_map = MEM_mallocN(sizeof(*dist_map)*nverts*nverts, "isomap_distance_map");
+ #ifndef OLD_DIST_CONSTRUCTION
char *visited = MEM_mallocN(nverts, "isomap_visited_flags");
- PVert **graph_stack = MEM_mallocN(sizeof(*graph_stack)*nverts, "isomap_distance_stack");
- int graph_stack_depth = 0;
+ Heap *graph_heap = BLI_heap_new();
+ #endif
param_isomap_new_solver(nverts);
@@ -3153,51 +3156,68 @@
int ic = p_cent->u.id;
/* iterate through all edges and update distances to distance matrix */
- PEdge *e_iter, *e_init;
- PVert *p_viter;
- int ij;
- float sum_dist;
+ PEdge *e_iter, *e_init, *e_ipair;
+ PVert *p_viter;
+ int ij;
+ float sum_dist;
- e_iter = e_init = p_cent->edge;
- p_viter = e_iter->next->vert;
+ e_iter = e_init = p_cent->edge;
+ e_ipair = e_init->pair;
+ p_viter = e_iter->next->vert;
+ ij = p_viter->u.id;
+ sum_dist = dist_map[ic*nverts + i0] + p_edge_length(e_iter);
+ dist_map[i0*nverts + ij] = dist_map[ij*nverts + i0] =
+ minf(dist_map[i0*nverts + ij], sum_dist);
+
+ /* add pverts in the hash and tag as visited */
+ if (!visited[ij]) {
+ BLI_heap_insert(graph_heap, dist_map[i0*nverts + ij] , p_viter);
+ visited[ij] = TRUE;
+ }
+
+ do {
+ e_iter = e_iter->next->next;
+ p_viter = e_iter->vert;
ij = p_viter->u.id;
- sum_dist = dist_map[ic*nverts + i0] + p_edge_length(e_iter);
- dist_map[i0*nverts + ij] = dist_map[ij*nverts + i0] =
- minf(dist_map[i0*nverts + ij], sum_dist);
+ sum_dist = dist_map[ic*nverts + i0] + p_edge_length(e_iter);
+ dist_map[i0*nverts + ij] = dist_map[ij*nverts + i0] =
+ minf(dist_map[i0*nverts + ij], sum_dist);
- /* add pverts in the hash and tag as visited */
- if (!visited[ij]) {
- graph_stack[graph_stack_depth++] = p_viter;
- visited[ij] = TRUE;
- }
+ /* add pverts in the hash and tag as visited */
+ if (!visited[ij]) {
+ BLI_heap_insert(graph_heap, dist_map[i0*nverts + ij] , p_viter);
+ visited[ij] = TRUE;
+ }
- do {
- e_iter = e_iter->next->next;
- p_viter = e_iter->vert;
- ij = p_viter->u.id;
- sum_dist = dist_map[ic*nverts + i0] + p_edge_length(e_iter);
- dist_map[i0*nverts + ij] = dist_map[ij*nverts + i0] =
- minf(dist_map[i0*nverts + ij], sum_dist);
+ /* assert that one of the two edge vertices is actually the p_cent vertex */
+ BLI_assert (e_iter->vert == p_cent || e_iter->next->vert == p_cent);
+ /* also assert that one of the two edge vertices is actually the p_viter vertex */
+ BLI_assert (e_iter->vert == p_viter || e_iter->next->vert == p_viter);
- /* add pverts in the hash and tag as visited */
- if (!visited[ij]) {
- graph_stack[graph_stack_depth++] = p_viter;
- visited[ij] = TRUE;
- }
+ e_iter = e_iter->pair;
+ } while (e_iter && e_iter != e_init);
- e_iter = e_iter->pair;
- } while (e_iter && e_iter != e_init);
+ BLI_assert(e_iter || !e_ipair);
- if (graph_stack_depth > 0)
- p_cent = graph_stack[--graph_stack_depth];
+ if(BLI_heap_size(graph_heap) > 0)
+ p_cent = BLI_heap_popmin(graph_heap);
else
p_cent = NULL;
}
}
+
+ for (i = 0; i < nverts; i++) {
+ for (j = 0; j < i + 1; j++) {
+ dist_map[i*nverts + j] *= dist_map[i*nverts + j];
+ dist_map[j*nverts + i] *= dist_map[j*nverts + i];
+ }
+ }
+
+
MEM_freeN(visited);
- MEM_freeN(graph_stack);
+ BLI_heap_free(graph_heap, NULL);
#endif
Modified: branches/soc-2012-bratwurst/source/blender/editors/uvedit/uvedit_parametrizer_isomap.cpp
===================================================================
--- branches/soc-2012-bratwurst/source/blender/editors/uvedit/uvedit_parametrizer_isomap.cpp 2012-08-05 01:50:08 UTC (rev 49568)
+++ branches/soc-2012-bratwurst/source/blender/editors/uvedit/uvedit_parametrizer_isomap.cpp 2012-08-05 02:34:31 UTC (rev 49569)
@@ -29,7 +29,7 @@
using namespace std;
using namespace Eigen;
-#define UNWRAP_DEBUG
+//#define UNWRAP_DEBUG
/**
containt the Eigen solver and does the actual solving
@@ -71,8 +71,8 @@
eigensolver.compute(final);
#ifdef UNWRAP_DEBUG
- cout << map_matrix << endl << endl;
- cout << final << endl << endl;
+ cout << "distance map" << endl << map_matrix << endl << endl;
+ cout << "final matrix" << endl << final << endl << endl;
#endif
if (eigensolver.info() != Success) {
More information about the Bf-blender-cvs
mailing list