1 /* $Id$Revision: */
2 /* vim:set shiftwidth=4 ts=8: */
3
4 /*************************************************************************
5 * Copyright (c) 2011 AT&T Intellectual Property
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 * Contributors: See CVS logs. Details at http://www.graphviz.org/
12 *************************************************************************/
13 #include "topfisheyeview.h"
14
15 //#include "glcomptext.h"
16 //#include "glcomptextpng.h"
17 #include "math.h"
18 #include "memory.h"
19 #include "viewport.h"
20 #include "viewportcamera.h"
21 #include "draw.h"
22 #include "smyrna_utils.h"
23
24 #include "assert.h"
25 #include "hier.h"
26 #include "topfisheyeview.h"
27 #include <string.h>
28 #include "color.h"
29 #include "colorprocs.h"
30
31 #ifdef _WIN32
32 #include <wincrypt.h>
33 #endif
34
35 static int get_temp_coords(topview * t, int level, int v, double *coord_x,
36 double *coord_y);
37 #ifdef UNUSED
38 static int get_temp_coords2(topview * t, int level, int v, double *coord_x,
39 double *coord_y, float *R, float *G, float *B);
40 #endif
41
color_interpolation(glCompColor srcColor,glCompColor tarColor,glCompColor * color,int levelcount,int level)42 static void color_interpolation(glCompColor srcColor, glCompColor tarColor,
43 glCompColor * color, int levelcount,
44 int level)
45 {
46 if (levelcount <= 0)
47 return;
48
49
50 color->R =
51 ((float) level * tarColor.R - (float) level * srcColor.R +
52 (float) levelcount * srcColor.R) / (float) levelcount;
53 color->G =
54 ((float) level * tarColor.G - (float) level * srcColor.G +
55 (float) levelcount * srcColor.G) / (float) levelcount;
56 color->B =
57 ((float) level * tarColor.B - (float) level * srcColor.B +
58 (float) levelcount * srcColor.B) / (float) levelcount;
59 }
60
61 #ifdef UNUSED
dist(double x1,double y1,double x2,double y2)62 static double dist(double x1, double y1, double x2, double y2)
63 {
64 return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
65 }
dist3d(double x1,double y1,double z1,double x2,double y2,double z2)66 static double dist3d(double x1, double y1, double z1, double x2, double y2,
67 double z2)
68 {
69 return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) +
70 (z1 - z2) * (z1 - z2));
71 }
72 #endif
73
74 #ifdef UNUSED
75 static void drawtopologicalfisheyestatic(topview * t);
76 #endif
77
78 #ifdef UNUSED
79
80 The code below now longer works. First, t->Nodes == NULL, since
81 we now rely on the libgraph graph for data. Second, the code that
82 drew the distorted view was left out of the move from topview.c
83 to topviewfuncs.c. The magnifiers were cute but not particularly
84 useful, so we leave the feature out for now.
85
86 static double G(double x)
87 {
88 // distortion function for fisheye display
89 return (view->fmg.fisheye_distortion_fac +
90 1) * x / (view->fmg.fisheye_distortion_fac * x + 1);
91 }
92
93
fisheye_polar(double x_focus,double y_focus,topview * t)94 void fisheye_polar(double x_focus, double y_focus, topview * t)
95 {
96 int i;
97 double distance, distorted_distance, ratio, range;
98
99 range = 0;
100 for (i = 1; i < t->Nodecount; i++) {
101 if (point_within_ellips_with_coords
102 ((float) x_focus, (float) y_focus, (float) view->fmg.R,
103 (float) view->fmg.R, t->Nodes[i].x, t->Nodes[i].y)) {
104 range = MAX(range,
105 dist(t->Nodes[i].x, t->Nodes[i].y, x_focus,
106 y_focus));
107 }
108 }
109
110 for (i = 1; i < t->Nodecount; i++) {
111
112 if (point_within_ellips_with_coords
113 ((float) x_focus, (float) y_focus, (float) view->fmg.R,
114 (float) view->fmg.R, t->Nodes[i].x, t->Nodes[i].y)) {
115 distance =
116 dist(t->Nodes[i].x, t->Nodes[i].y, x_focus, y_focus);
117 distorted_distance = G(distance / range) * range;
118 if (distance != 0) {
119 ratio = distorted_distance / distance;
120 } else {
121 ratio = 0;
122 }
123 t->Nodes[i].distorted_x =
124 (float) x_focus + (t->Nodes[i].x -
125 (float) x_focus) * (float) ratio;
126 t->Nodes[i].distorted_y =
127 (float) y_focus + (t->Nodes[i].y -
128 (float) y_focus) * (float) ratio;
129 t->Nodes[i].zoom_factor =
130 (float) 1 *(float) distorted_distance / (float) distance;
131 } else {
132 t->Nodes[i].distorted_x = t->Nodes[i].x;
133 t->Nodes[i].distorted_y = t->Nodes[i].y;
134 t->Nodes[i].zoom_factor = 1;
135 }
136 }
137 }
fisheye_spherical(double x_focus,double y_focus,double z_focus,topview * t)138 void fisheye_spherical(double x_focus, double y_focus, double z_focus,
139 topview * t)
140 {
141 int i;
142 double distance, distorted_distance, ratio, range;
143
144 range = 0;
145 for (i = 1; i < t->Nodecount; i++) {
146 if (point_within_sphere_with_coords
147 ((float) x_focus, (float) y_focus, (float) z_focus,
148 (float) view->fmg.R, t->Nodes[i].x, t->Nodes[i].y,
149 t->Nodes[i].z)) {
150
151
152 range =
153 MAX(range,
154 dist3d(t->Nodes[i].x, t->Nodes[i].y, t->Nodes[i].z,
155 x_focus, y_focus, z_focus));
156 }
157 }
158
159 for (i = 1; i < t->Nodecount; i++) {
160
161
162 if (point_within_sphere_with_coords
163 ((float) x_focus, (float) y_focus, (float) z_focus,
164 (float) view->fmg.R, t->Nodes[i].x, t->Nodes[i].y,
165 t->Nodes[i].z)) {
166 distance =
167 dist3d(t->Nodes[i].x, t->Nodes[i].y, t->Nodes[i].z,
168 x_focus, y_focus, z_focus);
169 distorted_distance = G(distance / range) * range;
170 if (distance != 0) {
171 ratio = distorted_distance / distance;
172 } else {
173 ratio = 0;
174 }
175 t->Nodes[i].distorted_x =
176 (float) x_focus + (t->Nodes[i].x -
177 (float) x_focus) * (float) ratio;
178 t->Nodes[i].distorted_y =
179 (float) y_focus + (t->Nodes[i].y -
180 (float) y_focus) * (float) ratio;
181 t->Nodes[i].distorted_z =
182 (float) z_focus + (t->Nodes[i].z -
183 (float) z_focus) * (float) ratio;
184 t->Nodes[i].zoom_factor =
185 (float) 1 *(float) distorted_distance / (float) distance;
186 } else {
187 t->Nodes[i].distorted_x = t->Nodes[i].x;
188 t->Nodes[i].distorted_y = t->Nodes[i].y;
189 t->Nodes[i].distorted_z = t->Nodes[i].z;
190 t->Nodes[i].zoom_factor = 1;
191 }
192 }
193 }
194 #endif
195
makeGraph(Agraph_t * gg,int * nedges)196 static v_data *makeGraph(Agraph_t* gg, int *nedges)
197 {
198 int i;
199 int ne = agnedges(gg);
200 int nv = agnnodes(gg);
201 v_data *graph = N_NEW(nv, v_data);
202 int *edges = N_NEW(2 * ne + nv, int); /* reserve space for self loops */
203 float *ewgts = N_NEW(2 * ne + nv, float);
204 Agnode_t *np;
205 Agedge_t *ep;
206 Agraph_t *g = NULL;
207 int i_nedges;
208 ne = 0;
209 i=0;
210 // for (i = 0; i < nv; i++) {
211 for (np = agfstnode(gg); np; np = agnxtnode(gg, np))
212 {
213 graph[i].edges = edges++; /* reserve space for the self loop */
214 graph[i].ewgts = ewgts++;
215 #ifdef STYLES
216 graph[i].styles = NULL;
217 #endif
218 i_nedges = 1; /* one for the self */
219
220 if (!g)
221 g = agraphof(np);
222 for (ep = agfstedge(g, np); ep; ep = agnxtedge(g, ep, np))
223 {
224 Agnode_t *vp;
225 Agnode_t *tp = agtail(ep);
226 Agnode_t *hp = aghead(ep);
227 assert(hp != tp);
228 /* FIX: handle multiedges */
229 vp = (tp == np ? hp : tp);
230 ne++;
231 i_nedges++;
232 // *edges++ = ((temp_node_record *) AGDATA(vp))->TVref;
233 *edges++ = ND_TVref(vp);
234 *ewgts++ = 1;
235
236 }
237
238 graph[i].nedges = i_nedges;
239 graph[i].edges[0] = i;
240 graph[i].ewgts[0] = 1 - i_nedges;
241 i++;
242 }
243 ne /= 2; /* each edge counted twice */
244 *nedges = ne;
245 return graph;
246 }
247
248
249
250
251 #if 0
252 static v_data *makeGraph_old(topview * tv, int *nedges)
253 {
254 int i;
255 int ne = tv->Edgecount; /* upper bound */
256 int nv = tv->Nodecount;
257 v_data *graph = N_NEW(nv, v_data);
258 int *edges = N_NEW(2 * ne + nv, int); /* reserve space for self loops */
259 float *ewgts = N_NEW(2 * ne + nv, float);
260 Agnode_t *np;
261 Agedge_t *ep;
262 Agraph_t *g = NULL;
263 int i_nedges;
264
265 ne = 0;
266 for (i = 0; i < nv; i++) {
267 graph[i].edges = edges++; /* reserve space for the self loop */
268 graph[i].ewgts = ewgts++;
269 #ifdef STYLES
270 graph[i].styles = NULL;
271 #endif
272 i_nedges = 1; /* one for the self */
273
274 np = tv->Nodes[i].Node;
275 if (!g)
276 g = agraphof(np);
277 for (ep = agfstedge(g, np); ep; ep = agnxtedge(g, ep, np))
278 {
279 Agnode_t *vp;
280 Agnode_t *tp = agtail(ep);
281 Agnode_t *hp = aghead(ep);
282 assert(hp != tp);
283 /* FIX: handle multiedges */
284 vp = (tp == np ? hp : tp);
285 ne++;
286 i_nedges++;
287 *edges++ = ((temp_node_record *) AGDATA(vp))->TVref;
288 *ewgts++ = 1;
289 }
290
291 graph[i].nedges = i_nedges;
292 graph[i].edges[0] = i;
293 graph[i].ewgts[0] = 1 - i_nedges;
294 }
295 ne /= 2; /* each edge counted twice */
296 *nedges = ne;
297 return graph;
298 }
299 #endif
300
refresh_old_values(topview * t)301 static void refresh_old_values(topview * t)
302 {
303 int level, v;
304 Hierarchy *hp = t->fisheyeParams.h;
305 for (level = 0; level < hp->nlevels; level++) {
306 for (v = 0; v < hp->nvtxs[level]; v++) {
307 ex_vtx_data *gg = hp->geom_graphs[level];
308 /* v_data *g = hp->graphs[level]; */
309 /* double x0,y0; */
310 gg[v].old_physical_x_coord = gg[v].physical_x_coord;
311 gg[v].old_physical_y_coord = gg[v].physical_y_coord;
312 gg[v].old_active_level = gg[v].active_level;
313 }
314 }
315
316 }
317
318 /* To use:
319 * double* x_coords; // initial x coordinates
320 * double* y_coords; // initial y coordinates
321 * focus_t* fs;
322 * int ne;
323 * v_data* graph = makeGraph (topview*, &ne);
324 * hierarchy = makeHier(topview->NodeCount, ne, graph, x_coords, y_coords);
325 * freeGraph (graph);
326 * fs = initFocus (topview->Nodecount); // create focus set
327 */
prepare_topological_fisheye(Agraph_t * g,topview * t)328 void prepare_topological_fisheye(Agraph_t* g,topview * t)
329 {
330 double *x_coords = N_NEW(t->Nodecount, double); // initial x coordinates
331 double *y_coords = N_NEW(t->Nodecount, double); // initial y coordinates
332 focus_t *fs;
333 int ne;
334 int i;
335 int closest_fine_node;
336 int cur_level = 0;
337 Hierarchy *hp;
338 ex_vtx_data *gg;
339 gvcolor_t cl;
340 Agnode_t *np;
341
342 v_data *graph = makeGraph(g, &ne);
343
344 // t->fisheyeParams.animate=1; //turn the animation on
345 i=0;
346 for (np = agfstnode(g); np; np = agnxtnode(g, np))
347 {
348 x_coords[i]=ND_A(np).x;
349 y_coords[i]=ND_A(np).y;
350 i++;
351 }
352 hp = t->fisheyeParams.h =
353 makeHier(agnnodes(g), ne, graph, x_coords, y_coords,
354 &(t->fisheyeParams.hier));
355 freeGraph(graph);
356 free(x_coords);
357 free(y_coords);
358
359 fs = t->fisheyeParams.fs = initFocus(agnnodes(g)); // create focus set
360 gg = hp->geom_graphs[0];
361
362 closest_fine_node = 0; /* first node */
363 fs->num_foci = 1;
364 fs->foci_nodes[0] = closest_fine_node;
365 fs->x_foci[0] = hp->geom_graphs[cur_level][closest_fine_node].x_coord;
366 fs->y_foci[0] = hp->geom_graphs[cur_level][closest_fine_node].y_coord;
367
368 view->Topview->fisheyeParams.repos.width =
369 (int) (view->bdxRight - view->bdxLeft);
370 view->Topview->fisheyeParams.repos.height =
371 (int) (view->bdyTop - view->bdyBottom);
372 view->Topview->fisheyeParams.repos.rescale = Polar;
373
374 //topological fisheye
375
376 colorxlate(get_attribute_value
377 ("topologicalfisheyefinestcolor", view,
378 view->g[view->activeGraph]), &cl, RGBA_DOUBLE);
379 view->Topview->fisheyeParams.srcColor.R = (float) cl.u.RGBA[0];
380 view->Topview->fisheyeParams.srcColor.G = (float) cl.u.RGBA[1];
381 view->Topview->fisheyeParams.srcColor.B = (float) cl.u.RGBA[2];
382 colorxlate(get_attribute_value
383 ("topologicalfisheyecoarsestcolor", view,
384 view->g[view->activeGraph]), &cl, RGBA_DOUBLE);
385 view->Topview->fisheyeParams.tarColor.R = (float) cl.u.RGBA[0];
386 view->Topview->fisheyeParams.tarColor.G = (float) cl.u.RGBA[1];
387 view->Topview->fisheyeParams.tarColor.B = (float) cl.u.RGBA[2];
388
389
390 sscanf(agget
391 (view->g[view->activeGraph],
392 "topologicalfisheyedistortionfactor"), "%lf",
393 &view->Topview->fisheyeParams.repos.distortion);
394 sscanf(agget
395 (view->g[view->activeGraph], "topologicalfisheyefinenodes"),
396 "%d", &view->Topview->fisheyeParams.level.num_fine_nodes);
397 sscanf(agget
398 (view->g[view->activeGraph],
399 "topologicalfisheyecoarseningfactor"), "%lf",
400 &view->Topview->fisheyeParams.level.coarsening_rate);
401 sscanf(agget
402 (view->g[view->activeGraph], "topologicalfisheyedist2limit"),
403 "%d", &view->Topview->fisheyeParams.hier.dist2_limit);
404 sscanf(agget(view->g[view->activeGraph], "topologicalfisheyeanimate"),
405 "%d", &view->Topview->fisheyeParams.animate);
406
407 set_active_levels(hp, fs->foci_nodes, fs->num_foci, &(t->fisheyeParams.level));
408 positionAllItems(hp, fs, &(t->fisheyeParams.repos));
409 refresh_old_values(t);
410
411 /* fprintf (stderr, "No. of active nodes = %d\n", count_active_nodes(hp)); */
412
413 }
414
415 #if 0
416 /*
417 draws all level 0 nodes and edges, during animation
418 */
419 void printalllevels(topview * t)
420 {
421 int level, v;
422 Hierarchy *hp = t->fisheyeParams.h;
423 glPointSize(5);
424 glBegin(GL_POINTS);
425 for (level = 0; level < hp->nlevels; level++) {
426 for (v = 0; v < hp->nvtxs[level]; v++) {
427 ex_vtx_data *gg = hp->geom_graphs[level];
428 if (gg[v].active_level == level) {
429 double x0, y0;
430 get_temp_coords(t, level, v, &x0, &y0);
431 glColor3f((GLfloat) (hp->nlevels - level) /
432 (GLfloat) hp->nlevels,
433 (GLfloat) level / (GLfloat) hp->nlevels, 0);
434 glVertex3f((GLfloat) x0, (GLfloat) y0, (GLfloat) 0);
435 }
436 }
437 }
438 glEnd();
439 }
440 #endif
441
drawtopfishnodes(topview * t)442 static void drawtopfishnodes(topview * t)
443 {
444 glCompColor srcColor;
445 glCompColor tarColor;
446 glCompColor color;
447 int level, v;
448 Hierarchy *hp = t->fisheyeParams.h;
449 static int max_visible_level = 0;
450 srcColor.R = view->Topview->fisheyeParams.srcColor.R;
451 srcColor.G = view->Topview->fisheyeParams.srcColor.G;
452 srcColor.B = view->Topview->fisheyeParams.srcColor.B;
453 tarColor.R = view->Topview->fisheyeParams.tarColor.R;
454 tarColor.G = view->Topview->fisheyeParams.tarColor.G;
455 tarColor.B = view->Topview->fisheyeParams.tarColor.B;
456
457
458 //draw focused node little bigger than others
459 /* ex_vtx_data *gg = hp->geom_graphs[0];
460 if ((gg[v].active_level == 0) &&(v==t->fisheyeParams.fs->foci_nodes[0]))*/
461
462
463 //drawing nodes
464 glPointSize(7);
465 level = 0;
466 glBegin(GL_POINTS);
467 for (level = 0; level < hp->nlevels; level++) {
468 for (v = 0; v < hp->nvtxs[level]; v++) {
469 double x0, y0;
470 if (get_temp_coords(t, level, v, &x0, &y0)) {
471
472 if (!(((-x0 / view->zoom > view->clipX1)
473 && (-x0 / view->zoom < view->clipX2)
474 && (-y0 / view->zoom > view->clipY1)
475 && (-y0 / view->zoom < view->clipY2))))
476 continue;
477
478 // if (level !=0)
479 // glColor4f((GLfloat) (hp->nlevels - level)*(GLfloat)0.5 / (GLfloat) hp->nlevels,
480 // (GLfloat) level / (GLfloat) hp->nlevels, (GLfloat)0,(GLfloat)view->defaultnodealpha);
481 // else
482 // glColor4f((GLfloat) 1,
483 // (GLfloat) level / (GLfloat) hp->nlevels*2, 0,view->defaultnodealpha);
484
485 if (max_visible_level < level)
486 max_visible_level = level;
487 color_interpolation(srcColor, tarColor, &color,
488 max_visible_level, level);
489 glColor4f(color.R, color.G, color.B,
490 (GLfloat) view->defaultnodealpha);
491
492 /* glColor3f((GLfloat) (hp->nlevels - level)*0.5 / (GLfloat) hp->nlevels,
493 (GLfloat) level / (GLfloat) hp->nlevels, 0);*/
494
495 glVertex3f((GLfloat) x0, (GLfloat) y0, (GLfloat) 0);
496 }
497 }
498 }
499 glEnd();
500
501 }
502
503 #if 0
504 static void drawtopfishnodelabels(topview * t)
505 {
506 int v, finenodes, focusnodes;
507 char buf[512];
508 char *str;
509 Hierarchy *hp = t->fisheyeParams.h;
510 finenodes = focusnodes = 0;
511 str =
512 agget(view->g[view->activeGraph],
513 "topologicalfisheyelabelfinenodes");
514 if (strcmp(str, "1") == 0) {
515 finenodes = 1;
516 }
517 str =
518 agget(view->g[view->activeGraph], "topologicalfisheyelabelfocus");
519 if (strcmp(str, "1") == 0) {
520 focusnodes = 1;
521 }
522 if ((finenodes) || (focusnodes)) {
523 for (v = 0; v < hp->nvtxs[0]; v++) {
524 ex_vtx_data *gg = hp->geom_graphs[0];
525 if (gg[v].active_level == 0) {
526 if (view->Topview->Nodes[v].Label)
527 strcpy(buf, view->Topview->Nodes[v].Label);
528 else
529 sprintf(buf, "%d", v);
530
531 if ((v == t->fisheyeParams.fs->foci_nodes[0]) && (focusnodes)) {
532 glColor4f((float) 0, (float) 0, (float) 1, (float) 1);
533 glprintfglut(GLUT_BITMAP_HELVETICA_18,
534 gg[v].physical_x_coord,
535 gg[v].physical_y_coord, 0, buf);
536 } else if (finenodes) {
537 glColor4f(0, 0, 0, 1);
538 glprintfglut(GLUT_BITMAP_HELVETICA_10,
539 gg[v].physical_x_coord,
540 gg[v].physical_y_coord, 0, buf);
541 }
542 }
543
544 }
545 }
546
547 }
548 #endif
drawtopfishedges(topview * t)549 static void drawtopfishedges(topview * t)
550 {
551 glCompColor srcColor;
552 glCompColor tarColor;
553 glCompColor color;
554
555 int level, v, i, n;
556 Hierarchy *hp = t->fisheyeParams.h;
557 static int max_visible_level = 0;
558 srcColor.R = view->Topview->fisheyeParams.srcColor.R;
559 srcColor.G = view->Topview->fisheyeParams.srcColor.G;
560 srcColor.B = view->Topview->fisheyeParams.srcColor.B;
561 tarColor.R = view->Topview->fisheyeParams.tarColor.R;
562 tarColor.G = view->Topview->fisheyeParams.tarColor.G;
563 tarColor.B = view->Topview->fisheyeParams.tarColor.B;
564
565 //and edges
566 glBegin(GL_LINES);
567 for (level = 0; level < hp->nlevels; level++) {
568 for (v = 0; v < hp->nvtxs[level]; v++) {
569 v_data *g = hp->graphs[level];
570 double x0, y0;
571 if (get_temp_coords(t, level, v, &x0, &y0)) {
572 for (i = 1; i < g[v].nedges; i++) {
573 double x, y;
574 n = g[v].edges[i];
575
576
577 if (max_visible_level < level)
578 max_visible_level = level;
579 color_interpolation(srcColor, tarColor, &color,
580 max_visible_level, level);
581 glColor4f(color.R, color.G, color.B,
582 (GLfloat) view->defaultnodealpha);
583
584
585 if (get_temp_coords(t, level, n, &x, &y)) {
586 glVertex3f((GLfloat) x0, (GLfloat) y0,
587 (GLfloat) 0);
588 glVertex3f((GLfloat) x, (GLfloat) y, (GLfloat) 0);
589 } else // if (gg[n].active_level > level)
590 {
591 int levell, nodee;
592 find_active_ancestor_info(hp, level, n, &levell,
593 &nodee);
594 // find_physical_coords(hp, level, n, &x, &y);
595 if (get_temp_coords(t, levell, nodee, &x, &y)) {
596
597 if ((!(((-x0 / view->zoom > view->clipX1)
598 && (-x0 / view->zoom < view->clipX2)
599 && (-y0 / view->zoom > view->clipY1)
600 && (-y0 / view->zoom < view->clipY2))))
601 && (!(((-x / view->zoom > view->clipX1)
602 && (-x / view->zoom < view->clipX2)
603 && (-y / view->zoom > view->clipY1)
604 && (-y / view->zoom <
605 view->clipY2)))))
606
607 continue;
608
609
610 glVertex3f((GLfloat) x0, (GLfloat) y0,
611 (GLfloat) 0);
612 glVertex3f((GLfloat) x, (GLfloat) y,
613 (GLfloat) 0);
614 }
615 }
616 }
617 }
618 }
619 }
620 glEnd();
621
622 }
623
get_active_frame(topview * t)624 static int get_active_frame(topview * t)
625 {
626 gulong microseconds;
627 gdouble seconds;
628 int fr;
629 seconds = g_timer_elapsed(view->timer, µseconds);
630 fr = (int) (seconds / ((double) view->frame_length / (double) 1000));
631 if (fr < view->total_frames) {
632
633 if (fr == view->active_frame)
634 return 0;
635 else {
636 view->active_frame = fr;
637 return 1;
638 }
639 } else {
640 g_timer_stop(view->timer);
641 view->Topview->fisheyeParams.animate = 0;
642 return 0;
643 }
644
645 }
646
drawtopologicalfisheye(topview * t)647 void drawtopologicalfisheye(topview * t)
648 {
649 get_active_frame(t);
650 drawtopfishnodes(t);
651 drawtopfishedges(t);
652 /* if (!t->fisheyeParams.animate)
653 drawtopfishnodelabels(t);*/
654
655 }
656
get_interpolated_coords(double x0,double y0,double x1,double y1,int fr,int total_fr,double * x,double * y)657 static void get_interpolated_coords(double x0, double y0, double x1, double y1,
658 int fr, int total_fr, double *x, double *y)
659 {
660 *x = x0 + (x1 - x0) / (double) total_fr *(double) (fr + 1);
661 *y = y0 + (y1 - y0) / (double) total_fr *(double) (fr + 1);
662 }
663
get_temp_coords(topview * t,int level,int v,double * coord_x,double * coord_y)664 int get_temp_coords(topview * t, int level, int v, double *coord_x,
665 double *coord_y)
666 {
667 Hierarchy *hp = t->fisheyeParams.h;
668 ex_vtx_data *gg = hp->geom_graphs[level];
669 /* v_data *g = hp->graphs[level]; */
670
671 if (!t->fisheyeParams.animate) {
672 if (gg[v].active_level != level)
673 return 0;
674
675 *coord_x = (double) gg[v].physical_x_coord;
676 *coord_y = (double) gg[v].physical_y_coord;
677 } else {
678
679
680 double x0, y0, x1, y1;
681 int OAL, AL;
682
683 x0 = 0;
684 y0 = 0;
685 x1 = 0;
686 y1 = 0;
687 AL = gg[v].active_level;
688 OAL = gg[v].old_active_level;
689
690 if ((OAL < level) || (AL < level)) //no draw
691 return 0;
692 if ((OAL >= level) || (AL >= level)) //draw the node
693 {
694 if ((OAL == level) && (AL == level)) //draw as is from old coords to new)
695 {
696 x0 = (double) gg[v].old_physical_x_coord;
697 y0 = (double) gg[v].old_physical_y_coord;
698 x1 = (double) gg[v].physical_x_coord;
699 y1 = (double) gg[v].physical_y_coord;
700 }
701 if ((OAL > level) && (AL == level)) //draw as from ancs to new)
702 {
703 find_old_physical_coords(t->fisheyeParams.h, level, v, &x0, &y0);
704 x1 = (double) gg[v].physical_x_coord;
705 y1 = (double) gg[v].physical_y_coord;
706 }
707 if ((OAL == level) && (AL > level)) //draw as from ancs to new)
708 {
709 find_physical_coords(t->fisheyeParams.h, level, v, &x1, &y1);
710 x0 = (double) gg[v].old_physical_x_coord;
711 y0 = (double) gg[v].old_physical_y_coord;
712 }
713 get_interpolated_coords(x0, y0, x1, y1, view->active_frame,
714 view->total_frames, coord_x, coord_y);
715 if ((x0 == 0) || (x1 == 0))
716 return 0;
717
718 }
719 }
720 return 1;
721 }
722
723
724
725 /* In loop,
726 * update fs.
727 * For example, if user clicks mouse at (p.x,p.y) to pick a single new focus,
728 * int closest_fine_node;
729 * find_closest_active_node(hierarchy, p.x, p.y, &closest_fine_node);
730 * fs->num_foci = 1;
731 * fs->foci_nodes[0] = closest_fine_node;
732 * fs->x_foci[0] = hierarchy->geom_graphs[cur_level][closest_fine_node].x_coord;
733 * fs->y_foci[0] = hierarchy->geom_graphs[cur_level][closest_fine_node].y_coord;
734 * set_active_levels(hierarchy, fs->foci_nodes, fs->num_foci);
735 * positionAllItems(hierarchy, fs, parms)
736 */
737
738 #if 0
739 void infotopfisheye(topview * t, float *x, float *y, float *z)
740 {
741
742 Hierarchy *hp = t->fisheyeParams.h;
743 int closest_fine_node;
744 find_closest_active_node(hp, *x, *y, &closest_fine_node);
745
746
747
748
749 /* hp->geom_graphs[0][closest_fine_node].x_coord;
750 hp->geom_graphs[0][closest_fine_node].y_coord;*/
751 }
752 #endif
753
754
755
changetopfishfocus(topview * t,float * x,float * y,float * z,int num_foci)756 void changetopfishfocus(topview * t, float *x, float *y,
757 float *z, int num_foci)
758 {
759
760 gvcolor_t cl;
761 focus_t *fs = t->fisheyeParams.fs;
762 int i;
763 int closest_fine_node;
764 int cur_level = 0;
765
766 Hierarchy *hp = t->fisheyeParams.h;
767 refresh_old_values(t);
768 fs->num_foci = num_foci;
769 for (i = 0; i < num_foci; i++) {
770 find_closest_active_node(hp, x[i], y[i], &closest_fine_node);
771 fs->foci_nodes[i] = closest_fine_node;
772 fs->x_foci[i] =
773 hp->geom_graphs[cur_level][closest_fine_node].x_coord;
774 fs->y_foci[i] =
775 hp->geom_graphs[cur_level][closest_fine_node].y_coord;
776 }
777
778
779 view->Topview->fisheyeParams.repos.width =
780 (int) (view->bdxRight - view->bdxLeft);
781 view->Topview->fisheyeParams.repos.height =
782 (int) (view->bdyTop - view->bdyBottom);
783
784 colorxlate(get_attribute_value
785 ("topologicalfisheyefinestcolor", view,
786 view->g[view->activeGraph]), &cl, RGBA_DOUBLE);
787 view->Topview->fisheyeParams.srcColor.R = (float) cl.u.RGBA[0];
788 view->Topview->fisheyeParams.srcColor.G = (float) cl.u.RGBA[1];
789 view->Topview->fisheyeParams.srcColor.B = (float) cl.u.RGBA[2];
790 colorxlate(get_attribute_value
791 ("topologicalfisheyecoarsestcolor", view,
792 view->g[view->activeGraph]), &cl, RGBA_DOUBLE);
793 view->Topview->fisheyeParams.tarColor.R = (float) cl.u.RGBA[0];
794 view->Topview->fisheyeParams.tarColor.G = (float) cl.u.RGBA[1];
795 view->Topview->fisheyeParams.tarColor.B = (float) cl.u.RGBA[2];
796
797
798
799 sscanf(agget
800 (view->g[view->activeGraph],
801 "topologicalfisheyedistortionfactor"), "%lf",
802 &view->Topview->fisheyeParams.repos.distortion);
803 sscanf(agget
804 (view->g[view->activeGraph], "topologicalfisheyefinenodes"),
805 "%d", &view->Topview->fisheyeParams.level.num_fine_nodes);
806 sscanf(agget
807 (view->g[view->activeGraph],
808 "topologicalfisheyecoarseningfactor"), "%lf",
809 &view->Topview->fisheyeParams.level.coarsening_rate);
810 sscanf(agget
811 (view->g[view->activeGraph], "topologicalfisheyedist2limit"),
812 "%d", &view->Topview->fisheyeParams.hier.dist2_limit);
813 sscanf(agget(view->g[view->activeGraph], "topologicalfisheyeanimate"),
814 "%d", &view->Topview->fisheyeParams.animate);
815
816
817
818
819 set_active_levels(hp, fs->foci_nodes, fs->num_foci, &(t->fisheyeParams.level));
820
821
822 positionAllItems(hp, fs, &(t->fisheyeParams.repos));
823
824 view->Topview->fisheyeParams.animate = 1;
825
826 if (t->fisheyeParams.animate) {
827 view->active_frame = 0;
828 g_timer_start(view->timer);
829 }
830
831 }
832
833
834
835 #ifdef UNUSED
drawtopologicalfisheyestatic(topview * t)836 void drawtopologicalfisheyestatic(topview * t)
837 {
838 int level, v;
839 Hierarchy *hp = t->fisheyeParams.h;
840
841 glPointSize(15);
842 glBegin(GL_POINTS);
843 for (level = 0; level < hp->nlevels; level++) {
844 for (v = 0; v < hp->nvtxs[level]; v++) {
845 ex_vtx_data *gg = hp->geom_graphs[level];
846 if (gg[v].active_level == level) {
847 double x0 = gg[v].physical_x_coord;
848 double y0 = gg[v].physical_y_coord;
849 // glColor3f((GLfloat)(hp->nlevels-level)/(GLfloat)hp->nlevels,(GLfloat)level/(GLfloat)hp->nlevels,0);
850 glColor4f((GLfloat) 0, (GLfloat) 1, (GLfloat) 0,
851 (GLfloat) 0.2);
852 glVertex3f((GLfloat) x0, (GLfloat) y0, (GLfloat) 0);
853 }
854 }
855 }
856 glEnd();
857
858
859
860
861 /* glBegin(GL_LINES);
862 for (level=0;level < hp->nlevels;level++) {
863 for (v=0;v < hp->nvtxs[level]; v++) {
864 ex_vtx_data* gg = hp->geom_graphs[level];
865 vtx_data* g = hp->graphs[level];
866 if(gg[v].active_level==level) {
867 double x0 = gg[v].physical_x_coord;
868 double y0 = gg[v].physical_y_coord;
869
870 for (i=1;i < g[v].nedges;i++) {
871 double x,y;
872 n = g[v].edges[i];
873 glColor3f((GLfloat)(hp->nlevels-level)/(GLfloat)hp->nlevels,(GLfloat)level/(GLfloat)hp->nlevels,0);
874 if (gg[n].active_level == level) {
875 if (v < n) {
876 x = gg[n].physical_x_coord;
877 y = gg[n].physical_y_coord;
878 glVertex3f((GLfloat)x0,(GLfloat)y0,(GLfloat)0);
879 glVertex3f((GLfloat)x,(GLfloat)y,(GLfloat)0);
880 }
881 }
882 else if (gg[n].active_level > level) {
883 find_physical_coords(hp, level, n, &x, &y);
884 glVertex3f((GLfloat)x0,(GLfloat)y0,(GLfloat)0);
885 glVertex3f((GLfloat)x,(GLfloat)y,(GLfloat)0);
886 }
887 }
888 }
889 }
890 }
891 glEnd();*/
892 }
893 #endif
894