Graphviz 13.0.0~dev.20250402.0110
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 objType;
143 float Alpha = 1;
144 Agsym_t* vis;
145
146 objType=AGTYPE(obj);
147
148 if(objType==AGEDGE) {
149 Alpha=getAttrFloat(g,objg,"defaultedgealpha",1);
150 vis = GE_visible (objg);
151 }
152 else {
153 assert(objType == AGNODE);
154 Alpha=getAttrFloat(g,objg,"defaultnodealpha",1);
155 vis = GN_visible (objg);
156 }
157 if (!visible(vis,obj))
158 return 0;
159
160 char *previous_color_scheme = setColorScheme(agget (obj, "colorscheme"));
161 /*get objects's color attribute */
162 const char *const bf = getAttrStr(g,obj,"color",NULL);
163 if(bf && (*bf)) {
164 colorxlate(bf, &cl, RGBA_DOUBLE);
165 c->R = cl.u.RGBA[0];
166 c->G = cl.u.RGBA[1];
167 c->B = cl.u.RGBA[2];
168 c->A = cl.u.RGBA[3]*Alpha;
169 }
170 else
171 {
172 if(objType==AGEDGE)
174 else
175 {
176 colorxlate(agget(g, "defaultnodecolor"),&cl, RGBA_DOUBLE);
177 c->R = cl.u.RGBA[0];
178 c->G = cl.u.RGBA[1];
179 c->B = cl.u.RGBA[2];
180 c->A = cl.u.RGBA[3];
181 }
182 c->A *= Alpha;
183
184 }
185
186 char *color_scheme = setColorScheme(previous_color_scheme);
187 free(color_scheme);
188 free(previous_color_scheme);
189
190 return 1;
191}
192
193
194/*
195 draws multi edges , single edges
196 this function assumes glBegin(GL_LINES) has been called
197*/
198static void draw_edge(glCompPoint *posT, glCompPoint *posH, float length,
199 int deg) {
200 double alpha, R, ITERANGLE;
201 double X1, Y1, X2, Y2;
202
203 if (deg) {
204 R = length / 20.0;
205 if ((deg / 2) * 2 != deg) /*odd */
206 ITERANGLE = (deg) * 15.00 * -1;
207 else
208 ITERANGLE = (deg) * 15.00;
209 ITERANGLE = DEG2RAD * ITERANGLE;
210
211 alpha = atan((posH->y - posT->y) / (posH->x - posT->x));
212 if (posT->x > posH->x)
213 ITERANGLE = 180 * DEG2RAD - ITERANGLE;
214 X1 = R * cos(alpha - ITERANGLE) + posT->x;
215 Y1 = R * sin(alpha - ITERANGLE) + posT->y;
216 X2 = R * cos(alpha - (180 * DEG2RAD - ITERANGLE)) + posH->x;
217 Y2 = R * sin(alpha - (180 * DEG2RAD - ITERANGLE)) + posH->y;
218 glVertex3f(posT->x, posT->y, posT->z);
219 glVertex3f(X1, Y1, posT->z);
220 glVertex3f(X1, Y1, posT->z);
221 glVertex3f(X2, Y2, posH->z);
222 glVertex3f(X2, Y2, posH->z);
223 glVertex3f(posH->x, posH->y, posH->z);
224 } else {
225 glVertex3f(posT->x, posT->y, posT->z);
226 glVertex3f(posH->x, posH->y, posH->z);
227
228 }
229
230}
231
232static char* labelOf (Agraph_t* g, Agnode_t* v)
233{
234 char* lbl;
235 char* s;
236
237 Agsym_t* data_attr = GN_labelattribute(g);
238 if (data_attr)
239 s = agxget (v, data_attr);
240 else
241 s = agxget (g, GG_labelattribute(g));
242 if ((*s == '\0') || !strcmp (s, "name"))
243 lbl = agnameof (v);
244 else {
245 lbl = agget (v, s);
246 if (!lbl) lbl = "";
247 }
248 return lbl;
249}
250
252{
253 Agnode_t *v;
254 xdot * x;
255 glCompPoint pos;
256 Agsym_t* l_color_attr = GG_nodelabelcolor(g);
257 glCompColor c;
258 int defaultNodeShape;
259 float nodeSize;
260
261 glCompColorxlate(&c,agxget(g,l_color_attr));
262
263 defaultNodeShape=getAttrBool(g,g,"defaultnodeshape",0);
264 if(defaultNodeShape==0)
265 glBegin(GL_POINTS);
266
267 for (v = agfstnode(g); v; v = agnxtnode(g, v))
268 {
269 if(!ND_selected(v))
270 continue;
272 draw_xdot(x,-1);
273 if(x)
274 freeXDot (x);
275 }
276
277 for (v = agfstnode(g); v; v = agnxtnode(g, v))
278 {
279 if(!ND_selected(v))
280 continue;
282 pos = ND_A(v);
283 nodeSize = ND_size(v);
284
285 if (defaultNodeShape == 0)
286 glVertex3f(pos.x, pos.y, pos.z + 0.001f);
287 else if (defaultNodeShape == 1)
288 drawCircle(pos.x, pos.y, nodeSize, pos.z + 0.001f);
289 }
290 if(defaultNodeShape==0)
291 glEnd();
292 for (v = agfstnode(g); v; v = agnxtnode(g, v))
293 {
294 if(!ND_selected(v))
295 continue;
296 if (ND_printLabel(v)==1)
297 {
298 pos = ND_A(v);
299 glColor4f(c.R, c.G,c.B, c.A);
300 glprintfglut(view->glutfont, pos.x, pos.y, pos.z + 0.002f, labelOf(g, v));
301 }
302 }
303}
304
305
306
307static void renderNodes(Agraph_t * g)
308{
309 Agnode_t *v;
310 glCompPoint pos;
311 Agsym_t* pos_attr = GN_pos(g);
312 Agsym_t* size_attr = GN_size(g);
313 Agsym_t* selected_attr = GN_selected(g);
314 int defaultNodeShape;
315 float nodeSize;
316 glCompColor c;
317 xdot * x;
318 int ind;
319
320 defaultNodeShape=getAttrInt(g,g,"defaultnodeshape",0);
321
323 if (x) {
324 draw_xdot(x, -0.2);
325 freeXDot (x);
326 }
327 for (v = agfstnode(g); v; v = agnxtnode(g, v))
328 {
329 if (!object_color(v, &(glCompColor){0}))
330 continue;
332 draw_xdot(x, -0.1);
333
334 if(x)
335 freeXDot (x);
336 }
337
338 if(defaultNodeShape==0)
339 glBegin(GL_POINTS);
340
341 ind=0;
342
343 for (v = agfstnode(g); v; v = agnxtnode(g, v))
344 {
345 ND_TVref(v) = ind;
346 if(!object_color(v,&c))
347 {
348 ND_visible(v) = 0;
349 continue;
350 }
351 else
352 ND_visible(v) = 1;
353
354 if(l_int(v, selected_attr,0))
355 {
356 ND_selected(v) = 1;
357 }
358 glColor4f(c.R,c.G,c.B,c.A);
359 pos=getPointFromStr(agxget(v, pos_attr));
360 nodeSize = l_float(v, size_attr, 0);
361
362 ND_A(v) = pos;
363
364 if (nodeSize > 0)
365 nodeSize=nodeSize*view->nodeScale;
366 else
367 nodeSize=view->nodeScale;
368 if(defaultNodeShape==0)
369 nodeSize=1;
370 ND_size(v) = nodeSize;
371 if (defaultNodeShape == 0)
372 glVertex3f(pos.x,pos.y,pos.z);
373 else if (defaultNodeShape == 1)
374 drawCircle(pos.x,pos.y,nodeSize,pos.z);
375 ind++;
376 }
377 if(defaultNodeShape==0)
378 glEnd();
379}
380
381
383{
384
385 Agedge_t *e;
386 Agnode_t *v;
387 xdot * x;
388 glCompPoint posT; /*Tail position*/
389 glCompPoint posH; /*Head position*/
390 /*xdots tend to be drawn as background shapes,that is why they are being rendered before edges*/
391
392 for (v = agfstnode(g); v; v = agnxtnode(g, v))
393 {
394 for (e = agfstout(g, v); e; e = agnxtout(g, e))
395 {
396 if(!ED_selected(e))
397 continue;
398 if (!object_color(e, &(glCompColor){0}))
399 continue;
400
402 draw_xdot(x,0);
403 if(x)
404 freeXDot (x);
405 }
406 }
407
408 glBegin(GL_LINES);
409 for (v = agfstnode(g); v; v = agnxtnode(g, v))
410 {
411 for (e = agfstout(g, v); e; e = agnxtout(g, e))
412 {
413 if(!ED_selected(e))
414 continue;
415
416 if (!object_color(e, &(glCompColor){0}))
417 continue;
418 glColor4f(1,0,0,1);
419 posT = ED_posTail(e);
420 posH = ED_posHead(e);
421 posT.z +=0.01f;
422 posH.z +=0.01f;
423 draw_edge(&posT,&posH,getEdgeLength(e),0);
424 }
425 }
426 glEnd();
427}
428
429/* skipWS:
430 * Skip whitespace
431 */
432static char* skipWS (char* p)
433{
434 while (gv_isspace(*p)) p++;
435 return p;
436}
437
438/* skipNWS:
439 * Skip non-whitespace
440 */
441static char* skipNWS (char* p)
442{
443 while (*p && !gv_isspace(*p)) p++;
444 return p;
445}
446
447/* readPoint:
448 * Parse x,y[,z] and store in pt.
449 * If z is not specified, set to 0.
450 * Return pointer to next character after reading the point.
451 * Return NULL on error.
452 */
453static char* readPoint (char* p, xdot_point* pt)
454{
455 char* endp;
456
457 pt->z = 0;
458 pt->x = strtod (p, &endp);
459 if (p == endp) {
460 return 0;
461 }
462 else
463 p = endp;
464 if (*p == ',') p++;
465 else return 0;
466
467 pt->y = strtod (p, &endp);
468 if (p == endp) {
469 return 0;
470 }
471 else
472 p = endp;
473 if ((*p == ' ') || (*p == '\0')) return p;
474 else if (*p == ',') p++;
475 else return 0;
476
477 pt->z = strtod (p, &endp);
478 if (p == endp) {
479 return 0;
480 }
481 else
482 return endp;
483}
484
485/* countPoints:
486 * count number of points in pos attribute; store in cntp;
487 * check for e and s points; store if found and increment number of
488 * points by 3 for each.
489 * return start of point list (skip over e and s points).
490 * return NULL on failure
491 */
492static char *countPoints(char *pos, int *have_sp, xdot_point *sp, int *have_ep,
493 xdot_point *ep, size_t *cntp) {
494 size_t cnt = 0;
495 char* p;
496
497 pos = skipWS (pos);
498 if (*pos == 's') {
499 if ((pos = readPoint (pos+2, sp))) {
500 *have_sp = 1;
501 cnt += 3;
502 }
503 else
504 return 0;
505 }
506 else
507 *have_sp = 0;
508
509 pos = skipWS (pos);
510 if (*pos == 'e') {
511 if ((pos = readPoint (pos+2, ep))) {
512 *have_ep = 1;
513 cnt += 3;
514 }
515 else
516 return 0;
517 }
518 else
519 *have_ep = 0;
520
521 p = pos = skipWS (pos);
522
523 while (*p) {
524 cnt++;
525 p = skipNWS (p);
526 p = skipWS (p);
527 }
528 *cntp = cnt;
529
530 return pos;
531}
532
533/* storePoints:
534 * read comma-separated list of points
535 * and store them in ps
536 * Assumes enough storage is available.
537 * return -1 on error
538 */
539static int storePoints (char* pos, xdot_point* ps)
540{
541
542 while (*pos) {
543 if ((pos = readPoint (pos, ps))) {
544 ps++;
545 pos = skipWS(pos);
546 }
547 else
548 return -1;
549 }
550 return 0;
551}
552
553/* makeXDotSpline:
554 * Generate an xdot representation of an edge's pos attribute
555 */
556static xdot* makeXDotSpline (char* pos)
557{
558 xdot_point s, e;
559 int v, have_s, have_e;
560 size_t cnt;
561 static const size_t sz = sizeof(sdot_op);
562
563 if (*pos == '\0') return NULL;
564
565 pos = countPoints (pos, &have_s, &s, &have_e, &e, &cnt);
566 if (pos == 0) return NULL;
567
568 xdot_point* pts = gv_calloc(cnt, sizeof(xdot_point));
569 if (have_s) {
570 v = storePoints (pos, pts+3);
571 pts[0] = pts[1] = s;
572 pts[2] = pts[3];
573 }
574 else
575 v = storePoints (pos, pts);
576 if (v) {
577 free (pts);
578 return NULL;
579 }
580
581 if (have_e) {
582 pts[cnt-1] = pts[cnt-2] = e;
583 pts[cnt-3] = pts[cnt-4];
584 }
585
586 xdot_op* op = gv_calloc(sz, sizeof(char));
589 op->u.bezier.cnt = cnt;
590 op->u.bezier.pts = pts;
591
592 xdot* xd = gv_alloc(sizeof(xdot));
593 xd->cnt = 1;
594 xd->sz = sz;
595 xd->ops = op;
596
597 return xd;
598}
599
600typedef void (*edgefn) (Agraph_t *, Agedge_t*, glCompColor);
601
602static void renderEdgesFn (Agraph_t * g, edgefn ef, int skipSelected)
603{
604 Agedge_t *e;
605 Agnode_t *v;
606 glCompColor c;
607
608 for (v = agfstnode(g); v; v = agnxtnode(g, v))
609 {
610 for (e = agfstout(g, v); e; e = agnxtout(g, e))
611 {
612 if ((ND_visible(agtail(e))==0) || (ND_visible(aghead(e))==0))
613 continue;
614
615 if(!object_color(e,&c)) {
616 continue;
617 }
618 if (ED_selected(e) && skipSelected)
619 continue;
620
621 ef (g, e, c);
622 }
623 }
624}
625
626static void edge_xdot (Agraph_t* g, Agedge_t* e, glCompColor c)
627{
628 (void)g;
629 (void)c;
630
631 xdot * x;
633 draw_xdot(x,0);
634 if(x)
635 freeXDot (x);
636}
637
638static void edge_seg (Agraph_t* g, Agedge_t* e, glCompColor c)
639{
640 Agsym_t* pos_attr = GN_pos(g);
641 glCompPoint posT; /*Tail position*/
642 glCompPoint posH; /*Head position*/
643
644 glColor4f(c.R,c.G,c.B,c.A);
645 posT=getPointFromStr(agxget(agtail(e), pos_attr));
646 posH=getPointFromStr(agxget(aghead(e), pos_attr));
647 draw_edge(&posT,&posH,getEdgeLength(e),0);
648 ED_posTail(e) = posT;
649 ED_posHead(e) = posH;
650}
651
653{
654 Agsym_t* pos_attr_e = GE_pos(g);
655 xdot * x;
656
657 glColor4f(c.R,c.G,c.B,c.A);
658 x = makeXDotSpline (agxget(e,pos_attr_e));
659 if (x) {
660 draw_xdot(x,0);
661 freeXDot (x);
662 }
663}
664
665static void renderEdges(Agraph_t * g)
666{
667 Agsym_t* pos_attr_e = GE_pos(g);
668 int drawSegs = !(pos_attr_e && view->drawSplines);
669 /*xdots tend to be drawn as background shapes,that is why they are being rendered before edges*/
670
671 renderEdgesFn (g, edge_xdot, 0);
672
673 if (drawSegs) {
674 glBegin(GL_LINES);
675 renderEdgesFn (g, edge_seg, 1);
676 glEnd();
677 }
678 else
680}
681
683{
684 Agnode_t *v;
685 glCompPoint pos;
686 Agsym_t* data_attr = GN_labelattribute(g);
687 Agsym_t* l_color_attr = GG_nodelabelcolor(g);
688 glCompColor c;
689
690 glCompColorxlate(&c,agxget(g,l_color_attr));
691
692 for (v = agfstnode(g); v; v = agnxtnode(g, v))
693 {
694 if(ND_visible(v)==0)
695 continue;
696 if(ND_selected(v)==1)
697 continue;
698
699 pos = ND_A(v);
700 glColor4f(c.R,c.G,c.B,c.A);
701 if(!data_attr)
702 glprintfglut(view->glutfont,pos.x,pos.y,pos.z,agnameof(v));
703 else
704 glprintfglut(view->glutfont,pos.x,pos.y,pos.z,agxget(v,data_attr));
705 }
706}
707
709{
710 Agedge_t *e;
711 Agnode_t *v;
712 glCompPoint posT;
713 glCompPoint posH;
714 Agsym_t* data_attr = GE_labelattribute(g);
715 Agsym_t* l_color_attr = GG_edgelabelcolor(g);
716 glCompColor c;
717
718 glCompColorxlate(&c,agxget(g,l_color_attr));
719
720 if(!data_attr || !l_color_attr)
721 return;
722
723 for (v = agfstnode(g); v; v = agnxtnode(g, v))
724 {
725 for (e = agfstout(g, v); e; e = agnxtout(g, e))
726 {
727
728 if (ND_visible(v)==0)
729 continue;
730
731 posT = ED_posTail(e);
732 posH = ED_posHead(e);
733 glColor4f(c.R,c.G,c.B,c.A);
734 float x = posH.x + (posT.x - posH.x) / 2;
735 float y = posH.y + (posT.y - posH.y) / 2;
736 float z = posH.z + (posT.z - posH.z) / 2;
737 glprintfglut(view->glutfont,x,y,z,agxget(e,data_attr));
738
739 }
740 }
741}
742
743
744
745
746
747static void cacheNodes(Agraph_t * g,topview* t)
748{
749 if (t->cache.node_id != UINT_MAX) // clean existing cache
750 glDeleteLists(t->cache.node_id,1);
751 t->cache.node_id=glGenLists(1);
752 glNewList(t->cache.node_id,GL_COMPILE);
753 renderNodes(g);
754 glEndList();
755
756
757
758
759}
760static void cacheEdges(Agraph_t * g,topview* t)
761{
762 if (t->cache.edge_id != UINT_MAX) // clean existing cache
763 glDeleteLists(t->cache.edge_id,1);
764 t->cache.edge_id=glGenLists(1);
765 glNewList(t->cache.edge_id,GL_COMPILE);
766 renderEdges(g);
767 glEndList();
768
769
770}
772{
773 if (t->cache.seledge_id != UINT_MAX) // clean existing cache
774 glDeleteLists(t->cache.seledge_id,1);
775 t->cache.seledge_id=glGenLists(1);
776 glNewList(t->cache.seledge_id,GL_COMPILE);
778 glEndList();
779
780
781}
783{
784 if (t->cache.selnode_id != UINT_MAX) // clean existing cache
785 glDeleteLists(t->cache.selnode_id,1);
786 t->cache.selnode_id=glGenLists(1);
787 glNewList(t->cache.selnode_id,GL_COMPILE);
789 glEndList();
790}
792{
793 if (t->cache.nodelabel_id != UINT_MAX) // clean existing cache
794 glDeleteLists(t->cache.nodelabel_id,1);
795 t->cache.nodelabel_id=glGenLists(1);
796 glNewList(t->cache.nodelabel_id,GL_COMPILE);
798 glEndList();
799}
801{
802 if (t->cache.edgelabel_id != UINT_MAX) // clean existing cache
803 glDeleteLists(t->cache.edgelabel_id,1);
804 t->cache.edgelabel_id=glGenLists(1);
805 glNewList(t->cache.edgelabel_id,GL_COMPILE);
807 glEndList();
808}
809
811{
812 Agnode_t *v;
813 Agedge_t *e;
814 float eLength=0;
815 float totalELength=0;
816
817 t->Nodecount=0;
818 t->maxedgelen=0;
819
820 t->global_z=0;
821 t->sel.selPoly = (glCompPoly_t){0};
822
823 if(!t)
824 return ;
825 /*Node Loop*/
826 for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
827 for (e = agfstout(g, v); e; e = agnxtout(g, e))
828 {
829 eLength=getEdgeLength(e);
830 if(eLength > t->maxedgelen)
831 t->maxedgelen=eLength;
832 totalELength += eLength;
833 }
834 t->Nodecount++;
835
836 }
837 aginit(g, AGNODE, "nodeRec", sizeof(nodeRec), false);
838 aginit(g, AGEDGE, "edgeRec", sizeof(edgeRec), false);
839
841 view->Topview=t;
842
843
844 /*render nodes once to get set some attributes set,THIS IS A HACK, FIX IT*/
845 renderNodes(g);
846 cacheEdges(g,t);
848 cacheNodes(g,t);
850 cacheEdgeLabels(g,t);
851 cacheNodeLabels(g,t);
852}
854{
855 /*create attribute list*/
857
858 // set topological fisheye to NULL
859 rv->fisheyeParams.h = NULL;
860
861 rv->fisheyeParams.active = 0;
862 rv->cache.node_id = UINT_MAX;
863 rv->cache.selnode_id = UINT_MAX;
864 rv->cache.edge_id = UINT_MAX;
865 rv->cache.seledge_id = UINT_MAX;
866 rv->sel.selectEdges = false;
867 rv->sel.selectNodes = true;
868
869 updateSmGraph(g,rv);
870}
871
873{
874 /*
875 we like to have blending affect where node and edge overlap
876 to achive this depth test should be turned off.
877 */
878
879 glEnable(GL_POINT_SMOOTH);
880 glEnable(GL_DEPTH_TEST);
881 glEnable(GL_DEPTH);
882
883 if(view->drawedges)
884 {
885 glCallList(t->cache.edge_id);
886 glCallList(t->cache.seledge_id);
888 {
889 if(view->zoom*-1 < t->fitin_zoom /(float)view->labelnumberofnodes*-1)
890 glCallList(t->cache.edgelabel_id);
891
892 }
893 }
894 if(view->drawnodes)
895 {
896 glPointSize(view->nodeScale*t->fitin_zoom/view->zoom);
897 glCallList(t->cache.node_id);
898 glCallList(t->cache.selnode_id);
900 {
901 if(view->zoom*-1 < t->fitin_zoom /(float)view->labelnumberofnodes*-1)
902 glCallList(t->cache.nodelabel_id);
903 }
904 }
905
906}
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:337
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:239
node NULL
Definition grammar.y:163
static int cnt(Dict_t *d, Dtlink_t **set)
Definition graph.c:200
char * agget(void *obj, char *name)
Definition attr.c:472
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:482
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:24
#define agtail(e)
Definition cgraph.h:992
#define aghead(e)
Definition cgraph.h:993
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:143
#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:118
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:548
ViewInfo * view
Definition viewport.c:37
#define GG_labelattribute(g)
Definition smyrnadefs.h:201
#define GG_nodelabelcolor(g)
Definition smyrnadefs.h:199
#define GE_pos(g)
Definition smyrnadefs.h:202
#define ED_posHead(e)
Definition smyrnadefs.h:176
#define ND_TVref(n)
Definition smyrnadefs.h:165
#define GN_labelattribute(g)
Definition smyrnadefs.h:200
#define GN_selected(g)
Definition smyrnadefs.h:198
#define ED_posTail(e)
Definition smyrnadefs.h:175
#define ND_size(n)
Definition smyrnadefs.h:164
#define GG_edgelabelcolor(g)
Definition smyrnadefs.h:205
#define ND_printLabel(n)
Definition smyrnadefs.h:162
#define GE_labelattribute(g)
Definition smyrnadefs.h:206
#define GE_visible(g)
Definition smyrnadefs.h:203
#define GN_size(g)
Definition smyrnadefs.h:196
#define ED_selected(e)
Definition smyrnadefs.h:174
#define ND_selected(n)
Definition smyrnadefs.h:161
#define ND_A(n)
Definition smyrnadefs.h:163
#define GN_visible(g)
Definition smyrnadefs.h:197
#define GN_pos(g)
Definition smyrnadefs.h:195
#define DEG2RAD
Definition smyrnadefs.h:56
#define ND_visible(n)
Definition smyrnadefs.h:160
graph or subgraph
Definition cgraph.h:424
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:651
float bdxLeft
Definition smyrnadefs.h:289
topview * Topview
Definition smyrnadefs.h:312
int drawnodes
Definition smyrnadefs.h:322
Agraph_t ** g
Definition smyrnadefs.h:295
int drawnodelabels
Definition smyrnadefs.h:324
int labelnumberofnodes
Definition smyrnadefs.h:331
float bdyTop
Definition smyrnadefs.h:289
int drawedges
Definition smyrnadefs.h:323
float nodeScale
Definition smyrnadefs.h:346
colorschemaset colschms
Definition smyrnadefs.h:339
int activeGraph
Definition smyrnadefs.h:299
glCompColor selectedNodeColor
Definition smyrnadefs.h:273
int drawSplines
Definition smyrnadefs.h:338
float bdxRight
Definition smyrnadefs.h:290
float bdyBottom
Definition smyrnadefs.h:290
float zoom
Definition smyrnadefs.h:257
int drawedgelabels
Definition smyrnadefs.h:325
void * glutfont
Definition smyrnadefs.h:328
glCompPoly_t selPoly
Definition smyrnadefs.h:213
bool selectEdges
Definition smyrnadefs.h:215
bool selectNodes
Definition smyrnadefs.h:214
xdot_kind kind
Definition xdot.h:147
xdot_polyline bezier
Definition xdot.h:152
union _xdot_op::@127 u
drawfunc_t drawfunc
Definition xdot.h:161
double RGBA[4]
Definition color.h:32
union color_s::@72 u
xdot_op op
Definition smyrnadefs.h:86
double global_z
Definition smyrnadefs.h:238
struct topview::@56 fisheyeParams
Hierarchy * h
Definition smyrnadefs.h:227
topviewcache cache
Definition smyrnadefs.h:241
int active
Definition smyrnadefs.h:221
size_t Nodecount
Definition smyrnadefs.h:219
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:235
unsigned selnode_id
Definition smyrnadefs.h:117
unsigned nodelabel_id
Definition smyrnadefs.h:119
unsigned node_id
Definition smyrnadefs.h:115
unsigned edge_id
Definition smyrnadefs.h:116
unsigned seledge_id
Definition smyrnadefs.h:118
unsigned edgelabel_id
Definition smyrnadefs.h:120
double x
Definition xdot.h:79
double z
Definition xdot.h:79
double y
Definition xdot.h:79
size_t cnt
Definition xdot.h:87
xdot_point * pts
Definition xdot.h:88
Definition xdot.h:166
xdot_op * ops
Definition xdot.h:169
size_t cnt
Definition xdot.h:167
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:340
void freeXDot(xdot *x)
Definition xdot.c:760
parsing and deparsing of xdot operations
@ xop_bezier
Definition xdot.h:130
@ xd_unfilled_bezier
Definition xdot.h:114