From: arif <devnull@localhost>
Date: Mon, 15 Feb 2010 17:46:54 +0000 (+0000)
Subject: new smyrna files
X-Git-Tag: LAST_LIBGRAPH~32^2~1441
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=edec982d09b14c79a568b1dd7573196328f9b697;p=graphviz

new smyrna files
---

diff --git a/cmd/smyrna/selectionfuncs.c b/cmd/smyrna/selectionfuncs.c
new file mode 100644
index 000000000..a70ee24d6
--- /dev/null
+++ b/cmd/smyrna/selectionfuncs.c
@@ -0,0 +1,215 @@
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#include "selectionfuncs.h"
+#include "topviewfuncs.h"
+#include "smyrna_utils.h"
+
+static void select_node(Agraph_t* g,Agnode_t*  obj,int reverse)
+{
+    static Agsym_t* sel_attr=(Agsym_t*)0;
+    if(!sel_attr)
+	sel_attr=agattr(g, AGNODE,"selected","0");
+    if(!reverse)
+    {
+        agxset(obj,sel_attr,"1");
+        ((nodeRec*)(aggetrec(obj,"nodeRec",0)))->selected=1;
+    }
+    else
+    {
+	if(((nodeRec*)(aggetrec(obj,"nodeRec",0)))->selected==1)
+	{
+            agxset(obj,sel_attr,"0");
+	    ((nodeRec*)(aggetrec(obj,"nodeRec",0)))->selected=0;
+	    ((edgeRec*)(aggetrec(obj,"nodeRec",0)))->printLabel=0;
+
+
+	}
+	else
+	{
+            agxset(obj,sel_attr,"1");
+	    ((nodeRec*)(aggetrec(obj,"nodeRec",0)))->selected=1;
+
+	}
+
+    }
+
+
+}
+static void select_edge(Agraph_t* g,Agedge_t*  obj,int reverse)
+{
+    static Agsym_t* sel_attr=(Agsym_t*)0;
+    if(!sel_attr)
+	sel_attr=agattr(g, AGEDGE,"selected","0");
+    if (!reverse)
+    {
+	agxset(obj,sel_attr,"1");
+	((edgeRec*)(aggetrec(obj,"edgeRec",0)))->selected=1;
+    }
+    else
+    {
+	if(((edgeRec*)(aggetrec(obj,"edgeRec",0)))->selected==1)
+	{
+	    agxset(obj,sel_attr,"0");
+	    ((edgeRec*)(aggetrec(obj,"edgeRec",0)))->selected=0;
+	    ((edgeRec*)(aggetrec(obj,"edgeRec",0)))->printLabel=0;
+	}
+	else
+	{
+	    agxset(obj,sel_attr,"1");
+	    ((edgeRec*)(aggetrec(obj,"edgeRec",0)))->selected=1;
+	}
+    }
+
+
+}
+
+
+static void pick_objects_in_rect(Agraph_t* g,GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)
+{
+    static Agnode_t *v;
+    static Agedge_t *e;
+    static glCompPoint posT;
+    static glCompPoint posH;
+    static glCompPoint posN;
+     
+     for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	posN=((nodeRec*)(aggetrec(v,"nodeRec",0)))->A;
+	if(is_point_in_rectangle(posN.x,posN.y,x1,y1,x2-x1,y2-y1))
+	    select_node(g,v,0);
+	for (e = agfstout(g, v); e; e = agnxtout(g, e)) 
+	{
+	    posT=((edgeRec*)(aggetrec(e,"edgeRec",0)))->posTail;
+	    posH=((edgeRec*)(aggetrec(e,"edgeRec",0)))->posHead;
+    	    if(is_point_in_rectangle(posT.x,posT.y,x1,y1,x2-x1,y2-y1))
+		if(is_point_in_rectangle(posH.x,posH.y,x1,y1,x2-x1,y2-y1))
+		    select_edge(g,e,0);
+	}
+    }
+}
+
+
+
+static void* pick_object(Agraph_t* g,glCompPoint p)
+{
+    static Agsym_t* size_attr=(Agsym_t*)0;
+    static Agsym_t* pos_attr=(Agsym_t*)0;
+
+    static Agnode_t *v;
+     static Agedge_t *e;
+     static glCompPoint posT;
+     static glCompPoint posH;
+     static glCompPoint posN;
+     float dist=999999999;
+     static GLfloat nd=0; /*node distance to point*/
+     static GLfloat ed=0; /*edge distance to point*/
+     static GLfloat nodeSize=0;
+     void* rv=(void*)0;
+     nd=0; /*node distance to point*/
+     ed=0; /*edge distance to point*/
+
+    if(!size_attr)
+	size_attr=agattr(g, AGNODE,"size",0);
+
+    if(!pos_attr)
+	pos_attr=agattr(g, AGNODE,"pos",0);
+
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	posN=((nodeRec*)(aggetrec(v,"nodeRec",0)))->A;
+	nodeSize=(GLfloat)l_float(v, size_attr,0);
+	if (nodeSize > 0)
+    	    nodeSize=nodeSize * view->Topview->init_node_size;
+        else
+	    nodeSize=view->Topview->init_node_size;
+	nd=distBetweenPts(posN,p,nodeSize);
+	if( nd < dist )
+	{
+	    rv=v;dist=nd;
+	}
+
+	for (e = agfstout(g, v); e; e = agnxtout(g, e)) 
+	{
+	    posT=((edgeRec*)(aggetrec(e,"edgeRec",0)))->posTail;
+	    posH=((edgeRec*)(aggetrec(e,"edgeRec",0)))->posHead;
+	    ed=point_to_lineseg_dist(p, posT,posH);
+	    if( ed < dist ) {rv=e;dist=ed;}
+	}
+    }
+    return rv;
+}
+
+void pick_object_xyz(Agraph_t* g,topview* t,GLfloat x,GLfloat y,GLfloat z) 
+{
+    static glCompPoint p;
+    void* a;
+    p.x=x;p.y=y;p.z=z;
+    a=pick_object(g,p);
+    if (!a)
+	return;
+    if(agobjkind(a)==AGNODE)
+    {
+	
+	select_node(g,a,1);	
+	((nodeRec*)(aggetrec(a,"nodeRec",0)))->printLabel=1;
+
+	cacheSelectedNodes(g,t);
+
+    }
+    if(agobjkind(a)==AGEDGE)
+    {
+	select_edge(g,a,1);	
+	cacheSelectedEdges(g,t);
+	((edgeRec*)(aggetrec(a,"edgeRec",0)))->printLabel=1;
+    }
+
+
+}
+void pick_objects_rect(Agraph_t* g) 
+{
+
+    static GLfloat x1;
+    static GLfloat y1;
+    static GLfloat x2;
+    static GLfloat y2;
+    if(view->mouse.GLfinalPos.x > view->mouse.GLinitPos.x)
+    {
+        x1=view->mouse.GLinitPos.x;
+	x2=view->mouse.GLfinalPos.x;
+    }
+    else
+    {
+        x2=view->mouse.GLinitPos.x;
+	x1=view->mouse.GLfinalPos.x;
+
+    }
+    if(view->mouse.GLfinalPos.y > view->mouse.GLinitPos.y)
+    {
+        y1=view->mouse.GLinitPos.y;
+	y2=view->mouse.GLfinalPos.y;
+    }
+    else
+    {
+        y2=view->mouse.GLinitPos.y;
+	y1=view->mouse.GLfinalPos.y;
+    }
+    pick_objects_in_rect(g,x1,y1,x2,y2);
+    cacheSelectedNodes(g,view->Topview);
+    cacheSelectedEdges(g,view->Topview);
+}
+
+
diff --git a/cmd/smyrna/selectionfuncs.h b/cmd/smyrna/selectionfuncs.h
new file mode 100644
index 000000000..3a5cbc7e3
--- /dev/null
+++ b/cmd/smyrna/selectionfuncs.h
@@ -0,0 +1,31 @@
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#ifndef SELECTIONFUNCS_H
+#define SELECTIONFUNCS_H
+
+#include "draw.h"
+#include <GL/gl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void pick_objects_rect(Agraph_t* g) ;
+
+#ifdef __cplusplus
+}				/* end extern "C" */
+#endif
+#endif
diff --git a/cmd/smyrna/smyrna.vcproj.RESEARCH.arif.user b/cmd/smyrna/smyrna.vcproj.RESEARCH.arif.user
index c13d86073..a5df9467e 100644
--- a/cmd/smyrna/smyrna.vcproj.RESEARCH.arif.user
+++ b/cmd/smyrna/smyrna.vcproj.RESEARCH.arif.user
@@ -11,7 +11,7 @@
 			<DebugSettings
 				Command="$(TargetPath)"
 				WorkingDirectory="C:\graphviz-ms\bin"
