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