From f001495e686e55bae130ee788209d1824c8823eb Mon Sep 17 00:00:00 2001 From: Jiaming Guo Date: Thu, 12 Jan 2017 11:44:17 -0600 Subject: [PATCH] fix minor errors for loading and rendering networks from swc files --- main.cu | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------- 1 file changed, 182 insertions(+), 56 deletions(-) diff --git a/main.cu b/main.cu index 8801e52..d66c0ad 100644 --- a/main.cu +++ b/main.cu @@ -1,7 +1,11 @@ -#include +#ifndef GL_MULTISAMPLE +#define GL_MULTISAMPLE 0x809D +#endif + +#include #include #include -#include +#include //OpenGL includes #include @@ -19,12 +23,6 @@ #include #endif -//ANN includes -//#include - -//chrono includes -//#include - //BOOST includes #include @@ -32,15 +30,20 @@ stim::gl_aaboundingbox bb; //axis-aligned bounding box object stim::camera cam; //camera object +// number of networks unsigned num_nets = 0; + +// networks stim::gl_network GT; //ground truth network stim::gl_network T; //test network stim::gl_network _GT; //splitted GT stim::gl_network _T; //splitted T +// indicator unsigned ind = 0; //indicator of mapping unsigned swc_ind = 0; //indicator of rendering swc file as networks +// relationships std::vector _gt_t; // store indices of nearest edge points in _T for _GT std::vector _t_gt; // store indices of nearest edge points in _GT for _T @@ -57,6 +60,10 @@ bool RButtonDown = false; int mouse_x; int mouse_y; +// mouse wheel move +float des = 0.0f; + +// render modes bool compareMode = true; // default mode is compare mode bool mappingMode = false; @@ -117,6 +124,7 @@ void glut_render_modelview(){ stim::vec3 focus = cam.getLookAt(); //get the camera focal point stim::vec3 up = cam.getUp(); //get the camera "up" orientation + eye[2] += des; //get camera closer to target by factor des gluLookAt(eye[0], eye[1], eye[2], focus[0], focus[1], focus[2], up[0], up[1], up[2]); //set up the OpenGL camera } @@ -125,9 +133,10 @@ void glut_render(void) { //no mapping, just comparing if (ind == 0) { - //working with obj files + //-----working with obj files----- if (swc_ind == 0) { if (num_nets == 1) { //if a single network is loaded + glEnable(GL_DEPTH_TEST); //enable depth glut_render_single_projection(); //fill the entire viewport glut_render_modelview(); //set up the modelview matrix with camera details glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen @@ -135,7 +144,7 @@ void glut_render(void) { } if (num_nets == 2) { //if two networks are loaded - + glEnable(GL_DEPTH_TEST); //enable depth glut_render_left_projection(); //set up a projection for the left half of the window glut_render_modelview(); //set up the modelview matrix using camera details glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen @@ -144,16 +153,17 @@ void glut_render(void) { glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); //texture map will be used as the network color glBindTexture(GL_TEXTURE_1D, cmap_tex); //bind the Brewer texture map - GT.glCenterline(); //render the GT network + GT.glCylinder(); //render the GT network glut_render_right_projection(); //set up a projection for the right half of the window glut_render_modelview(); //set up the modelview matrix using camera details - T.glCenterline(); //render the T network + T.glCylinder(); //render the T network } } - //working with swc files + //-----working with swc files----- else { if (num_nets == 1) { //if a single network is loaded + glEnable(GL_DEPTH_TEST); //enable depth glut_render_single_projection(); //fill the entire viewport glut_render_modelview(); //set up the modelview matrix with camera details glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen @@ -161,7 +171,7 @@ void glut_render(void) { } if (num_nets == 2) { //if two networks are loaded - + glEnable(GL_DEPTH_TEST); //enable depth glut_render_left_projection(); //set up a projection for the left half of the window glut_render_modelview(); //set up the modelview matrix using camera details glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen @@ -179,9 +189,9 @@ void glut_render(void) { } } - //do mapping + //do comparing and mapping else { - //working with obj files + //-----working with obj files----- if (swc_ind == 0) { if (num_nets == 1) { //if a single network is loaded std::cout << "You should have at least two networks to do mapping." << std::endl; //exit program because there isn't enough network @@ -189,6 +199,48 @@ void glut_render(void) { } if (num_nets == 2) { //if two networks are loaded if (compareMode) { + glEnable(GL_DEPTH_TEST); //enable depth + glut_render_left_projection(); //set up a projection for the left half of the window + glut_render_modelview(); //set up the modelview matrix using camera details + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen + + glEnable(GL_TEXTURE_1D); //enable texture mapping + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); //texture map will be used as the network color + glBindTexture(GL_TEXTURE_1D, cmap_tex); //bind the Brewer texture map + + _GT.glCylinder(); //render the GT network + + glut_render_right_projection(); //set up a projection for the right half of the window + glut_render_modelview(); //set up the modelview matrix using camera details + _T.glCylinder(); //render the T network + + } + else { + glEnable(GL_DEPTH_TEST); //enable depth + glut_render_left_projection(); //set up a projection for the left half of the window + glut_render_modelview(); //set up the modelview matrix using camera details + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen + + //_GT.glRandColorCenterlineGT(dlist1, _gt_t, colormap); + _GT.glRandColorCylinder1(dlist1, _gt_t, colormap); + + glut_render_right_projection(); //set up a projection for the right half of the window + glut_render_modelview(); //set up the modelview matrix using camera details + //_T.glRandColorCenterlineT(dlist2, _t_gt, colormap); + _T.glRandColorCylinder2(dlist2, _t_gt, colormap); + } + } + } + //-----working with swc files----- + else { + if (num_nets == 1) { //if a single network is loaded + std::cout << "You should have at least two networks to do mapping." << std::endl; //exit program because there isn't enough network + exit(1); + } + if (num_nets == 2) { //if two networks are loaded + //in compare mode + if (compareMode) { + glEnable(GL_DEPTH_TEST); //enable depth glut_render_left_projection(); //set up a projection for the left half of the window glut_render_modelview(); //set up the modelview matrix using camera details glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen @@ -204,37 +256,38 @@ void glut_render(void) { _T.glCenterline(); //render the T network } + //in mapping mode else { - glEnable(GL_DEPTH_TEST); + glEnable(GL_DEPTH_TEST); //enable depth glut_render_left_projection(); //set up a projection for the left half of the window glut_render_modelview(); //set up the modelview matrix using camera details glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen //_GT.glRandColorCenterlineGT(dlist1, _gt_t, colormap); - _GT.glCylinderGT(dlist1, _gt_t, colormap); + _GT.glRandColorCylinder1_swc(dlist1, _gt_t, colormap); glut_render_right_projection(); //set up a projection for the right half of the window glut_render_modelview(); //set up the modelview matrix using camera details //_T.glRandColorCenterlineT(dlist2, _t_gt, colormap); - _T.glCylinderT(dlist2, _t_gt, colormap); + _T.glRandColorCylinder2_swc(dlist2, _t_gt, colormap); } } } } - if (num_nets == 2) { + if (num_nets == 2) { // works only with two networks std::ostringstream ss; if (mappingMode) // if it is in mapping mode ss << "Mapping Mode"; else - ss << "Compare Mode"; // default mode is compare mode + ss << "Compare Mode"; // default mode is compare mode glDisable(GL_TEXTURE_1D); - glMatrixMode(GL_PROJECTION); //Set up the 2d viewport for mode text printing + glMatrixMode(GL_PROJECTION); // set up the 2d viewport for mode text printing glPushMatrix(); glLoadIdentity(); - int X = glutGet(GLUT_WINDOW_WIDTH); - int Y = glutGet(GLUT_WINDOW_HEIGHT); + int X = glutGet(GLUT_WINDOW_WIDTH); // get the current window width + int Y = glutGet(GLUT_WINDOW_HEIGHT); // get the current window height glViewport(0, 0, X / 2, Y); // locate to left bottom corner gluOrtho2D(0, X, 0, Y); // define othogonal aspect glColor3f(0.0, 1.0, 0.0); // using green to show mode @@ -243,7 +296,7 @@ void glut_render(void) { glPushMatrix(); glLoadIdentity(); - glRasterPos2f(0, 5); //print text in the bottom left corner + glRasterPos2f(0, 5); //print text in the left bottom corner glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, (const unsigned char*)(ss.str().c_str())); glPopMatrix(); @@ -270,6 +323,22 @@ void glut_motion(int x, int y){ } } +// sets the menu options +void glut_menu(int value) { + if (value == 1) { // menu 1 represents comparing mode + compareMode = true; + mappingMode = false; + } + if (value == 2) { // menu 2 represents mapping mode + compareMode = false; + mappingMode = true; + } + if (value == 3) { + exit(0); + } + glutPostRedisplay(); +} + // sets the mouse position when clicked void glut_mouse(int button, int state, int x, int y){ @@ -319,8 +388,23 @@ void glut_mouse(int button, int state, int x, int y){ } } +// define camera move based on mouse wheel move(actually we can combine this with glut_mouse) +void glut_wheel(int wheel, int direction, int x, int y) { + float cam_move_fac; // camera move unit length + stim::vec3 eye = cam.getPosition(); // get the camera position (eye point) + stim::vec3 focus = cam.getLookAt(); // get the camera focal point + cam_move_fac = fabs(focus[2] - eye[2]) / 50; // divided by 50 + + if (direction > 0) // if it is button 3(up) + des -= cam_move_fac; + else // if it is button 4(down) + des += cam_move_fac; + glutPostRedisplay(); +} + +// define keyboard inputs void glut_keyboard(unsigned char key, int x, int y){ - if(key == 'm') // press m to change mode + if(key == 'm') // if keyboard 'm' is pressed { if(compareMode && !mappingMode){ // if it is in compare mode compareMode = false; @@ -331,6 +415,9 @@ void glut_keyboard(unsigned char key, int x, int y){ mappingMode = false; } } + if (key == 27) { // if keyboard "ESC" is pressed + exit(0); // exit + } glutPostRedisplay(); } @@ -370,18 +457,27 @@ void glut_initialize(){ myargv [0]=strdup ("netmets"); glutInit(&myargc, myargv); //pass bogus arguments to glutInit() - glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); //generate a color buffer, depth buffer, and enable double buffering + glutSetOption(GLUT_MULTISAMPLE, 8); + glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE); //generate a color buffer, depth buffer, and enable double buffering glutInitWindowPosition(100,100); //set the initial window position glutInitWindowSize(320, 320); //set the initial window size glutCreateWindow("NetMets - STIM Lab, UH"); //set the dialog box title - + glEnable(GL_MULTISAMPLE); // register callback functions glutDisplayFunc(glut_render); //function executed for rendering - renders networks glutMouseFunc(glut_mouse); //executed on a mouse click - sets starting mouse positions for rotations glutMotionFunc(glut_motion); //executed when the mouse is moved while a button is pressed - if(ind == 1) //only in mapping mode, keyboard will be used - glutKeyboardFunc(glut_keyboard); + if (ind == 1) { //only in mapping mode, keyboard will be used + glutKeyboardFunc(glut_keyboard); //register keyboard callback + glutCreateMenu(glut_menu); //register menu option callback + glutAddMenuEntry("Comparing Mode", 1);//register menu 1 as comparing mode + glutAddMenuEntry("Mapping Mode", 2); //register menu 2 as mapping mode + glutAddMenuEntry("Exit", 3); //register menu 3 as exiting + glutAttachMenu(GLUT_RIGHT_BUTTON); //register right mouse to open menu option + } + if (swc_ind == 1) //only in rendering swc files, mouse wheel will be used + glutMouseWheelFunc(glut_wheel); texture_initialize(); //set up texture mapping (create texture maps, enable features) @@ -393,6 +489,7 @@ void glut_initialize(){ } #ifdef __CUDACC__ +// set specific device to work on void setdevice(int &device){ int count; cudaGetDeviceCount(&count); // numbers of device that are available @@ -403,7 +500,7 @@ void setdevice(int &device){ } #else void setdevice(int &device){ - device = -1; + device = -1; // set to default -1 } #endif @@ -421,18 +518,22 @@ void compare(float sigma, int device){ std::cout << "FPR: " << FNR << std::endl; } +//split and map two networks and fill the networks' R with metric information void map(float sigma, int device, float threshold){ + // compare and split two networks _GT.split(GT, T, sigma, device, threshold); _T.split(T, GT, sigma, device, threshold); + // mapping two new splitted networks and get their edge relation _GT.mapping(_T, _gt_t, device, threshold); _T.mapping(_GT, _t_gt, device, threshold); + // generate random color set based on the number of edges in GT size_t num = _gt_t.size(); // also create random color for unmapping edge, but won't be used though colormap.resize(3 * num); // 3 portions compound RGB for(int i = 0; i < 3 * num; i++) - colormap[i] = rand()/(float)RAND_MAX; + colormap[i] = rand()/(float)RAND_MAX; // set to [0, 1] //calculate the metrics float FPR = _GT.average(0); //calculate the metrics @@ -442,6 +543,30 @@ void map(float sigma, int device, float threshold){ std::cout << "FPR: " << FNR << std::endl; } +void map_swc(float sigma, int device, float threshold) { + + // compare two networks + _GT = GT.compare(T, sigma, device); //compare the ground truth to the test case - store errors in _GT + _T = T.compare(_GT, sigma, device); //compare the test case to the ground truth - store errors in _T + + // mapping two networks and get their edge relation + _GT.mapping(_T, _gt_t, device, threshold); + _T.mapping(_GT, _t_gt, device, threshold); + + // generate random color set based on the number of edges in GT + size_t num = _gt_t.size(); // also create random color for unmapping edge, but won't be used though + colormap.resize(3 * num); // 3 portions compound RGB + for (int i = 0; i < 3 * num; i++) + colormap[i] = rand() / (float)RAND_MAX; // set to [0, 1] + + //calculate the metrics + float FPR = _GT.average(0); //calculate the metrics + float FNR = _T.average(0); + + std::cout << "FNR: " << FPR << std::endl; //print false alarms and misses + std::cout << "FPR: " << FNR << std::endl; +} + // writes features of the networks i.e average segment length, tortuosity, branching index, contraction, fractal dimension, number of end and branch points to a csv file // Pranathi wrote this - saves network features to a CSV file void features(std::string filename){ @@ -480,7 +605,7 @@ void advertise(){ std::cout<<"========================================================================="<= 1) { // if at least one network file is specified - num_nets = 1; // set the number of networks to one - GT.load_swc(args.arg(0)); // load the specified file as the ground truth - } - if (args.nargs() == 2) { //if two files are specified, they will be displayed in neighboring viewports and compared + if (args.nargs() >= 1) { // if at least one network file is specified + num_nets = 1; // set the number of networks to one + std::vector tmp = stim::parser::split(args.arg(0), '.'); // split the filename at '.' + if ("swc" == tmp[1]) { // loading swc file + GT.load_swc(args.arg(0)); // load the specified file as the ground truth + swc_ind = 1; // set the indicator of swc file to 1 + } + else if ("obj" == tmp[1]) // loading obj file + GT.load_obj(args.arg(0)); // load the specified file as the ground truth + else { + std::cout << "Invalid loading file" << std::endl; + exit(1); + } + } + + if (args.nargs() == 2) { //if two files are specified, they will be displayed in neighboring viewports and compared + if (1 == swc_ind) { //loading swc files int device = args["device"].as_int(); //get the device value from the user num_nets = 2; //set the number of networks to two - //does it need to be resampled?? + //does it need to be resampled?? float sigma = args["sigma"].as_float(); //get the sigma value from the user T.load_swc(args.arg(1)); //load the second (test) network if (args["features"].is_set()) //if the user wants to save features @@ -526,21 +661,15 @@ int main(int argc, char* argv[]) GT = GT.resample(resample_rate * sigma); //resample both networks based on the sigma value T = T.resample(resample_rate * sigma); if (args["mapping"].is_set()) { - std::cout << "right now networks that are loaded from swc files do not need to be mapped with each other!" << std::endl; - exit(1); + float threshold = args["mapping"].as_float(); + map_swc(sigma, device, threshold); + //std::cout << "right now networks that are loaded from swc files do not need to be mapped with each other!" << std::endl; + //exit(1); } else compare(sigma, device); //run the comparison algorithm } - } - - else { //if it is to load a obj file - if (args.nargs() >= 1) { //if at least one network file is specified - num_nets = 1; //set the number of networks to one - GT.load_obj(args.arg(0)); //load the specified file as the ground truth - /*GT.to_txt("Graph.txt");*/ - } - if (args.nargs() == 2) { //if two files are specified, they will be displayed in neighboring viewports and compared + else { int device = args["device"].as_int(); //get the device value from the user num_nets = 2; //set the number of networks to two float sigma = args["sigma"].as_float(); //get the sigma value from the user @@ -554,15 +683,12 @@ int main(int argc, char* argv[]) map(sigma, device, threshold); } else - compare(sigma, device); //run the comparison algorithm + compare(sigma, device); //run the comparison algorithm } } //if a GUI is requested, display the network using OpenGL if(args["gui"].is_set()){ - if (args["swc"].is_set()) { - swc_ind = 1; - } if (args["mapping"].is_set()) { ind = 1; //set indicator of mapping to 1(true) bb = _GT.boundingbox(); //generate a bounding volume -- libgit2 0.21.4