Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

TclGraphLayout.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010 * RCS INFORMATION:
00011 *
00012 *      $RCSfile: TclGraphLayout.C,v $
00013 *      $Author: johns $      $Locker:  $               $State: Exp $
00014 *      $Revision: 1.5 $         $Date: 2020/10/15 16:07:31 $
00015 *
00016 ***************************************************************************/
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <math.h>
00026 #include "VMDApp.h"
00027 #include "Inform.h"
00028 #include "GraphLayout.h"
00029 #include <tcl.h>
00030 #include "TclCommands.h"
00031 #include "config.h" // for CMDLEN
00032 
00033 //#if defined(VMDCUDA)
00034 //#include "CUDAGraphLayout.h"
00035 //#endif
00036 
00037 int layout_fr(VMDApp *app, int argc, Tcl_Obj * const objv[], Tcl_Interp *interp) {
00038   int i;
00039   if ((argc <3) || (argc > 12 )) {
00040     msgErr << "Usage: node_count iterations [-weights weightlist]" << sendmsg;
00041     return 0;
00042   }
00043 
00044   int n = 0;
00045   int iters = 0;
00046   float area = 1.0f;
00047   float kscale = 1.0e3f;
00048   float tempscale = 0.2f;
00049   float distance_epsilon = 1.0e-6f;
00050   float *weights = NULL;
00051 
00052   if (Tcl_GetIntFromObj(interp, objv[1], &n) != TCL_OK) {
00053     Tcl_AppendResult(interp, "\n node_count incorrectly specified",NULL);
00054     return TCL_ERROR;
00055   }
00056   if (n<1) {
00057     Tcl_AppendResult(interp, "\n node_count incorrectly specified",NULL);
00058     return TCL_ERROR;
00059   }
00060 
00061   if (Tcl_GetIntFromObj(interp, objv[2], &iters) != TCL_OK) {
00062     Tcl_AppendResult(interp, "\n iterations incorrectly specified",NULL);
00063     return TCL_ERROR;
00064   }
00065   if (iters<0) {
00066     Tcl_AppendResult(interp, "\n iterations incorrectly specified",NULL);
00067     return TCL_ERROR;
00068   }
00069 
00070 
00071   for (i=3; i < argc; i++) {
00072     char *opt = Tcl_GetStringFromObj(objv[i], NULL);
00073     if (!strcmp(opt, "-weights")) {
00074       if (i == argc-1) {
00075         Tcl_AppendResult(interp, "No weights specified",NULL);
00076         return TCL_ERROR;
00077       }
00078 
00079       int matlen = 0;
00080       Tcl_Obj **data;
00081       if (Tcl_ListObjGetElements(interp, objv[i+1], &matlen, &data) != TCL_OK) {
00082         return TCL_ERROR;
00083       }
00084 
00085       if (matlen != (n*n)) {
00086         Tcl_AppendResult(interp, "Incorrect weight matrix size specified",NULL);
00087         return TCL_ERROR;
00088       }
00089 
00090       weights = new float[n*n];
00091       for (i=0; i<matlen; i++) {
00092         double tmp;
00093         if (Tcl_GetDoubleFromObj(interp, data[i], &tmp) != TCL_OK) {
00094           delete [] weights;
00095           return TCL_ERROR;
00096         }
00097         weights[i] = float(tmp);
00098       }
00099     }
00100 
00101     if (!strcmp(opt, "-area")) {
00102       double tmp;
00103       if (Tcl_GetDoubleFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
00104         return TCL_ERROR;
00105       }
00106       area = float(tmp);
00107     }
00108 
00109     if (!strcmp(opt, "-kscale")) {
00110       double tmp;
00111       if (Tcl_GetDoubleFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
00112         return TCL_ERROR;
00113       }
00114       kscale = float(tmp);
00115     }
00116 
00117     if (!strcmp(opt, "-tempscale")) {
00118       double tmp;
00119       if (Tcl_GetDoubleFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
00120         return TCL_ERROR;
00121       }
00122       tempscale = float(tmp);
00123     }
00124 
00125     if (!strcmp(opt, "-distance_epsilon")) {
00126       double tmp;
00127       if (Tcl_GetDoubleFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
00128         return TCL_ERROR;
00129       }
00130       distance_epsilon = float(tmp);
00131     }
00132   }
00133 
00134 
00135 //printf("layout_fr()\n");
00136   GraphLayout *g = new GraphLayout(n, 0);
00137 
00138 //printf("init_positions()\n");
00139   g->init_positions_box();
00140 
00141   if (weights != NULL) {
00142 //printf("add_weight_matrix()\n");
00143     g->add_weight_matrix(weights);
00144   }
00145 
00146 //printf("compute()\n");
00147   g->compute(iters, area, kscale, tempscale, distance_epsilon);
00148 
00149 
00150 //printf("get_vertex_ptrs()\n");
00151   int numverts=0;
00152   const float *posx, *posy;
00153   g->get_vertex_ptrs(numverts, posx, posy);
00154 
00155 //printf("generating vertex positions resul list...\n");
00156   Tcl_Obj *vertexlist = Tcl_NewListObj(0, NULL);
00157   for (i=0; i<numverts; i++) {
00158     Tcl_Obj *vertex = Tcl_NewListObj(0, NULL);
00159     Tcl_ListObjAppendElement(interp, vertex, Tcl_NewDoubleObj(posx[i]));
00160     Tcl_ListObjAppendElement(interp, vertex, Tcl_NewDoubleObj(posy[i]));
00161     Tcl_ListObjAppendElement(interp, vertexlist, vertex);
00162   }
00163   Tcl_SetObjResult(interp, vertexlist);
00164 
00165 //printf("delete g\n");
00166   delete g;
00167 
00168   if (weights) {
00169 //printf("delete weights\n");
00170     delete [] weights;
00171   }
00172 
00173   return 0;
00174 }
00175 
00176 
00177 int obj_graphlayout(ClientData cd, Tcl_Interp *interp, int argc,
00178                      Tcl_Obj * const objv[]){
00179   if (argc < 2) {
00180     Tcl_SetResult(interp,
00181     (char *) "Usage: graphlayout <command> [args...]\n"
00182       "Commands:\n"
00183       "fr -- Perform Fruchterman-Reingold style spring layout\n"
00184       ,
00185       TCL_STATIC);
00186     return TCL_ERROR;
00187   }
00188   char *argv1 = Tcl_GetStringFromObj(objv[1],NULL);
00189 
00190   VMDApp *app = (VMDApp *)cd;
00191   if (!strupncmp(argv1, "fr", CMDLEN))
00192     return layout_fr(app, argc-1, objv+1, interp);
00193 
00194   Tcl_SetResult(interp, (char *) "Type 'graphlayout' for summary of usage\n", TCL_VOLATILE);
00195   return TCL_OK;
00196 }
00197 
00198 

Generated on Thu Mar 28 02:44:13 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002