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 Tue Nov 18 02:48:08 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /