Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
topviewfuncs.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <assert.h>
12#include "topviewfuncs.h"
13#include <cgraph/cgraph.h>
14#include "smyrna_utils.h"
15#include <common/colorprocs.h>
16#include "draw.h"
17#include "frmobjectui.h"
18#include <xdot/xdot.h>
19#include <glcomp/glutils.h>
20#include "selectionfuncs.h"
21#include <common/types.h>
22#include <common/utils.h>
23#include <limits.h>
24#include <float.h>
25#include <math.h>
26#include <stdbool.h>
27#include <stdlib.h>
28#include <util/alloc.h>
29#include <util/gv_ctype.h>
30
31static xdot *parseXdotwithattrs(void *e)
32{
33 xdot* xDot=NULL;
34 xDot=parseXDotFOn (agget(e,"_draw_" ), OpFns,sizeof(sdot_op), xDot);
35 if (agobjkind(e) == AGRAPH)
36 xDot=parseXDotFOn (agget(e,"_background" ), OpFns,sizeof(sdot_op), xDot);
37 xDot=parseXDotFOn (agget(e,"_ldraw_" ), OpFns,sizeof(sdot_op), xDot);
38 xDot=parseXDotFOn (agget(e,"_hdraw_" ), OpFns,sizeof(sdot_op), xDot);
39 xDot=parseXDotFOn (agget(e,"_tdraw_" ), OpFns,sizeof(sdot_op), xDot);
40 xDot=parseXDotFOn (agget(e,"_hldraw_" ), OpFns,sizeof(sdot_op), xDot);
41 xDot=parseXDotFOn (agget(e,"_tldraw_" ), OpFns,sizeof(sdot_op), xDot);
42 if(xDot)
43 {
44 for (size_t cnt = 0; cnt < xDot->cnt; cnt++)
45 {
46 ((sdot_op*)(xDot->ops))[cnt].obj=e;
47 }
48 }
49 return xDot;
50
51}
52
53static void set_boundaries(Agraph_t * g)
54{
55 Agnode_t *v;
56 Agsym_t* pos_attr = GN_pos(g);
57 glCompPoint pos;
58 float left = FLT_MAX, right = -FLT_MAX, top = -FLT_MAX, bottom = FLT_MAX;
59
60 for (v = agfstnode(g); v; v = agnxtnode(g, v))
61 {
62 pos=getPointFromStr(agxget(v, pos_attr));
63
64 left = fminf(left, pos.x);
65 right = fmaxf(right, pos.x);
66 top = fmaxf(top, pos.y);
67 bottom = fminf(bottom, pos.y);
68 }
69 view->bdxLeft = left;
70 view->bdyTop = top;
72 view->bdyBottom = bottom;
73}
74
75static void draw_xdot(xdot* x, double base_z)
76{
77 sdot_op *op;
78 if (!x)
79 return;
80
81 view->Topview->global_z=base_z;
82
83 op=(sdot_op*)x->ops;
84 for (size_t i = 0; i < x->cnt; i++, op++)
85 {
86 if(op->op.drawfunc)
87 op->op.drawfunc(&op->op,0);
88 }
89
90
91}
92
93
94
96{
97 return getPointFromStr(agget(aghead(edge),"pos"));
98}
100{
101 return getPointFromStr(agget(agtail(edge),"pos"));
102}
103
108 float rv = (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y) + (A.z - B.z) * (A.z - B.z);
109 rv=sqrtf(rv);
110 return rv;
111}
112
113static void glCompColorxlate(glCompColor *c, const char *str) {
114 gvcolor_t cl;
116 c->R=cl.u.RGBA[0];
117 c->G=cl.u.RGBA[1];
118 c->B=cl.u.RGBA[2];
119 c->A=cl.u.RGBA[3];
120}
121
122/* If the "visible" attribute is not set or "", return true
123 * else evaluate as boolean
124 */
125static int visible(Agsym_t* attr, void* obj)
126{
127 char* s;
128
129 if (attr) {
130 s = agxget (obj, attr);
131 if (*s) return mapbool(s);
132 else return 1;
133 }
134 else return 1;
135}
136
137static int object_color(void* obj,glCompColor* c)
138{
139 gvcolor_t cl;
141 Agraph_t* objg=agraphof(obj);
142 int return_value = 1;
143 int objType;
144 float Alpha = 1;
145 Agsym_t* vis;
146
147 objType=AGTYPE(obj);
148
149 if(objType==AGEDGE) {
150 Alpha=getAttrFloat(g,objg,"defaultedgealpha",1);
151 vis = GE_visible (objg);
152 }
153 else {
154 assert(objType == AGNODE);
155 Alpha=getAttrFloat(g,objg,"defaultnodealpha",1);
156 vis = GN_visible (objg);
157 }
158 if (!visible(vis,obj))
159 return 0;
160
161 char *previous_color_scheme = setColorScheme(agget (obj, "colorscheme"));
162 /*get objects's color attribute */
163 const char *const bf = getAttrStr(g,obj,"color",NULL);
164 if(bf && (*bf)) {
165 colorxlate(bf, &cl, RGBA_DOUBLE);
166 c->R = cl.u.RGBA[0];
167 c->G = cl.u.RGBA[1];
168 c->B = cl.u.RGBA[2];
169 c->A = cl.u.RGBA[3]*Alpha;
170 }
171 else
172 {
173 if(objType==AGEDGE)
175 else
176 {
177 colorxlate(agget(g, "defaultnodecolor"),&cl, RGBA_DOUBLE);
178 c->R = cl.u.RGBA[0];
179 c->G = cl.u.RGBA[1];
180 c->B = cl.u.RGBA[2];
181 c->A = cl.u.RGBA[3];
182 }
183 c->A *= Alpha;
184
185 }
186
187 char *color_scheme = setColorScheme(previous_color_scheme);
188 free(color_scheme);
189 free(previous_color_scheme);
190
191 return return_value;
192}
193
194
195/*
196 draws multi edges , single edges
197 this function assumes glBegin(GL_LINES) has been called
198*/
199static void draw_edge(glCompPoint *posT, glCompPoint *posH, float length,
200 int deg) {
201 double alpha, R, ITERANGLE;
202 double X1, Y1, X2, Y2;
203
204 if (deg) {
205 R = length / 20.0;
206 if ((deg / 2) * 2 != deg) /*odd */
207 ITERANGLE = (deg) * 15.00 * -1;
208 else
209 ITERANGLE = (deg) * 15.00;
210 ITERANGLE = DEG2RAD * ITERANGLE;
211
212 alpha = atan((posH->y - posT->y) / (posH->x - posT->x));
213 if (posT->x > posH->x)
214 ITERANGLE = 180 * DEG2RAD - ITERANGLE;
215 X1 = R * cos(alpha - ITERANGLE) + posT->x;
216 Y1 = R * sin(alpha - ITERANGLE) + posT->y;
217 X2 = R * cos(alpha - (180 * DEG2RAD - ITERANGLE)) + posH->x;
218 Y2 = R * sin(alpha - (180 * DEG2RAD - ITERANGLE)) + posH->y;
219 glVertex3f(posT->x, posT->y, posT->z);
220 glVertex3f(X1, Y1, posT->z);
221 glVertex3f(X1, Y1, posT->z);
222 glVertex3f(X2, Y2, posH->z);
223 glVertex3f(X2, Y2, posH->z);
224 glVertex3f(posH->x, posH->y, posH->z);
225 } else {
226 glVertex3f(posT->x, posT->y, posT->z);
227 glVertex3f(posH->x, posH->y, posH->z);
228
229 }
230
231}
232
233static char* labelOf (Agraph_t* g, Agnode_t* v)
234{
235 char* lbl;
236 char* s;
237
238 Agsym_t* data_attr = GN_labelattribute(g);
239 if (data_attr)
240 s = agxget (v, data_attr);
241 else
242 s = agxget (g, GG_labelattribute(g));
243 if ((*s == '\0') || !strcmp (s, "name"))
244 lbl = agnameof (v);
245 else {
246 lbl = agget (v, s);
247 if (!lbl) lbl = "";
248 }
249 return lbl;
250}
251
253{
254 Agnode_t *v;
255 xdot * x;
256 glCompPoint pos;
257 Agsym_t* l_color_attr = GG_nodelabelcolor(g);
258 glCompColor c;
259 int defaultNodeShape;
260 float nodeSize;
261
262 glCompColorxlate(&c,agxget(g,l_color_attr));
263
264 defaultNodeShape=getAttrBool(g,g,"defaultnodeshape",0);
265 if(defaultNodeShape==0)
266 glBegin(GL_POINTS);
267
268 for (v = agfstnode(g); v; v = agnxtnode(g, v))
269 {
270 if(!ND_selected(v))
271 continue;
273 draw_xdot(x,-1);
274 if(x)
275 freeXDot (x);
276 }
277
278 for (v = agfstnode(g); v; v = agnxtnode(g, v))
279 {
280 if(!ND_selected(v))
281 continue;
283 pos = ND_A(v);
284 nodeSize = ND_size(v);
285
286 if (defaultNodeShape == 0)
287 glVertex3f(pos.x, pos.y, pos.z + 0.001f);
288 else if (defaultNodeShape == 1)
289 drawCircle(pos.x, pos.y, nodeSize, pos.z + 0.001f);
290 }
291 if(defaultNodeShape==0)
292 glEnd();
293 for (v = agfstnode(g); v; v = agnxtnode(g, v))
294 {
295 if(!ND_selected(v))
296 continue;
297 if (ND_printLabel(v)==1)
298 {
299 pos = ND_A(v);
300 glColor4f(c.R, c.G,c.B, c.A);
301 glprintfglut(view->glutfont, pos.x, pos.y, pos.z + 0.002f, labelOf(g, v));
302 }
303 }
304}
305
306
307
308static void renderNodes(Agraph_t * g)
309{
310 Agnode_t *v;
311 glCompPoint pos;
312 Agsym_t* pos_attr = GN_pos(g);
313 Agsym_t* size_attr = GN_size(g);
314 Agsym_t* selected_attr = GN_selected(g);
315 int defaultNodeShape;
316 float nodeSize;
317 glCompColor c;
318 xdot * x;
319 int ind;
320
321 defaultNodeShape=getAttrInt(g,g,"defaultnodeshape",0);
322
324 if (x) {
325 draw_xdot(x, -0.2);
326 freeXDot (x);
327 }
328 for (v = agfstnode(g); v; v = agnxtnode(g, v))
329 {
330 if(!object_color(v,&c))
331 continue;
333 draw_xdot(x, -0.1);
334
335 if(x)
336 freeXDot (x);
337 }
338
339 if(defaultNodeShape==0)
340 glBegin(GL_POINTS);
341
342 ind=0;
343
344 for (v = agfstnode(g); v; v = agnxtnode(g, v))
345 {
346 ND_TVref(v) = ind;
347 if(!object_color(v,&c))
348 {
349 ND_visible(v) = 0;
350 continue;
351 }
352 else
353 ND_visible(v) = 1;
354
355 if(l_int(v, selected_attr,0))
356 {
357 ND_selected(v) = 1;
358 }
359 glColor4f(c.R,c.G,c.B,c.A);
360 pos=getPointFromStr(agxget(v, pos_attr));
361 nodeSize = l_float(v, size_attr, 0);
362
363 ND_A(v) = pos;
364
365 if (nodeSize > 0)
366 nodeSize=nodeSize*view->nodeScale;
367 else
368 nodeSize=view->nodeScale;
369 if(defaultNodeShape==0)
370 nodeSize=1;
371 ND_size(v) = nodeSize;
372 if (defaultNodeShape == 0)
373 glVertex3f(pos.x,pos.y,pos.z);
374 else if (defaultNodeShape == 1)
375 drawCircle(pos.x,pos.y,nodeSize,pos.z);
376 ind++;
377 }
378 if(defaultNodeShape==0)
379 glEnd();
380}
381
382
384{
385
386 Agedge_t *e;
387 Agnode_t *v;
388 xdot * x;
389 glCompPoint posT; /*Tail position*/
390 glCompPoint posH; /*Head position*/
391 glCompColor c;
392 /*xdots tend to be drawn as background shapes,that is why they are being rendered before edges*/
393
394 for (v = agfstnode(g); v; v = agnxtnode(g, v))
395 {
396 for (e = agfstout(g, v); e; e = agnxtout(g, e))
397 {
398 if(!ED_selected(e))
399 continue;
400 if(!object_color(e,&c))
401 continue;
402
404 draw_xdot(x,0);
405 if(x)
406 freeXDot (x);
407 }
408 }
409
410 glBegin(GL_LINES);
411 for (v = agfstnode(g); v; v = agnxtnode(g, v))
412 {
413 for (e = agfstout(g, v); e; e = agnxtout(g, e))
414 {
415 if(!ED_selected(e))
416 continue;
417
418 if(!object_color(e,&c))
419 continue;
420 glColor4f(1,0,0,1);
421 posT = ED_posTail(e);
422 posH = ED_posHead(e);
423 posT.z +=0.01f;
424 posH.z +=0.01f;
425 draw_edge(&posT,&posH,getEdgeLength(e),0);
426 }
427 }
428 glEnd();
429}
430
431/* skipWS:
432 * Skip whitespace
433 */
434static char* skipWS (char* p)
435{
436 while (gv_isspace(*p)) p++;
437 return p;
438}
439
440/* skipNWS:
441 * Skip non-whitespace
442 */
443static char* skipNWS (char* p)
444{
445 while (*p && !gv_isspace(*p)) p++;
446 return p;
447}
448
449/* readPoint:
450 * Parse x,y[,z] and store in pt.
451 * If z is not specified, set to 0.
452 * Return pointer to next character after reading the point.
453 * Return NULL on error.
454 */
455static char* readPoint (char* p, xdot_point* pt)
456{
457 char* endp;
458
459 pt->z = 0;
460 pt->x = strtod (p, &endp);
461 if (p == endp) {
462 return 0;
463 }
464 else
465 p = endp;
466 if (*p == ',') p++;
467 else return 0;
468
469 pt->y = strtod (p, &endp);
470 if (p == endp) {
471 return 0;
472 }
473 else
474 p = endp;
475 if ((*p == ' ') || (*p == '\0')) return p;
476 else if (*p == ',') p++;
477 else return 0;
478
479 pt->z = strtod (p, &endp);
480 if (p == endp) {
481 return 0;
482 }
483 else
484 return endp;
485}
486
487/* countPoints:
488 * count number of points in pos attribute; store in cntp;
489 * check for e and s points; store if found and increment number of
490 * points by 3 for each.
491 * return start of point list (skip over e and s points).
492 * return NULL on failure
493 */
494static char *countPoints(char *pos, int *have_sp, xdot_point *sp, int *have_ep,
495 xdot_point *ep, size_t *cntp) {
496 size_t cnt = 0;
497 char* p;
498
499 pos = skipWS (pos);
500 if (*pos == 's') {
501 if ((pos = readPoint (pos+2, sp))) {
502 *have_sp = 1;
503 cnt += 3;
504 }
505 else
506 return 0;
507 }
508 else
509 *have_sp = 0;
510
511 pos = skipWS (pos);
512 if (*pos == 'e') {
513 if ((pos = readPoint (pos+2, ep))) {
514 *have_ep = 1;
515 cnt += 3;
516 }
517 else
518 return 0;
519 }
520 else
521 *have_ep = 0;
522
523 p = pos = skipWS (pos);
524
525 while (*p) {
526 cnt++;
527 p = skipNWS (p);
528 p = skipWS (p);
529 }
530 *cntp = cnt;
531
532 return pos;
533}
534
535/* storePoints:
536 * read comma-separated list of points
537 * and store them in ps
538 * Assumes enough storage is available.
539 * return -1 on error
540 */
541static int storePoints (char* pos, xdot_point* ps)
542{
543
544 while (*pos) {
545 if ((pos = readPoint (pos, ps))) {
546 ps++;
547 pos = skipWS(pos);
548 }
549 else
550 return -1;
551 }
552 return 0;
553}
554
555/* makeXDotSpline:
556 * Generate an xdot representation of an edge's pos attribute
557 */
558static xdot* makeXDotSpline (char* pos)
559{
560 xdot_point s, e;
561 int v, have_s, have_e;
562 size_t cnt;
563 static const size_t sz = sizeof(sdot_op);
564
565 if (*pos == '\0') return NULL;
566
567 pos = countPoints (pos, &have_s, &s, &have_e, &e, &cnt);
568 if (pos == 0) return NULL;
569
570 xdot_point* pts = gv_calloc(cnt, sizeof(xdot_point));
571 if (have_s) {
572 v = storePoints (pos, pts+3);
573 pts[0] = pts[1] = s;
574 pts[2] = pts[3];
575 }
576 else
577 v = storePoints (pos, pts);
578 if (v) {
579 free (pts);
580 return NULL;
581 }
582
583 if (have_e) {
584 pts[cnt-1] = pts[cnt-2] = e;
585 pts[cnt-3] = pts[cnt-4];
586 }
587
588 xdot_op* op = gv_calloc(sz, sizeof(char));
591 op->u.bezier.cnt = cnt;
592 op->u.bezier.pts = pts;
593
594 xdot* xd = gv_alloc(sizeof(xdot));
595 xd->cnt = 1;
596 xd->sz = sz;
597 xd->ops = op;
598
599 return xd;
600}
601
602typedef void (*edgefn) (Agraph_t *, Agedge_t*, glCompColor);
603
604static void renderEdgesFn (Agraph_t * g, edgefn ef, int skipSelected)
605{
606 Agedge_t *e;
607 Agnode_t *v;
608 glCompColor c;
609
610 for (v = agfstnode(g); v; v = agnxtnode(g, v))
611 {
612 for (e = agfstout(g, v); e; e = agnxtout(g, e))
613 {
614 if ((ND_visible(agtail(e))==0) || (ND_visible(aghead(e))==0))
615 continue;
616
617 if(!object_color(e,&c)) {
618 continue;
619 }
620 if (ED_selected(e) && skipSelected)
621 continue;
622
623 ef (g, e, c);
624 }
625 }
626}
627
628static void edge_xdot (Agraph_t* g, Agedge_t* e, glCompColor c)
629{
630 (void)g;
631 (void)c;
632
633 xdot * x;
635 draw_xdot(x,0);
636 if(x)
637 freeXDot (x);
638}
639
640static void edge_seg (Agraph_t* g, Agedge_t* e, glCompColor c)
641{
642 Agsym_t* pos_attr = GN_pos(g);
643 glCompPoint posT; /*Tail position*/
644 glCompPoint posH; /*Head position*/
645
646 glColor4f(c.R,c.G,c.B,c.A);
647 posT=getPointFromStr(agxget(agtail(e), pos_attr));
648 posH=getPointFromStr(agxget(aghead(e), pos_attr));
649 draw_edge(&posT,&posH,getEdgeLength(e),0);
650 ED_posTail(e) = posT;
651 ED_posHead(e) = posH;
652}
653
655{
656 Agsym_t* pos_attr_e = GE_pos(g);
657 xdot * x;
658
659 glColor4f(c.R,c.G,c.B,c.A);
660 x = makeXDotSpline (agxget(e,pos_attr_e));
661 if (x) {
662 draw_xdot(x,0);
663 freeXDot (x);
664 }
665}
666
667static void renderEdges(Agraph_t * g)
668{
669 Agsym_t* pos_attr_e = GE_pos(g);
670 int drawSegs = !(pos_attr_e && view->drawSplines);
671 /*xdots tend to be drawn as background shapes,that is why they are being rendered before edges*/
672
673 renderEdgesFn (g, edge_xdot, 0);
674
675 if (drawSegs) {
676 glBegin(GL_LINES);
677 renderEdgesFn (g, edge_seg, 1);
678 glEnd();
679 }
680 else
682}
683
685{
686 Agnode_t *v;
687 glCompPoint pos;
688 Agsym_t* data_attr = GN_labelattribute(g);
689 Agsym_t* l_color_attr = GG_nodelabelcolor(g);
690 glCompColor c;
691
692 glCompColorxlate(&c,agxget(g,l_color_attr));
693
694 for (v = agfstnode(g); v; v = agnxtnode(g, v))
695 {
696 if(ND_visible(v)==0)
697 continue;
698 if(ND_selected(v)==1)
699 continue;
700
701 pos = ND_A(v);
702 glColor4f(c.R,c.G,c.B,c.A);
703 if(!data_attr)
704 glprintfglut(view->glutfont,pos.x,pos.y,pos.z,agnameof(v));
705 else
706 glprintfglut(view->glutfont,pos.x,pos.y,pos.z,agxget(v,data_attr));
707 }
708}
709
711{
712 Agedge_t *e;
713 Agnode_t *v;
714 glCompPoint posT;
715 glCompPoint posH;
716 Agsym_t* data_attr = GE_labelattribute(g);
717 Agsym_t* l_color_attr = GG_edgelabelcolor(g);
718 glCompColor c;
719
720 glCompColorxlate(&c,agxget(g,l_color_attr));
721
722 if(!data_attr || !l_color_attr)
723 return;
724
725 for (v = agfstnode(g); v; v = agnxtnode(g, v))
726 {
727 for (e = agfstout(g, v); e; e = agnxtout(g, e))
728 {
729
730 if (ND_visible(v)==0)
731 continue;
732
733 posT = ED_posTail(e);
734 posH = ED_posHead(e);
735 glColor4f(c.R,c.G,c.B,c.A);
736 float x = posH.x + (posT.x - posH.x) / 2;
737 float y = posH.y + (posT.y - posH.y) / 2;
738 float z = posH.z + (posT.z - posH.z) / 2;
739 glprintfglut(view->glutfont,x,y,z,agxget(e,data_attr));
740
741 }
742 }
743}
744
745
746
747
748
749static void cacheNodes(Agraph_t * g,topview* t)
750{
751 if (t->cache.node_id != UINT_MAX) // clean existing cache
752 glDeleteLists(t->cache.node_id,1);
753 t->cache.node_id=glGenLists(1);
754 glNewList(t->cache.node_id,GL_COMPILE);
755 renderNodes(g);
756 glEndList();
757
758
759
760
761}
762static void cacheEdges(Agraph_t * g,topview* t)
763{
764 if (t->cache.edge_id != UINT_MAX) // clean existing cache
765 glDeleteLists(t->cache.edge_id,1);
766 t->cache.edge_id=glGenLists(1);
767 glNewList(t->cache.edge_id,GL_COMPILE);
768 renderEdges(g);
769 glEndList();
770
771
772}
774{
775 if (t->cache.seledge_id != UINT_MAX) // clean existing cache
776 glDeleteLists(t->cache.seledge_id,1);
777 t->cache.seledge_id=glGenLists(1);
778 glNewList(t->cache.seledge_id,GL_COMPILE);
780 glEndList();
781
782
783}
785{
786 if (t->cache.selnode_id != UINT_MAX) // clean existing cache
787 glDeleteLists(t->cache.selnode_id,1);
788 t->cache.selnode_id=glGenLists(1);
789 glNewList(t->cache.selnode_id,GL_COMPILE);
791 glEndList();
792}
794{
795 if (t->cache.nodelabel_id != UINT_MAX) // clean existing cache
796 glDeleteLists(t->cache.nodelabel_id,1);
797 t->cache.nodelabel_id=glGenLists(1);
798 glNewList(t->cache.nodelabel_id,GL_COMPILE);
800 glEndList();
801}
803{
804 if (t->cache.edgelabel_id != UINT_MAX) // clean existing cache
805 glDeleteLists(t->cache.edgelabel_id,1);
806 t->cache.edgelabel_id=glGenLists(1);
807 glNewList(t->cache.edgelabel_id,GL_COMPILE);
809 glEndList();
810}
811
813{
814 Agnode_t *v;
815 Agedge_t *e;
816 float eLength=0;
817 float totalELength=0;
818
819 t->Nodecount=0;
820 t->maxedgelen=0;
821 t->minedgelen=-1;
822
823 t->global_z=0;
824 t->sel.selPoly = (glCompPoly_t){0};
825
826 if(!t)
827 return ;
828 /*Node Loop*/
829 for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
830 for (e = agfstout(g, v); e; e = agnxtout(g, e))
831 {
832 eLength=getEdgeLength(e);
833 if((t->minedgelen == -1) || (t->minedgelen > eLength))
834 t->minedgelen=eLength;
835 if(eLength > t->maxedgelen)
836 t->maxedgelen=eLength;
837 totalELength += eLength;
838 }
839 t->Nodecount++;
840
841 }
842 aginit(g, AGNODE, "nodeRec", sizeof(nodeRec), false);
843 aginit(g, AGEDGE, "edgeRec", sizeof(edgeRec), false);
844
846 view->Topview=t;
847
848
849 /*render nodes once to get set some attributes set,THIS IS A HACK, FIX IT*/
850 renderNodes(g);
851 cacheEdges(g,t);
853 cacheNodes(g,t);
855 cacheEdgeLabels(g,t);
856 cacheNodeLabels(g,t);
857}
859{
860 /*create attribute list*/
862
863 // set topological fisheye to NULL
864 rv->fisheyeParams.h = NULL;
865
866 rv->fisheyeParams.active = 0;
867 rv->cache.node_id = UINT_MAX;
868 rv->cache.selnode_id = UINT_MAX;
869 rv->cache.edge_id = UINT_MAX;
870 rv->cache.seledge_id = UINT_MAX;
871 rv->sel.selectEdges = false;
872 rv->sel.selectNodes = true;
873
874 updateSmGraph(g,rv);
875}
876
878{
879 /*
880 we like to have blending affect where node and edge overlap
881 to achive this depth test should be turned off.
882 */
883
884 glEnable(GL_POINT_SMOOTH);
885 glEnable(GL_DEPTH_TEST);
886 glEnable(GL_DEPTH);
887
888 if(view->drawedges)
889 {
890 glCallList(t->cache.edge_id);
891 glCallList(t->cache.seledge_id);
893 {
894 if(view->zoom*-1 < t->fitin_zoom /(float)view->labelnumberofnodes*-1)
895 glCallList(t->cache.edgelabel_id);
896
897 }
898 }
899 if(view->drawnodes)
900 {
901 glPointSize(view->nodeScale*t->fitin_zoom/view->zoom);
902 glCallList(t->cache.node_id);
903 glCallList(t->cache.selnode_id);
905 {
906 if(view->zoom*-1 < t->fitin_zoom /(float)view->labelnumberofnodes*-1)
907 glCallList(t->cache.nodelabel_id);
908 }
909 }
910
911}
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
static void * gv_alloc(size_t size)
Definition alloc.h:47
abstract graph C library, Cgraph API
#define right(i)
Definition closest.c:79
@ RGBA_DOUBLE
Definition color.h:27
COLORPROCS_API char * setColorScheme(const char *s)
Definition colxlate.c:395
void colorxlate(char *str, agxbuf *buf)
Definition colxlate.c:46
bool mapbool(const char *p)
Definition utils.c:335
void drawCircle(float x, float y, float radius, float zdepth)
Definition draw.c:384
drawfunc_t OpFns[]
Definition draw.c:400
#define left
Definition dthdr.h:12
#define A(n, t)
Definition expr.h:76
attr_list * load_attr_list(Agraph_t *g)
void glprintfglut(void *font, float xpos, float ypos, float zpos, char *bf)
Definition glcompfont.c:31
void free(void *)
edge
Definition gmlparse.y:240
node NULL
Definition grammar.y:163
static int cnt(Dict_t *d, Dtlink_t **set)
Definition graph.c:210
char * agget(void *obj, char *name)
Definition attr.c:439
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:455
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:24
#define agtail(e)
Definition cgraph.h:880
#define aghead(e)
Definition cgraph.h:881
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:39
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:47
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:40
Agraph_t * agraphof(void *obj)
Definition obj.c:185
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:158
#define AGTYPE(obj)
returns AGRAPH, AGNODE, or AGEDGE depending on the type of the object
Definition cgraph.h:216
int agobjkind(void *obj)
Definition obj.c:252
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
@ AGRAPH
Definition cgraph.h:207
void aginit(Agraph_t *g, int kind, const char *rec_name, int rec_size, int move_to_front)
attach new records to objects of specified kind
Definition rec.c:170
replacements for ctype.h functions
static bool gv_isspace(int c)
Definition gv_ctype.h:55
static xdot_state_t * xd
static int z
#define B
Definition hierarchy.c:117
textitem scanner parser str
Definition htmlparse.y:224
static Agedge_t * top(edge_stack_t *sp)
Definition tred.c:73
static int * ps
Definition lu.c:51
#define alpha
Definition shapes.c:4058
float getAttrFloat(Agraph_t *g, void *obj, char *attr_name, float def)
int getAttrInt(Agraph_t *g, void *obj, char *attr_name, int def)
int getAttrBool(Agraph_t *g, void *obj, char *attr_name, int def)
glCompPoint getPointFromStr(const char *str)
char * getAttrStr(Agraph_t *g, void *obj, char *attr_name, char *def)
int l_int(void *obj, Agsym_t *attr, int def)
float l_float(void *obj, Agsym_t *attr, float def)
void getcolorfromschema(const colorschemaset sc, float l, float maxl, glCompColor *c)
Definition viewport.c:550
ViewInfo * view
Definition viewport.c:37
#define GG_labelattribute(g)
Definition smyrnadefs.h:202
#define GG_nodelabelcolor(g)
Definition smyrnadefs.h:200
#define GE_pos(g)
Definition smyrnadefs.h:203
#define ED_posHead(e)
Definition smyrnadefs.h:177
#define ND_TVref(n)
Definition smyrnadefs.h:166
#define GN_labelattribute(g)
Definition smyrnadefs.h:201
#define GN_selected(g)
Definition smyrnadefs.h:199
#define ED_posTail(e)
Definition smyrnadefs.h:176
#define ND_size(n)
Definition smyrnadefs.h:165
#define GG_edgelabelcolor(g)
Definition smyrnadefs.h:206
#define ND_printLabel(n)
Definition smyrnadefs.h:163
#define GE_labelattribute(g)
Definition smyrnadefs.h:207
#define GE_visible(g)
Definition smyrnadefs.h:204
#define GN_size(g)
Definition smyrnadefs.h:197
#define ED_selected(e)
Definition smyrnadefs.h:175
#define ND_selected(n)
Definition smyrnadefs.h:162
#define ND_A(n)
Definition smyrnadefs.h:164
#define GN_visible(g)
Definition smyrnadefs.h:198
#define GN_pos(g)
Definition smyrnadefs.h:196
#define DEG2RAD
Definition smyrnadefs.h:56
#define ND_visible(n)
Definition smyrnadefs.h:161
graph or subgraph
Definition cgraph.h:425
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:637
float bdxLeft
Definition smyrnadefs.h:290
topview * Topview
Definition smyrnadefs.h:313
int drawnodes
Definition smyrnadefs.h:323
Agraph_t ** g
Definition smyrnadefs.h:296
int drawnodelabels
Definition smyrnadefs.h:325
int labelnumberofnodes
Definition smyrnadefs.h:332
float bdyTop
Definition smyrnadefs.h:290
int drawedges
Definition smyrnadefs.h:324
float nodeScale
Definition smyrnadefs.h:347
colorschemaset colschms
Definition smyrnadefs.h:340
int activeGraph
Definition smyrnadefs.h:300
glCompColor selectedNodeColor
Definition smyrnadefs.h:274
int drawSplines
Definition smyrnadefs.h:339
float bdxRight
Definition smyrnadefs.h:291
float bdyBottom
Definition smyrnadefs.h:291
float zoom
Definition smyrnadefs.h:258
int drawedgelabels
Definition smyrnadefs.h:326
void * glutfont
Definition smyrnadefs.h:329
glCompPoly_t selPoly
Definition smyrnadefs.h:214
bool selectEdges
Definition smyrnadefs.h:216
bool selectNodes
Definition smyrnadefs.h:215
xdot_kind kind
Definition xdot.h:136
xdot_polyline bezier
Definition xdot.h:141
union _xdot_op::@125 u
drawfunc_t drawfunc
Definition xdot.h:150
double RGBA[4]
Definition color.h:32
union color_s::@71 u
xdot_op op
Definition smyrnadefs.h:86
double global_z
Definition smyrnadefs.h:238
Hierarchy * h
Definition smyrnadefs.h:226
topviewcache cache
Definition smyrnadefs.h:241
int active
Definition smyrnadefs.h:222
struct topview::@55 fisheyeParams
size_t Nodecount
Definition smyrnadefs.h:220
float minedgelen
Definition smyrnadefs.h:235
attr_list * attributes
Definition smyrnadefs.h:239
float fitin_zoom
Definition smyrnadefs.h:236
selection sel
Definition smyrnadefs.h:242
float maxedgelen
Definition smyrnadefs.h:234
unsigned selnode_id
Definition smyrnadefs.h:116
unsigned nodelabel_id
Definition smyrnadefs.h:118
unsigned node_id
Definition smyrnadefs.h:114
unsigned edge_id
Definition smyrnadefs.h:115
unsigned seledge_id
Definition smyrnadefs.h:117
unsigned edgelabel_id
Definition smyrnadefs.h:119
double x
Definition xdot.h:82
double z
Definition xdot.h:82
double y
Definition xdot.h:82
size_t cnt
Definition xdot.h:90
xdot_point * pts
Definition xdot.h:91
Definition xdot.h:155
xdot_op * ops
Definition xdot.h:158
size_t cnt
Definition xdot.h:156
static char * skipNWS(char *p)
static int storePoints(char *pos, xdot_point *ps)
void cacheSelectedEdges(Agraph_t *g, topview *t)
static void edge_seg(Agraph_t *g, Agedge_t *e, glCompColor c)
static char * readPoint(char *p, xdot_point *pt)
static float getEdgeLength(Agedge_t *edge)
static void renderSelectedNodes(Agraph_t *g)
static void draw_edge(glCompPoint *posT, glCompPoint *posH, float length, int deg)
static glCompPoint getEdgeHead(Agedge_t *edge)
static xdot * parseXdotwithattrs(void *e)
static void edge_xdot(Agraph_t *g, Agedge_t *e, glCompColor c)
void updateSmGraph(Agraph_t *g, topview *t)
static char * countPoints(char *pos, int *have_sp, xdot_point *sp, int *have_ep, xdot_point *ep, size_t *cntp)
static void cacheNodeLabels(Agraph_t *g, topview *t)
static void cacheEdgeLabels(Agraph_t *g, topview *t)
static void draw_xdot(xdot *x, double base_z)
void(* edgefn)(Agraph_t *, Agedge_t *, glCompColor)
static xdot * makeXDotSpline(char *pos)
static void edge_spline(Agraph_t *g, Agedge_t *e, glCompColor c)
static void renderNodes(Agraph_t *g)
static char * labelOf(Agraph_t *g, Agnode_t *v)
static void renderEdges(Agraph_t *g)
static void renderEdgeLabels(Agraph_t *g)
void renderSmGraph(topview *t)
static void cacheEdges(Agraph_t *g, topview *t)
static void glCompColorxlate(glCompColor *c, const char *str)
static void set_boundaries(Agraph_t *g)
static void renderSelectedEdges(Agraph_t *g)
static int visible(Agsym_t *attr, void *obj)
static void cacheNodes(Agraph_t *g, topview *t)
static char * skipWS(char *p)
static void renderEdgesFn(Agraph_t *g, edgefn ef, int skipSelected)
void initSmGraph(Agraph_t *g, topview *rv)
static void renderNodeLabels(Agraph_t *g)
static glCompPoint getEdgeTail(Agedge_t *edge)
void cacheSelectedNodes(Agraph_t *g, topview *t)
static int object_color(void *obj, glCompColor *c)
graphs, nodes and edges info: Agraphinfo_t, Agnodeinfo_t and Agedgeinfo_t
Definition grammar.c:93
xdot * parseXDotFOn(char *s, drawfunc_t fns[], size_t sz, xdot *x)
Definition xdot.c:343
void freeXDot(xdot *x)
Definition xdot.c:782
parsing and deparsing of xdot operations
@ xop_bezier
Definition xdot.h:124
@ xd_unfilled_bezier
Definition xdot.h:114