//=========================================================================== // SISL - SINTEF Spline Library, version 4.5.0. // Definition and interrogation of NURBS curves and surfaces. // // Copyright (C) 2000-2005, 2010 SINTEF ICT, Applied Mathematics, Norway. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., // 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // Contact information: E-mail: tor.dokken@sintef.no // SINTEF ICT, Department of Applied Mathematics, // P.O. Box 124 Blindern, // 0314 Oslo, Norway. // // Other licenses are also available for this software, notably licenses // for: // - Building commercial software. // - Building software whose source code you wish to keep private. //=========================================================================== 00040 #ifndef WIN32 00041 # include <unistd.h> // usleep 00042 #else 00043 # define MIDDLE_EMU 00044 #endif 00045 00046 #ifdef MICROSOFT 00047 # include <time.h> 00048 #endif 00049 00050 static const int DEFAULT_REF = 30000000; 00051 static const int DEFAULT_MAX_REF = 100; 00052 00053 char init_key_string[1000]; 00054 double axis_thickness=0.3, axis_length=0.7, marker_size=1.0; 00055 int draw_edges=0; 00056 float wire_col=0.0, background_col=0.0; 00057 int draw_axes=1; 00058 int frames_without_movement=0; 00059 00060 #define MAX_SURFACES 100 00061 #define MAX_CURVES 2000 00062 #define MAX_LINES 100 00063 00064 SISLSurf *surface[MAX_SURFACES]; 00065 int surfaces=0, selected_surface=-1, surface_highlights=0, curve_highlights=0; 00066 int selected_curve=-1; 00067 double *normal[MAX_SURFACES]; 00068 int surf_enabled[MAX_SURFACES]; 00069 int curve_enabled[MAX_CURVES]; 00070 char *surface_name[MAX_SURFACES]; 00071 char *curve_name[MAX_CURVES]; 00072 SISLCurve *curve[MAX_CURVES]; 00073 int curves=0; 00074 double *discr_curve[MAX_CURVES]; // This must be filled with NULLs. 00075 vector< vector3t<float> > pcloud; 00076 00077 // 001101: Moving these out of set_material, so they can be used by the 00078 // curve-drawing functions too... 00079 // 021203: There is a problem with duplicated code here... Should be 00080 // resolved some time... 00081 // 00082 const int predef_colours=6; 00083 const double col_setting[3*predef_colours] 00084 ={1.0, 0.0, 0.0, 00085 0.0, 1.0, 0.0, 00086 0.0, 0.0, 1.0, 00087 1.0, 1.0, 0.0, 00088 0.0, 1.0, 1.0, 00089 1.0, 0.0, 1.0}; 00090 const double col_x_setting_back[3*predef_colours] 00091 ={0.6, 0.2, 0.0, 00092 0.0, 0.6, 0.2, 00093 0.2, 0.0, 0.6, 00094 0.6, 0.6, 0.2, 00095 0.2, 0.6, 0.6, 00096 0.6, 0.2, 0.6}; 00097 00098 00099 static std::string general_help_string = 00100 //-------|---------|---------|---------|---------|---------|---------|---------| 00101 "USAGE:\n" 00102 "sisl_view_demo <option list> \n" 00103 "The options are: \n" 00104 "'s' - next string is the filename of one or more surfaces to read \n" 00105 "'c' - next string is the filename of one or more curves to read \n" 00106 "'p' - next string is the filename of a pointcloud to read \n" 00107 //"'r' - set refinement factor (Note! Must appear before 's' option.)\n" 00108 //"'R' - set max refinement factor (Note! Must appear before 's' option.)\n" 00109 "'r' - set max refinement factor (Note! Must appear before 's' option.)\n" 00110 "'e' - a string with keypresses to execute follows \n" 00111 "'hotkeys' - display a list of hotkeys that can be used \n" 00112 " when viewing an object\n\n"; 00113 00114 00115 static std::string hotkey_help_string = 00116 //-------|---------|---------|---------|---------|---------|---------|---------| 00117 "\nCommand keys in viewer are: \n" 00118 "\n" 00119 "---General---\n" 00120 "'q' - Quit\n" 00121 "\n" 00122 "---Selection---\n" 00123 "<space> - select curve by cycling through each of them\n" 00124 "<tab> - select surface by cycling through each of them\n" 00125 "\n" 00126 "---Toggles---\n" 00127 "'B' - toggle between black and white color for backgrounds\n" 00128 "'A' - toggle axes on/off\n" 00129 "'w' - toggle wireframe on/off\n" 00130 "\n" 00131 "---Enabling/disabling---\n" 00132 "'e' - enable/disable currently selected surface\n" 00133 "<ctrl-e> - enable/disable currently selected curve\n" 00134 "'a' - enable all surfaces\n" 00135 "<ctrl-a> - enable all curves\n" 00136 "'d' - disable all other surfaces than this\n" 00137 "<ctrl-d> - disable all other curves than this\n" 00138 "\n" 00139 "---Centering of elements---\n" 00140 "'O' - center and rescale (i.e. ditch aspect ratio) all objects around origo\n" 00141 " such that they fit snuggly into a (-1, -1, -1) to (1, 1, 1) cube.\n" 00142 "'o' - center all objects around origo, no rescaling done, aspect ratios\n" 00143 " preserved.\n" 00144 "\n" 00145 "---Size of elements---\n" 00146 "'+' - increase thickness of axes\n" 00147 "'-' - decrease thickness of axes\n" 00148 "'>' - increase size of points\n" 00149 "'<' - decrease size of points\n" 00150 "'*' / increase length of axes\n" 00151 "'/' - decrease length of axes\n" 00152 "\n" 00153 "---Load/save viewpoint---\n" 00154 "[n] is here an integer from 0 to 9.\n" 00155 "<esc>-'w'-[n] - store viewpoint in slot [n]\n" 00156 "<esc>-'r'-[n] - load viewpoint from slot[n]\n" 00157 "\n\n"; 00158 00159 static std::istream& eatwhite(std::istream& is) 00160 { 00161 char c; 00162 while (is.get(c)) { 00163 if (!isspace(c)) { 00164 is.putback(c); 00165 break; 00166 } 00167 } 00168 return is; 00169 } 00170 00171 static void set_material(int i) 00172 { 00173 const double a=0.8; 00174 int j; 00175 i=i+4; 00176 i=i % predef_colours; 00177 00178 float front_mat_shininess[] = {150.0}; 00179 float front_mat_specular[] = {0.9, 0.9, 0.9, a}; 00180 00181 float front_mat_ambient[] = {0.2, 0.1, 0.1, a}; 00182 float front_mat_diffuse[] = {0.6, 0.2, 0.2, a}; 00183 float front_mat_emission[] = {0.2, 0.05, 0.05, a}; 00184 float back_mat_ambient[] = {0.2, 0.2, 0.1, a}; 00185 float back_mat_diffuse[] = {0.6, 0.6, 0.2, a}; 00186 float back_mat_emission[] = {0.2, 0.2, 0.05, a}; 00187 00188 for (j=0; j<3; j++) 00189 { 00190 front_mat_ambient[j] =0.1 *col_setting[ 3*i+j]+0.1 ; 00191 front_mat_diffuse[j] =0.5 *col_setting[ 3*i+j]+0.2 ; 00192 front_mat_emission[j]=0.15*col_setting[ 3*i+j]+0.05; 00193 back_mat_ambient[j] =0.1 *col_x_setting_back[3*i+j]+0.1 ; 00194 back_mat_diffuse[j] =0.5 *col_x_setting_back[3*i+j]+0.2 ; 00195 back_mat_emission[j] =0.15*col_x_setting_back[3*i+j]+0.05; 00196 } 00197 00198 glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess); 00199 glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular); 00200 glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse); 00201 glMaterialfv(GL_FRONT, GL_AMBIENT, front_mat_ambient); 00202 glMaterialfv(GL_FRONT, GL_EMISSION, front_mat_emission); 00203 00204 glMaterialfv(GL_BACK, GL_SHININESS, front_mat_shininess); 00205 glMaterialfv(GL_BACK, GL_SPECULAR, front_mat_specular); 00206 glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse); 00207 glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient); 00208 glMaterialfv(GL_BACK, GL_EMISSION, back_mat_emission); 00209 } 00210 00211 00212 00213 00214 00215 00216 static void show_general_help() 00217 { 00218 puts(general_help_string.c_str()); 00219 } 00220 00221 00222 00223 00224 00225 00226 static void show_hotkey_help() 00227 { 00228 puts(hotkey_help_string.c_str()); 00229 } 00230 00231 00232 00233 00234 00235 00236 static void draw_all_surfaces(void) 00237 { 00238 00239 int i, j, k; 00240 00241 for (i=0; i<surfaces; i++) 00242 { 00243 if ((surface_highlights) && (selected_surface==i)) 00244 glDisable(GL_LIGHTING); 00245 set_material(i); 00246 00247 // 00248 // As a first brute force solution, we draw single triangles, 00249 // and we draw the control polygon. Normals should already be 00250 // computed and stored in the array 'normal'. 00251 // 00252 // A surface is drawn if it is enabled, or if it is selected. 00253 // 00254 if ((surf_enabled[i]) || 00255 ((surface_highlights) && (selected_surface==i))) 00256 // 00257 // ... or else, we fall back on the control polygon solution. 00258 // 00259 for (j=0; j<surface[i]->in1-1; j++) 00260 { 00261 // 00262 // Now, we do a strip in the second (v) 00263 // parameter direction. 00264 // 00265 glBegin(GL_TRIANGLE_STRIP); 00266 glColor3f(1.0, 1.0, 1.0); 00267 for (k=0; k<surface[i]->in2; k++) 00268 { 00269 int p=3*(j+k*surface[i]->in1); 00270 glNormal3f(normal[i][p+0], normal[i][p+1], normal[i][p+2]); 00271 glColor3f(0.0, 1.0, 0.0); 00272 glTexCoord2d((double)k, 0.0); 00273 glVertex3f(surface[i]->ecoef[p+0], 00274 surface[i]->ecoef[p+1], 00275 surface[i]->ecoef[p+2]); 00276 p+=3; 00277 glNormal3f(normal[i][p+0], normal[i][p+1], normal[i][p+2]); 00278 glColor3f(1.0, 0.0, 0.0); 00279 glTexCoord2d((double)k, 1.0); 00280 glVertex3f(surface[i]->ecoef[p+0], 00281 surface[i]->ecoef[p+1], 00282 surface[i]->ecoef[p+2]); 00283 } 00284 glEnd(); 00285 00286 if (draw_edges) 00287 { 00288 glBegin(GL_LINE_STRIP); 00289 glColor3f(1.0, 1.0, 1.0); 00290 for (k=0; k<surface[i]->in2; k++) 00291 { 00292 int p=3*(j+k*surface[i]->in1); 00293 glNormal3f(normal[i][p+0], normal[i][p+1], 00294 normal[i][p+2]); 00295 glColor3f(0.0, 1.0, 0.0); 00296 glTexCoord2d((double)k, 0.0); 00297 glVertex3f(surface[i]->ecoef[p+0], 00298 surface[i]->ecoef[p+1], 00299 surface[i]->ecoef[p+2]); 00300 p+=3; 00301 glNormal3f(normal[i][p+0], normal[i][p+1], 00302 normal[i][p+2]); 00303 glColor3f(1.0, 0.0, 0.0); 00304 glTexCoord2d((double)k, 1.0); 00305 glVertex3f(surface[i]->ecoef[p+0], 00306 surface[i]->ecoef[p+1], 00307 surface[i]->ecoef[p+2]); 00308 } 00309 00310 glEnd(); 00311 } 00312 00313 } 00314 00315 if ((surface_highlights) && (selected_surface==i)) 00316 { 00317 surface_highlights--; 00318 glEnable(GL_LIGHTING); 00319 } 00320 glDisable(GL_BLEND); 00321 } 00322 } 00323 00324 00325 00326 00327 00328 00329 static void draw_all_points(void) 00330 { 00331 int i; 00332 00333 glDisable(GL_LIGHTING); 00334 glPointSize(marker_size); 00335 glBegin(GL_POINTS); 00336 glColor3f(1.0, 1.0, 1.0); 00337 for (i=0; i<int(pcloud.size()); i++) 00338 glVertex3fv(pcloud[i].raw()); 00339 glEnd(); 00340 glEnable(GL_LIGHTING); 00341 } 00342 00343 00344 00345 00346 00347 00348 void draw_all_curves(void) 00349 { 00350 int i, j; 00351 00352 for (i=0; i<curves; i++) 00353 { 00354 if (curve_enabled[i]) 00355 { 00356 // 00357 // As a first brute force solution, we simply evaluate the curves 00358 // in 100 points and draw straight line segments. 00359 // All evaluations are done once, since the curves are not evolving 00360 // in any way. 00361 // 00362 #define CURVE_EVALUATIONS 500 00363 if (discr_curve[i]==NULL) 00364 { 00365 discr_curve[i]=new double[3*CURVE_EVALUATIONS]; 00366 int left=0; 00367 00368 for (j=0; j<CURVE_EVALUATIONS; j++) 00369 { 00370 double t= 00371 curve[i]->et[curve[i]->ik-1]+ 00372 (curve[i]->et[curve[i]->in]-curve[i]->et[curve[i]->ik-1])* 00373 j/(CURVE_EVALUATIONS-1.0); 00374 { 00375 int stat; 00376 00377 s1227(curve[i], 0, t, &left, discr_curve[i]+3*j, &stat); 00378 if (stat!=0) 00379 CRIT_ERR(printf("s1227 returned status %d.\n", stat)); 00380 } 00381 } 00382 } 00383 00384 // 00385 // Now we draw all the line segments. 00386 // 00387 glLineWidth(1.0); 00388 glDisable(GL_LIGHTING); 00389 glBegin(GL_LINE_STRIP); 00390 { 00391 // int c=i % predef_colours; 00392 00393 for (j=0; j<CURVE_EVALUATIONS; j++) 00394 { 00395 //glColor3dv(col_setting+3*c); 00396 //glColor3f(0.0, 0.0, 0.0); 00397 glColor3f(1.0-background_col, 00398 1.0-background_col, 00399 1.0-background_col); 00400 glVertex3dv(discr_curve[i]+3*j); 00401 // printf("%4d: %f %f %f\n", j, discr_curve[i][3*j], 00402 // discr_curve[i][3*j+1], discr_curve[i][3*j+2]); 00403 } 00404 } 00405 glEnd(); 00406 glEnable(GL_LIGHTING); 00407 00408 } // end of if(curve_enabled[i]) ... 00409 } 00410 } 00411 00412 00413 00414 00415 00416 00417 static void draw(void) 00418 { 00419 /* We don't push the matrix stack, we just keep adding rotations. */ 00420 rotate(yrot*0.01, xrot*0.01, zrot*0.01); 00421 00422 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00423 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00424 00425 draw_all_surfaces(); 00426 draw_all_curves(); 00427 draw_all_points(); 00428 00429 if (draw_axes) 00430 draw_gl_axes_old(10, axis_length, 00431 axis_thickness*0.01, axis_thickness*0.04, 0.1); 00432 glFlush(); 00433 glutSwapBuffers(); 00434 glutPostRedisplay(); 00435 00436 mouse_movement=0; 00437 } 00438 00439 00440 00441 00442 00443 00444 static void Reshape(int width, int height) 00445 { 00446 glViewport(0, 0, (GLint)width, (GLint)height); 00447 /* 00448 glutPostRedisplay(); 00449 */ 00450 } 00451 00452 00453 00454 00455 00456 00457 static void center_and_scale(const int rescale) 00458 { 00459 int i, j; 00460 double minx=1e30, miny=1e30, minz=1e30; 00461 double maxx=-1e30, maxy=-1e30, maxz=-1e30; 00462 00463 for (i=0; i<surfaces; i++) 00464 if ((surf_enabled[i]) && (surface[i]->idim==3)) 00465 for (j=0; j<surface[i]->in1*surface[i]->in2; j++) 00466 { 00467 minx=MIN(minx, surface[i]->ecoef[3*j+0]); 00468 miny=MIN(miny, surface[i]->ecoef[3*j+1]); 00469 minz=MIN(minz, surface[i]->ecoef[3*j+2]); 00470 maxx=MAX(maxx, surface[i]->ecoef[3*j+0]); 00471 maxy=MAX(maxy, surface[i]->ecoef[3*j+1]); 00472 maxz=MAX(maxz, surface[i]->ecoef[3*j+2]); 00473 } 00474 00475 for (i=0; i<curves; i++) 00476 if (curve_enabled[i]) 00477 for (j=0; j<curve[i]->in; j++) 00478 { 00479 minx=MIN(minx, curve[i]->ecoef[3*j+0]); 00480 miny=MIN(miny, curve[i]->ecoef[3*j+1]); 00481 minz=MIN(minz, curve[i]->ecoef[3*j+2]); 00482 maxx=MAX(maxx, curve[i]->ecoef[3*j+0]); 00483 maxy=MAX(maxy, curve[i]->ecoef[3*j+1]); 00484 maxz=MAX(maxz, curve[i]->ecoef[3*j+2]); 00485 } 00486 00487 for (i=0; i<int(pcloud.size()); i++) 00488 { 00489 minx=MIN(minx, pcloud[i].x()); 00490 miny=MIN(miny, pcloud[i].y()); 00491 minz=MIN(minz, pcloud[i].z()); 00492 maxx=MAX(maxx, pcloud[i].x()); 00493 maxy=MAX(maxy, pcloud[i].y()); 00494 maxz=MAX(maxz, pcloud[i].z()); 00495 } 00496 00497 // printf("%f %f\n%f %f\n%f %f\n", minx, maxx, miny, maxy, minz, maxz); 00498 00499 if (minx==1e30) 00500 { 00501 puts("\n\n!Oops! No surfaces/curves " 00502 "enabled for 'center_and_rescale'?!\n\n"); 00503 return; 00504 } 00505 00506 double x=-0.5*(maxx+minx); 00507 double y=-0.5*(maxy+miny); 00508 double z=-0.5*(maxz+minz); 00509 double xs=1.0, ys=1.0, zs=1.0; 00510 // printf("transl: %f %f %f\n", x, y, z); 00511 00512 if (rescale) 00513 { 00514 xs=1.0/(maxx+x); 00515 ys=1.0/(maxy+y); 00516 zs=1.0/(maxz+z); 00517 if (fabs(maxx-minx)<1e-10) // We're probably in a plane... 00518 xs=1.0; 00519 if (fabs(maxy-miny)<1e-10) // We're probably in a plane... 00520 ys=1.0; 00521 if (fabs(maxz-minz)<1e-10) // We're probably in a plane... 00522 zs=1.0; 00523 } 00524 00525 for (i=0; i<curves; i++) 00526 { 00527 delete discr_curve[i]; 00528 discr_curve[i]=NULL; 00529 for (j=0; j<curve[i]->in; j++) 00530 { 00531 curve[i]->ecoef[3*j+0]=(curve[i]->ecoef[3*j+0]+x)*xs; 00532 curve[i]->ecoef[3*j+1]=(curve[i]->ecoef[3*j+1]+y)*ys; 00533 curve[i]->ecoef[3*j+2]=(curve[i]->ecoef[3*j+2]+z)*zs; 00534 } 00535 } 00536 00537 for (i=0; i<surfaces; i++) 00538 { 00539 if (surface[i]->ikind!=1) 00540 printf("\nRational (?) surface probably going to be ****** up...\n"); 00541 for (j=0; j<surface[i]->in1*surface[i]->in2; j++) 00542 if (surface[i]->idim==3) 00543 { 00544 surface[i]->ecoef[3*j+0]=(surface[i]->ecoef[3*j+0]+x)*xs; 00545 surface[i]->ecoef[3*j+1]=(surface[i]->ecoef[3*j+1]+y)*ys; 00546 surface[i]->ecoef[3*j+2]=(surface[i]->ecoef[3*j+2]+z)*zs; 00547 } 00548 // if dim!=3, nothing happens... not very graceful, this, but, ... 00549 } 00550 00551 for (i=0; i<int(pcloud.size()); i++) 00552 { 00553 pcloud[i].coo[0]=(pcloud[i].coo[0]+x)*xs; 00554 pcloud[i].coo[1]=(pcloud[i].coo[1]+y)*ys; 00555 pcloud[i].coo[2]=(pcloud[i].coo[2]+z)*zs; 00556 } 00557 00558 // printf("xxx scale: %f %f %f\n", xscale, yscale, zscale); 00559 scale(1.0/xscale, 1.0/yscale, 1.0/zscale); 00560 00561 if (!rescale) 00562 // we don't rescale the data but try to fit it into the frustum. 00563 { 00564 xs=1.0/(maxx+x); 00565 ys=1.0/(maxy+y); 00566 zs=1.0/(maxz+z); 00567 if (fabs(maxx-minx)<1e-10) // We're probably in a plane... 00568 xs=1.0; 00569 if (fabs(maxy-miny)<1e-10) // We're probably in a plane... 00570 ys=1.0; 00571 if (fabs(maxz-minz)<1e-10) // We're probably in a plane... 00572 zs=1.0; 00573 // printf("frustum fit: %f %f %f %f\n", 00574 // xs, ys, zs, std::max(zs, std::max(xs, ys))); 00575 scale(std::max(zs, std::max(xs, ys)), 00576 std::max(zs, std::max(xs, ys)), 00577 std::max(zs, std::max(xs, ys))); 00578 } 00579 00580 } 00581 00582 00583 00584 00585 00586 00587 // 00588 // A forward decl. here, since the 'h' function only works properly 00589 // if the 'read_curves_and_surfaces' follows after 'Key'... 00590 // 00591 static void read_curves_and_surfaces(int argc, char *argv[]); 00592 00593 00594 00595 00596 00597 00598 static void parse_keys(const int key_in, 00599 const unsigned char * const key_ptr=NULL, 00600 const int keys=1) 00601 { 00602 int i; 00603 00604 for (i=0; i<keys; i++) 00605 { 00606 int rescale=0; // Used by 'o' and 'O'. 00607 // Default is the 'no rescale' of 'o'. 00608 int key; 00609 if (key_ptr==NULL) 00610 // Now 'keys' should be 1! 00611 key=key_in; 00612 else 00613 // 00614 // First, we try to detect the "pseudocharacter" '<ESC>'. Or '<TAB>'. 00615 // 010508: Trying to add <CTRL> 00616 // 00617 { 00618 #define ESC_STRING "<ESC>" 00619 #define TAB_STRING "<TAB>" 00620 #define CTRL_STRING "<CTRL>" 00621 const int esc_len=strlen(ESC_STRING); 00622 const int tab_len=strlen(TAB_STRING); 00623 const int ctrl_len=strlen(CTRL_STRING); 00624 00625 if ((keys-i>=esc_len+2) && 00626 (strncmp((const char *)key_ptr+i, ESC_STRING, esc_len)==0)) 00627 { 00628 key = (27<<16) + (key_ptr[i+esc_len]<<8) + key_ptr[i+esc_len+1]; 00629 // 011211: Format seems to be: 27*65536+code1*256+code2. 00630 i+=esc_len+1; 00631 } 00632 else 00633 if ((keys-i>=tab_len) && 00634 (strncmp((const char *)key_ptr+i, TAB_STRING, tab_len)==0)) 00635 { 00636 key=9; 00637 i+=tab_len-1; 00638 } 00639 else 00640 if ((keys-i>=ctrl_len+1) && 00641 (strncmp((const char *)key_ptr+i, CTRL_STRING, ctrl_len)==0)) 00642 { 00643 key = tolower(key_ptr[i+ctrl_len])-'a'+1; 00644 i+=ctrl_len; 00645 } 00646 else 00647 key=key_ptr[i]; 00648 } 00649 00650 // printf("key=%d (%c)\n", key, key); 00651 00652 switch (key) 00653 { 00654 // 00655 // 021203: What was this? Only place obj_trans (from old mouse.h or something 00656 // was used...?!) 00657 // 00658 // case 0: // @H@ Toggle mouse-translation mode. 00659 // obj_trans=1-obj_trans; 00660 // printf("obj_trans=%d\n", obj_trans); 00661 // break; 00662 00663 //-------------------------------------------------- 00664 // 00665 // Selection, enabling etc. of surfaces. 00666 // 00667 //-------------------------------------------------- 00668 00669 case 9: 00670 // (tab) Select surface by cycling through all surfaces. 00671 printf("Surfaces=%d\n", surfaces); 00672 if ((surfaces>0) /* && (surface_highlights==0) */ ) 00673 { 00674 selected_surface++; 00675 if (selected_surface==surfaces) 00676 selected_surface=0; 00677 printf("Surface selected is '%s', which has dim=%d.\n", 00678 surface_name[selected_surface], 00679 surface[selected_surface]->idim); 00680 // 00681 // Now, we signal highlighting of the 00682 // surface for a few frames. 00683 // 00684 surface_highlights=50; 00685 } 00686 break; 00687 00688 case 'e': 00689 // Enable/Disable the selected surface. 00690 if (selected_surface>-1) 00691 surf_enabled[selected_surface]= 00692 1-surf_enabled[selected_surface]; 00693 if (surf_enabled[selected_surface]) 00694 printf("Enabled surface '%s'.\n", 00695 surface_name[selected_surface]); 00696 else 00697 printf("Disabled surface '%s'.\n", 00698 surface_name[selected_surface]); 00699 break; 00700 00701 case 'd': 00702 // Disable all other surfaces than this. 00703 if (selected_surface>-1) 00704 { 00705 int i; 00706 00707 for (i=0; i<surfaces; i++) 00708 surf_enabled[i]=(i==selected_surface); 00709 } 00710 printf("Enabled surface '%s'.\n", 00711 surface_name[selected_surface]); 00712 break; 00713 00714 case 'a': 00715 // Enable all surfaces. 00716 { 00717 int i; 00718 00719 for (i=0; i<surfaces; i++) 00720 surf_enabled[i]=1; 00721 } 00722 puts("All surfaces enabled."); 00723 break; 00724 00725 //-------------------------------------------------- 00726 // 00727 // Selection, enabling etc. of curves. 00728 // 00729 //-------------------------------------------------- 00730 00731 case ' ': 00732 // (space) Select curve by cycling through all of them. 00733 if ((curves>0) && (curve_highlights==0)) 00734 { 00735 selected_curve++; 00736 if (selected_curve==curves) 00737 selected_curve=0; 00738 printf("Curve selected is '%s'.\n", 00739 curve_name[selected_curve]); 00740 surface_highlights=5; 00741 } 00742 break; 00743 00744 case 5: 00745 // (ctrl-e) Enable/Disable the selected curve. 00746 if (selected_curve>-1) 00747 curve_enabled[selected_curve]=1-curve_enabled[selected_curve]; 00748 if (curve_enabled[selected_curve]) 00749 printf("Enabled curve '%s'.\n", curve_name[selected_curve]); 00750 else 00751 printf("Disabled curve '%s'.\n", curve_name[selected_curve]); 00752 break; 00753 case 4: // (ctrl-d) Disable all other curves than this. 00754 if (selected_curve>-1) 00755 { 00756 int i; 00757 00758 for (i=0; i<curves; i++) 00759 curve_enabled[i]=(i==selected_curve); 00760 } 00761 printf("Enabled curve '%s'.\n", curve_name[selected_curve]); 00762 break; 00763 00764 case 1: // (ctrl-a) Enable all curves. 00765 { 00766 int i; 00767 00768 for (i=0; i<curves; i++) 00769 curve_enabled[i]=1; 00770 } 00771 puts("All curves enabled."); 00772 break; 00773 00774 // 00775 // 001206: Hmm... How should we handle the centering and rescaling 00776 // for inifinte straight lines? Could use the point closest 00777 // to origo, perhaps??? 00778 // 00779 case 'O': // Center and rescale all objects around origo. 00780 rescale=1; 00781 // 00782 // Note how we simply continue into the code for 'o'... 00783 // 00784 case 'o': // Center all objects around origo. Possibly rescale. 00785 center_and_scale(rescale); 00786 break; 00787 00788 case 'q': // Quit. 00789 exit(0); 00790 00791 //-------------------------------------------------- 00792 // 00793 // Colour stuff. 00794 // 00795 //-------------------------------------------------- 00796 00797 case 'b': // Toggle between black and white for wireframes. 00798 wire_col=1.0-wire_col; 00799 break; 00800 case 'B': // Toggle between black and white for the background. 00801 background_col=1.0-background_col; 00802 glClearColor(background_col, background_col, background_col, 0.0); 00803 break; 00804 00805 //-------------------------------------------------- 00806 00807 case '+': // Increase thickness of axes. 00808 axis_thickness*=1.1; 00809 //printf("axis_thickness=%f\n", axis_thickness); 00810 break; 00811 case '-': // Decrease thickness of axes. 00812 if (axis_thickness>0.1) 00813 axis_thickness*=0.9; 00814 //printf("axis_thickness=%f\n", axis_thickness); 00815 break; 00816 00817 case '>': // Increase size of point markers. 00818 marker_size*=1.1; 00819 //printf("marker_size=%.5f\n", marker_size); 00820 break; 00821 case '<': // Decrease size of point markers. 00822 if (marker_size>0.00001) 00823 marker_size*=0.9; 00824 //printf("marker_size=%.5f\n", marker_size); 00825 break; 00826 00827 case '*': // Increase length of axes. 00828 axis_length*=1.1; 00829 //printf("axis_length=%f\n", axis_length); 00830 break; 00831 case '/': // Decrease length of axes. 00832 if (axis_length>0.1) 00833 axis_length*=0.9; 00834 //printf("axis_length=%f\n", axis_length); 00835 break; 00836 00837 case 'A': // Toggle axes on/off. 00838 draw_axes=1-draw_axes; 00839 //printf("draw_axes=%d\n", draw_axes); 00840 break; 00841 00842 case 'w': // Toggle wireframe mode on/off, no hidden line removal. 00843 draw_edges=1-draw_edges; 00844 //printf("draw_edges=%d\n", draw_edges); 00845 break; 00846 00847 //-------------------------------------------------- 00848 // 00849 // Reading and writing of viewing parameters. 00850 // 00851 //-------------------------------------------------- 00852 00853 case (27<<16)+('w'<<8)+'1': // (Esc-w-<n>) Storing viewing parameters in slot <n>. 00854 case (27<<16)+('w'<<8)+'2': 00855 case (27<<16)+('w'<<8)+'3': 00856 case (27<<16)+('w'<<8)+'4': 00857 case (27<<16)+('w'<<8)+'5': 00858 case (27<<16)+('w'<<8)+'6': 00859 case (27<<16)+('w'<<8)+'7': 00860 case (27<<16)+('w'<<8)+'8': 00861 case (27<<16)+('w'<<8)+'9': 00862 { 00863 int slot=(key&255)-'1'+1; 00864 00865 printf("Storing viewing parameters in slot %d.\n", slot); 00866 char tmp[1000]; 00867 #ifdef MICROSOFT 00868 // don't know which headerfile to use for VC++... 00869 // Also: Using root instead of home directory... 00870 sprintf(tmp, "view%d", slot); 00871 #else 00872 snprintf(tmp, 1000, "view%d", slot); 00873 #endif 00874 FILE *f=fopen(tmp, "w"); 00875 if (f==NULL) 00876 CRIT_ERR(printf("Error opening file '%s' for writing.\n", tmp)); 00877 write_gl_matrices(f); 00878 fprintf(f, "%.15e %.15e %.15e\n", xtrans, ytrans, ztrans); 00879 fprintf(f, "%.15e %.15e %.15e\n", xscale, yscale, zscale); 00880 fclose(f); 00881 } 00882 break; 00883 case (27<<16)+('r'<<8)+'1': // (Esc-r-<n>) Retrieving viewing parameters in slot <n>. 00884 case (27<<16)+('r'<<8)+'2': 00885 case (27<<16)+('r'<<8)+'3': 00886 case (27<<16)+('r'<<8)+'4': 00887 case (27<<16)+('r'<<8)+'5': 00888 case (27<<16)+('r'<<8)+'6': 00889 case (27<<16)+('r'<<8)+'7': 00890 case (27<<16)+('r'<<8)+'8': 00891 case (27<<16)+('r'<<8)+'9': 00892 { 00893 int slot=(key&255)-'1'+1; 00894 00895 printf("Retrieving viewing parameters from slot %d.\n", slot); 00896 char tmp[1000]; 00897 #ifdef MICROSOFT 00898 // don't know which headerfile to use for VC++... 00899 // Also: Using root instead of home directory... 00900 sprintf(tmp, "/view%d", slot); 00901 #else 00902 snprintf(tmp, 1000, "view%d", slot); 00903 #endif 00904 FILE *f=fopen(tmp, "r"); 00905 if (f==NULL) 00906 printf("Error opening file '%s' for reading, skipping.\n", tmp); 00907 else 00908 { 00909 read_gl_matrices(f); 00910 fscanf(f, "%lf %lf %lf\n", &xtrans, &ytrans, &ztrans); 00911 fscanf(f, "%lf %lf %lf\n", &xscale, &yscale, &zscale); 00912 fclose(f); 00913 } 00914 } 00915 break; 00916 00917 default: 00918 ; 00919 } 00920 } 00921 } 00922 00923 00924 00925 00926 00927 00928 static void Key(unsigned char key_in, int x, int y) 00929 { 00930 static unsigned char multi_key[3]; 00931 static int multi_key_length=0; 00932 int key=key_in; 00933 00934 if ((key==27) && (multi_key_length==0)) 00935 // 00936 // Esc as first key in sequence was pressed. 00937 // 00938 { 00939 multi_key[0]=key; 00940 multi_key_length=1; 00941 return; 00942 } 00943 00944 if ((multi_key_length==1) && (multi_key[0]==27)) 00945 // 00946 // Second key in esc sequence was pressed. 00947 // 00948 { 00949 if ((key=='r') || (key=='w')) 00950 { 00951 multi_key_length=2; 00952 multi_key[1]=key; 00953 return; 00954 } 00955 // 00956 // This causes a two-key esc sequence to be parsed. 00957 // 00958 key+=256*multi_key[0]; 00959 multi_key_length=0; 00960 } 00961 00962 if (multi_key_length==2) 00963 // 00964 // Third key in a known three-key esc sequence was pressed. 00965 // 00966 { 00967 if ((multi_key[1]=='r') || (multi_key[1]=='w')) 00968 if ((key>='1') && (key<='9')) 00969 printf("Storing/retrieving viewing parameters in slot '%c'.\n", key); 00970 // 00971 // This causes the three-key esc sequence to be parsed. 00972 // 00973 key=(multi_key[0]<<16) + (multi_key[1]<<8) + key; 00974 printf("mk=%d %d %d key=%d\n", 00975 multi_key[0], multi_key[1], multi_key[2], key); 00976 multi_key_length=0; 00977 } 00978 00979 // 00980 // Now key can be extended into max. 3 bytes... 00981 // 00982 parse_keys(key); 00983 00984 glutPostRedisplay(); 00985 } 00986 00987 00988 00989 00990 00991 00992 static void idle_func(void) 00993 { 00994 } 00995 00996 00997 00998 00999 01000 01001 static void read_curves_and_surfaces(int argc, char *argv[]) 01002 { 01003 xscale=yscale=zscale=1.0; 01004 int ref=DEFAULT_REF; // Number of new knots between old ones. 01005 int maxref=DEFAULT_MAX_REF; // Maximal number of coeffs in any given direction. 01006 // (n, n) makes sure new knots are inserted close to max limit = n... 01007 int i; 01008 01009 // 01010 // This must be reset every time we change control vertices, since 01011 // the discretization is done in the drawing routine. 01012 // 01013 for (i=0; i<curves; i++) { 01014 if (discr_curve[i]!=NULL) { 01015 delete discr_curve[i]; 01016 discr_curve[i]=NULL; 01017 } 01018 } 01019 01020 // @HH@ 01021 // @HH@ Use the following optional command line options: 01022 // @HH@ 01023 01024 surfaces=0; 01025 curves=0; 01026 01027 01028 01029 for (i=1; i<argc; i++) { 01030 switch (argv[i][0]) { 01031 case 's': { 01032 // Next string is filename for surface. (One surface.) 01033 01034 puts("Reading surfaces"); 01035 // surface[surfaces-1]=read_nurbs_sf(argv[i+1]); // old format 01036 01037 std::vector<SISLSurf*> tmp; 01038 std::ifstream is(argv[i+1]); 01039 if (!is) { 01040 CRIT_ERR(printf("Could not open file: '%s'.\n", argv[i+1])); 01041 } 01042 try { 01043 eatwhite(is); 01044 while (!is.eof()) { 01045 //surface[surfaces-1] = readGoSurface(is); 01046 tmp.push_back(readGoSurface(is)); 01047 eatwhite(is); 01048 } 01049 } catch (std::exception& e) { 01050 CRIT_ERR(printf("Error occured while reading surface: %s\n", e.what())); 01051 } 01052 is.close(); 01053 int num_surfaces = tmp.size(); 01054 if (surfaces + num_surfaces > MAX_SURFACES) { 01055 CRIT_ERR(puts("Increase MAX_SURFACES.")); 01056 } 01057 01058 for (int k = 0; k < num_surfaces; ++k) { 01059 // 01060 // 010116: This should be a quick fix for periodic 01061 // surfaces... 01062 // 01063 if (tmp[k] == NULL) { 01064 CRIT_ERR(printf("Couldn't read SISLSurf '%s'.\n", argv[i+1])); 01065 } 01066 01067 if ((tmp[k]->cuopen_1 == SISL_CRV_PERIODIC || 01068 tmp[k]->cuopen_2 == SISL_CRV_PERIODIC)) { 01069 int kstat; 01070 SISLSurf *tmp_surf; 01071 make_sf_kreg(tmp[k], &tmp_surf, &kstat); 01072 if (kstat < 0) { 01073 CRIT_ERR(printf("make_sf_kreg failed!\n")); 01074 } 01075 freeSurf(tmp[k]); 01076 tmp[k] = tmp_surf; 01077 } 01078 if (tmp[k]->idim != 3) { 01079 CRIT_ERR(printf("Dimension of surface is %d and not 3!\n", 01080 tmp[k]->idim)); 01081 } 01082 01083 if (surface[surfaces]) { 01084 // deleting old surface 01085 freeSurf(surface[surfaces]); 01086 } 01087 surface[surfaces] = tmp[k]; 01088 surface_name[surfaces] = argv[i+1]; 01089 surf_enabled[surfaces] = 1; 01090 01091 // Generating an approximating polygon. 01092 lower_degree_and_subdivide(surface + surfaces, ref, maxref); 01093 01094 // evaluating normals (normalized) 01095 delete normal[surfaces]; 01096 compute_surface_normals(surface[surfaces], normal + surfaces); 01097 01098 ++surfaces; 01099 } 01100 } 01101 i++; 01102 break; 01103 01104 case 'c': { 01105 // Next string is filename for file containing 1 curve. 01106 01107 printf("Reading a single curve into slot %d.\n", curves); 01108 01109 std::vector<SISLCurve*> tmp; 01110 01111 //n=get_curve_set(argv[i+1], &tmp, &stat); 01112 //get_single_curve(argv[i+1], &tmp, &stat); // old format 01113 std::ifstream is(argv[i+1]); 01114 if (!is) { 01115 CRIT_ERR(printf("Could not open file: '%s'.\n", argv[i+1])); 01116 } 01117 try { 01118 eatwhite(is); 01119 while (!is.eof()) { 01120 tmp.push_back(readGoCurve(is)); 01121 eatwhite(is); 01122 } 01123 } catch (std::exception& e) { 01124 CRIT_ERR(printf("Error occured while reading curve: %s\n", e.what())); 01125 } 01126 is.close(); 01127 int num_curves = tmp.size(); 01128 01129 if (curves + num_curves > MAX_CURVES) { 01130 CRIT_ERR(puts("Increase MAX_CURVES.")); 01131 } 01132 01133 for(int k = 0; k < num_curves; ++k) { 01134 if (curve[curves + k] != NULL) { 01135 freeCurve(curve[curves + k]); 01136 } 01137 curve[curves + k] = tmp[k]; 01138 01139 // 01140 // 001206: If the dimension is 2, we set up a 01141 // new curve, filling in zeros. 01142 // 01143 if (curve[curves + k]->idim==2) { 01144 01145 double *new_coeffs= 01146 new double[3*curve[curves + k]->in]; 01147 if (new_coeffs==NULL) 01148 CRIT_ERR(puts("Couldn't allocate memory.")); 01149 int j; 01150 01151 for (j=0; j<curve[curves + k]->in; j++) { 01152 new_coeffs[3*j+0]= curve[curves + k]->ecoef[2*j+0]; 01153 new_coeffs[3*j+1]= curve[curves + k]->ecoef[2*j+1]; 01154 new_coeffs[3*j+2]=0.0; 01155 } 01156 SISLCurve *tmp2=curve[curves + k]; 01157 curve[curves + k]= newCurve(tmp2->in, tmp2->ik, tmp2->et, 01158 new_coeffs, tmp2->ikind, 3, 1); 01159 freeCurve(tmp2); 01160 } 01161 01162 if (curve[curves + k]->idim!=3) { 01163 CRIT_ERR(printf("Dimension of curve is %d and not 3?!\n", 01164 curve[curves + k]->idim)); 01165 } 01166 01167 curve_name[curves + k]=argv[i+1]; 01168 curve_enabled[curves + k]=1; 01169 } 01170 curves+=num_curves; 01171 } 01172 i++; 01173 break; 01174 01175 case 'p': { 01176 // Next string is filename for file containing a point cloud. 01177 01178 printf("Reading a point cloud.\n"); 01179 01180 std::ifstream is(argv[i+1]); 01181 if (!is) { 01182 CRIT_ERR(printf("Could not open file: '%s'.\n", argv[i+1])); 01183 } 01184 try { 01185 vector<double> coords; 01186 readGoPoints(coords, is); 01187 int num_points = int(coords.size()) / 3; 01188 printf("Number of vertices: %d\n", num_points); 01189 for (int i = 0; i < num_points; ++i) { 01190 pcloud.push_back(vector3t<float>(coords[3 * i], 01191 coords[3 * i + 1], 01192 coords[3 * i + 2])); 01193 } 01194 // eatwhite(is); 01195 // int tmp; 01196 // is >> tmp; 01197 // is >> tmp; 01198 // is >> tmp; 01199 // is >> tmp; 01200 // is >> tmp; 01201 // is >> tmp; 01202 // is >> tmp; 01203 // is >> tmp; 01204 // eatwhite(is); 01205 // is >> tmp; 01206 // printf("Number of vertices: %d\n", tmp); 01207 // while (!is.eof()) { 01208 // double x, y, z; 01209 // is >> x; 01210 // is >> y; 01211 // is >> z; 01212 // //printf("point: %f %f %f\n", x, y, z); 01213 // pcloud.push_back(vector3t<float>(x, y, z)); 01214 // eatwhite(is); 01215 // } 01216 } catch (std::exception& e) { 01217 CRIT_ERR(printf("Error occured while reading curve: %s\n", e.what())); 01218 } 01219 is.close(); 01220 printf("pcloud size is now %d\n", pcloud.size()); 01221 } 01222 i++; 01223 break; 01224 01225 // case 'r': 01226 // // Set refinement factor. Default value is ???. 01227 01228 // puts("Reading surface refinement factor"); 01229 // ref=atoi(argv[i+1]); 01230 // i++; 01231 // break; 01232 01233 // case 'R': 01234 case 'r': 01235 // Set max refinement factor. Default value is ???. 01236 01237 puts("Reading upper bound for surface refinement."); 01238 maxref=atoi(argv[i+1]); 01239 i++; 01240 break; 01241 01242 case 'e': 01243 // String with keypresses to execute follows. Not 01244 // everything will work! 01245 01246 printf("Executing '%s'.\n", argv[i+1]); 01247 strncpy(init_key_string, argv[i+1], 1000); 01248 i++; 01249 break; 01250 01251 default: 01252 puts("Huh?! Unknown option."); 01253 exit(0); 01254 01255 } 01256 } 01257 } 01258 01259 01260 01261 01262 01263 int main(int argc, char *argv[]) 01264 { 01265 if (argc == 1) { 01266 // program called with no arguments. Show info 01267 show_general_help(); 01268 return 0; 01269 } else if (argc == 2 && 01270 (std::string(argv[1]) == "hotkeys" || std::string(argv[1]) == "HOTKEYS")) { 01271 show_hotkey_help(); 01272 return 0; 01273 } 01274 xscale=yscale=zscale=1.0; 01275 int i; 01276 01277 01278 for (i=0; i<MAX_SURFACES; i++) 01279 { 01280 surface[i]=NULL; 01281 normal[i]=NULL; 01282 } 01283 for (i=0; i<MAX_CURVES; i++) 01284 curve[i]=NULL; 01285 01286 for (i=0; i<MAX_CURVES; i++) 01287 discr_curve[i]=NULL; 01288 01289 read_curves_and_surfaces(argc, argv); 01290 01291 { 01292 int tx=32, ty=32; // gl_init needs variables, but doesn't do 01293 // anything when texfile==NULL. 01294 #ifdef MICROSOFT 01295 gl_init(argc, argv, 500, 500, 180, 100, true, 01296 #else 01297 gl_init(argc, argv, 1100, 1100, 460, 20, true, 01298 #endif 01299 1, GL_TRUE, 1, GL_TRUE, 01300 xtrans, ytrans, ztrans, 01301 // xscale, yscale, zscale, tx, ty, NULL); 01302 xscale, yscale, zscale, tx, ty, 01303 // GL_MODULATE, 01304 // GL_BLEND, 01305 GL_DECAL, 01306 NULL // NULL produces a frame. 01307 // "greyclouds3.pgm" // A texture. 01308 ); 01309 } 01310 01311 // 01312 // This will have the same effect as pressing 'tab'+'d'. 01313 // 01314 if (surfaces>0) 01315 { 01316 int i; 01317 01318 selected_surface=0; 01319 for (i=0; i<surfaces; i++) 01320 surf_enabled[i]= 1 ; //(i==selected_surface); 01321 } 01322 01323 // 01324 // This will have the same effect as pressing 'space'+'ctrl-d'. 01325 // 01326 if (curves>0) 01327 { 01328 int i; 01329 01330 selected_curve=0; 01331 for (i=0; i<curves; i++) 01332 curve_enabled[i]=1; // (i==selected_curve); 01333 } 01334 01335 glPolygonOffset(1.0, 1.0); 01336 glEnable(GL_POLYGON_OFFSET_POINT); 01337 glEnable(GL_POLYGON_OFFSET_LINE); 01338 glEnable(GL_POLYGON_OFFSET_FILL); 01339 01340 glutReshapeFunc(Reshape); 01341 glutKeyboardFunc(Key); 01342 glutMotionFunc(MouseRotate); 01343 glutMouseFunc(Mouse); 01344 glutDisplayFunc(draw); 01345 glutIdleFunc(idle_func); 01346 01347 scale(0.5, 0.5, 0.5); 01348 glEnable(GL_NORMALIZE); 01349 01350 01351 parse_keys(0, 01352 (const unsigned char *)init_key_string, 01353 strlen(init_key_string)); 01354 01355 // making sure loaded object is centered 01356 //parse_keys('o'); // doesn't work as expected 01357 01358 01359 glutMainLoop(); 01360 01361 return 0; 01362 }
Generated on Tue Sep 21 17:28:53 2010 for SISL by  doxygen 1.6.3