/* * A Reaction-Diffusion simulator for PLY objects. (rdspots) * * for usage info, run program without any parameters * */ #include #include #include #include "rply.h" /* R-D constants and arrays */ GLfloat DA = 0.03199; GLfloat DI = 0.229; GLfloat S = 0.005; GLfloat *BETA; GLfloat *cA; GLfloat *cI; GLfloat *oldCA; GLfloat *oldCI; GLfloat *activator; /* 3d object data arrays */ GLfloat **vertices; GLfloat **normals; GLfloat **diffusion; long **faces; long **neighbours; /* just some vars for extracting data from PLY (could be done better) */ long vertex=0, axis=0, face=0, fvertex=0, home=0, neighb=0; GLfloat maxv = -100; GLfloat minv = 100; /* angles and stuff for rotating and zooming the object */ GLfloat xangle = 0.0; GLfloat yangle = 0.0; GLfloat zangle = 0.0; GLfloat zoom = 1.5; GLfloat atX = 0.0; GLfloat atY = 0.0; /* global for number of vertices and faces */ long nvertices,nfaces; e_ply_type vertex_t, face_length_t, face_value_t; /* GLUT window identifier and viewport size (so we see whole object)*/ static int win; GLfloat view; /* input PLY filename */ char *filename; char *nbsfile; /* just some global variables for stuff that should be implemented better */ int plyHasNeighbs=0, plyHasNormals=0, plyHasDiff=0; int runningRD=1; /* * * Display usage info * */ void printUsage() { printf("Reaction-Diffusion Simulator (Spots)\n\nusage:\trdspots [-p ]\n\n"); printf("\tOptions:\n\t-p\t\t- Use R-D parameters in \n\t\t\t [If not specified defaults are used]\n\n"); printf("\tControls:\n\t\tRotate on X axis: 'a' and 'd'\n\t\tRotate on Y axis: 's' and 'w'\n\t\tRotate on Z axis: 'z' and 'c'\n\t\tZoom in and out: '+', '-'\n\t\tMove object: Left, Right, Up and Down arrows\n\t\tReset view: 'r'\n\t\tPause/resume simulation: 'p'\n\t\tExport concentration levels: 'e'\n\t\tQuit: 'q'\n\n"); printf("\tParameter file format:\n\t\t\t\t- Activator diffusion constant (~0.04)\n\t\t\t\t- Inhibitor diffusion constant (~0.2)\n\t\t\t\t- Initial S value (~0.002)\n\n"); printf("If the PLY input file does not contain additional data about vertex normals and neighbour cells, this will be generated before R-D simulation begins. In this case a PLY file with the extra data is stored at _nbs.ply, and this file should be used in future to save on computation time.\n\n"); } /* * * The Reaction-Diffusion Jazz * */ void updateConc() /* * updateConc(): calculate the new values of activator (cA) and inhibitor (cI) * concentrations for each cell, using the R-D equations. */ { long i; GLfloat iR, aR, iD, aD; /* run through each triangular face (cell) */ for (i=1;i maxv) maxv = vertices[vertex][axis]; if (vertices[vertex][axis] < minv) minv = vertices[vertex][axis]; axis++; if (eol) { vertex++; axis=0; } return 1; } static int normal_cb(p_ply_argument argument) /* * normal_cb(argument): RPly normal callback. Store the normal for each vertex. */ { long eol; ply_get_argument_user_data(argument, NULL, &eol); normals[vertex-1][axis] = (GLfloat)ply_get_argument_value(argument); axis++; if (eol) { //vertex++; axis=0; } return 1; } static int face_cb(p_ply_argument argument) /* * face_cb(argument): RPly face callback. Store vertex indices for each face. */ { long length, value_index; p_ply_property property; ply_get_argument_property(argument, &property, &length, &value_index); ply_get_property_info(property, NULL, NULL, &face_length_t, &face_value_t); switch (value_index) { case 0: case 1: faces[face][fvertex++] = (long)ply_get_argument_value(argument); break; case 2: faces[face][fvertex++] = (long)ply_get_argument_value(argument); face++; fvertex=0; break; default: break; } return 1; } static int neighbours_cb(p_ply_argument argument) /* * neighbours_cb(argument): RPly neighbour callback. Retrieves the neighbour indices. * home variable indexs current cell, neighb indexs its neighbours. Bit of a cludge to * cover the case where neighbours ar found but not diffusion weightings. */ { long value_index; ply_get_argument_property(argument, NULL, NULL, &value_index); switch (value_index) { case 0: case 1: neighbours[home][neighb++] = (long)ply_get_argument_value(argument); break; case 2: neighbours[home][neighb++] = (long)ply_get_argument_value(argument); if (plyHasDiff == 0) home++; neighb=0; break; default: break; } return 1; } static int diffusion_cb(p_ply_argument argument) /* * diffusion_cb(argument): RPly diffusion weightings callback. */ { long value_index; ply_get_argument_property(argument, NULL, NULL, &value_index); switch (value_index) { case 0: case 1: diffusion[home][neighb++] = (GLfloat)ply_get_argument_value(argument); break; case 2: diffusion[home][neighb++] = (GLfloat)ply_get_argument_value(argument); home++; neighb=0; break; default: break; } return 1; } int outputPLY(char *filename) /* * outputPLY(filename): calls all the RPly output functions in correct order to write * a PLY file with all additional data (neighbours, normals, diffusion weightings). */ { int i,j; p_ply ply; ply = ply_create(filename, PLY_ASCII, NULL); /* add vertex element header info */ if (!ply_add_element(ply, "vertex", nvertices)) printf("cant add vertex element\n"); ply_add_scalar_property(ply, "x", vertex_t); ply_add_scalar_property(ply, "y", vertex_t); ply_add_scalar_property(ply, "z", vertex_t); ply_add_scalar_property(ply, "xnorm", vertex_t); ply_add_scalar_property(ply, "ynorm", vertex_t); ply_add_scalar_property(ply, "znorm", vertex_t); /* add faces element info */ if (!ply_add_element(ply, "face", nfaces)) printf("cant add face element\n"); ply_add_list_property(ply, "vertex_indices", face_length_t, face_value_t); /* add neighbours element info */ if (!ply_add_element(ply, "neighbours", nfaces)) printf("cant add neighbours element\n"); ply_add_list_property(ply, "vertex_indices", face_length_t, face_value_t); ply_add_list_property(ply, "diffusion_weighting", face_length_t, vertex_t); /* add comment saying created by our prog and added neighbours */ ply_add_comment(ply, "Extra neighbour and vertex normal data generated for Reaction-Diffusion simulations"); /* write the header */ if (!ply_write_header(ply)) printf("cant write header\n"); /* write the properties one by one */ for (i=0;i