-				CommandArguments="c:/4elt.dot"
+				CommandArguments=""
 				Attach="false"
 				DebuggerType="3"
 				Remote="1"
diff --git a/cmd/smyrna/topviewfuncs.c b/cmd/smyrna/topviewfuncs.c
new file mode 100644
index 000000000..7e61112d3
--- /dev/null
+++ b/cmd/smyrna/topviewfuncs.c
@@ -0,0 +1,744 @@
+#include "topviewfuncs.h"
+#include "cgraph.h"
+#include "smyrna_utils.h"
+#include "colorprocs.h"
+#include "draw.h"
+#include "glcompui.h"
+#include "frmobjectui.h"
+#include "xdot.h"
+#include "glutils.h"
+#include "selectionfuncs.h"
+
+#define WITH_CGRAPH 1
+static xdot *parseXdotwithattrs(void *e);
+static Agsym_t* pos_attr=(Agsym_t*)0;
+
+
+
+
+static void set_boundaries(Agraph_t * g, topview * t)
+{
+    Agnode_t *v;
+    static glCompPoint pos;
+    float left, right, top, bottom;
+    int id=0;
+    if(!pos_attr)
+	pos_attr=agattr(g, AGNODE,"pos",0);
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	pos=getPointFromStr(agxget(v, pos_attr));
+	if(id==0)
+	{
+	    left=pos.x;
+	    right=pos.x;
+	    top=pos.y;
+	    bottom=pos.y;
+	}
+	if (left > pos.x)
+	    left = pos.x;
+	if (right < pos.x)
+	    right = pos.x;
+	if (bottom > pos.y)
+	    bottom = pos.y;
+	if (top < pos.y)
+	    top = pos.y;
+	id++;
+    }
+    view->bdxLeft = left;
+    view->bdyTop = top;
+    view->bdxRight = right;
+    view->bdyBottom = bottom;
+
+    view->bdzTop = 0;
+    view->bdzBottom = 0;
+
+
+
+}
+
+static float init_node_size(Agraph_t * g, topview * t)
+{
+    float vsize;
+    int percent;
+    float sz;
+    percent = atoi(agget(g, "nodesize"));
+    if (percent == 0)
+	percent = 0.000001;
+    vsize =
+	0.05 * sqrt((view->bdxRight - view->bdxLeft) *
+		    (view->bdyTop - view->bdyBottom));
+    sz =	vsize * 2  * percent / 100.0 /
+	sqrt(t->Nodecount);
+/*    if (t->init_node_size < 1)
+	t->init_node_size=1;*/
+//    t->init_zoom = view->zoom;
+    t->init_zoom = -20;
+    return  sz;
+
+}
+
+
+
+static void draw_xdot(xdot* x,float base_z)
+{
+	int i;
+	sdot_op *op;
+	if (!x)
+		return;
+
+	view->Topview->global_z=base_z;
+
+	op=(sdot_op*)x->ops;
+	for (i=0; i < x->cnt; i++,op++)
+	{
+		if(op->op.drawfunc)
+			op->op.drawfunc(&op->op,0);
+	}
+
+
+}
+
+
+
+static glCompPoint getEdgeHead(Agedge_t * edge)
+{   
+    return getPointFromStr(agget(aghead(edge),"pos"));
+}
+static glCompPoint getEdgeTail(Agedge_t *  edge)
+{
+    return getPointFromStr(agget(agtail(edge),"pos"));
+}
+static GLfloat getEdgeLength(Agedge_t *  edge)
+{
+    GLfloat rv=0;	
+    glCompPoint A,B;
+    A=getEdgeTail(edge);
+    B=getEdgeHead(edge);
+    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);
+    rv=sqrt(rv);
+    return rv;
+}
+static void glCompColorxlate(glCompColor* c,char* str)
+{
+        static gvcolor_t cl;
+	colorxlate(str, &cl, RGBA_DOUBLE);
+	c->R=cl.u.RGBA[0];
+	c->G=cl.u.RGBA[1];
+	c->B=cl.u.RGBA[2];
+	c->A=cl.u.RGBA[3];
+}
+
+int object_color(void* obj,glCompColor* c)
+{
+    static gvcolor_t cl;
+    Agraph_t* g=view->g[view->activeGraph];
+    int return_value = 1;
+    int objType;
+    float Alpha = 1;
+    char* bf;
+
+    objType=AGTYPE(obj);
+
+    if(objType==AGEDGE)
+	Alpha=getAttrFloat(g,obj,"defaultedgealpha",1);
+    if(objType==AGNODE)
+	Alpha=getAttrFloat(g,obj,"defaultnodealpha",1);
+    if(!getAttrBool(g,obj,"visible",1))
+	return 0;
+    if(getAttrBool(g,obj,"selected",0))
+    {
+	setColor(c,view->selectedEdgeColor.R, view->selectedEdgeColor.G,view->selectedEdgeColor.B, view->selectedEdgeColor.A);
+	return return_value;
+    }
+    /*get edge's color attribute */
+    bf=getAttrStr(g,obj,"color",NULL);
+    if((bf)&&(strlen(bf)>0))
+    {
+	colorxlate(bf, &cl, RGBA_DOUBLE);
+	c->R=cl.u.RGBA[0];
+	c->G=cl.u.RGBA[1];
+	c->B=cl.u.RGBA[2];
+	c->A=cl.u.RGBA[3];
+
+    }
+    else
+    {
+	if(objType==AGEDGE)
+	    getcolorfromschema(view->colschms, getEdgeLength(obj), view->Topview->maxedgelen,c);
+	else
+	{
+	    colorxlate(agget(g, "defaultnodecolor"),&cl, RGBA_DOUBLE);
+		c->R=cl.u.RGBA[0];
+	    c->G=cl.u.RGBA[1];
+	    c->B=cl.u.RGBA[2];
+	    c->A=cl.u.RGBA[3];
+	}
+
+    }
+    return return_value;
+}
+
+
+
+
+/*
+	draws multi edges , single edges
+	this function assumes     glBegin(GL_LINES) has been called 
+*/
+static void draw_edge(glCompPoint* posT,glCompPoint* posH, GLfloat length,int deg)
+{
+    double alpha, R, ITERANGLE;
+    double X1, Y1, X2, Y2;
+
+    if (deg) {
+	R = length / 20.0;
+	if ((deg / 2) * 2 != deg)	/*odd */
+	    ITERANGLE = (deg) * 15.00 * -1;
+	else
+	    ITERANGLE = (deg) * 15.00;
+	ITERANGLE = DEG2RAD * ITERANGLE;
+
+	alpha = atan((posH->y - posT->y) / (posH->x - posT->x));
+	if (posT->x > posH->x)
+	    ITERANGLE = 180 * DEG2RAD - ITERANGLE;
+	X1 = R * cos(alpha - ITERANGLE) + posT->x;
+	Y1 = R * sin(alpha - ITERANGLE) + posT->y;
+	X2 = R * cos(alpha - (180 * DEG2RAD - ITERANGLE)) + posH->x;
+	Y2 = R * sin(alpha - (180 * DEG2RAD - ITERANGLE)) + posH->y;
+	glVertex3f(posT->x, posT->y, posT->z);
+	glVertex3f(X1, Y1, posT->z);
+	glVertex3f(X1, Y1, posT->z);
+	glVertex3f(X2, Y2, posH->z);
+	glVertex3f(X2, Y2, posH->z);
+	glVertex3f(posH->x, posH->y, posH->z);
+    } else {
+	glVertex3f(posT->x, posT->y, posT->z);
+	glVertex3f(posH->x, posH->y, posH->z);
+
+    }
+
+}
+void renderSelectedNodes(Agraph_t * g)
+{
+    Agnode_t *v;
+    static xdot * x;
+        static glCompPoint pos;
+
+
+    static int defaultNodeShape=0;
+    static GLfloat nodeSize=0;
+    if(!defaultNodeShape)
+	defaultNodeShape=getAttrBool(g,g,"defaultnodeshape",0);
+    if(defaultNodeShape==0)
+	glBegin(GL_POINTS);
+
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	if(!((nodeRec*)(aggetrec(v,"nodeRec",0)))->selected);
+	    continue;
+	x=parseXdotwithattrs(v);
+	draw_xdot(x,0);
+	if(x)
+	    freeXDot (x);
+    }
+
+
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	if(!((nodeRec*)(aggetrec(v,"nodeRec",0)))->selected)
+	    continue;
+	glColor4f(1,0,0,1);	    
+	pos=((nodeRec*)(aggetrec(v,"nodeRec",0)))->A;
+	nodeSize=((nodeRec*)(aggetrec(v,"nodeRec",0)))->size;
+
+	if (defaultNodeShape == 0) 
+	    glVertex3f(pos.x,pos.y,pos.z);
+	else if (defaultNodeShape == 1) 
+
+	    drawCircle(pos.x,pos.y,nodeSize,pos.z);
+	if(((nodeRec*)(aggetrec(v,"nodeRec",0)))->printLabel==1)
+            glprintfglut(view->glutfont,pos.x+nodeSize,pos.y+nodeSize,pos.z,agnameof(v));
+
+    }
+    if(defaultNodeShape==0)
+	glEnd();
+}
+
+
+
+void renderNodes(Agraph_t * g)
+{
+    Agnode_t *v;
+    static glCompPoint pos;
+    static Agsym_t* size_attr=(Agsym_t*)0;
+    static Agsym_t* selected_attr=(Agsym_t*)0;
+    static int defaultNodeShape=0;
+    static GLfloat nodeSize=0;
+    static glCompColor c;
+    static xdot * x;
+
+
+    if(!defaultNodeShape)
+	defaultNodeShape=getAttrBool(g,g,"defaultnodeshape",0);
+    if(!pos_attr)
+	pos_attr=agattr(g, AGNODE,"pos",0);
+    if(!size_attr)
+	size_attr=agattr(g, AGNODE,"size",0);
+    if(!selected_attr)
+	selected_attr=agattr(g, AGNODE,"selected",0);
+
+    if(defaultNodeShape==0)
+	glBegin(GL_POINTS);
+
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	    if(!object_color(v,&c))
+		continue;
+	    x=parseXdotwithattrs(v);
+	    draw_xdot(x,0);
+
+
+	    if(x)
+		freeXDot (x);
+    }
+
+
+
+
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	if(!object_color(v,&c))
+	{
+	    ((nodeRec*)(aggetrec(v,"nodeRec",0)))->visible=0;
+	    continue;
+	}
+	else
+	    ((nodeRec*)(aggetrec(v,"nodeRec",0)))->visible=1;
+
+
+	if(l_int(v, selected_attr,0))
+	{
+	    ((nodeRec*)(aggetrec(v,"nodeRec",0)))->selected=1;
+	    continue;
+	}
+	glColor4f(c.R,c.G,c.B,c.A);	    
+	pos=getPointFromStr(agxget(v, pos_attr));
+	nodeSize=(GLfloat)l_float(v, size_attr,0);
+
+	((nodeRec*)(aggetrec(v,"nodeRec",0)))->A=pos;
+
+        if (nodeSize > 0)
+	    nodeSize=nodeSize*view->Topview->init_node_size;
+	else
+	    nodeSize=view->Topview->init_node_size;
+	if(defaultNodeShape==0)
+	    nodeSize=1;
+	((nodeRec*)(aggetrec(v,"nodeRec",0)))->size=nodeSize;
+	if (defaultNodeShape == 0) 
+	    glVertex3f(pos.x,pos.y,pos.z);
+	else if (defaultNodeShape == 1) 
+	    drawCircle(pos.x,pos.y,nodeSize,pos.z);
+    }
+    if(defaultNodeShape==0)
+	glEnd();
+}
+
+
+void renderSelectedEdges(Agraph_t * g)
+{
+
+    Agedge_t *e;
+    Agnode_t *v;
+    static xdot * x;
+    static glCompPoint posT;	/*Tail position*/
+    static glCompPoint posH;	/*Head position*/
+    static glCompColor c;
+    /*xdots tend to be drawn as background shapes,that is why they are being rendered before edges*/
+
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	for (e = agfstout(g, v); e; e = agnxtout(g, e)) 
+	{
+	    if(!((edgeRec*)(aggetrec(e,"edgeRec",0)))->selected)
+		continue;
+	    if(!object_color(e,&c))
+		continue;
+
+	    x=parseXdotwithattrs(e);
+	    draw_xdot(x,0);
+	    if(x)
+		freeXDot (x);
+	}
+    }
+
+
+
+
+    glBegin(GL_LINES);
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	for (e = agfstout(g, v); e; e = agnxtout(g, e)) 
+	{
+	    if(!((edgeRec*)(aggetrec(e,"edgeRec",0)))->selected)
+		continue;
+
+	    if(!object_color(e,&c))
+		continue;
+	    glColor4f(1,0,0,1);	    
+	    posT=((edgeRec*)(aggetrec(e,"edgeRec",0)))->posTail;
+	    posH=((edgeRec*)(aggetrec(e,"edgeRec",0)))->posHead;
+	    posT.z +=0.01;
+	    posH.z +=0.01;
+	    draw_edge(&posT,&posH,getEdgeLength(e),0);
+	}
+    }
+    glEnd();
+}
+
+
+
+
+void renderEdges(Agraph_t * g)
+{
+
+    Agedge_t *e;
+    Agnode_t *v;
+    static xdot * x;
+    static glCompPoint posT;	/*Tail position*/
+    static glCompPoint posH;	/*Head position*/
+    static glCompColor c;
+    if(!pos_attr)
+	pos_attr=agattr(g, AGNODE,"pos",0);
+    /*xdots tend to be drawn as background shapes,that is why they are being rendered before edges*/
+
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	for (e = agfstout(g, v); e; e = agnxtout(g, e)) 
+	{
+	    if(!object_color(e,&c))
+	    {
+		((edgeRec*)(aggetrec(e,"edgeRec",0)))->visible=0;
+		continue;
+	    }
+	    else
+		((edgeRec*)(aggetrec(e,"edgeRec",0)))->visible=1;
+
+	    if(((edgeRec*)(aggetrec(e,"edgeRec",0)))->selected)
+		continue;
+
+	    x=parseXdotwithattrs(e);
+	    draw_xdot(x,0);
+
+
+	    if(x)
+		freeXDot (x);
+	}
+    }
+
+
+
+
+    glBegin(GL_LINES);
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	for (e = agfstout(g, v); e; e = agnxtout(g, e)) 
+	{
+	    if(!object_color(e,&c))
+		continue;
+	    if(((edgeRec*)(aggetrec(e,"edgeRec",0)))->selected)
+		continue;
+	    glColor4f(c.R,c.G,c.B,c.A);	    
+	    posT=getPointFromStr(agxget(agtail(e), pos_attr));
+	    posH=getPointFromStr(agxget(aghead(e), pos_attr));
+	    draw_edge(&posT,&posH,getEdgeLength(e),0);
+    	    ((edgeRec*)(aggetrec(e,"edgeRec",0)))->posTail=posT;
+	    ((edgeRec*)(aggetrec(e,"edgeRec",0)))->posHead=posH;
+
+
+	}
+    }
+    glEnd();
+}
+
+void renderNodeLabels(Agraph_t * g)
+{
+    Agnode_t *v;
+    static glCompPoint pos;
+    static Agsym_t* data_attr=(Agsym_t*)0;
+    static Agsym_t* l_color_attr=(Agsym_t*)0;
+    static GLfloat nodeSize=0;
+    static glCompColor c;
+    if(!data_attr)
+	data_attr=agattr(g, AGNODE,agget(g, "nodelabelattribute"),0);
+    if(!l_color_attr)
+	l_color_attr=agattr(g, AGRAPH,"nodelabelcolor",0);
+
+
+
+
+    glCompColorxlate(&c,agxget(g,l_color_attr));
+
+
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	 if(((nodeRec*)(aggetrec(v,"nodeRec",0)))->visible==0)
+	    continue;
+	 if(((nodeRec*)(aggetrec(v,"nodeRec",0)))->selected==1)
+	    continue;
+
+	pos=((nodeRec*)(aggetrec(v,"nodeRec",0)))->A;
+	nodeSize=((nodeRec*)(aggetrec(v,"nodeRec",0)))->size;
+	glColor4f(c.R,c.G,c.B,c.A);
+        if (nodeSize > 0)
+	    nodeSize=nodeSize*view->Topview->init_node_size;
+	else
+	    nodeSize=view->Topview->init_node_size;
+	if(!data_attr)
+            glprintfglut(view->glutfont,pos.x+nodeSize,pos.y+nodeSize,pos.z,agnameof(v));
+	else
+	    glprintfglut(view->glutfont,pos.x+nodeSize,pos.y+nodeSize,pos.z,agxget(v,data_attr));
+    }
+}
+void renderEdgeLabels(Agraph_t * g)
+{
+    Agedge_t *e;
+    Agnode_t *v;
+    static glCompPoint posT;
+    static glCompPoint posH;
+    static Agsym_t* data_attr=(Agsym_t*)0;
+    static Agsym_t* l_color_attr=(Agsym_t*)0;
+    static GLfloat nodeSize=0;
+    static glCompColor c;
+    GLfloat x,y,z;
+
+    if(!data_attr)
+	data_attr=agattr(g, AGNODE,agget(g, "edgelabelattribute"),0);
+    if(!l_color_attr)
+	l_color_attr=agattr(g, AGRAPH,"edgelabelcolor",0);
+
+    glCompColorxlate(&c,agxget(g,l_color_attr));
+
+    if(!data_attr)
+	return;
+
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
+    {
+	for (e = agfstout(g, v); e; e = agnxtout(g, e)) 
+	{
+
+	    if(((edgeRec*)(aggetrec(v,"nodeRec",0)))->visible==0)
+		continue;
+
+	    posT=((edgeRec*)(aggetrec(e,"edgeRec",0)))->posTail;
+	    posH=((edgeRec*)(aggetrec(e,"edgeRec",0)))->posHead;
+	    glColor4f(c.R,c.G,c.B,c.A);
+	    x=posH.x+(posT.x-posH.x)/2;
+	    y=posH.y+(posT.y-posH.y)/2;
+	    z=posH.z+(posT.z-posH.z)/2;
+	    glprintfglut(view->glutfont,x,y,z,agxget(e,data_attr));
+
+	}
+    }
+}
+
+
+
+
+
+
+static xdot *parseXdotwithattrs(void *e)
+{
+	
+	xdot* xDot=NULL;
+	xDot=parseXDotFOn (agget(e,"_draw_" ), OpFns,sizeof(sdot_op), xDot);
+	xDot=parseXDotFOn (agget(e,"_ldraw_" ), OpFns,sizeof(sdot_op), xDot);
+	xDot=parseXDotFOn (agget(e,"_hdraw_" ), OpFns,sizeof(sdot_op), xDot);
+	xDot=parseXDotFOn (agget(e,"_tdraw_" ), OpFns,sizeof(sdot_op), xDot);
+	xDot=parseXDotFOn (agget(e,"_hldraw_" ), OpFns,sizeof(sdot_op), xDot);
+	xDot=parseXDotFOn (agget(e,"_tldraw_" ), OpFns,sizeof(sdot_op), xDot);
+	return xDot;
+
+}
+
+void cacheNodes(Agraph_t * g,topview* t)
+{
+    if(t->cache.node_id!=-1)	/*clean existing cache*/
+	glDeleteLists(t->cache.node_id,1);
+    t->cache.node_id=glGenLists(1);
+    glNewList(t->cache.node_id,GL_COMPILE);
+    renderNodes(g);
+    glEndList();
+
+
+
+
+}
+void cacheEdges(Agraph_t * g,topview* t)
+{
+    if(t->cache.edge_id!=-1)	/*clean existing cache*/
+	glDeleteLists(t->cache.edge_id,1);
+    t->cache.edge_id=glGenLists(1);
+    glNewList(t->cache.edge_id,GL_COMPILE);
+    renderEdges(g);
+    glEndList();
+
+
+}
+void cacheSelectedEdges(Agraph_t * g,topview* t)
+{
+    if(t->cache.seledge_id!=-1)	/*clean existing cache*/
+	glDeleteLists(t->cache.seledge_id,1);
+    t->cache.seledge_id=glGenLists(1);
+    glNewList(t->cache.seledge_id,GL_COMPILE);
+    renderSelectedEdges(g);
+    glEndList();
+
+
+}
+void cacheSelectedNodes(Agraph_t * g,topview* t)
+{
+    if(t->cache.selnode_id!=-1)	/*clean existing cache*/
+	glDeleteLists(t->cache.selnode_id,1);
+    t->cache.selnode_id=glGenLists(1);
+    glNewList(t->cache.selnode_id,GL_COMPILE);
+    renderSelectedNodes(g);
+    glEndList();
+}
+void cacheNodeLabels(Agraph_t * g,topview* t)
+{
+    if(t->cache.nodelabel_id!=-1)	/*clean existing cache*/
+	glDeleteLists(t->cache.nodelabel_id,1);
+    t->cache.nodelabel_id=glGenLists(1);
+    glNewList(t->cache.nodelabel_id,GL_COMPILE);
+    renderNodeLabels(g);
+    glEndList();
+}
+void cacheEdgeLabels(Agraph_t * g,topview* t)
+{
+    if(t->cache.edgelabel_id!=-1)	/*clean existing cache*/
+	glDeleteLists(t->cache.edgelabel_id,1);
+    t->cache.edgelabel_id=glGenLists(1);
+    glNewList(t->cache.edgelabel_id,GL_COMPILE);
+    renderEdgeLabels(g);
+    glEndList();
+}
+
+void updateSmGraph(Agraph_t * g,topview* t)
+{
+    Agnode_t *v;
+    Agedge_t *e;
+    float eLength=0;
+    float totalELength=0;
+
+    t->Nodecount=0;
+    t->Edgecount=0;
+    t->avgedgelength=0;
+    t->maxedgelen=0;
+    t->minedgelen=-1;
+
+    t->picked_node_count = 0;
+    t->picked_nodes = '\0';
+    t->picked_edge_count = 0;
+    t->picked_edges = '\0';
+    t->global_z=0;
+
+
+
+    if(!t)
+	return ;
+    /*Node Loop*/
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
+	for (e = agfstout(g, v); e; e = agnxtout(g, e)) 
+	{
+	    t->Edgecount++;
+	    eLength=getEdgeLength(e);
+	    if((t->minedgelen == -1) || (t->minedgelen > eLength))
+		t->minedgelen=eLength;
+	    if(eLength > t->maxedgelen)
+		t->maxedgelen=eLength;
+	    totalELength += eLength;
+	}
+	t->Nodecount++;
+
+    }
+    aginit(g, AGNODE, "nodeRec", sizeof(nodeRec), 0);
+    aginit(g, AGEDGE, "edgeRec", sizeof(edgeRec), 0);
+
+    set_boundaries(g,t);
+    t->avgedgelength = totalELength / t->Edgecount;
+    t->init_node_size=init_node_size(g, t);
+    view->Topview=t;
+    cacheNodes(g,t);
+    cacheEdges(g,t);
+    cacheSelectedNodes(g,t);
+    cacheSelectedEdges(g,t);
+    cacheNodeLabels(g,t);
+    cacheEdgeLabels(g,t);
+}
+topview* initSmGraph(Agraph_t * g)
+{
+    topview* rv=(topview*)malloc(sizeof(topview));
+    rv->maxnodedegree = 1;
+        
+    /*create glcomp menu system */
+    view->widgets = glcreate_gl_topview_menu();
+
+    /*create attribute list*/
+    rv->attributes=load_attr_list(view->g[view->activeGraph]);
+    rv->filtered_attr_list=NULL;
+
+    /*set topologilca fisheye to NULL */
+    rv->fisheyeParams.h = '\0';
+
+    if (view->dfltViewType == VT_TOPFISH)
+	rv->fisheyeParams.active = 1;
+    else
+	rv->fisheyeParams.active = 0;
+    rv->cache.node_id=-1;
+    rv->cache.selnode_id=-1;
+    rv->cache.edge_id=-1;
+    rv->cache.seledge_id=-1;
+    updateSmGraph(g,rv);
+    return rv;
+}
+
+void renderSmGraph(Agraph_t * g,topview* t)
+{
+
+    if(view->drawnodes)
+    {
+	glCallList(t->cache.node_id);
+        glCallList(t->cache.selnode_id);
+        if(view->drawnodelabels)
+	{
+	    if(view->zoom*-1 <	t->fitin_zoom /(float)view->labelnumberofnodes*-1) 
+		glCallList(t->cache.nodelabel_id);
+	}
+
+    }
+
+    if(view->drawedges)
+    {
+	glCallList(t->cache.edge_id);
+        glCallList(t->cache.seledge_id);
+        if(view->drawedgelabels)
+	{
+	    if(view->zoom*-1 <	t->fitin_zoom /(float)view->labelnumberofnodes*-1) 
+		    glCallList(t->cache.edgelabel_id);
+
+	}
+    }
+
+}
+
+void freeSmGraph(Agraph_t * g,topview* t)
+{
+    return ;
+}
+void move_TVnodes()
+{
+    return;
+}
+
+
+
diff --git a/cmd/smyrna/topviewfuncs.h b/cmd/smyrna/topviewfuncs.h
new file mode 100644
index 000000000..1fa4c7259
--- /dev/null
+++ b/cmd/smyrna/topviewfuncs.h
@@ -0,0 +1,35 @@
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#ifndef TOPVIEWFUNCS_H
+#define TOPVIEWFUNCS_H
+
+#include "smyrnadefs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void pick_object_xyz(Agraph_t* g,topview* t,GLfloat x,GLfloat y,GLfloat z) ;
+extern topview* initSmGraph(Agraph_t * g);
+extern void renderSmGraph(Agraph_t * g,topview* t);
+extern void freeSmGraph(Agraph_t * g,topview* t);
+extern void cacheSelectedEdges(Agraph_t * g,topview* t);
+extern void cacheSelectedNodes(Agraph_t * g,topview* t);
+
+#ifdef __cplusplus
+}				/* end extern "C" */
+#endif
+#endif